From e21c2622ba4b116a74587ef489a10db05de53607 Mon Sep 17 00:00:00 2001 From: "fmislam.3105@gmail.com" Date: Sat, 14 Mar 2026 14:36:36 -0600 Subject: [PATCH] Fixed logic for the CDC indexing, as well as the logic for reading OK/0 messages from the script --- Core/Inc/Tasks/USB/USBController.hpp | 1 + Core/Src/Tasks/USB/USBController.cpp | 51 +++++++++++++++++++--------- USB_DEVICE/App/usbd_cdc_if.c | 45 +++++++++++++----------- stm32_dyno_firmware_sensor_board | 2 +- 4 files changed, 62 insertions(+), 37 deletions(-) diff --git a/Core/Inc/Tasks/USB/USBController.hpp b/Core/Inc/Tasks/USB/USBController.hpp index ad09d4d..2c4084b 100644 --- a/Core/Inc/Tasks/USB/USBController.hpp +++ b/Core/Inc/Tasks/USB/USBController.hpp @@ -92,6 +92,7 @@ class USBController uint8_t _txBuffer[USB_TX_BUFFER_SIZE]; int _txBufferIndex = 0; + int _rxBufferIndex = 0; }; #endif // INC_TASKS_USB_USBCONTROLLER_HPP_ diff --git a/Core/Src/Tasks/USB/USBController.cpp b/Core/Src/Tasks/USB/USBController.cpp index 1602261..e259c03 100644 --- a/Core/Src/Tasks/USB/USBController.cpp +++ b/Core/Src/Tasks/USB/USBController.cpp @@ -13,6 +13,7 @@ extern size_t task_error_circular_buffer_index_writer; extern task_error_data task_error_circular_buffer[TASK_ERROR_CIRCULAR_BUFFER_SIZE]; extern uint8_t usb_controller_rx_buffer[USB_CONTROLLER_RX_BUFFER_SIZE]; +extern size_t usb_controller_rx_index; USBController::USBController(osMessageQueueId_t sessionControllerToUsbController, osMessageQueueId_t taskMonitorToUsbControllerHandle) : _task_errors_buffer_reader(task_error_circular_buffer, &task_error_circular_buffer_index_writer, TASK_ERROR_CIRCULAR_BUFFER_SIZE), @@ -22,7 +23,8 @@ USBController::USBController(osMessageQueueId_t sessionControllerToUsbController _taskMonitorToUsbControllerHandle(taskMonitorToUsbControllerHandle), _sessionControllerToUsbController(sessionControllerToUsbController), _txBuffer{}, - _txBufferIndex(0) + _txBufferIndex(0), + _rxBufferIndex(0) {} bool USBController::Init() @@ -32,27 +34,44 @@ bool USBController::Init() void USBController::ReceiveAppAck() { - while (true) - { - // Attempt to receive data over USB - if (usb_controller_rx_buffer[0] == 'O' && usb_controller_rx_buffer[1] == 'K' && usb_controller_rx_buffer[2] == '\0') + int usb_rx_index_copy = usb_controller_rx_index; + + // Attempt to receive data over USB + while (true) { - break; - } - - osDelay(10); // Small delay to prevent busy-waiting - } + if (_rxBufferIndex == usb_rx_index_copy) + { + return; + } + else if (_rxBufferIndex > usb_rx_index_copy) // Checks if usb_controller_rx_index + { + _rxBufferIndex = 0; + } + + /* Might want to consider a critical section if: + - buffer size is too small to fit many messages + - USBController.cpp isn't run very frequently + + KEEP IN MIND... NOTHING ELSE CAN RUN DURING A CRITICAL SECTION. These should be used + sparingly and for very small sections of code. Interrupts and context switches cannot + occur during a critical section, which would have to be "locked" using mutexes or + taskENTER_CRITICAL followed by taskEXIT_CRITICAL from FreeRTOS. + */ + if (usb_controller_rx_buffer[_rxBufferIndex] == 'O' && usb_controller_rx_buffer[_rxBufferIndex + 1] == 'K' && usb_controller_rx_buffer[_rxBufferIndex + 2] == '\0') + { + _txBufferIndex = 0; // Resets the microcontroller buffer after reading from the CDC buffer + } + _rxBufferIndex += 3 * sizeof(char); + } } void USBController::Run() { bool enableUSB = false; - // Wait for "OK" before starting data transmission - ReceiveAppAck(); - while (1) { + GetLatestFromQueue( _sessionControllerToUsbController, &enableUSB, @@ -65,6 +84,8 @@ void USBController::Run() continue; } + ReceiveAppAck(); + #if !defined(OPTICAL_ENCODER_TASK_ENABLE) @@ -97,9 +118,7 @@ void USBController::Run() ProcessTaskData(_taskMonitorToUsbControllerHandle, TASK_ID_TASK_MONITOR); #endif - ProcessErrorsAndWarnings(); - - + ProcessErrorsAndWarnings(); if (CDC_Transmit_FS(_txBuffer, _txBufferIndex) == USBD_BUSY) { continue; diff --git a/USB_DEVICE/App/usbd_cdc_if.c b/USB_DEVICE/App/usbd_cdc_if.c index 2524a3b..10020a2 100644 --- a/USB_DEVICE/App/usbd_cdc_if.c +++ b/USB_DEVICE/App/usbd_cdc_if.c @@ -255,46 +255,51 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) * 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) + * @param cdc_buf: Buffer of data to be received + * @param length: 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) -{ +static int8_t CDC_Receive_FS(uint8_t* cdc_buf, uint32_t *length) { /* USER CODE BEGIN 6 */ + uint32_t len = *length; // More efficient to store immediate rather than load/store each time uint8_t status = USBD_OK; - if (*Len > USB_CONTROLLER_RX_BUFFER_SIZE) + if (len > USB_CONTROLLER_RX_BUFFER_SIZE) { // drop packet or set error flag status = USBD_FAIL; goto complete_transfer; } - uint32_t len = *Len; - uint32_t idx = usb_controller_rx_index; - - uint32_t space_to_end = USB_CONTROLLER_RX_BUFFER_SIZE - idx; - - if (len <= space_to_end) - { - memcpy(&usb_controller_rx_buffer[idx], Buf, len); - } - else - { - memcpy(&usb_controller_rx_buffer[idx], Buf, space_to_end); - memcpy(&usb_controller_rx_buffer[0], Buf + space_to_end, len - space_to_end); + if (len <= USB_CONTROLLER_RX_BUFFER_SIZE - usb_controller_rx_index) { + memcpy(&usb_controller_rx_buffer[usb_controller_rx_index], cdc_buf, len); + usb_controller_rx_index += len; + } else { + // memcpy(&usb_controller_rx_buffer[idx], Buf, space_to_end); + // memcpy(&usb_controller_rx_buffer[0], Buf + space_to_end, len - space_to_end); + memcpy(&usb_controller_rx_buffer[0], cdc_buf, len); + usb_controller_rx_index = len; // Idea is for usb_controller_rx_index to be at the first AVAILABLE index past everything before } - usb_controller_rx_index = (idx + len) % USB_CONTROLLER_RX_BUFFER_SIZE; + complete_transfer: - USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); + USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &cdc_buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); return (status); /* USER CODE END 6 */ } +// static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) +// { +// USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); +// USBD_CDC_ReceivePacket(&hUsbDeviceFS); +// USB_CDC_RxHandler(UserRxBufferFS, *Len); +// memset(UserRxBufferFS, '\0', *Len); +// return (USBD_OK); + +// } + /** * @brief CDC_Transmit_FS * Data to send over USB IN endpoint are sent over CDC interface diff --git a/stm32_dyno_firmware_sensor_board b/stm32_dyno_firmware_sensor_board index 6c5ec81..115ab87 160000 --- a/stm32_dyno_firmware_sensor_board +++ b/stm32_dyno_firmware_sensor_board @@ -1 +1 @@ -Subproject commit 6c5ec816016a8f0e486cba28a79b09a267bbdc0f +Subproject commit 115ab873b540a3631e028117de7faf2ae9a3ff0a