hi to all, i am emulating a usb floppy, and i decide to use keil usb middleware with custom class(usb floppies most implement ufi class and it dose not implemented by keil) to done this project, but i have a problem with that. in some place host driver decide to reset bulk in and out pipes, and as result it will reset host data toggle to DATA0 without sending any CLEAR_FEATURE to reset device data toggle. below table is part of usb communication dump of my device:
device-endpoint phase data desc 12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 23 00 00 00 00 00 00 00 fc 00 00 00 control-data 12.2 in 00 00 00 08 00 00 0b 40 03 00 02 00 bulk-in 12.1 in 00 00 interrupt-in 12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 00 00 00 00 00 00 00 00 00 00 00 00 control-data 12.1 in 3a 00 interrupt-in 12.2 reset reset bulk pipe 12.2 reset reset bulk pipe 12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 03 00 00 00 12 00 00 00 00 00 00 00 control-data 12 SSTS timeout 12 SSTS request flushed 12 reset bus reset 12 ok
as you can see every thing is ok until host decide to reset bulk pipes and as result it reset host toggle but device toggle is DATA1 and as result next data transfer in bulk in endpoint will timeout and then host reset usb pipe and this is my problem. i know that this is mistake by host, but i know where host reset pipe and now i am searching for a way to reset data toggle of my device bulk endpoints. i did not find any function or utility in keil usb middelware api to reset data toggle. now any one know any way to done that???
You are right there is no way to reset the endpoint data toggle from user API.
There are 2 suggestions: 1. you should investigate why host resets the bulk endpoints as that usually means host has detected that something is not right, or is is not getting expected responses, so by addressing the problem you should prevent host from resetting the bulk endpoints 2. Write directly to your microcontroller's USB controller and reset data toggles
hi Milorad and thanks for response, i know why host try to reset pipes, ufi spec has command with opcode 0x00(test unit ready) and when host send this command to device, device must return an 2 byte status code to host, when there is no floppy in floppy drive device must sent 0x3A 00 in interrupt endpoint to indicate that there is no media in floppy drive(i see this in original floppy drive communication dump that i want to emulate)and after that host reset pipes and after that host sent another commands(because original floppy drive reset bulk toggle in this situation it work after that but i do not). now i think cmsis_usb_device driver must has any api to done that, i am going to test that.
What is your response on bulk IN endpoint on Host requesting TestUnitReady on bulk OUT endpoint?
As ufi specifications specified TestUnitReady command send only status on interrupt endpoint and do not need send anything on bulk in endpoint, and when i sniff original floppy drive(y-e data floppy drive), it act as i describe.
The only thing besides directly accessing USB controller is trying to stall and then un-stall the bulk endpoints (function USBD_EndpointStall) as un-stall should clear data toggle.
Hi Alireza and Milorad,
A) Wrong sequence In your log, just before the host put pipe-reset, the host puts TUR (Test Unit Ready) command
12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 00 00 00 00 00 00 00 00 00 00 00 00 control-data <-- TUR 12.1 in 3a 00 interrupt-in <-- wrong
In above sequence, your device sends error code to the interrupt IN EP, maybe because no media is mounted. It is the wrong part. - Your device should STALL the Control transfer at the STATUS stage, to make the host know that the command (TUR) fails. - And then, the host should pass REQUEST SENSE (RS) command, immediately. - - Your device returns sense data block of Sense Key - ASC:ASCQ = 02 - 3A:00 (NOT READY - MEDIUM NOT PRESENT)
Supposed sequence is as follows,
12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 00 00 00 00 00 00 00 00 00 00 00 00 control-data <-- TUR <-- STALL should be reported 12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 03 00 00 00 12 00 00 00 00 00 00 00 control-data <-- RS 12.2 in 70 00 02 00 00 00 00 0A 00 00 00 00 bulk-in <- sense data 3A 00 00 00 00 00 12.1 in 00 00 interrupt-in
B) Pipe reset
> host driver decide to reset bulk in and out pipes, and as result it will reset host data toggle to DATA0 without sending any CLEAR_FEATURE to reset device data toggle.
You are monitoring on a software sniffer (bus hound?). Software sniffers can't catch CLEAR_FEATURE(ENDPOINT_HALT) request on the bus, which is issued by USBDI (low-level system driver) as the result of pipe-reset request. Software sniffers catch the USB requests just at the entry of USBDI. They can't catch transfers under USBDI.
I believe the host should send CLEAR_FEATURE(ENDPOINT_HALT) to your device.
Tsuneo
Hi Tsuneo,
I'm not sure that procedure is ok, as in case that you suggest you actually signal that command block has failed which would most likely cause host to execute Command Block Reset.
I would rather suggest that status "3a 00" that is returned on interrupt endpoint is wrong and that it should actually be "00 01" which would signal that TestUnitReady failed and host will probably ask for ReqestSense to get the reason of failure.
This seems same as what happens on BOT MSC device after TestUnitReady fails host executes RequestSense.
hi Tsuneo, i follow your advice in section A, and YESSSSSS-it worked and there is no any timeout(because there is no any pipe reset) and windows explorer currectly report floppy dose not exist. because i follow just y-e data floppy and implement behavior of that(it dose not stall in control endpoint and return 0x3A 0x00 on interrupt endpoint), i done in that manner and just return 0x3a 0x00 on interrupt endpoint. > You are monitoring on a software sniffer (bus hound?). Software sniffers .... yes i use bus hound sniffer under windows and as you say it dose not show low level packets(i did now that,i am new in usb) and host send CLEAR_FEATURE request during pipe_reset, i saw that with filtering setup packet in USBD_Device0_Endpoint0_SetupPacketReceived function with CLEAR_FEATURE and breakpoint on that.
and hi milorad, > I would rather suggest that status "3a 00" that is returned on interrupt endpoint is wrong and that it should actually be "00 01" which would signal that TestUnitReady failed and host will probably ask for ReqestSense to get the reason of failure. cbi spec indicate interrupt endpoint block for ufi device must be like below :
byte0 -> ASC byte1 -> ASCQ
and 0x00 0x01 is not valid ASC ASCQ sequence(as defined in ufi spec), anyway i apply your advice and again host after receiving that reset pipes and again timeout occur.
and after that i again think that timeout occur because DATA toggle mismatch, (www.dropbox.com/.../mydevice.txt this link is my device communication dump with host, in that i add to column that indicate expected host data toggle and sent data toggle by device(with assuming that data toggle of bulk endpoint dose not reset in reset pipe), and as i indicated in that dump in follow of mismatch, timeout occur and sometime accidentally data toggles are match, communication is ok and any timeout dose not occur. (www.dropbox.com/.../y-e_floppy_absent_windows10.txt floppy drive communication that may be helpful. and this my function that will handle read capacity command that will stall bulk endpoint when floppy dose not exist :
//ReadCapasity op code is 0x25 void HReadCapacity(void) { if(FloppyExist == present) { .. } else { USBD_EndpointStall(0, USB_ENDPOINT_IN(BULK_IN),true); SendSenseData(); } }
another thing that astonished me, is that after reset pipe condition stall condition is still present.
device-endpoint phase data desc 12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 25 00 00 00 00 00 00 00 00 00 00 00 control-data 12.2 USTS c0000004 stall pid 12.2 reset reset bulk pipe 12.2 reset reset bulk pipe 12.0 ctl 21 00 00 00 00 00 0c 00 control-setup 12.0 out 03 00 00 00 00 00 00 00 00 00 00 00 control-data 12.2 USTS c0000004 stall pid 12 SSTS 0e bus reset
in above table, at first host send command with op code 0x25(READ_CAPACITY) and because there is no media i stall bulk endpoint in order to fail command,after host reset bulk endpoints(and send CLEAR_FEATURE request, i can see these commands in debug mode) and then send 0x03(REQUEST_SENSE) command, still stall condition present(i stall bulk in endpoint once during handling of READ_CAPACITY command and after that reset pipe occur). i can not imagine what is the problem !!!??
Hi Alireza,
regarding response on interrupt endpoint you are using bInterfaceSubClass = 04h device which I was not aware of.
Anyways, correct way of handling your current problem is to catch CLEAR_FEATURE request, and call USBD_EndpointStall with parameter stall = 0 to clear halt condition on your bulk endpoint. BTW, that procedure would have already worked on your initial problem also if you did stall the bulk endpoint on TestUnitReady request then host sent CLEAR_FEATURE in which case you would un-stall the bulk endpoint and that should also reset the data toggle bit.
thank you very much Milorad, your advice work and my problem solved.
> this my function that will handle read capacity command that will stall bulk endpoint when floppy dose not exist
C) READ CAPACITY (0x25), READ FORMAT CAPACITY (0x23)
While no media is inserted, READ CAPACITY should be STALLed at the STATUS stage of the ADSC control transfer, like above TEST UNIT READY case. For the REQUEST SENSE just after this command, the same sense data block (NOT READY - MEDIUM NOT PRESENT) should be returned.
READ FORMAT CAPACITY is differently answered: To the bulk IN transfer, a data block of Capacity List Header + Maximum Capacity Header is returned.
00 00 00 08 Header: Capacity List Length 00 00 0B 40 Max cap descriptor: Number of blocks (2880) 03 Max cap descriptor: Descriptor code (No media) 00 02 00 Max cap descriptor: Block Length (512)
I'm just curious, do you actually try these things on real hardware, or are you just reading specifications?
Your answers are generally very detailed, exact and work, so I was just wondering how do you do it? (or a magician never reveals his secrets :-) )
Best regards, Milorad
P.S. Sorry Alireza for digressing
hi Tsuneo, as you said we can fail a request in status stage of ADSC control transfer, and also CBI spec indicated that we can fail a command in bulk stage of DATA IN TRANSPORT commands, and developer can choice one of them. and at end i accept miloarad opinion, you have huge knowledge about usb, i read your posts in other forums and i am also surprised how you do that.
thanks for your helps, best regard - alireza