2025-09-05 8:25 AM
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:
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:
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:
Solved! Go to Solution.
2025-09-09 8:15 AM
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:
2025-09-05 11:51 AM
Use Wireshark to be sure the software is sending the checksum, just to rule that out.
2025-09-05 12:16 PM
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.
2025-09-09 8:15 AM
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: