HsUSBD Proper Read-out method for Bulk-OUT EPs

Post Reply
Posts: 2
Joined: 18 Apr 2017, 16:39

09 Jan 2019, 09:24

Dear fellows,

I've been working on my HsUSB device implentation project.
Now facing at problem in read-out process for BulkOut endpoint,
especially in a case where ...
  • Buffer memory allocation size for that Endpoint :
    Due to enjoy better USB transaction in bus utilization point of view,
    NYET/PING should be happened as less as possible.
    If I allocate buffer memory just for one packet size, the Endpoint
    should always respond with NYET, no chance to respond with ACK,
    and makes a Host invoke PING at the next time it wants to send
    another packet.
    At least the twice packet size of memory should be allocated for
    those endpoints if I want to supress NYET/PING occurence.
    So, I allocated 1KB for an Bulk Ep described as whose max packet size
    is 512 bytes.
  • Read-out process to be delayed as the decvice firmware can process:
    The corresponding recieving data process may take variable times.
    Or, even delayed to relinquish CPU for other higher priority tasks.
    Even in such case, USB's handshake mechanism should work
    When a new data packet is sent to the device during the several
    unprocessed received data is still left in the endpoint FIFO, endpoint
    control mechanism of USB device for bulk out should work fine.

    So, my interrupt handler for HsUSBD is just signaling the fact of
    new data reception to the consumer task, clear RXPKIF immediately
    and simply returns.
    Certain time later, the consumer task is then invoked and it
    starts reading-out the recieved data one by one from the allocated
    endpoint buffer inside HsUSBD block at consumers processing pace.
    When the final data is read-out by the consumer task, then the Endpoint
    controller can decide to change its handshake for the next reception.
    e.g., if allocated buffer is completely empty, then next responce can be ACK.
    if still some are left, then NYET (or NAK) respectively.

    In this implementation, how the consumer task can know the emptiness
    after at each read-out process
I have tried two different ways, but neither in success....
One is checking EPxDATCNT after reading EPxDAT and another is
checking BUFEMPTYIF flag after reading EPxDAT.

I've already confirmed that as long as the consumer task is
keeping up (no more than one packet is held in Ep buffer, responding always by ACK), both
method work as expected, the same successful results.
But, it once goes behind (another new packet is recieved,
responded with NYET, during the data in the first packet is
still unread completely)

I've also confirmed that EPxDATCNT indicates more than 0x200 when
another packet is received while the first one is not read-out.

The problem I experienced for the former method is ...
BUFEMPTY never arise after it once respond with NYET (or received PING).
So, the consumer process can never proper end of received data and
the process goes on working in endless-loop....

In case of the later method,.....
EPxDATCNT is decremented by 4 at each word-readout access, but
never goes down thru 0x200 to approaching zero.
So, also in the case by this method, the consumer process can NOT get out from
the endless loop.....

By the way, the my implementations described above may include some
challenges which the technical reference manual does not explain detail.
So, I may misunderstand very basic behavior about this HsUSBD HW block.

I allocated twice size memory for an bulkout endpoint to suppress
NYET/PING. I confirmed it seems to be working well....
Is this a proper ways to get expected response behavior for the HsUSBD HW block?

I immediately clear RXPKIF before reading out from EPxDATA and
let the HsUSBD's Endpoint control mechanism continure to respond
to the new USB TOKENs properly.
Is the really OK for that HsUSBD HW block ?

Any comments is welcome.


Dylan Hsieh
Posts: 21
Joined: 22 Mar 2017, 09:54

09 Jan 2019, 19:09

Hi Kojima-san,

According to HSUSB specification if Endpoint buffer have no enough space to store the one packet size, NYET will be returned. Allocate twice size memory (in your case 512K x 2 = 1K Bytes) to suppress the NYET/PING is correct way.

To let the USB transfer more efficiency, I suggest using the DMA to read out the RX data from Endpoint buffer :
Each DAM transmission is 512 bytes, when transmission is finish DMA will issue a interrupt so that you can know when the RX data totally read out.

For the HUSBD DMA operation, please visit the link as below:
https://github.com/OpenNuvoton/M480BSP/ ... VENDOR_LBK

Thanks ;)

Post Reply
  • Information
  • Who is online

    Users browsing this forum: No registered users and 1 guest