Skip to main content
RRajb.2
Associate III
August 7, 2023
Question

USB Host Bulk Input NAK || STM32U575

Hi All,

I am working on the STM32U575 for host mass storage class.

I am not using stm32 middle ware for this due to some reasons.

I am using TinyUSB open-source stack to implement the Host mass storage class.

with my current implementation I am able to use HID device, but I got stuck at MSC enumeration.

Currently facing below issue.
1. During enumeration process After sending the Unit Test Ready Command I am getting correct CSW
response from device but soon after that Getting NAK from USB device.
-- What could be the reasons for getting the NAK - Also I after getting NAK I am continuously getting Channel halted interrupt.

I have attached the logic analyzer file for batter understanding.

Any Help will be highly appreciated!

This topic has been closed for replies.

19 replies

RRajb.2
RRajb.2Author
Associate III
August 13, 2023

Hi, any one from ST can please respond to above query? It will be great help.

STOne-32
ST Technical Moderator
August 13, 2023

Dear @RRajb.2 ,

a NAK means the Firmware stack not able to respond in required timing to an IN packet, so most probably the state machine  of the stack seems in a wrong state before or when responding to the Unit Test ready command , therefore all next transactions are halted . I would suggest to try to comment that command in the stack for debugging purposes and see if the issue is happening in the command just before ? Another check to use another USB key or any other mass storage device to check if such commands are supported.  I’m not expert of USB just to give some pointers. Hope it helps you.

Ciao

STOne-32

ACapo.1
Associate III
December 13, 2023

@RRajb.2 

Did you find a reason for this?

I am seeing exactly the same thing, basically the second command always fails.

I can Send "Unit test ready", works fine. Then send it again and just NAKs.

Cheers

Andy

RRajb.2
RRajb.2Author
Associate III
December 13, 2023

ACapo.1 not sure if the root cause will be same for you or not? as in my case I was using our own implementation for developing low level USB drivers, we were not using cube MX.

but any how, the root cause was related to the size of data bytes. as after unit test ready command, when we were trying to send next command which was having data bytes more then 256 bytes, USB device was giving NAK.

to overcome this issue, we were sending the data in chunk of 256 bytes.

ACapo.1
Associate III
December 13, 2023

Hi @RRajb.2 

Thanks for the super fast response.

Looks like it is possibly a different issue then as I have a test setup here just sending the same command twice.

Driving me mad!

 

Thanks

Andy

RRajb.2
RRajb.2Author
Associate III
December 13, 2023

which code are you using??? CubeMX generated code?

ACapo.1
Associate III
December 13, 2023

The HAL_HCD_HC_ stuff.

So the TinyUSB hcd code is using:

HAL_HCD_Init

HAL_HCD_Start

HAL_HCD_HC_Init

HAL_HCD_HC_SubmitRequest

 

And the following callbacks:

HAL_HCD_Connect_Callback

HAL_HCD_Disconnect_Callback

HAL_HCD_SOF_Callback

HAL_HCD_HC_NotifyURBChange_Callback

 

Interestingly I have just tested a midi controller using BULK EPs and that is working fine.

The example TinyUSB MSC example though is not working.

RRajb.2
RRajb.2Author
Associate III
December 13, 2023

Okay so you are also using the same tinyUSB stack, so Mostly you might have used the same driver file which I used.

 

STM32F7xx Host driver (github.com)

 

I was also able to use the MIDI initially and then facing the issue with bulk driver only.

for tinyUSB driver file you should handle data in chunk for length more then 256 byte.

Also

under HAL_HCD_HC_NotifyURBChange_Callback function()

currently endpoint toggle is unconditional,

   ep->toggle = (hc->ep_is_in) ? hc->toggle_in ^ 1 : hc->toggle_out;
change it to.
    if (hc->ep_type == EP_TYPE_INTR)
    {
      ep->toggle = (hc->ep_is_in) ? hc->toggle_in ^ 1 : hc->toggle_out;
    }
ACapo.1
Associate III
December 13, 2023

Thanks very much for the help on this.

Yes I based it on that code, changed slightly for the H7

The ep->toggle is currently conditional in HAL_HCD_HC_NotifyURBChange_Callback(), or are you saying it should be in _endpoint_xfer() as well?

Not transferring > 256 either, currently I have it forced to FS so it is dealing with 64 byte packets. Unless I am misunderstanding?

 

SCSI Test Unit Ready
[1] Claimed EP 0x02
 Queue EP 02 with 31 bytes ... 
