2023-10-07 12:06 AM
Hello,
I am trying to transmit some data on my STM32F042F6P6. But my PC's serial monitor only picks up some of it. Here is the code and the serial monitor output:
void readAllRegs(void){
uint8_t value;
for (uint8_t addr = 0x00; addr <= 0x2E; addr++) {
value = readReg(addr);
printf("0x%x: 0x%x (%d) \n", addr, value, value);
fflush(stdout);
}
}
int _write(int file, char *ptr, int len){
CDC_Transmit_FS((uint8_t *)ptr, len);
return len;
}
0x0: 0x29 (41)
0x1: 0x2e (46)
0x4: 0xd3 (211)
0x6: 0xff (255)
0x7: 0x4 (4)
0xa: 0x0 (0)
0xd: 0x1e (30)
0x10: 0x8c (140)
0x13: 0x22 (34)
0x14: 0xf8 (248)
0x16: 0x7 (7)
0x19: 0x76 (118)
0x1a: 0x6c (108)
0x1d: 0x91 (145)
0x1f: 0x6b (107)
0x20: 0xf8 (248)
0x23: 0xa9 (169)
0x25: 0x20 (32)
0x26: 0xd (13)
0x29: 0x59 (89)
0x2c: 0x88 (136)
When I change the Tx buffer size from 128 bytes to 512 bytes, there is even more data loss:
0090
5f040x00 f80230x07406 :(
:(0210002(001xb
Can someone explain to me what is happening here? I thought CDC was reliable
Thank you
Solved! Go to Solution.
2023-10-08 08:20 AM
> Isn't the data supposed to be transmitted at full speed once CDC_Transmit_FS() is called, without data loss?
No :( USB device can send anything only when the host polls it. So CDC_Transmit_FS should not be called again until the previous call succeeds. Else it will stomp on the previously sent data and data loss will occur.
2023-10-07 07:18 AM
CDC is reliable if used correctly. Where have you found this implementation of _write? Look for good examples.
2023-10-07 02:22 PM
I don't think the problem is _write. I modified the function and removed _write:
void readAllRegs(void){
uint8_t value;
for (uint8_t addr = 0x00; addr <= 0x2E; addr++) {
//value = readReg(addr);
//printf("0x%x: 0x%x (%d) \n", addr, value, value);
//fflush(stdout);
uint8_t strings[] = "register \n";
value = addr + 48;
CDC_Transmit_FS(&value, 1);
CDC_Transmit_FS(strings, sizeof(strings));
}
}
Now there is no _write, but the results are similar: the loop is supposed to run 0x2E times, and my PC's serial monitor picks up just a few chars:
0?Q
If I instead transmit the string before, it sometimes prints "register" once, sometimes 3 times, when it should print 0x2E times ...
2023-10-07 11:50 PM
Again, please look for *good* examples of using CDC_Transmit_FS.
2023-10-08 07:12 AM
What do you mean by good examples? Isn't the data supposed to be transmitted at full speed once CDC_Transmit_FS() is called, without data loss? Are you suggesting it is some kind of memory or buffer issue? Do I need more code to guaranty that the data is transmitted successfully?
2023-10-08 08:20 AM
> Isn't the data supposed to be transmitted at full speed once CDC_Transmit_FS() is called, without data loss?
No :( USB device can send anything only when the host polls it. So CDC_Transmit_FS should not be called again until the previous call succeeds. Else it will stomp on the previously sent data and data loss will occur.
2023-10-08 12:45 PM - edited 2023-10-08 12:53 PM
Ok thanks, I was using CDC_Transmit_FS() as a serial.print() equivalent of the arduino, I will look at some examples on how to properly implement it.
I tried the following which seems to fix the issue:
int _write(int file, char *ptr, int len){
while(CDC_Transmit_FS((uint8_t *)ptr, len));
return len;
}
Now, if the transmission returns USBD_BUSY, it retries. Not sure if it is the best way, but it seems to work fine
2024-03-01 01:56 AM
Hi LLope31,
You can use a _write alternative on STM32 like:
int _write(int file, char *data, int len)
{
if (file != STDOUT_FILENO && file != STDERR_FILENO)
{
return -1;
}
while(CDC_Transmit_FS((uint8_t *)data, len))
{
HAL_Delay(1);
};
return len;
}