Author Topic: Blackfin+ USB Driver  (Read 3142 times)

0 Members and 1 Guest are viewing this topic.

Online blueskull

  • Supporter
  • ****
  • Posts: 14197
  • Country: cn
  • Power Electronics Guy
Blackfin+ USB Driver
« on: August 03, 2017, 07:07:59 am »
---------- Sorry for the long text, but USB is that complicated! ----------

Hi all. I attempted to write a USB stack for BF707 2 years ago, and I failed, and I gave up on the project. Recently I decided to pick it up from where I left, but I didn't make much progress.

I wonder if there are anyone here that has USB development experience can can point me a path.

So basically due to the marketing decision (they sell $8000 uC-OS3 license), they don't provide non-OS USB drivers for their new BF+ processors (using Mentor graphics OTG USB core with on die PHY).

What I was doing so far was to crack the license verification of their uC-USB installer and extract the source code, then reverse engineer the driver.

What the uC-USB driver told me is how do they call driver functions provided by ADI low level driver (shipped for free with CCES), and I tried to mimic the calls.

So far, I am able to initialize USB, see bus events (suspend, resume, HS chirp), and I'm able to receive setup packets (from EP0). I'm able to respond with corresponding descriptors requested, and I can see the ADI low level driver calling TX complete callback.

However, Windows will not complete the enumeration process and it will stuck on get device descriptor, suspend device and resume device. Windows will try that 4 times and then it will give up enumerating device.

Since Windows never passed get device descriptor stage, all I can see from EP0 is that request, and so far I reply the 18 byte descriptor and a ZLP, then Windows suspends the device.

Since USB HS requires DMA and async calling, I actually wrote a URB scheduling queue, which is basically a dual port ring buffer with underflow and overflow detection, and the USB interrupt causes new reply URBs to be added to queue, and my main loop sends pending URBs to corresponding endpoints (currently only EP0) whenever endpoint is free.

I inserted printf() calls in a lot of places, and I can see the URBs are indeed being sent to USB low level driver core, and I can see the EP data TX interrupt being called twice in correct sequence (data, then ZLP).

Now, what should I do to keep the development process going?

I've already ordered a USB bus analyzer, but that will take some days to arrive, say next Monday or so, and I don't want to waste this weekend.

I would like to know if there are any free or paid (with trial period, I only need it until my LeCroy T2 arrives) software analyzers that can capture USB packets before enumeration (I tried HHD, but it only allows the analyzing of existing device. It does have a next inserted device analyzing function, but it doesn't work on my PC). I tried USBtrace, with nothing but BSOD and instant license expiration after reboot.

For whatever reasons, USBPcap didn't capture early enumeration of my device, though it can capture for some other devices from first setup packet. Weird.

---------- OT start ----------

BTW, the ultimate goal is to develop a USB audio class 2.0 application (24 bit, 192kHz) to challenge the absolute market share of XMOS. All XMOS devices I own (both from top HiFi manufacturers, namely, a Sony PHA-3, an Apogee Groove and a Bladelius USB DAC) suck at warm boot reliability. They won't enumerate, or enumerate without being able to play sound, after a warm boot (device plugged to a powered USB port after computer shut down).

My goal is to build a single chip solution based on BF70x that does:
1. USB audio class 2.0 communication
2. Interpolation to 12.288Msps (44.1k/88.2k/176.4k->48k/98k/192k, then 48k/96k->192k, then 192k->768k, then 768k->3072k, then 3072k->12288k)
3. Dither and reduce to 4-bit (sigma delta modulation)

The modulated audio bitstream will be DA converted using two (one per channel) 4-bit DACs, LPFed, and amplified to reconstruct analog signal. The goal is to implement essentially the functionality of ES9038 (the best audiophile DAC nowadays in terms of measured figures) from ground up.

Now, I have the DSP code written, optimized and profiled, and it's prove to work on BF70x at 400MHz with less than 80% CPU usage. I'm now stuck at getting audio signal from the computer, which is the USB part.

Before anyone jumps in the discussion whether 24/192 is worth it, I can tell you it's bullshit, high sample rate is only needed for easing LPF design, not to preserve more audio data, but that audiophile market really likes this idea, and I have to implement it. Also, it's mandatory to support >40kHz analog bandwidth in order to get Sony Hi-Res certification.

I can't teach my target audience how SDM and DAC works and DSP theory, as not everyone with $-4 figure on audio DAC has a degree in math or EE. What I can do is to make the product they like, and polish it so that it's a piece of engineering marvel.

This project is also sentimental to me because it's been my side project along my entire PhD career (my PhD career is on power electronics, nothing DSP related, so it's just a hobby). The BF70x part is only part of the project, the rest is an ASIC based on OnSemi C5N for the 4-bit DAC, another ASIC for power regulation and a digital audio player front end based on iMX6ULL (which is what I was working on this spring). Since I just passed my prelim exam today, I figured I can pace down a bit on my PhD research and spend some time on my side projects.