hcd_edpt_xfer on pipe for devaddr:1 epaddr:02 in slot 8, ep_type 2, ep_dir 0, len 31
***** HAL_HCD_HC_Init ch_num = 8, epnum = 2, dev_address = 1, speed = 1, ep_type = 2, mps = 64
***** HAL_HCD_HC_SubmitRequest ch_num = 8, direction = 0, type = 2, token = 1, length = 31, do_ping = 1
BULK OUT
55 53 42 43 42 53 55 54 00 00 00 00 00 00 06 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
OK
Transfer SUCCESS devaddr 01 ep:02 31 bytes, channel 8
on EP 02 with 31 bytes: OK

MSC xfer callback
 Queue EP 81 with 13 bytes ... 
hcd_edpt_xfer on pipe for devaddr:1 epaddr:81 in slot 7, ep_type 2, ep_dir 1, len 13
***** HAL_HCD_HC_Init ch_num = 7, epnum = 129, dev_address = 1, speed = 1, ep_type = 2, mps = 64
***** HAL_HCD_HC_SubmitRequest ch_num = 7, direction = 1, type = 2, token = 1, length = 13, do_ping = 1
BULK IN
OK
Transfer SUCCESS devaddr 01 ep:81 13 bytes, channel 7
on EP 81 with 13 bytes: OK

MSC xfer callback
SCSI Read Capacity
[1] Claimed EP 0x02
 Queue EP 02 with 31 bytes ... 
hcd_edpt_xfer on pipe for devaddr:1 epaddr:02 in slot 8, ep_type 2, ep_dir 0, len 31
***** HAL_HCD_HC_Init ch_num = 8, epnum = 2, dev_address = 1, speed = 1, ep_type = 2, mps = 64
***** HAL_HCD_HC_SubmitRequest ch_num = 8, direction = 0, type = 2, token = 1, length = 31, do_ping = 1
BULK OUT
55 53 42 43 42 53 55 54 08 00 00 00 80 00 0a 25 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
OK
Transfer SUCCESS devaddr 01 ep:02 31 bytes, channel 8
on EP 02 with 31 bytes: OK
MSC xfer callback
 Queue EP 81 with 8 bytes ... 
hcd_edpt_xfer on pipe for devaddr:1 epaddr:81 in slot 7, ep_type 2, ep_dir 1, len 8
***** HAL_HCD_HC_Init ch_num = 7, epnum = 129, dev_address = 1, speed = 1, ep_type = 2, mps = 64
***** HAL_HCD_HC_SubmitRequest ch_num = 7, direction = 1, type = 2, token = 1, length = 8, do_ping = 1
BULK IN
OK

 

So that is what I see with the MSC example

SCSI Test Unit Ready : 31 bytes out, then 13 bytes back.
SCSI Read Capacity : 31 bytes out, no bytes back and NAK nightmare.

 

RRajb.2
RRajb.2Author
Associate III
December 13, 2023

Sorry my bad, you have to change in _endpoint_xfer() function only,

if (ep->ep_type != 2)

{
    uint8_t *toggle = (hc->ep_is_in) ? &hc->toggle_in : &hc->toggle_out;
    *toggle = ep->toggle;
}
 
RRajb2_0-1702466054192.png

 

I kept one more check in HAL_HCD_HC_NotifyURBChange_Callback(), but it was for some other purpose.

regarding handling of data more then 256 bytes(rather size more then wMaxPacketSize), you will face that problem may be after making this change. because that is not handled currently in that driver file.

ACapo.1
Associate III
December 13, 2023

Great thanks for that, I will change that in _endpoint_xfer()...

ACapo.1
Associate III
December 13, 2023

Hi @RRajb.2

That _endpoint_xfer() change brings it all to life, thanks very much.

If I have the USB inited as HS then both FS and HS devices work fine, I do not get the issue with the transfers being bigger than the packet size.

With it inited as FS then I see the issue that you mention with HS devices, but strangely FS devices work even though the transfers are bigger than the packet size.

Very strange!

Once again thanks for all your help on this, it is really appreciated.

Andy

Piranha
Principal III
December 14, 2023
ACapo.1
Associate III
December 14, 2023

Hi @Piranha 


But there is no host support which is what we are talking about.

Piranha
Principal III
December 15, 2023

OK, but then it would be even better to implement that driver at a somewhat decent level and upstream it to the TinyUSB project. :)