From e8b7deac5a251edee22b8ffe07fb13155aa39be8 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 01:30:13 -0500 Subject: [PATCH 01/12] Make _write wait for CDC transmission to finish --- Firmware/Src/syscalls.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index 3cd2a073..1b8e7589 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -5,7 +5,9 @@ ****************************************************************************** */ -#include +#include +#include +#include #include #include #include @@ -19,6 +21,8 @@ #define UART_TX_BUFFER_SIZE 64 static uint8_t uart_tx_buf[UART_TX_BUFFER_SIZE]; +extern PCD_HandleTypeDef hpcd_USB_OTG_FS; +extern USBD_HandleTypeDef hUsbDeviceFS; int _write(int file, char *data, int len) { //number of bytes written @@ -49,5 +53,15 @@ int _write(int file, char *data, int len) { } break; } + // Wait for transmission to complete + USBD_CDC_HandleTypeDef* hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; + while (hcdc->TxState != 0) { + osSemaphoreWait(sem_usb_irq, 0); + // We have a new incoming USB transmission: handle it + HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); + // Let the irq (OTG_FS_IRQHandler) fire again. + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + } + return written; } From c0aa7c1157ca5c6d9ad2670541bc552a08da7274 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 01:47:40 -0500 Subject: [PATCH 02/12] Make UART block until transmission completes --- Firmware/Src/syscalls.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index 1b8e7589..183fa830 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -47,6 +47,9 @@ int _write(int file, char *data, int len) { // Start DMA background trasnfer HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); } break; + while (huart4.gState != HAL_UART_STATE_READY) { + // Do nothing + } default: { written = 0; From 2bb18056572e683a6cd93b733beb4af5f2c3237f Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 01:48:33 -0500 Subject: [PATCH 03/12] Move USB CDC block to case statement + formatting --- Firmware/Src/syscalls.c | 80 ++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index 183fa830..cd9d449d 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -5,13 +5,12 @@ ****************************************************************************** */ -#include #include -#include -#include -#include #include - +#include +#include +#include +#include //int _read(int file, char *data, int len) {} //int _close(int file) {} @@ -24,47 +23,46 @@ static uint8_t uart_tx_buf[UART_TX_BUFFER_SIZE]; extern PCD_HandleTypeDef hpcd_USB_OTG_FS; extern USBD_HandleTypeDef hUsbDeviceFS; -int _write(int file, char *data, int len) { - //number of bytes written - int written = 0; - switch (serial_printf_select) { +int _write(int file, char* data, int len) { + //number of bytes written + int written = 0; + switch (serial_printf_select) { + case SERIAL_PRINTF_IS_USB: { + // transmit over CDC + uint8_t status = CDC_Transmit_FS((uint8_t*)data, len); + written = (status == USBD_OK) ? len : 0; - case SERIAL_PRINTF_IS_USB: { - // transmit over CDC - uint8_t status = CDC_Transmit_FS((uint8_t*)data, len); - written = (status == USBD_OK) ? len : 0; - } break; + // Wait for transmission to complete + USBD_CDC_HandleTypeDef* hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; + while (hcdc->TxState != 0) { + osSemaphoreWait(sem_usb_irq, 0); + // We have a new incoming USB transmission: handle it + HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); + // Let the irq (OTG_FS_IRQHandler) fire again. + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + } + } break; - case SERIAL_PRINTF_IS_UART: { - //Check length - if (len > UART_TX_BUFFER_SIZE) - return 0; - // Check if transfer is already ongoing - if(huart4.gState != HAL_UART_STATE_READY) - return 0; - // memcpy data into uart_tx_buf - memcpy(uart_tx_buf, data, len); - // Start DMA background trasnfer - HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); - } break; + case SERIAL_PRINTF_IS_UART: { + //Check length + if (len > UART_TX_BUFFER_SIZE) + return 0; + // Check if transfer is already ongoing + if (huart4.gState != HAL_UART_STATE_READY) + return 0; + // memcpy data into uart_tx_buf + memcpy(uart_tx_buf, data, len); + // Start DMA background trasnfer + HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); while (huart4.gState != HAL_UART_STATE_READY) { // Do nothing } + } break; - default: { - written = 0; - } break; - } + default: { + written = 0; + } break; + } - // Wait for transmission to complete - USBD_CDC_HandleTypeDef* hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; - while (hcdc->TxState != 0) { - osSemaphoreWait(sem_usb_irq, 0); - // We have a new incoming USB transmission: handle it - HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); - // Let the irq (OTG_FS_IRQHandler) fire again. - HAL_NVIC_EnableIRQ(OTG_FS_IRQn); - } - - return written; + return written; } From 1a1f1a1d93432343db5928e18ac5600ec700ddad Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 05:38:14 -0500 Subject: [PATCH 04/12] Implement new thread for USB IRQ pump --- Firmware/Inc/freertos_vars.h | 3 +++ Firmware/MotorControl/commands.c | 46 +++++++++++++++++++++++--------- Firmware/MotorControl/commands.h | 3 +++ Firmware/Src/freertos.c | 20 ++++++++++++-- Firmware/Src/syscalls.c | 19 +++++++------ Firmware/Src/usbd_cdc_if.c | 7 +++-- 6 files changed, 70 insertions(+), 28 deletions(-) diff --git a/Firmware/Inc/freertos_vars.h b/Firmware/Inc/freertos_vars.h index fd0bf85d..b0d73b35 100644 --- a/Firmware/Inc/freertos_vars.h +++ b/Firmware/Inc/freertos_vars.h @@ -4,10 +4,13 @@ // List of semaphore osSemaphoreId sem_usb_irq; +osSemaphoreId sem_uart_dma; +osSemaphoreId sem_usb_rx; // List of threads osThreadId thread_motor_0; osThreadId thread_motor_1; osThreadId thread_cmd_parse; +osThreadId thread_usb_pump; #endif /* __FREERTOS_H */ \ No newline at end of file diff --git a/Firmware/MotorControl/commands.c b/Firmware/MotorControl/commands.c index 0c01ccd9..fa5425e1 100644 --- a/Firmware/MotorControl/commands.c +++ b/Firmware/MotorControl/commands.c @@ -4,6 +4,7 @@ #include #include #include +#include extern PCD_HandleTypeDef hpcd_USB_OTG_FS; @@ -21,6 +22,10 @@ SerialPrintf_t serial_printf_select = SERIAL_PRINTF_IS_NONE; static const GpioMode_t gpio_mode = GPIO_MODE_UART; //GPIO 1,2 is UART Tx,Rx // static const GpioMode_t gpio_mode = GPIO_MODE_STEP_DIR; //GPIO 1,2 is M0 Step,Dir +static uint8_t usb_buf[64]; +static uint32_t usb_len; +extern USBD_HandleTypeDef hUsbDeviceFS; + // variables exposed to usb/serial interface via set/get/monitor // Note: this will be depricated soon static float* const exposed_floats[] = { @@ -163,6 +168,10 @@ void motor_parse_cmd(uint8_t* buffer, int len, SerialPrintf_t response_interface if (numscan == 2 && motor_number < num_motors) { set_current_setpoint(&motors[motor_number], current_feed_forward); } + } else if(buffer[0] == 'e'){ + int val = printf("Test 1\n"); + int val2 = printf("test 2\n"); + val = 0; } else if (buffer[0] == 'g') { // GET // g <0:float,1:int,2:bool,3:uint16> index int type = 0; @@ -335,21 +344,34 @@ void cmd_parse_thread(void const * argument) { } } } - // When we reach here, we are out of immediate characters to fetch out of UART buffer - // Now we check if there is any USB processing to do: we wait for up to 1 ms, - // before going back to checking UART again. - int USB_check_timeout = 1; - // Wait for signalling from USB interrupt (OTG_FS_IRQHandler) - osStatus semaphore_status = osSemaphoreWait(sem_usb_irq, USB_check_timeout); - if (semaphore_status == osOK) { - // We have a new incoming USB transmission: handle it - HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); - // Let the irq (OTG_FS_IRQHandler) fire again. - HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + osStatus sem_stat = osSemaphoreWait(sem_usb_rx, 1); + if(sem_stat == osOK){ + motor_parse_cmd(usb_buf, usb_len, SERIAL_PRINTF_IS_USB); + USBD_CDC_ReceivePacket(&hUsbDeviceFS); // Allow next packet } } while (!reset_read_state); } - // If we get here, then this task is done vTaskDelete(osThreadGetId()); +} + +// Called from CDC_Receive_FS callback function, this allows motor_parse_cmd to access the +// incoming USB data +void set_cmd_buffer(const uint8_t *buf, uint32_t len) { + memcpy(usb_buf, buf, len); + usb_len = len; +} + +void usb_update_thread() { + for (;;) { + // Wait for signalling from USB interrupt (OTG_FS_IRQHandler) + osStatus semaphore_status = osSemaphoreWait(sem_usb_irq, osWaitForever); + if (semaphore_status == osOK) { + // We have a new incoming USB transmission: handle it + HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); + // Let the irq (OTG_FS_IRQHandler) fire again. + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + } + } + vTaskDelete(osThreadGetId()); } \ No newline at end of file diff --git a/Firmware/MotorControl/commands.h b/Firmware/MotorControl/commands.h index 1483af9c..80d1b77a 100644 --- a/Firmware/MotorControl/commands.h +++ b/Firmware/MotorControl/commands.h @@ -27,4 +27,7 @@ void init_communication(); void cmd_parse_thread(void const * argument); void motor_parse_cmd(uint8_t* buffer, int len, SerialPrintf_t response_interface); +void set_cmd_buffer(const uint8_t *buf, uint32_t len); +void usb_update_thread(); + #endif /* COMMANDS_H */ diff --git a/Firmware/Src/freertos.c b/Firmware/Src/freertos.c index da369f40..49d17383 100644 --- a/Firmware/Src/freertos.c +++ b/Firmware/Src/freertos.c @@ -88,10 +88,22 @@ void MX_FREERTOS_Init(void) { /* USER CODE END RTOS_MUTEX */ /* USER CODE BEGIN RTOS_SEMAPHORES */ - // Init usb irq binary semaphore, and start with no tolkens by removing the starting one. + // Init usb irq binary semaphore, and start with no tokens by removing the starting one. osSemaphoreDef(sem_usb_irq); sem_usb_irq = osSemaphoreCreate(osSemaphore(sem_usb_irq), 1); osSemaphoreWait(sem_usb_irq, 0); + + // Create a semaphore for UART DMA and remove a token + osSemaphoreDef(sem_uart_dma); + sem_uart_dma = osSemaphoreCreate(osSemaphore(sem_uart_dma), 1); + osSemaphoreWait(sem_uart_dma, 0); + + // Create a semaphore for USB RX + osSemaphoreDef(sem_usb_rx); + sem_usb_rx = osSemaphoreCreate(osSemaphore(sem_usb_rx), 1); + osSemaphoreWait(sem_usb_irq, 0); // Remove a token. + + /* USER CODE END RTOS_SEMAPHORES */ /* USER CODE BEGIN RTOS_TIMERS */ @@ -132,10 +144,14 @@ void StartDefaultTask(void const * argument) thread_motor_0 = osThreadCreate(osThread(task_motor_0), &motors[0]); thread_motor_1 = osThreadCreate(osThread(task_motor_1), &motors[1]); - // Start USB command handling thread + // Start command handling thread osThreadDef(task_cmd_parse, cmd_parse_thread, osPriorityNormal, 0, 512); thread_cmd_parse = osThreadCreate(osThread(task_cmd_parse), NULL); + // Start USB interrupt handler thread + osThreadDef(task_usb_pump, usb_update_thread, osPriorityNormal, 0, 512); + thread_usb_pump = osThreadCreate(osThread(task_usb_pump), NULL); + //If we get to here, then the default task is done. vTaskDelete(defaultTaskHandle); diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index cd9d449d..cbe72817 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -35,11 +35,7 @@ int _write(int file, char* data, int len) { // Wait for transmission to complete USBD_CDC_HandleTypeDef* hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; while (hcdc->TxState != 0) { - osSemaphoreWait(sem_usb_irq, 0); - // We have a new incoming USB transmission: handle it - HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); - // Let the irq (OTG_FS_IRQHandler) fire again. - HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + // Do nothing } } break; @@ -48,15 +44,14 @@ int _write(int file, char* data, int len) { if (len > UART_TX_BUFFER_SIZE) return 0; // Check if transfer is already ongoing - if (huart4.gState != HAL_UART_STATE_READY) - return 0; + //if (huart4.gState != HAL_UART_STATE_READY) + //return 0; // memcpy data into uart_tx_buf memcpy(uart_tx_buf, data, len); // Start DMA background trasnfer HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); - while (huart4.gState != HAL_UART_STATE_READY) { - // Do nothing - } + // Wait for the transmission to complete + osSemaphoreWait(sem_uart_dma, osWaitForever); } break; default: { @@ -66,3 +61,7 @@ int _write(int file, char* data, int len) { return written; } + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef* huart) { + osSemaphoreRelease(sem_uart_dma); +} \ No newline at end of file diff --git a/Firmware/Src/usbd_cdc_if.c b/Firmware/Src/usbd_cdc_if.c index 8f6b7317..475c969e 100644 --- a/Firmware/Src/usbd_cdc_if.c +++ b/Firmware/Src/usbd_cdc_if.c @@ -51,6 +51,7 @@ /* USER CODE BEGIN INCLUDE */ #include "utils.h" #include "commands.h" +#include /* USER CODE END INCLUDE */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY @@ -272,10 +273,8 @@ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) int modified_len = MACRO_MIN(*Len+1, APP_RX_DATA_SIZE); Buf[modified_len-1] = 0; - motor_parse_cmd(Buf, modified_len, SERIAL_PRINTF_IS_USB); - - // Allow next packet - USBD_CDC_ReceivePacket(&hUsbDeviceFS); + set_cmd_buffer(Buf, modified_len); + osSemaphoreRelease(sem_usb_rx); return (USBD_OK); /* USER CODE END 6 */ From 7e99b06ad1f3afc6ffeee40a848baceb947685c4 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 05:39:15 -0500 Subject: [PATCH 05/12] Remove unused extern near _write --- Firmware/Src/syscalls.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index cbe72817..12624fb7 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -20,7 +20,6 @@ #define UART_TX_BUFFER_SIZE 64 static uint8_t uart_tx_buf[UART_TX_BUFFER_SIZE]; -extern PCD_HandleTypeDef hpcd_USB_OTG_FS; extern USBD_HandleTypeDef hUsbDeviceFS; int _write(int file, char* data, int len) { From 29ba915b54e694dfe6674a73fe08ae0f21810a4d Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 17:39:33 -0500 Subject: [PATCH 06/12] Modify USB TX to use a semaphore from usb_cdc --- Firmware/Inc/freertos_vars.h | 1 + .../STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c | 4 +++- Firmware/Src/freertos.c | 4 ++++ Firmware/Src/syscalls.c | 10 ++-------- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Firmware/Inc/freertos_vars.h b/Firmware/Inc/freertos_vars.h index b0d73b35..9a08d016 100644 --- a/Firmware/Inc/freertos_vars.h +++ b/Firmware/Inc/freertos_vars.h @@ -6,6 +6,7 @@ osSemaphoreId sem_usb_irq; osSemaphoreId sem_uart_dma; osSemaphoreId sem_usb_rx; +osSemaphoreId sem_usb_tx; // List of threads osThreadId thread_motor_0; diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index b2ca5f16..345b0b0f 100644 --- a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -62,6 +62,8 @@ #include "usbd_cdc.h" #include "usbd_desc.h" #include "usbd_ctlreq.h" +#include +#include /** @addtogroup STM32_USB_DEVICE_LIBRARY @@ -669,7 +671,7 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) { hcdc->TxState = 0; - + osSemaphoreRelease(sem_usb_tx); return USBD_OK; } else diff --git a/Firmware/Src/freertos.c b/Firmware/Src/freertos.c index 49d17383..1ebf93a0 100644 --- a/Firmware/Src/freertos.c +++ b/Firmware/Src/freertos.c @@ -103,6 +103,10 @@ void MX_FREERTOS_Init(void) { sem_usb_rx = osSemaphoreCreate(osSemaphore(sem_usb_rx), 1); osSemaphoreWait(sem_usb_irq, 0); // Remove a token. + // Create a semaphore for USB RX + osSemaphoreDef(sem_usb_tx); + sem_usb_tx = osSemaphoreCreate(osSemaphore(sem_usb_tx), 1); + osSemaphoreWait(sem_usb_tx, 0); // Remove a token. /* USER CODE END RTOS_SEMAPHORES */ diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index 12624fb7..5c92c709 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -20,7 +20,6 @@ #define UART_TX_BUFFER_SIZE 64 static uint8_t uart_tx_buf[UART_TX_BUFFER_SIZE]; -extern USBD_HandleTypeDef hUsbDeviceFS; int _write(int file, char* data, int len) { //number of bytes written @@ -32,23 +31,18 @@ int _write(int file, char* data, int len) { written = (status == USBD_OK) ? len : 0; // Wait for transmission to complete - USBD_CDC_HandleTypeDef* hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; - while (hcdc->TxState != 0) { - // Do nothing - } + osSemaphoreWait(sem_usb_tx, osWaitForever); } break; case SERIAL_PRINTF_IS_UART: { //Check length if (len > UART_TX_BUFFER_SIZE) return 0; - // Check if transfer is already ongoing - //if (huart4.gState != HAL_UART_STATE_READY) - //return 0; // memcpy data into uart_tx_buf memcpy(uart_tx_buf, data, len); // Start DMA background trasnfer HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); + // Wait for the transmission to complete osSemaphoreWait(sem_uart_dma, osWaitForever); } break; From 8bdd4b9161a1cc2901c086cf5926411f301bb6d6 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 17:45:48 -0500 Subject: [PATCH 07/12] Fix formatting in freertos.c --- Firmware/Src/freertos.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/Src/freertos.c b/Firmware/Src/freertos.c index 1ebf93a0..d91e3ae0 100644 --- a/Firmware/Src/freertos.c +++ b/Firmware/Src/freertos.c @@ -103,10 +103,10 @@ void MX_FREERTOS_Init(void) { sem_usb_rx = osSemaphoreCreate(osSemaphore(sem_usb_rx), 1); osSemaphoreWait(sem_usb_irq, 0); // Remove a token. - // Create a semaphore for USB RX - osSemaphoreDef(sem_usb_tx); - sem_usb_tx = osSemaphoreCreate(osSemaphore(sem_usb_tx), 1); - osSemaphoreWait(sem_usb_tx, 0); // Remove a token. + // Create a semaphore for USB RX + osSemaphoreDef(sem_usb_tx); + sem_usb_tx = osSemaphoreCreate(osSemaphore(sem_usb_tx), 1); + osSemaphoreWait(sem_usb_tx, 0); // Remove a token. /* USER CODE END RTOS_SEMAPHORES */ From ee6c1cebb4cf5091cf0b5d9a0fa74b87d613ac41 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 19:39:42 -0500 Subject: [PATCH 08/12] Modify the _write lock to wait on resource instead of xfer --- Firmware/Src/syscalls.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index 5c92c709..ee9da08f 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -26,25 +26,24 @@ int _write(int file, char* data, int len) { int written = 0; switch (serial_printf_select) { case SERIAL_PRINTF_IS_USB: { - // transmit over CDC - uint8_t status = CDC_Transmit_FS((uint8_t*)data, len); - written = (status == USBD_OK) ? len : 0; - - // Wait for transmission to complete - osSemaphoreWait(sem_usb_tx, osWaitForever); + // Wait for the interface to be available + osStatus sem_stat = osSemaphoreWait(sem_usb_tx, osWaitForever); + if (sem_stat == osOK) { + uint8_t status = CDC_Transmit_FS((uint8_t*)data, len); // transmit over CDC + written = (status == USBD_OK) ? len : 0; + } } break; case SERIAL_PRINTF_IS_UART: { //Check length if (len > UART_TX_BUFFER_SIZE) return 0; - // memcpy data into uart_tx_buf - memcpy(uart_tx_buf, data, len); - // Start DMA background trasnfer - HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); - - // Wait for the transmission to complete - osSemaphoreWait(sem_uart_dma, osWaitForever); + // Wait for the interface to be available + osStatus sem_stat = osSemaphoreWait(sem_uart_dma, osWaitForever); + if (sem_stat == osOK) { + memcpy(uart_tx_buf, data, len); // memcpy data into uart_tx_buf + HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); // Start DMA background transfer + } } break; default: { From 81513a97b2e6164bf5a7ed9770031264534305d1 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 19:40:31 -0500 Subject: [PATCH 09/12] Flip the default tx signal value --- Firmware/Src/freertos.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Firmware/Src/freertos.c b/Firmware/Src/freertos.c index d91e3ae0..e80163b2 100644 --- a/Firmware/Src/freertos.c +++ b/Firmware/Src/freertos.c @@ -96,7 +96,6 @@ void MX_FREERTOS_Init(void) { // Create a semaphore for UART DMA and remove a token osSemaphoreDef(sem_uart_dma); sem_uart_dma = osSemaphoreCreate(osSemaphore(sem_uart_dma), 1); - osSemaphoreWait(sem_uart_dma, 0); // Create a semaphore for USB RX osSemaphoreDef(sem_usb_rx); @@ -106,7 +105,6 @@ void MX_FREERTOS_Init(void) { // Create a semaphore for USB RX osSemaphoreDef(sem_usb_tx); sem_usb_tx = osSemaphoreCreate(osSemaphore(sem_usb_tx), 1); - osSemaphoreWait(sem_usb_tx, 0); // Remove a token. /* USER CODE END RTOS_SEMAPHORES */ From 17375b41d8a550900bfbf9181fb0343ac1da6406 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 19:40:52 -0500 Subject: [PATCH 10/12] Remove memcpy from set_cmd_buffer --- Firmware/MotorControl/commands.c | 9 +++++---- Firmware/MotorControl/commands.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Firmware/MotorControl/commands.c b/Firmware/MotorControl/commands.c index fa5425e1..2b8c1e4e 100644 --- a/Firmware/MotorControl/commands.c +++ b/Firmware/MotorControl/commands.c @@ -22,7 +22,7 @@ SerialPrintf_t serial_printf_select = SERIAL_PRINTF_IS_NONE; static const GpioMode_t gpio_mode = GPIO_MODE_UART; //GPIO 1,2 is UART Tx,Rx // static const GpioMode_t gpio_mode = GPIO_MODE_STEP_DIR; //GPIO 1,2 is M0 Step,Dir -static uint8_t usb_buf[64]; +static uint8_t* usb_buf; static uint32_t usb_len; extern USBD_HandleTypeDef hUsbDeviceFS; @@ -344,7 +344,8 @@ void cmd_parse_thread(void const * argument) { } } } - osStatus sem_stat = osSemaphoreWait(sem_usb_rx, 1); + // Check if there is USB processing to do. + osStatus sem_stat = osSemaphoreWait(sem_usb_rx, 0); if(sem_stat == osOK){ motor_parse_cmd(usb_buf, usb_len, SERIAL_PRINTF_IS_USB); USBD_CDC_ReceivePacket(&hUsbDeviceFS); // Allow next packet @@ -357,8 +358,8 @@ void cmd_parse_thread(void const * argument) { // Called from CDC_Receive_FS callback function, this allows motor_parse_cmd to access the // incoming USB data -void set_cmd_buffer(const uint8_t *buf, uint32_t len) { - memcpy(usb_buf, buf, len); +void set_cmd_buffer(uint8_t *buf, uint32_t len) { + usb_buf = buf; usb_len = len; } diff --git a/Firmware/MotorControl/commands.h b/Firmware/MotorControl/commands.h index 80d1b77a..1cb5ad31 100644 --- a/Firmware/MotorControl/commands.h +++ b/Firmware/MotorControl/commands.h @@ -27,7 +27,7 @@ void init_communication(); void cmd_parse_thread(void const * argument); void motor_parse_cmd(uint8_t* buffer, int len, SerialPrintf_t response_interface); -void set_cmd_buffer(const uint8_t *buf, uint32_t len); +void set_cmd_buffer(uint8_t *buf, uint32_t len); void usb_update_thread(); #endif /* COMMANDS_H */ From 70b8b4799c7e8b4169783d5ad5e511a96a8f084d Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 8 Nov 2017 20:12:46 -0500 Subject: [PATCH 11/12] Fix timeouts --- Firmware/MotorControl/commands.c | 11 +++++++---- Firmware/Src/syscalls.c | 6 ++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Firmware/MotorControl/commands.c b/Firmware/MotorControl/commands.c index 2b8c1e4e..76006a54 100644 --- a/Firmware/MotorControl/commands.c +++ b/Firmware/MotorControl/commands.c @@ -344,11 +344,14 @@ void cmd_parse_thread(void const * argument) { } } } - // Check if there is USB processing to do. - osStatus sem_stat = osSemaphoreWait(sem_usb_rx, 0); - if(sem_stat == osOK){ + // When we reach here, we are out of immediate characters to fetch out of UART buffer + // Now we check if there is any USB processing to do: we wait for up to 1 ms, + // before going back to checking UART again. + const uint32_t usb_check_timeout = 1; // ms + osStatus sem_stat = osSemaphoreWait(sem_usb_rx, usb_check_timeout); + if (sem_stat == osOK) { motor_parse_cmd(usb_buf, usb_len, SERIAL_PRINTF_IS_USB); - USBD_CDC_ReceivePacket(&hUsbDeviceFS); // Allow next packet + USBD_CDC_ReceivePacket(&hUsbDeviceFS); // Allow next packet } } while (!reset_read_state); } diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index ee9da08f..8e422c7b 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -27,7 +27,8 @@ int _write(int file, char* data, int len) { switch (serial_printf_select) { case SERIAL_PRINTF_IS_USB: { // Wait for the interface to be available - osStatus sem_stat = osSemaphoreWait(sem_usb_tx, osWaitForever); + const uint32_t usb_tx_timeout = 100; // ms + osStatus sem_stat = osSemaphoreWait(sem_usb_tx, usb_tx_timeout); if (sem_stat == osOK) { uint8_t status = CDC_Transmit_FS((uint8_t*)data, len); // transmit over CDC written = (status == USBD_OK) ? len : 0; @@ -39,7 +40,8 @@ int _write(int file, char* data, int len) { if (len > UART_TX_BUFFER_SIZE) return 0; // Wait for the interface to be available - osStatus sem_stat = osSemaphoreWait(sem_uart_dma, osWaitForever); + const uint32_t uart_tx_timeout = 100; // ms + osStatus sem_stat = osSemaphoreWait(sem_uart_dma, uart_tx_timeout); if (sem_stat == osOK) { memcpy(uart_tx_buf, data, len); // memcpy data into uart_tx_buf HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); // Start DMA background transfer From 4425cf6b0e762832d3361e38a4696035a00f4693 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 8 Nov 2017 17:23:41 -0800 Subject: [PATCH 12/12] Update syscalls.c --- Firmware/Src/syscalls.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Firmware/Src/syscalls.c b/Firmware/Src/syscalls.c index 8e422c7b..0f850cda 100644 --- a/Firmware/Src/syscalls.c +++ b/Firmware/Src/syscalls.c @@ -26,26 +26,28 @@ int _write(int file, char* data, int len) { int written = 0; switch (serial_printf_select) { case SERIAL_PRINTF_IS_USB: { - // Wait for the interface to be available + // Wait on semaphore for the interface to be available + // Note that the USB driver will release the interface again when the TX completes const uint32_t usb_tx_timeout = 100; // ms osStatus sem_stat = osSemaphoreWait(sem_usb_tx, usb_tx_timeout); if (sem_stat == osOK) { uint8_t status = CDC_Transmit_FS((uint8_t*)data, len); // transmit over CDC written = (status == USBD_OK) ? len : 0; - } + } // If the semaphore times out, we simply leave "written" as 0 } break; case SERIAL_PRINTF_IS_UART: { //Check length if (len > UART_TX_BUFFER_SIZE) return 0; - // Wait for the interface to be available + // Wait on semaphore for the interface to be available + // Note that HAL_UART_TxCpltCallback will release the interface again when the TX completes const uint32_t uart_tx_timeout = 100; // ms osStatus sem_stat = osSemaphoreWait(sem_uart_dma, uart_tx_timeout); if (sem_stat == osOK) { memcpy(uart_tx_buf, data, len); // memcpy data into uart_tx_buf HAL_UART_Transmit_DMA(&huart4, uart_tx_buf, len); // Start DMA background transfer - } + } // If the semaphore times out, we simply leave "written" as 0 } break; default: { @@ -58,4 +60,4 @@ int _write(int file, char* data, int len) { void HAL_UART_TxCpltCallback(UART_HandleTypeDef* huart) { osSemaphoreRelease(sem_uart_dma); -} \ No newline at end of file +}