cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC Receive, missing last byte on incoming traffic

Raf-Per
Associate

Hi!

I'm having an issue with the CDC class for USB on my STM32L476 board. I am using the Receive function in usbd_cdc_if.c file to track incoming Modbus traffic from USB. I am noticing that when I write multiple registers (function code 0x10) to the slave using Modbus Poll Software, the incoming buffer always has the last byte as 00. Here are some images to help explain:

The following image is a Communication Log from Modbus Poll Software that shows the Modbus Frame being sent:

RafPer_0-1757085070088.png

Notice the highlighted portions, which are the CRC Lo and CRC Hi bytes. I also confirm with a USB sniffer program that these exact frames are being sent to the slave. Also note that the first frame is function code 0x06 (Write Single Register), and the remaining frames are function code 0x10 (Write Multiple Registers).

 

Now, here is the incoming Buf in usbd_cdc_if.c, printed to the terminal right away:

RafPer_1-1757085319060.png

Notice that for the first frame (Write Single Register), the CRC bytes at the end are intact and matches what we sent. Notice the remaining frames where I am having trouble with the last byte of the frame comes in as 00, which does not match what was sent by Modbus Poll.

This is causing write failures as the CRC check fails due to the frame not being complete.

Any ideas would be helpful!

 

Note: This USB CDC/Modbus implementation was started by another Engineer who has since left the company, so I am trying to take over and finish it, so forgive me if I'm not the most caught up to speed with the language and terminologies. 

 

Also, here is the receive function that is generating the terminal prints, in case this is useful:

RafPer_2-1757085820216.png

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Raf-Per
Associate

Thank you for the feedback! It's much appreciated and will take into consideration.

 

I wanted to share the change in stm32l4xx_ll_usb.c that ended up fixing the issue. In ST's GitHub, I found that this file was slightly different than mine was, so most likely we were using an outdated version.

Here were the changes that directly fixed the issue:

RafPer_2-1757430909388.png

RafPer_0-1757430822349.png

 

View solution in original post

3 REPLIES 3
Karl Yamashita
Principal

Use Wireshark to be sure the software is sending the checksum, just to rule that out. 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.
CAN Jammer an open source CAN bus hacking tool
gbm
Principal

Your code is incorrect. SetRxBuffer is not needed at all, bout this is not a problem. You should not call receive until you have processed the incoming data. ReceivePacket call enable reception of the next packet.  NOw CDC_Receive is called form USB interrupt. By calling printf you actually put the processor into a polling loop waiting for UART or some other interface which is a very bad idea. Moreover, your USB packet buffer may be overwritten by the next packet - and this happens while you are trying to display the buffer content using printf.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Raf-Per
Associate

Thank you for the feedback! It's much appreciated and will take into consideration.

 

I wanted to share the change in stm32l4xx_ll_usb.c that ended up fixing the issue. In ST's GitHub, I found that this file was slightly different than mine was, so most likely we were using an outdated version.

Here were the changes that directly fixed the issue:

RafPer_2-1757430909388.png

RafPer_0-1757430822349.png