Hello,
Sometimes, my controller hangs after being polled by a CDC connection. I see when I debug the ISR that my device status registers contains the vale 0x41 (11110001), which can be interpreted using the following data sheet table:
bit0 The frame interrupt occurs every 1 ms. This is used in isochronous packet transfers. bit1 Fast endpoint interrupt. If an Endpoint Interrupt Priority register (USBEpIntPri) bit is set, the corresponding endpoint interrupt will be routed to this bit. bit2 Slow endpoints interrupt. If an Endpoint Interrupt Priority Register (USBEpIntPri) bit is not set, the corresponding endpoint interrupt will be routed to this bit. bit3 Set when USB Bus reset, USB suspend change or Connect change event occurs. Refer to Section 13â€"11.6 “Set Device Status (Command: 0xFE, Data: write 1 byte)†on page 366. bit4 The command code register (USBCmdCode) is empty (New command can be written). bit5 Command data register (USBCmdData) is full (Data can be read now). bit6 The current packet in the endpoint buffer is transferred to the CPU. bit7 The number of data bytes transferred to the endpoint buffer equals the number of bytes programmed in the TxPacket length register (USBTxPLen).
I don't fully understand why this is happening (it just appears after some time; no endpoint is triggered anymore as a result). Windows issue? software failure? Thanks in advance
oops. that's what I meant...0xF1 !
Just from the device status register, the cause isn't specified.
What do you mean CDC connection is broken? No transfer goes to PC, or comes from? Or read or write on the COM port shows error on the PC application?
Some related matters are,
a) End of IN transfer on the CDC bulk IN endpoint - ZLP (Zero-Length Packet) When the transfer ends with a full-packet (64 bytes), ZLP is always required to terminate the transfer.
b) Extra ZLP for IOCTL_SERIAL_WAIT_ON_MASK - usbser.sys When the PC app waits for income of data on IOCTL_SERIAL_WAIT_ON_MASK, long delay may be observed after the device sends data over the bulk IN EP. Extra ZLP speeds up the process on usbser.sys
c) Weak recovery from noise - usbser.sys Noise on the bus easily makes bulk IN traffic hang on usbser.sys Reset the device driver with IOCTL_SERIAL_RESET_DEVICE
Tsuneo
OMG.
The sort of mistake that can result in lost lives!
Hello Tsuneo,
I did not yet recreate this problem while a sniffer hangs on the bus. however, I can say that the device's endpoints are never triggered once it goes wrong (however, I have here a system running all night long without a failure). the ISR in the device is triggered, it is only that the endpoints are not. I did not write the PC side application so I cannot tell what its serial calls return...
Reset the device driver with IOCTL_SERIAL_RESET_DEVICE
I understand that this can only be done fro the PC side...? Not being a USB expert, how can I send a ZLP packet using Keil's software? is attempt to send an empty buffer good enough?
Come on, man, get a life...
One for the epitaph?
Look, I really don't have time to start one of these quarrels now (busy busy busy busy X 100^123, that is far more that the number of particles in the known universe). I would suggest you address Cpt. Vince for a Greek/Latin lesson (he made a few funny "fishy" remarks in Latin in the past; search the forum!).
Look, I really don't have time to start one of these quarrels now
Clearly your sense of humour is less well developed than your engineering skills.
I'll take that is a compliment.
I meant: I'll take that as a compliment (but I doubt whether it was intended that way. whatever.)
The interaction between human beings is very complicated. If Per says that, I believe Tamir will take that as a friendly kidding.
Tamir,
> how can I send a ZLP packet using Keil's software? is attempt to send an empty buffer good enough?
That's right.
USB_WriteEP(EP_address, NULL, 0); // put ZLP to EP
> no endpoint is triggered anymore as a result
In most case of CDC firmware, EP interrupt is used just to raise a flag. Your firmware polls this flag and processes data, in your main line superloop, or timered polling, or in an ISR other than USB (timer, ADC, ...). For IN EP, your firmware checks this flag to know the EP buffer is empty. And then, it passes data to the EP. For OUT EP, your firmware knows data is sent from host by this flag. And then, it unloads the data from the EP and processes the data.
When the firmware sends/receives large data more than wMaxPacketSize (64 bytes) at a time, the first packet is handled like above, but the second and more packets are handled in the EP ISR.
In this way, your firmware can process USB traffic at the timing as it likes. It straightens the code flow, makes your life easy.
When USB_WriteEP() and USB_ReadEP() is called from mainline code, guard these calls disabling USB interrupt around the calls. Or, apply SWI for these calls. It was discussed once in this topic. http://www.keil.com/forum/docs/thread15613.asp
Thanks a lot Tsuneo!
It may surprise you, but it was.
Please don't allow that to have any influence on the way you respond to my posts, however. I always welcome criticism.
I appreciate that. Thank you.
'scuse me while I just throw up.