diff --git a/hal/targets.json b/hal/targets.json index b948d3de9df..9fcef8a6ef9 100644 --- a/hal/targets.json +++ b/hal/targets.json @@ -656,7 +656,7 @@ "inherits": ["Target"], "progen": {"target": "nucleo-f070rb"}, "detect_code": ["0755"], - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "release_versions": ["2", "5"] }, "NUCLEO_F072RB": { @@ -668,7 +668,7 @@ "inherits": ["Target"], "progen": {"target": "nucleo-f072rb"}, "detect_code": ["0730"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "release_versions": ["2", "5"] }, "NUCLEO_F091RC": { @@ -680,7 +680,7 @@ "inherits": ["Target"], "progen": {"target": "nucleo-f091rc"}, "detect_code": ["0750"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "release_versions": ["2", "5"] }, "NUCLEO_F103RB": { diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h index 1525138e10c..4a19b70bd67 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/objects.h @@ -66,17 +66,6 @@ struct dac_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - struct spi_s { SPIName spi; uint32_t bits; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h index e14f939d833..16c179a610f 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/objects.h @@ -60,17 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - struct spi_s { SPIName spi; uint32_t bits; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h index e14f939d833..16c179a610f 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/objects.h @@ -60,17 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - struct spi_s { SPIName spi; uint32_t bits; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h index 1418bcf0f5d..10cf3d139bd 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h @@ -60,17 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - struct spi_s { SPIName spi; uint32_t bits; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h index e14f939d833..16c179a610f 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/objects.h @@ -60,17 +60,6 @@ struct analogin_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - struct spi_s { SPIName spi; uint32_t bits; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h index f12f2323779..8f908717dc5 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h @@ -66,17 +66,6 @@ struct dac_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - struct spi_s { SPIName spi; uint32_t bits; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h index f12f2323779..8f908717dc5 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h @@ -66,17 +66,6 @@ struct dac_s { uint32_t channel; }; -struct serial_s { - UARTName uart; - int index; // Used by irq - uint32_t baudrate; - uint32_t databits; - uint32_t stopbits; - uint32_t parity; - PinName pin_tx; - PinName pin_rx; -}; - struct spi_s { SPIName spi; uint32_t bits; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/common_objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/common_objects.h index a3c3410cb3f..41fa23726fe 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/common_objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/common_objects.h @@ -49,6 +49,25 @@ struct pwmout_s { uint8_t inverted; }; +struct serial_s { + UARTName uart; + int index; // Used by irq + uint32_t baudrate; + uint32_t databits; + uint32_t stopbits; + uint32_t parity; + PinName pin_tx; + PinName pin_rx; +#if DEVICE_SERIAL_ASYNCH + uint32_t events; +#endif +#if DEVICE_SERIAL_FC + uint32_t hw_flow_ctl; + PinName pin_rts; + PinName pin_cts; +#endif +}; + #include "gpio_object.h" #ifdef __cplusplus @@ -56,4 +75,3 @@ struct pwmout_s { #endif #endif - diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/serial_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/serial_api.c index f0d95275c4a..a5b49e1ef87 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/serial_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/serial_api.c @@ -36,143 +36,156 @@ #include "pinmap.h" #include #include "PeripheralPins.h" +#include "mbed_error.h" #if defined (TARGET_STM32F091RC) -#define UART_NUM (8) - -static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0, 0, 0, 0}; - + #define UART_NUM (8) #elif defined (TARGET_STM32F030R8) || defined (TARGET_STM32F051R8) || defined (TARGET_STM32F042K6) -#define UART_NUM (2) - -static uint32_t serial_irq_ids[UART_NUM] = {0, 0}; - + #define UART_NUM (2) #elif defined (TARGET_STM32F031K6) -#define UART_NUM (1) - -static uint32_t serial_irq_ids[UART_NUM] = {0}; - + #define UART_NUM (1) #else -#define UART_NUM (4) - -static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0}; - + #define UART_NUM (4) #endif -static uart_irq_handler irq_handler; +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static UART_HandleTypeDef uart_handlers[UART_NUM]; -UART_HandleTypeDef UartHandle; +static uart_irq_handler irq_handler; int stdio_uart_inited = 0; serial_t stdio_uart; -static void init_uart(serial_t *obj) { - UartHandle.Instance = (USART_TypeDef *)(obj->uart); - - UartHandle.Init.BaudRate = obj->baudrate; - UartHandle.Init.WordLength = obj->databits; - UartHandle.Init.StopBits = obj->stopbits; - UartHandle.Init.Parity = obj->parity; - UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; +#if DEVICE_SERIAL_ASYNCH + #define SERIAL_S(obj) (&((obj)->serial)) +#else + #define SERIAL_S(obj) (obj) +#endif - if (obj->pin_rx == NC) { - UartHandle.Init.Mode = UART_MODE_TX; - } else if (obj->pin_tx == NC) { - UartHandle.Init.Mode = UART_MODE_RX; +static void init_uart(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + huart->Instance = (USART_TypeDef *)(obj_s->uart); + + huart->Init.BaudRate = obj_s->baudrate; + huart->Init.WordLength = obj_s->databits; + huart->Init.StopBits = obj_s->stopbits; + huart->Init.Parity = obj_s->parity; +#if DEVICE_SERIAL_FC + huart->Init.HwFlowCtl = obj_s->hw_flow_ctl; +#else + huart->Init.HwFlowCtl = UART_HWCONTROL_NONE; +#endif + huart->TxXferCount = 0; + huart->TxXferSize = 0; + huart->RxXferCount = 0; + huart->RxXferSize = 0; + + if (obj_s->pin_rx == NC) { + huart->Init.Mode = UART_MODE_TX; + } else if (obj_s->pin_tx == NC) { + huart->Init.Mode = UART_MODE_RX; } else { - UartHandle.Init.Mode = UART_MODE_TX_RX; + huart->Init.Mode = UART_MODE_TX_RX; } - // Disable the reception overrun detection - UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; - UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; + /* uAMR & ARM: Call to UART init is done between reset of pre-initialized variables */ + /* and before HAL Init. SystemCoreClock init required here */ + SystemCoreClockUpdate(); - HAL_UART_Init(&UartHandle); + if (HAL_UART_Init(huart) != HAL_OK) { + error("Cannot initialize UART\n"); + } } -void serial_init(serial_t *obj, PinName tx, PinName rx) { +void serial_init(serial_t *obj, PinName tx, PinName rx) +{ + struct serial_s *obj_s = SERIAL_S(obj); + // Determine the UART to use (UART_1, UART_2, ...) UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object - obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx); - MBED_ASSERT(obj->uart != (UARTName)NC); + obj_s->uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT(obj_s->uart != (UARTName)NC); // Enable USART clock - if (obj->uart == UART_1) { + if (obj_s->uart == UART_1) { __HAL_RCC_USART1_FORCE_RESET(); __HAL_RCC_USART1_RELEASE_RESET(); __HAL_RCC_USART1_CLK_ENABLE(); - obj->index = 0; + obj_s->index = 0; } #if defined USART2_BASE - if (obj->uart == UART_2) { + if (obj_s->uart == UART_2) { __HAL_RCC_USART2_FORCE_RESET(); __HAL_RCC_USART2_RELEASE_RESET(); __HAL_RCC_USART2_CLK_ENABLE(); - obj->index = 1; + obj_s->index = 1; } #endif #if defined USART3_BASE - if (obj->uart == UART_3) { + if (obj_s->uart == UART_3) { __HAL_RCC_USART3_FORCE_RESET(); __HAL_RCC_USART3_RELEASE_RESET(); __HAL_RCC_USART3_CLK_ENABLE(); - obj->index = 2; + obj_s->index = 2; } #endif #if defined USART4_BASE - if (obj->uart == UART_4) { + if (obj_s->uart == UART_4) { __HAL_RCC_USART4_FORCE_RESET(); __HAL_RCC_USART4_RELEASE_RESET(); __HAL_RCC_USART4_CLK_ENABLE(); - obj->index = 3; + obj_s->index = 3; } #endif #if defined USART5_BASE - if (obj->uart == UART_5) { + if (obj_s->uart == UART_5) { __HAL_RCC_USART5_FORCE_RESET(); __HAL_RCC_USART5_RELEASE_RESET(); __HAL_RCC_USART5_CLK_ENABLE(); - obj->index = 4; + obj_s->index = 4; } #endif #if defined USART6_BASE - if (obj->uart == UART_6) { + if (obj_s->uart == UART_6) { __HAL_RCC_USART6_FORCE_RESET(); __HAL_RCC_USART6_RELEASE_RESET(); __HAL_RCC_USART6_CLK_ENABLE(); - obj->index = 5; + obj_s->index = 5; } #endif #if defined USART7_BASE - if (obj->uart == UART_7) { + if (obj_s->uart == UART_7) { __HAL_RCC_USART7_FORCE_RESET(); __HAL_RCC_USART7_RELEASE_RESET(); __HAL_RCC_USART7_CLK_ENABLE(); - obj->index = 6; + obj_s->index = 6; } #endif #if defined USART8_BASE - if (obj->uart == UART_8) { + if (obj_s->uart == UART_8) { __HAL_RCC_USART8_FORCE_RESET(); __HAL_RCC_USART8_RELEASE_RESET(); __HAL_RCC_USART8_CLK_ENABLE(); - obj->index = 7; + obj_s->index = 7; } #endif // Configure the UART pins pinmap_pinout(tx, PinMap_UART_TX); pinmap_pinout(rx, PinMap_UART_RX); + if (tx != NC) { pin_mode(tx, PullUp); } @@ -181,33 +194,40 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) { } // Configure UART - obj->baudrate = 9600; - obj->databits = UART_WORDLENGTH_8B; - obj->stopbits = UART_STOPBITS_1; - obj->parity = UART_PARITY_NONE; + obj_s->baudrate = 9600; + obj_s->databits = UART_WORDLENGTH_8B; + obj_s->stopbits = UART_STOPBITS_1; + obj_s->parity = UART_PARITY_NONE; + +#if DEVICE_SERIAL_FC + obj_s->hw_flow_ctl = UART_HWCONTROL_NONE; +#endif - obj->pin_tx = tx; - obj->pin_rx = rx; + obj_s->pin_tx = tx; + obj_s->pin_rx = rx; init_uart(obj); // For stdio management - if (obj->uart == STDIO_UART) { + if (obj_s->uart == STDIO_UART) { stdio_uart_inited = 1; memcpy(&stdio_uart, obj, sizeof(serial_t)); } } -void serial_free(serial_t *obj) { +void serial_free(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + // Reset UART and disable clock - if (obj->uart == UART_1) { + if (obj_s->uart == UART_1) { __USART1_FORCE_RESET(); __USART1_RELEASE_RESET(); __USART1_CLK_DISABLE(); } #if defined(USART2_BASE) - if (obj->uart == UART_2) { + if (obj_s->uart == UART_2) { __USART2_FORCE_RESET(); __USART2_RELEASE_RESET(); __USART2_CLK_DISABLE(); @@ -215,7 +235,7 @@ void serial_free(serial_t *obj) { #endif #if defined USART3_BASE - if (obj->uart == UART_3) { + if (obj_s->uart == UART_3) { __USART3_FORCE_RESET(); __USART3_RELEASE_RESET(); __USART3_CLK_DISABLE(); @@ -223,7 +243,7 @@ void serial_free(serial_t *obj) { #endif #if defined USART4_BASE - if (obj->uart == UART_4) { + if (obj_s->uart == UART_4) { __USART4_FORCE_RESET(); __USART4_RELEASE_RESET(); __USART4_CLK_DISABLE(); @@ -231,7 +251,7 @@ void serial_free(serial_t *obj) { #endif #if defined USART5_BASE - if (obj->uart == UART_5) { + if (obj_s->uart == UART_5) { __USART5_FORCE_RESET(); __USART5_RELEASE_RESET(); __USART5_CLK_DISABLE(); @@ -239,7 +259,7 @@ void serial_free(serial_t *obj) { #endif #if defined USART6_BASE - if (obj->uart == UART_6) { + if (obj_s->uart == UART_6) { __USART6_FORCE_RESET(); __USART6_RELEASE_RESET(); __USART6_CLK_DISABLE(); @@ -247,7 +267,7 @@ void serial_free(serial_t *obj) { #endif #if defined USART7_BASE - if (obj->uart == UART_7) { + if (obj_s->uart == UART_7) { __USART7_FORCE_RESET(); __USART7_RELEASE_RESET(); __USART7_CLK_DISABLE(); @@ -255,51 +275,56 @@ void serial_free(serial_t *obj) { #endif #if defined USART8_BASE - if (obj->uart == UART_8) { + if (obj_s->uart == UART_8) { __USART8_FORCE_RESET(); __USART8_RELEASE_RESET(); __USART8_CLK_DISABLE(); } #endif - // Configure GPIOs - pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - pin_function(obj->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); + pin_function(obj_s->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); + pin_function(obj_s->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); - serial_irq_ids[obj->index] = 0; + serial_irq_ids[obj_s->index] = 0; } -void serial_baud(serial_t *obj, int baudrate) { - obj->baudrate = baudrate; +void serial_baud(serial_t *obj, int baudrate) +{ + struct serial_s *obj_s = SERIAL_S(obj); + + obj_s->baudrate = baudrate; init_uart(obj); } -void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) +{ + struct serial_s *obj_s = SERIAL_S(obj); + if (data_bits == 9) { - obj->databits = UART_WORDLENGTH_9B; + obj_s->databits = UART_WORDLENGTH_9B; } else { - obj->databits = UART_WORDLENGTH_8B; + obj_s->databits = UART_WORDLENGTH_8B; } switch (parity) { case ParityOdd: - case ParityForced0: - obj->parity = UART_PARITY_ODD; + obj_s->parity = UART_PARITY_ODD; break; case ParityEven: - case ParityForced1: - obj->parity = UART_PARITY_EVEN; + obj_s->parity = UART_PARITY_EVEN; break; default: // ParityNone - obj->parity = UART_PARITY_NONE; + case ParityForced0: // unsupported! + case ParityForced1: // unsupported! + obj_s->parity = UART_PARITY_NONE; break; } if (stop_bits == 2) { - obj->stopbits = UART_STOPBITS_2; + obj_s->stopbits = UART_STOPBITS_2; } else { - obj->stopbits = UART_STOPBITS_1; + obj_s->stopbits = UART_STOPBITS_1; } init_uart(obj); @@ -309,116 +334,139 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b * INTERRUPTS HANDLING ******************************************************************************/ -static void uart_irq(UARTName name, int id) { - UartHandle.Instance = (USART_TypeDef *)name; +static void uart_irq(int id) +{ + UART_HandleTypeDef * huart = &uart_handlers[id]; + if (serial_irq_ids[id] != 0) { - if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) { - irq_handler(serial_irq_ids[id], TxIrq); - __HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC); + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) { + if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) { + irq_handler(serial_irq_ids[id], TxIrq); + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); + } } - if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) { - irq_handler(serial_irq_ids[id], RxIrq); - volatile uint32_t tmpval = UartHandle.Instance->RDR; // Clear RXNE bit + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) { + if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) { + irq_handler(serial_irq_ids[id], RxIrq); + volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag + } + } + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) { + if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ORE) != RESET) { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + } } } } -static void uart1_irq(void) { - uart_irq(UART_1, 0); +static void uart1_irq(void) +{ + uart_irq(0); } #if defined(USART2_BASE) -static void uart2_irq(void) { - uart_irq(UART_2, 1); +static void uart2_irq(void) +{ + uart_irq(1); } #endif #if defined USART3_BASE -static void uart3_irq(void) { - uart_irq(UART_3, 2); +static void uart3_irq(void) +{ + uart_irq(2); } #endif #if defined USART4_BASE -static void uart4_irq(void) { - uart_irq(UART_4, 3); +static void uart4_irq(void) +{ + uart_irq(3); } #endif #if defined USART5_BASE -static void uart5_irq(void) { - uart_irq(UART_5, 4); +static void uart5_irq(void) +{ + uart_irq(4); } #endif #if defined USART6_BASE -static void uart6_irq(void) { - uart_irq(UART_6, 5); +static void uart6_irq(void) +{ + uart_irq(5); } #endif #if defined USART7_BASE -static void uart7_irq(void) { - uart_irq(UART_7, 6); +static void uart7_irq(void) +{ + uart_irq(6); } #endif #if defined USART8_BASE -static void uart8_irq(void) { - uart_irq(UART_8, 7); +static void uart8_irq(void) +{ + uart_irq(7); } #endif -void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) +{ + struct serial_s *obj_s = SERIAL_S(obj); + irq_handler = handler; - serial_irq_ids[obj->index] = id; + serial_irq_ids[obj_s->index] = id; } -void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; IRQn_Type irq_n = (IRQn_Type)0; uint32_t vector = 0; - UartHandle.Instance = (USART_TypeDef *)(obj->uart); - - if (obj->uart == UART_1) { + if (obj_s->uart == UART_1) { irq_n = USART1_IRQn; vector = (uint32_t)&uart1_irq; } #if defined(USART2_BASE) - if (obj->uart == UART_2) { + if (obj_s->uart == UART_2) { irq_n = USART2_IRQn; vector = (uint32_t)&uart2_irq; } #endif #if defined (TARGET_STM32F091RC) - if (obj->uart == UART_3) { + if (obj_s->uart == UART_3) { irq_n = USART3_8_IRQn; vector = (uint32_t)&uart3_irq; } - if (obj->uart == UART_4) { + if (obj_s->uart == UART_4) { irq_n = USART3_8_IRQn; vector = (uint32_t)&uart4_irq; } - if (obj->uart == UART_5) { + if (obj_s->uart == UART_5) { irq_n = USART3_8_IRQn; vector = (uint32_t)&uart5_irq; } - if (obj->uart == UART_6) { + if (obj_s->uart == UART_6) { irq_n = USART3_8_IRQn; vector = (uint32_t)&uart6_irq; } - if (obj->uart == UART_7) { + if (obj_s->uart == UART_7) { irq_n = USART3_8_IRQn; vector = (uint32_t)&uart7_irq; } - if (obj->uart == UART_8) { + if (obj_s->uart == UART_8) { irq_n = USART3_8_IRQn; vector = (uint32_t)&uart8_irq; } @@ -427,14 +475,14 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { #else #if defined(USART3_BASE) - if (obj->uart == UART_3) { + if (obj_s->uart == UART_3) { irq_n = USART3_4_IRQn; vector = (uint32_t)&uart3_irq; } #endif #if defined(USART4_BASE) - if (obj->uart == UART_4) { + if (obj_s->uart == UART_4) { irq_n = USART3_4_IRQn; vector = (uint32_t)&uart4_irq; } @@ -442,32 +490,33 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { #endif if (enable) { - if (irq == RxIrq) { - __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); + __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); } else { // TxIrq - __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC); + __HAL_UART_ENABLE_IT(huart, UART_IT_TC); } - NVIC_SetVector(irq_n, vector); NVIC_EnableIRQ(irq_n); } else { // disable - int all_disabled = 0; - if (irq == RxIrq) { - __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE); + __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); // Check if TxIrq is disabled too - if ((UartHandle.Instance->CR1 & USART_CR1_TCIE) == 0) all_disabled = 1; + if ((huart->Instance->CR1 & USART_CR1_TXEIE) == 0) { + all_disabled = 1; + } } else { // TxIrq - __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC); + __HAL_UART_DISABLE_IT(huart, UART_IT_TC); // Check if RxIrq is disabled too - if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; + if ((huart->Instance->CR1 & USART_CR1_RXNEIE) == 0) { + all_disabled = 1; + } } - if (all_disabled) NVIC_DisableIRQ(irq_n); - + if (all_disabled) { + NVIC_DisableIRQ(irq_n); + } } } @@ -475,50 +524,531 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { * READ/WRITE ******************************************************************************/ -int serial_getc(serial_t *obj) { - USART_TypeDef *uart = (USART_TypeDef *)(obj->uart); +int serial_getc(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + while (!serial_readable(obj)); - return (int)(uart->RDR & (uint16_t)0xFF); + return (int)(huart->Instance->RDR & (uint16_t)0xFF); } -void serial_putc(serial_t *obj, int c) { - USART_TypeDef *uart = (USART_TypeDef *)(obj->uart); +void serial_putc(serial_t *obj, int c) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + while (!serial_writable(obj)); - uart->TDR = (uint32_t)(c & (uint16_t)0xFF); + huart->Instance->TDR = (uint32_t)(c & (uint16_t)0xFF); } -int serial_readable(serial_t *obj) { - int status; - UartHandle.Instance = (USART_TypeDef *)(obj->uart); +int serial_readable(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + // Check if data is received - status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0); - return status; + return (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) ? 1 : 0; } -int serial_writable(serial_t *obj) { - int status; - UartHandle.Instance = (USART_TypeDef *)(obj->uart); +int serial_writable(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + // Check if data is transmitted - status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0); - return status; + return (__HAL_UART_GET_FLAG(huart, UART_FLAG_TXE) != RESET) ? 1 : 0; } -void serial_clear(serial_t *obj) { - UartHandle.Instance = (USART_TypeDef *)(obj->uart); - __HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC); - __HAL_UART_SEND_REQ(&UartHandle, UART_RXDATA_FLUSH_REQUEST); +void serial_clear(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + huart->TxXferCount = 0; + huart->RxXferCount = 0; } -void serial_pinout_tx(PinName tx) { +void serial_pinout_tx(PinName tx) +{ pinmap_pinout(tx, PinMap_UART_TX); } -void serial_break_set(serial_t *obj) { - // [TODO] +void serial_break_set(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + //HAL_LIN_SendBreak(huart); +} + +void serial_break_clear(serial_t *obj) +{ + (void)obj; +} + +#if DEVICE_SERIAL_ASYNCH + +/****************************************************************************** + * LOCAL HELPER FUNCTIONS + ******************************************************************************/ + +/** + * Configure the TX buffer for an asynchronous write serial transaction + * + * @param obj The serial object. + * @param tx The buffer for sending. + * @param tx_length The number of words to transmit. + */ +static void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width) +{ + (void)width; + + // Exit if a transmit is already on-going + if (serial_tx_active(obj)) { + return; + } + + obj->tx_buff.buffer = tx; + obj->tx_buff.length = tx_length; + obj->tx_buff.pos = 0; +} + +/** + * Configure the RX buffer for an asynchronous write serial transaction + * + * @param obj The serial object. + * @param tx The buffer for sending. + * @param tx_length The number of words to transmit. + */ +static void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width) +{ + (void)width; + + // Exit if a reception is already on-going + if (serial_rx_active(obj)) { + return; + } + + obj->rx_buff.buffer = rx; + obj->rx_buff.length = rx_length; + obj->rx_buff.pos = 0; } -void serial_break_clear(serial_t *obj) { - // [TODO] +/** + * Configure events + * + * @param obj The serial object + * @param event The logical OR of the events to configure + * @param enable Set to non-zero to enable events, or zero to disable them + */ +static void serial_enable_event(serial_t *obj, int event, uint8_t enable) +{ + struct serial_s *obj_s = SERIAL_S(obj); + + // Shouldn't have to enable interrupt here, just need to keep track of the requested events. + if (enable) { + obj_s->events |= event; + } else { + obj_s->events &= ~event; + } } + +/** +* Get index of serial object TX IRQ, relating it to the physical peripheral. +* +* @param obj pointer to serial object +* @return internal NVIC TX IRQ index of U(S)ART peripheral +*/ +static IRQn_Type serial_get_irq_n(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + IRQn_Type irq_n; + + switch (obj_s->index) { +#if defined(USART1_BASE) + case 0: + irq_n = USART1_IRQn; + break; +#endif +#if defined(USART2_BASE) + case 1: + irq_n = USART2_IRQn; + break; +#endif +#if defined (TARGET_STM32F091RC) + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + irq_n = USART3_8_IRQn; + break; +#elif !defined (TARGET_STM32F030R8) && !defined (TARGET_STM32F051R8) + case 2: + case 3: + irq_n = USART3_4_IRQn; + break; +#endif + default: + irq_n = (IRQn_Type)0; + } + + return irq_n; +} + + +/****************************************************************************** + * MBED API FUNCTIONS + ******************************************************************************/ + +/** + * Begin asynchronous TX transfer. The used buffer is specified in the serial + * object, tx_buff + * + * @param obj The serial object + * @param tx The buffer for sending + * @param tx_length The number of words to transmit + * @param tx_width The bit width of buffer word + * @param handler The serial handler + * @param event The logical OR of events to be registered + * @param hint A suggestion for how to use DMA with this transfer + * @return Returns number of data transfered, or 0 otherwise + */ +int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint) +{ + // TODO: DMA usage is currently ignored + (void) hint; + + // Check buffer is ok + MBED_ASSERT(tx != (void*)0); + MBED_ASSERT(tx_width == 8); // support only 8b width + + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef * huart = &uart_handlers[obj_s->index]; + + if (tx_length == 0) { + return 0; + } + + // Set up buffer + serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width); + + // Set up events + serial_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events + serial_enable_event(obj, event, 1); // Set only the wanted events + + // Enable interrupt + IRQn_Type irq_n = serial_get_irq_n(obj); + NVIC_ClearPendingIRQ(irq_n); + NVIC_DisableIRQ(irq_n); + NVIC_SetPriority(irq_n, 1); + NVIC_SetVector(irq_n, (uint32_t)handler); + NVIC_EnableIRQ(irq_n); + + // the following function will enable UART_IT_TXE and error interrupts + if (HAL_UART_Transmit_IT(huart, (uint8_t*)tx, tx_length) != HAL_OK) { + return 0; + } + + return tx_length; +} + +/** + * Begin asynchronous RX transfer (enable interrupt for data collecting) + * The used buffer is specified in the serial object, rx_buff + * + * @param obj The serial object + * @param rx The buffer for sending + * @param rx_length The number of words to transmit + * @param rx_width The bit width of buffer word + * @param handler The serial handler + * @param event The logical OR of events to be registered + * @param handler The serial handler + * @param char_match A character in range 0-254 to be matched + * @param hint A suggestion for how to use DMA with this transfer + */ +void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint) +{ + // TODO: DMA usage is currently ignored + (void) hint; + + /* Sanity check arguments */ + MBED_ASSERT(obj); + MBED_ASSERT(rx != (void*)0); + MBED_ASSERT(rx_width == 8); // support only 8b width + + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + serial_enable_event(obj, SERIAL_EVENT_RX_ALL, 0); + serial_enable_event(obj, event, 1); + + // set CharMatch + obj->char_match = char_match; + + serial_rx_buffer_set(obj, rx, rx_length, rx_width); + + IRQn_Type irq_n = serial_get_irq_n(obj); + NVIC_ClearPendingIRQ(irq_n); + NVIC_DisableIRQ(irq_n); + NVIC_SetPriority(irq_n, 0); + NVIC_SetVector(irq_n, (uint32_t)handler); + NVIC_EnableIRQ(irq_n); + + // following HAL function will enable the RXNE interrupt + error interrupts + HAL_UART_Receive_IT(huart, (uint8_t*)rx, rx_length); +} + +/** + * Attempts to determine if the serial peripheral is already in use for TX + * + * @param obj The serial object + * @return Non-zero if the TX transaction is ongoing, 0 otherwise + */ +uint8_t serial_tx_active(serial_t *obj) +{ + MBED_ASSERT(obj); + + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + return ((HAL_UART_GetState(huart) == HAL_UART_STATE_BUSY_TX) ? 1 : 0); +} + +/** + * Attempts to determine if the serial peripheral is already in use for RX + * + * @param obj The serial object + * @return Non-zero if the RX transaction is ongoing, 0 otherwise + */ +uint8_t serial_rx_active(serial_t *obj) +{ + MBED_ASSERT(obj); + + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + return ((HAL_UART_GetState(huart) == HAL_UART_STATE_BUSY_RX) ? 1 : 0); +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); + } +} + +void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); + } + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); + } + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_NE) != RESET) { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); + } + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + } +} + +/** + * The asynchronous TX and RX handler. + * + * @param obj The serial object + * @return Returns event flags if a TX/RX transfer termination condition was met or 0 otherwise + */ +int serial_irq_handler_asynch(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + volatile int return_event = 0; + uint8_t *buf = (uint8_t*)(obj->rx_buff.buffer); + uint8_t i = 0; + + // TX PART: + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_TC) != RESET) { + if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET) { + // Return event SERIAL_EVENT_TX_COMPLETE if requested + if ((obj_s->events & SERIAL_EVENT_TX_COMPLETE ) != 0) { + return_event |= (SERIAL_EVENT_TX_COMPLETE & obj_s->events); + } + } + } + + // Handle error events + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE) != RESET) { + if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) { + return_event |= (SERIAL_EVENT_RX_PARITY_ERROR & obj_s->events); + } + } + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) { + if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) { + return_event |= (SERIAL_EVENT_RX_FRAMING_ERROR & obj_s->events); + } + } + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) { + if (__HAL_UART_GET_IT_SOURCE(huart, USART_IT_ERR) != RESET) { + return_event |= (SERIAL_EVENT_RX_OVERRUN_ERROR & obj_s->events); + } + } + + HAL_UART_IRQHandler(huart); + + // Abort if an error occurs + if (return_event & SERIAL_EVENT_RX_PARITY_ERROR || + return_event & SERIAL_EVENT_RX_FRAMING_ERROR || + return_event & SERIAL_EVENT_RX_OVERRUN_ERROR) { + return return_event; + } + + //RX PART + if (huart->RxXferSize != 0) { + obj->rx_buff.pos = huart->RxXferSize - huart->RxXferCount; + } + if ((huart->RxXferCount == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) { + return_event |= (SERIAL_EVENT_RX_COMPLETE & obj_s->events); + } + + // Check if char_match is present + if (obj_s->events & SERIAL_EVENT_RX_CHARACTER_MATCH) { + if (buf != NULL) { + for (i = 0; i < obj->rx_buff.pos; i++) { + if (buf[i] == obj->char_match) { + obj->rx_buff.pos = i; + return_event |= (SERIAL_EVENT_RX_CHARACTER_MATCH & obj_s->events); + serial_rx_abort_asynch(obj); + break; + } + } + } + } + + return return_event; +} + +/** + * Abort the ongoing TX transaction. It disables the enabled interupt for TX and + * flush TX hardware buffer if TX FIFO is used + * + * @param obj The serial object + */ +void serial_tx_abort_asynch(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + __HAL_UART_DISABLE_IT(huart, UART_IT_TC); + __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); + + // clear flags + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); + + // reset states + huart->TxXferCount = 0; + // update handle state + if(huart->gState == HAL_UART_STATE_BUSY_TX_RX) { + huart->gState = HAL_UART_STATE_BUSY_RX; + } else { + huart->gState = HAL_UART_STATE_READY; + } +} + +/** + * Abort the ongoing RX transaction It disables the enabled interrupt for RX and + * flush RX hardware buffer if RX FIFO is used + * + * @param obj The serial object + */ +void serial_rx_abort_asynch(serial_t *obj) +{ + struct serial_s *obj_s = SERIAL_S(obj); + UART_HandleTypeDef *huart = &uart_handlers[obj_s->index]; + + // disable interrupts + __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); + __HAL_UART_DISABLE_IT(huart, UART_IT_PE); + __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); + + // clear flags + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF | UART_CLEAR_FEF | UART_CLEAR_OREF); + volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag + + // reset states + huart->RxXferCount = 0; + // update handle state + if(huart->RxState == HAL_UART_STATE_BUSY_TX_RX) { + huart->RxState = HAL_UART_STATE_BUSY_TX; + } else { + huart->RxState = HAL_UART_STATE_READY; + } +} + +#endif + +#if DEVICE_SERIAL_FC + +/** + * Set HW Control Flow + * @param obj The serial object + * @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS) + * @param rxflow Pin for the rxflow + * @param txflow Pin for the txflow + */ +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) +{ + struct serial_s *obj_s = SERIAL_S(obj); + + // Determine the UART to use (UART_1, UART_2, ...) + UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS); + UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS); + + // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object + obj_s->uart = (UARTName)pinmap_merge(uart_cts, uart_rts); + MBED_ASSERT(obj_s->uart != (UARTName)NC); + + if(type == FlowControlNone) { + // Disable hardware flow control + obj_s->hw_flow_ctl = UART_HWCONTROL_NONE; + } + if (type == FlowControlRTS) { + // Enable RTS + MBED_ASSERT(uart_rts != (UARTName)NC); + obj_s->hw_flow_ctl = UART_HWCONTROL_RTS; + obj_s->pin_rts = rxflow; + // Enable the pin for RTS function + pinmap_pinout(rxflow, PinMap_UART_RTS); + } + if (type == FlowControlCTS) { + // Enable CTS + MBED_ASSERT(uart_cts != (UARTName)NC); + obj_s->hw_flow_ctl = UART_HWCONTROL_CTS; + obj_s->pin_cts = txflow; + // Enable the pin for CTS function + pinmap_pinout(txflow, PinMap_UART_CTS); + } + if (type == FlowControlRTSCTS) { + // Enable CTS & RTS + MBED_ASSERT(uart_rts != (UARTName)NC); + MBED_ASSERT(uart_cts != (UARTName)NC); + obj_s->hw_flow_ctl = UART_HWCONTROL_RTS_CTS; + obj_s->pin_rts = rxflow; + obj_s->pin_cts = txflow; + // Enable the pin for CTS function + pinmap_pinout(txflow, PinMap_UART_CTS); + // Enable the pin for RTS function + pinmap_pinout(rxflow, PinMap_UART_RTS); + } + + init_uart(obj); +} + +#endif + #endif diff --git a/libraries/tests/utest/serial_asynch/serial_asynch.cpp b/libraries/tests/utest/serial_asynch/serial_asynch.cpp index 7daf9bf05a3..6ee6aad4468 100644 --- a/libraries/tests/utest/serial_asynch/serial_asynch.cpp +++ b/libraries/tests/utest/serial_asynch/serial_asynch.cpp @@ -63,6 +63,18 @@ #define TEST_SERIAL_ONE_TX_PIN PB_10 // UART3 #define TEST_SERIAL_TWO_RX_PIN PA_10 // UART1 +#elif defined(TARGET_NUCLEO_F070RB) +#define TEST_SERIAL_ONE_TX_PIN PB_10 // UART3 +#define TEST_SERIAL_TWO_RX_PIN PA_10 // UART1 + +#elif defined(TARGET_NUCLEO_F072RB) +#define TEST_SERIAL_ONE_TX_PIN PB_10 // UART3 +#define TEST_SERIAL_TWO_RX_PIN PA_10 // UART1 + +#elif defined(TARGET_NUCLEO_F091RC) +#define TEST_SERIAL_ONE_TX_PIN PB_6 // UART1 +#define TEST_SERIAL_TWO_RX_PIN PC_7 // UART7 + #elif defined(TARGET_NUCLEO_F207ZG) #define TEST_SERIAL_ONE_TX_PIN PC_12 // UART5 #define TEST_SERIAL_TWO_RX_PIN PC_11 // UART4