---------- OT end ----------

Thanks a lot.

Update 09/25/17: see post #6.
« Last Edit: September 25, 2017, 05:42:08 am by blueskull »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 6974
  • Country: us
    • Personal site
Re: Blackfin+ USB Driver
« Reply #1 on: August 03, 2017, 07:34:00 am »
Just a couple of quick things that stand out:
1. You don't need to send ZLP if you have sent the descriptor. This will probably trip windows off.
2. You need to send the requested number of bytes, not a fixed 18.
Alex
 

Online blueskull

  • Supporter
  • ****
  • Posts: 14197
  • Country: cn
  • Power Electronics Guy
Re: Blackfin+ USB Driver
« Reply #2 on: August 03, 2017, 07:36:47 am »
Just a couple of quick things that stand out:
1. You don't need to send ZLP if you have sent the descriptor. This will probably trip windows off.
2. You need to send the requested number of bytes, not a fixed 18.

1. I tried to send only descriptor whenever a data phase is expected, and a ZLP when a data phase is not required. Not working.
2. I sent MIN(sizeof(descriptor), bRequestLen[0]+bRequestedLen[1]<<number_eight /*<- stupid SMF formatting thing*/).
« Last Edit: August 03, 2017, 07:44:28 am by blueskull »
 

Online blueskull

  • Supporter
  • ****
  • Posts: 14197
  • Country: cn
  • Power Electronics Guy
Re: Blackfin+ USB Driver
« Reply #3 on: August 07, 2017, 10:59:47 pm »
I think I know the problem, but I don't know how to solve it.
My LeCroy T2 has arrived today, and I used it to sniff the bus.
My device returns NAK all the time, even if the host has sent infinite amount (9k+) of IN request.
After filtering away all NAK replies, the only sensible my device replies is a single ACK after receiving SETUP packet. That's it.

So, I still think there is something wrong in the USB driver part. I can't let my chip to send anything back to the host.
I already assembled the URBs and submitted them, but the low level USB driver doesn't like to send them, though I can receive a TX interrupt.

Any idea what's going wrong?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 6974
  • Country: us
    • Personal site
Re: Blackfin+ USB Driver
« Reply #4 on: August 07, 2017, 11:14:05 pm »
I'm not familiar with Blackfin USB peripheral, so just guessing. Did you acknowledge receipt of that SETUP packet so that corresponding hardware buffer is actually free?

And why not get rid of the USB driver and make your own? You are already handling significant part of the thing, it must be a pretty thin layer. You will have more control that way, or at least you will be able to look into status bits directly.
Alex
 

Online blueskull

  • Supporter
  • ****
  • Posts: 14197
  • Country: cn
  • Power Electronics Guy
Re: Blackfin+ USB Driver
« Reply #5 on: August 07, 2017, 11:33:54 pm »
And why not get rid of the USB driver and make your own? You are already handling significant part of the thing, it must be a pretty thin layer.

The "pretty thin layer" has some 8000 lines and it handles ACK, NAK, chirp detection, URB scheduling, DMA, mutex and interrupt.
It exposes an URB interface rather than raw register interface, so that I can program it from a very high level.
Anyway, even if I want to do the low level thing, I don't have access to MUSBMHDRC datasheet, and I have very limited knowledge in that particular USB controller IP core.
The ADI document on USB part is written to be very cryptic and it told me pretty much nothing.
 

Online blueskull

  • Supporter
  • ****
  • Posts: 14197
  • Country: cn
  • Power Electronics Guy
Re: Blackfin+ USB Driver
« Reply #6 on: September 25, 2017, 05:52:19 am »
Update after a long time:

Problem has been solved. Instead of a TXZLP, I'm actually supposed to send an RXZLP after each transaction for get requests, and TXZLP (TXZLP based on reverse engineering of uC-OSiii code, but actually an RXZLP works better for whatever reason) on set requests.
Then, I found that my DSP can't set USB address, which was caused by interrupt handling issues, and after writing a simple USB task scheduler and do all USB related calls in non-interrupt area, it works.
Now I can establish connection between host and device, and I can get my device to enumerate.

I will now start to refactorize my code, and to make it more maintainable, then add interface and endpoint support. Finally, I will add USB audio class 2.0 support and HID support.
I will post the refactorized USB core engine to ASI EZ forum, here and GitHub, just to make sure other people don't end up spending a few months of time and $1000+ worth of equipment to figure out how the damn USB works.
ADI intentionally made USB hard to use in order to sell uC-OSiii, and I hope my code serves a big F to their policy. I tried to ask on EZ zone and through email to ADI support, and all answers being I have to use uC-OSiii.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf