Qt Serial Port do not correctly work with USB CDC
-
Greetings everyone!
The issue I have encountered is - I am trying to establish connection with USB CDC STM Virtual COM port.
I am connecting to virtual com port with standard QSerialPort. If I am translating data to my STM32F103C8 chip with terminal 1.9b - everythings works just fine, I am getting everything I supposed to get. But when I am trying to do the same thing with the help of COM->write, my stm firmware stucks completly. If I try to see the parcel via null modem by connecting my Widget app to terminal1.9b -I see that my parcel from the app is correct.
Anybody help me please :)
Here is the Qt slot for sending:void MainWindow::getEcho(void) { QByteArray ba_1; char len = 0x06; char crc = 0; char echo = ECHO; ba_1.append(SYNCHRO); ba_1.append(char(0x00)); ba_1.append(len); ba_1.append(UART_ADDR); ba_1.append(echo); for(int i = 0; i < ba_1.size(); i++) { crc ^= ba_1.at(i); } ba_1.append(crc); if(COM->write(ba_1) != -1) { COM->waitForBytesWritten(200); COM->waitForReadyRead(300); } //ui->echo_button->setEnabled(false); }
Here is my st cdc receive:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); HAL_GPIO_TogglePin(PC13_LED_GPIO_Port, PC13_LED_Pin); memcpy((USB_RX_MASS + usb_parcel_counter), Buf, *Len); usb_parcel_counter++; return (USBD_OK); /* USER CODE END 6 */ }
-
At last I have managed to solve this one.
The problem was related (as I expected) to USB CDC receiving bytes from QSerialPort (my Qt term App).
It was my mistake to expect CDC Receive ONE byte by each interrupt as it can obviously receive a number of bytes (*Len).So what I have done - I made the CDC Receive int handler add a number of received bytes (*Len) to a global var. That totally solved everything.
Here is the code:/** * @brief Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will issue a NAK packet on any OUT packet received on * USB endpoint until exiting this function. If you exit this function * before transfer is complete on CDC interface (ie. using DMA controller) * it will result in receiving more data while previous ones are still * not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); memcpy((USB_RX_MASS + usb_parcel_counter), Buf, *Len); //CDC_Transmit_FS(UserRxBufferFS, 6); usb_parcel_counter = usb_parcel_counter + *Len; return (USBD_OK); /* USER CODE END 6 */ }
Good luck codeMasters!
-
Greetings everyone!
The issue I have encountered is - I am trying to establish connection with USB CDC STM Virtual COM port.
I am connecting to virtual com port with standard QSerialPort. If I am translating data to my STM32F103C8 chip with terminal 1.9b - everythings works just fine, I am getting everything I supposed to get. But when I am trying to do the same thing with the help of COM->write, my stm firmware stucks completly. If I try to see the parcel via null modem by connecting my Widget app to terminal1.9b -I see that my parcel from the app is correct.
Anybody help me please :)
Here is the Qt slot for sending:void MainWindow::getEcho(void) { QByteArray ba_1; char len = 0x06; char crc = 0; char echo = ECHO; ba_1.append(SYNCHRO); ba_1.append(char(0x00)); ba_1.append(len); ba_1.append(UART_ADDR); ba_1.append(echo); for(int i = 0; i < ba_1.size(); i++) { crc ^= ba_1.at(i); } ba_1.append(crc); if(COM->write(ba_1) != -1) { COM->waitForBytesWritten(200); COM->waitForReadyRead(300); } //ui->echo_button->setEnabled(false); }
Here is my st cdc receive:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); HAL_GPIO_TogglePin(PC13_LED_GPIO_Port, PC13_LED_Pin); memcpy((USB_RX_MASS + usb_parcel_counter), Buf, *Len); usb_parcel_counter++; return (USBD_OK); /* USER CODE END 6 */ }
-
Greetings!
Done it - still no result.
I begin to think that it is due to some QSerialPort authority issues x_x
It looks like the app gets stuck getting bytes from my Qt App via serial port just within CDC_Receive_FS().
I will try to use this https://fpoussin.github.io/doxygen/qtusb/0.7.x/qusbdevice.html
instead of QSerialPort. -
At last I have managed to solve this one.
The problem was related (as I expected) to USB CDC receiving bytes from QSerialPort (my Qt term App).
It was my mistake to expect CDC Receive ONE byte by each interrupt as it can obviously receive a number of bytes (*Len).So what I have done - I made the CDC Receive int handler add a number of received bytes (*Len) to a global var. That totally solved everything.
Here is the code:/** * @brief Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will issue a NAK packet on any OUT packet received on * USB endpoint until exiting this function. If you exit this function * before transfer is complete on CDC interface (ie. using DMA controller) * it will result in receiving more data while previous ones are still * not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); memcpy((USB_RX_MASS + usb_parcel_counter), Buf, *Len); //CDC_Transmit_FS(UserRxBufferFS, 6); usb_parcel_counter = usb_parcel_counter + *Len; return (USBD_OK); /* USER CODE END 6 */ }
Good luck codeMasters!