mbed library sources. Supersedes mbed-src. GR-PEACH runs on RAM.
Fork of mbed-dev by
Revision 69:41db872bbc3a, committed 2016-02-22
- Comitter:
- mbed_official
- Date:
- Mon Feb 22 13:15:10 2016 +0000
- Parent:
- 68:59749b18b9de
- Child:
- 70:885f1c2f67b1
- Commit message:
- Synchronized with git revision 028465a9b8e42300bf0eb1b362f8f474f40fae9b
Full URL: https://github.com/mbedmicro/mbed/commit/028465a9b8e42300bf0eb1b362f8f474f40fae9b/
Use only the index, not the UARTName any more.
In case of app with 2 serial (using DMA) + 1 serial (stdio), we have found a bug. The dma handler is overwritten by the last initialized serial object.
Therefore read and write functions did not work anymore.
We have reworked this file to save 1 handler per UART IP, and align it with MBED OS file.
Tests have been passed. Same status as before (OK except MBED_37, manual test for SERIAL_ASYNC also OK).
Changed in this revision
--- a/targets/hal/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/objects.h Mon Feb 22 11:15:09 2016 +0000 +++ b/targets/hal/TARGET_STM/TARGET_STM32F4/TARGET_B96B_F446VE/objects.h Mon Feb 22 13:15:10 2016 +0000 @@ -66,8 +66,7 @@ }; struct serial_s { - UARTName uart; - int index; // Used by irq + int index; uint32_t baudrate; uint32_t databits; uint32_t stopbits;
--- a/targets/hal/TARGET_STM/TARGET_STM32F4/serial_api.c Mon Feb 22 11:15:09 2016 +0000 +++ b/targets/hal/TARGET_STM/TARGET_STM32F4/serial_api.c Mon Feb 22 13:15:10 2016 +0000 @@ -27,7 +27,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* */ +#ifdef YOTTA_CFG_MBED_OS +#include "target_config.h" +#include "uvisor-lib/uvisor-lib.h" +#include "mbed-drivers/mbed_assert.h" +#else #include "mbed_assert.h" +#endif #include "serial_api.h" #if DEVICE_SERIAL @@ -36,25 +42,53 @@ #include "pinmap.h" #include <string.h> #include "PeripheralPins.h" +#ifdef YOTTA_CFG_MBED_OS +#include "mbed-drivers/mbed_error.h" +#else #include "mbed_error.h" +#endif + +#define DEBUG_STDIO 0 + +#ifndef DEBUG_STDIO +# define DEBUG_STDIO 0 +#endif + +#if DEBUG_STDIO +# include <stdio.h> +# define DEBUG_PRINTF(...) do { printf(__VA_ARGS__); } while(0) +#else +# define DEBUG_PRINTF(...) {} +#endif #define UART_NUM (8) #define UART_STATE_RX_ACTIVE 0x20 #define UART_STATE_TX_ACTIVE 0x10 -static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0, 0, 0, 0}; +#if DEVICE_SERIAL_ASYNCH_DMA +static const uint32_t DMA_UartRx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, \ + DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5}; +DMA_Stream_TypeDef *DMA_UartRx_Stream[UART_NUM] = { + DMA2_Stream5, DMA1_Stream5, DMA1_Stream1, \ + DMA1_Stream2, DMA1_Stream0, DMA2_Stream1, \ + DMA1_Stream3, DMA1_Stream6 +}; +static const uint32_t DMA_UartTx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, \ + DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5}; +DMA_Stream_TypeDef *DMA_UartTx_Stream[UART_NUM] = { + DMA2_Stream7, DMA1_Stream6, DMA1_Stream3, \ + DMA1_Stream4, DMA1_Stream7, DMA2_Stream6,\ + DMA1_Stream1, DMA1_Stream0 +}; +DMA_HandleTypeDef DmaHandle; +#endif -#if DEVICE_SERIAL_ASYNCH_DMA -static const uint32_t DMA_UartRx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5}; -static const uint32_t DMA_UartRx_Stream[UART_NUM] = {(uint32_t)DMA2_Stream5, (uint32_t) DMA1_Stream5, (uint32_t) DMA1_Stream1, (uint32_t) DMA1_Stream2, (uint32_t) DMA1_Stream0, (uint32_t) DMA2_Stream5, (uint32_t) DMA1_Stream3, (uint32_t) DMA1_Stream6}; -static const uint32_t DMA_UartTx_Channel[UART_NUM] = {DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_4, DMA_CHANNEL_5, DMA_CHANNEL_5, DMA_CHANNEL_5}; -static const uint32_t DMA_UartTx_Stream[UART_NUM] = {(uint32_t)DMA2_Stream7, (uint32_t) DMA1_Stream6, (uint32_t) DMA1_Stream3, (uint32_t) DMA1_Stream4, (uint32_t) DMA1_Stream7, (uint32_t) DMA2_Stream6, (uint32_t) DMA1_Stream1, (uint32_t) DMA1_Stream0}; - -#endif +uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0, 0, 0, 0}; static uart_irq_handler irq_handler; -DMA_HandleTypeDef DmaHandle; -UART_HandleTypeDef UartHandle; +static DMA_HandleTypeDef DmaTxHandle[UART_NUM]; +static DMA_HandleTypeDef DmaRxHandle[UART_NUM]; +static UART_HandleTypeDef UartHandle[UART_NUM]; int stdio_uart_inited = 0; serial_t stdio_uart; @@ -65,81 +99,91 @@ #define SERIAL_OBJ(X) (obj->X) #endif -static void init_uart(serial_t *obj) +static void init_uart(serial_t *obj, UARTName instance) { -#if DEVICE_SERIAL_ASYNCH_DMA - static DMA_HandleTypeDef hdma_tx; - static DMA_HandleTypeDef hdma_rx; -#endif - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + handle->Instance = (USART_TypeDef *)instance; - UartHandle.Init.BaudRate = SERIAL_OBJ(baudrate); - UartHandle.Init.WordLength = SERIAL_OBJ(databits); - UartHandle.Init.StopBits = SERIAL_OBJ(stopbits); - UartHandle.Init.Parity = SERIAL_OBJ(parity); + handle->Init.BaudRate = SERIAL_OBJ(baudrate); + handle->Init.WordLength = SERIAL_OBJ(databits); + handle->Init.StopBits = SERIAL_OBJ(stopbits); + handle->Init.Parity = SERIAL_OBJ(parity); #if DEVICE_SERIAL_FC - UartHandle.Init.HwFlowCtl = SERIAL_OBJ(hw_flow_ctl); + handle->Init.HwFlowCtl = SERIAL_OBJ(hw_flow_ctl); #else - UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + handle->Init.HwFlowCtl = UART_HWCONTROL_NONE; #endif - UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; + handle->Init.OverSampling = UART_OVERSAMPLING_16; + handle->TxXferCount = 0; + handle->RxXferCount = 0; if (SERIAL_OBJ(pin_rx) == NC) { - UartHandle.Init.Mode = UART_MODE_TX; + handle->Init.Mode = UART_MODE_TX; } else if (SERIAL_OBJ(pin_tx) == NC) { - UartHandle.Init.Mode = UART_MODE_RX; + handle->Init.Mode = UART_MODE_RX; } else { - UartHandle.Init.Mode = UART_MODE_TX_RX; + handle->Init.Mode = UART_MODE_TX_RX; } + +#ifdef YOTTA_CFG_MBED_OS + if (SERIAL_OBJ(pin_tx) == STDIO_UART_TX && SERIAL_OBJ(pin_rx) == STDIO_UART_RX) { + handle->Init.BaudRate = YOTTA_CFG_MBED_OS_STDIO_DEFAULT_BAUD; + } +#endif + #if DEVICE_SERIAL_ASYNCH_DMA if (SERIAL_OBJ(pin_tx) != NC) { // set DMA in the UartHandle + DMA_HandleTypeDef *hdma_tx = &DmaTxHandle[SERIAL_OBJ(index)]; /* Configure the DMA handler for Transmission process */ - hdma_tx.Instance = (DMA_Stream_TypeDef *)DMA_UartTx_Stream[SERIAL_OBJ(index)]; - hdma_tx.Init.Channel = DMA_UartTx_Channel[SERIAL_OBJ(index)]; - hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; - hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; - hdma_tx.Init.MemInc = DMA_MINC_ENABLE; - hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_tx.Init.Mode = DMA_NORMAL; - hdma_tx.Init.Priority = DMA_PRIORITY_LOW; - hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; - hdma_tx.Init.MemBurst = DMA_MBURST_INC4; - hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4; + hdma_tx->Instance = (DMA_Stream_TypeDef *)DMA_UartTx_Stream[SERIAL_OBJ(index)]; + hdma_tx->Init.Channel = DMA_UartTx_Channel[SERIAL_OBJ(index)]; + hdma_tx->Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_tx->Init.PeriphInc = DMA_PINC_DISABLE; + hdma_tx->Init.MemInc = DMA_MINC_ENABLE; + hdma_tx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_tx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_tx->Init.Mode = DMA_NORMAL; + hdma_tx->Init.Priority = DMA_PRIORITY_LOW; + hdma_tx->Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_tx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_tx->Init.MemBurst = DMA_MBURST_INC4; + hdma_tx->Init.PeriphBurst = DMA_PBURST_INC4; - HAL_DMA_Init(&hdma_tx); + HAL_DMA_Init(hdma_tx); /* Associate the initialized DMA handle to the UART handle */ - __HAL_LINKDMA(&UartHandle, hdmatx, hdma_tx); + handle->hdmatx = hdma_tx; + hdma_tx->Parent = handle; } if (SERIAL_OBJ(pin_rx) != NC) { /* Configure the DMA handler for reception process */ - hdma_rx.Instance = (DMA_Stream_TypeDef *)DMA_UartRx_Stream[SERIAL_OBJ(index)]; - hdma_rx.Init.Channel = DMA_UartRx_Channel[SERIAL_OBJ(index)]; - hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; - hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; - hdma_rx.Init.MemInc = DMA_MINC_ENABLE; - hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - hdma_rx.Init.Mode = DMA_NORMAL; - hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; - hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; - hdma_rx.Init.MemBurst = DMA_MBURST_INC4; - hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4; + DMA_HandleTypeDef *hdma_rx = &DmaRxHandle[SERIAL_OBJ(index)]; + hdma_rx->Instance = (DMA_Stream_TypeDef *)DMA_UartRx_Stream[SERIAL_OBJ(index)]; + hdma_rx->Init.Channel = DMA_UartRx_Channel[SERIAL_OBJ(index)]; + hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE; + hdma_rx->Init.MemInc = DMA_MINC_ENABLE; + hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_rx->Init.Mode = DMA_NORMAL; + hdma_rx->Init.Priority = DMA_PRIORITY_HIGH; + hdma_rx->Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_rx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_rx->Init.MemBurst = DMA_MBURST_INC4; + hdma_rx->Init.PeriphBurst = DMA_PBURST_INC4; - HAL_DMA_Init(&hdma_rx); + HAL_DMA_Init(hdma_rx); /* Associate the initialized DMA handle to the UART handle */ - __HAL_LINKDMA(&UartHandle, hdmarx, hdma_rx); + handle->hdmarx = hdma_rx; + hdma_rx->Parent = handle; } #endif - if (HAL_UART_Init(&UartHandle) != HAL_OK) { + if (HAL_UART_Init(handle) != HAL_OK) { error("Cannot initialize UART\n"); } } @@ -151,12 +195,12 @@ 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 - SERIAL_OBJ(uart) = (UARTName)pinmap_merge(uart_tx, uart_rx); + UARTName instance = (UARTName)pinmap_merge(uart_tx, uart_rx); - MBED_ASSERT(SERIAL_OBJ(uart) != (UARTName)NC); + MBED_ASSERT(instance != (UARTName)NC); // Enable USART clock - switch (SERIAL_OBJ(uart)) { + switch (instance) { case UART_1: __HAL_RCC_USART1_CLK_ENABLE(); SERIAL_OBJ(index) = 0; @@ -247,38 +291,45 @@ SERIAL_OBJ(pin_tx) = tx; SERIAL_OBJ(pin_rx) = rx; - init_uart(obj); + init_uart(obj, instance); +#ifndef YOTTA_CFG_MBED_OS // For stdio management - if (SERIAL_OBJ(uart) == STDIO_UART) { + if ((int)(UartHandle[SERIAL_OBJ(index)].Instance) == STDIO_UART) { stdio_uart_inited = 1; memcpy(&stdio_uart, obj, sizeof(serial_t)); } +#endif + + DEBUG_PRINTF("UART%u: Init\n", obj->serial.module+1); } void serial_free(serial_t *obj) { // Reset UART and disable clock - switch (SERIAL_OBJ(uart)) { - case UART_1: + switch (SERIAL_OBJ(index)) { + case 0: __USART1_FORCE_RESET(); __USART1_RELEASE_RESET(); __USART1_CLK_DISABLE(); break; - case UART_2: + case 1: __USART2_FORCE_RESET(); __USART2_RELEASE_RESET(); __USART2_CLK_DISABLE(); +#if DEVICE_SERIAL_ASYNCH_DMA + __HAL_RCC_DMA1_CLK_DISABLE(); +#endif break; #if defined(USART3_BASE) - case UART_3: + case 2: __USART3_FORCE_RESET(); __USART3_RELEASE_RESET(); __USART3_CLK_DISABLE(); break; #endif #if defined(UART4_BASE) - case UART_4: + case 3: __UART4_FORCE_RESET(); __UART4_RELEASE_RESET(); __UART4_CLK_DISABLE(); @@ -288,100 +339,138 @@ break; #endif #if defined(UART5_BASE) - case UART_5: + case 4: __UART5_FORCE_RESET(); __UART5_RELEASE_RESET(); __UART5_CLK_DISABLE(); break; #endif #if defined(USART6_BASE) - case UART_6: + case 5: __USART6_FORCE_RESET(); __USART6_RELEASE_RESET(); __USART6_CLK_DISABLE(); break; #endif #if defined(UART7_BASE) - case UART_7: + case 6: __UART7_FORCE_RESET(); __UART7_RELEASE_RESET(); __UART7_CLK_DISABLE(); break; #endif #if defined(UART8_BASE) - case UART_8: + case 7: __UART8_FORCE_RESET(); __UART8_RELEASE_RESET(); __UART8_CLK_DISABLE(); break; #endif } + // Configure GPIOs pin_function(SERIAL_OBJ(pin_tx), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); pin_function(SERIAL_OBJ(pin_rx), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); serial_irq_ids[SERIAL_OBJ(index)] = 0; + + DEBUG_PRINTF("UART%u: Free\n", obj->serial.module+1); } void serial_baud(serial_t *obj, int baudrate) { + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + SERIAL_OBJ(baudrate) = baudrate; - init_uart(obj); + handle->Init.BaudRate = baudrate; + + if (HAL_UART_Init(handle) != HAL_OK) { + error("Cannot initialize UART\n"); + } + + DEBUG_PRINTF("UART%u: Baudrate: %u\n", obj->serial.module+1, baudrate); } void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + if (data_bits == 9) { SERIAL_OBJ(databits) = UART_WORDLENGTH_9B; + handle->Init.WordLength = UART_WORDLENGTH_9B; } else { SERIAL_OBJ(databits) = UART_WORDLENGTH_8B; + handle->Init.WordLength = UART_WORDLENGTH_8B; } switch (parity) { case ParityOdd: - case ParityForced0: SERIAL_OBJ(parity) = UART_PARITY_ODD; + handle->Init.Parity = UART_PARITY_ODD; break; case ParityEven: - case ParityForced1: SERIAL_OBJ(parity) = UART_PARITY_EVEN; + handle->Init.Parity = UART_PARITY_EVEN; break; default: // ParityNone + case ParityForced0: // unsupported! + case ParityForced1: // unsupported! SERIAL_OBJ(parity) = UART_PARITY_NONE; + handle->Init.Parity = UART_PARITY_NONE; break; } if (stop_bits == 2) { SERIAL_OBJ(stopbits) = UART_STOPBITS_2; + handle->Init.StopBits = UART_STOPBITS_2; } else { SERIAL_OBJ(stopbits) = UART_STOPBITS_1; + handle->Init.StopBits = UART_STOPBITS_1; } - init_uart(obj); + if (HAL_UART_Init(handle) != HAL_OK) { + error("Cannot initialize UART\n"); + } + + DEBUG_PRINTF("UART%u: Format: %u, %u, %u\n", obj->serial.module+1, data_bits, parity, stop_bits); } /****************************************************************************** * INTERRUPTS HANDLING ******************************************************************************/ -static void uart_irq(UARTName name, int id) +static void uart_irq(int id) { - UartHandle.Instance = (USART_TypeDef *)name; + UART_HandleTypeDef *handle = &UartHandle[id]; if (serial_irq_ids[id] != 0) { - if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) { + if (__HAL_UART_GET_FLAG(handle, UART_FLAG_TC) != RESET) { irq_handler(serial_irq_ids[id], TxIrq); - __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TC); + __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_TC); } - if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) { + if (__HAL_UART_GET_FLAG(handle, UART_FLAG_RXNE) != RESET) { irq_handler(serial_irq_ids[id], RxIrq); - __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_RXNE); + __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_RXNE); } } } + #if DEVICE_SERIAL_ASYNCH_DMA -static void dma_irq(DMAName name, int id) +static void dma_irq(DMAName name, int id, SerialIrq txrxirq) { - // TO DO + + if (serial_irq_ids[id] != 0) { + if (txrxirq == RxIrq) { + if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) { + irq_handler(serial_irq_ids[id], RxIrq); + __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF2_6); + } + } else { + if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) { + irq_handler(serial_irq_ids[id], TxIrq); + __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF0_4); + } + } + } DmaHandle.Instance = (DMA_Stream_TypeDef *)name; if (serial_irq_ids[id] != 0) { if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) { @@ -398,66 +487,131 @@ static void uart1_irq(void) { - uart_irq(UART_1, 0); + uart_irq(0); } static void uart2_irq(void) { - uart_irq(UART_2, 1); + uart_irq(1); } #if defined(USART3_BASE) static void uart3_irq(void) { - uart_irq(UART_3, 2); + uart_irq(2); } #endif #if defined(UART4_BASE) static void uart4_irq(void) { - uart_irq(UART_4, 3); + uart_irq(3); } +#endif + #if DEVICE_SERIAL_ASYNCH_DMA +#if defined(UART5_BASE) +static void dma1_stream0_irq(void) +{ + dma_irq(DMA_1, 4, RxIrq); // uart5_rx +} +#endif + +#if defined(USART3_BASE) +static void dma1_stream1_irq(void) +{ + dma_irq(DMA_1, 2, RxIrq); // uart3_rx +} +#endif + +#if defined(UART4_BASE) static void dma1_stream2_irq(void) { - dma_irq(DMA_1, 3 /* TO DO : ??? WHAT IS THIS 3 ??? */); + dma_irq(DMA_1, 3, RxIrq); // uart4_rx +} +#endif + +#if defined(USART3_BASE) +static void dma1_stream3_irq(void) +{ + dma_irq(DMA_1, 2, TxIrq); // uart3_tx +} +#endif + +#if defined(UART4_BASE) +static void dma1_stream4_irq(void) +{ + dma_irq(DMA_1, 3, TxIrq); // uart4_tx +} +#endif + +static void dma1_stream5_irq(void) +{ + dma_irq(DMA_1, 1, RxIrq); // uart2_rx +} + +static void dma1_stream6_irq(void) +{ + dma_irq(DMA_1, 1, TxIrq); // uart2_tx } +#if defined(UART5_BASE) +static void dma1_stream7_irq(void) +{ + dma_irq(DMA_1, 4, TxIrq); // uart5_tx +} +#endif -static void dma1_stream4_irq(void) +#if defined(USART6_BASE) +static void dma2_stream1_irq(void) { - dma_irq(DMA_1, 3 /* TO DO : ??? WHAT IS THIS 3 ??? */); + dma_irq(DMA_2, 5, RxIrq); // uart6_rx } #endif -#endif + +static void dma2_stream5_irq(void) +{ + dma_irq(DMA_2, 0, RxIrq); // uart1_rx +} + +static void dma2_stream6_irq(void) +{ + dma_irq(DMA_2, 5, TxIrq); // uart6_tx +} + +static void dma2_stream7_irq(void) +{ + dma_irq(DMA_2, 0, TxIrq); // uart1_tx +} + +#endif // DEVICE_SERIAL_ASYNCH_DMA #if defined(UART5_BASE) static void uart5_irq(void) { - uart_irq(UART_5, 4); + uart_irq(4); } #endif #if defined(USART6_BASE) static void uart6_irq(void) { - uart_irq(UART_6, 5); + uart_irq(5); } #endif #if defined(UART7_BASE) static void uart7_irq(void) { - uart_irq(UART_7, 6); + uart_irq(6); } #endif #if defined(UART8_BASE) static void uart8_irq(void) { - uart_irq(UART_8, 7); + uart_irq(7); } #endif @@ -476,26 +630,53 @@ uint32_t vector_dma = 0; #endif - UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; - switch (SERIAL_OBJ(uart)) { - case UART_1: + switch (SERIAL_OBJ(index)) { + case 0: irq_n = USART1_IRQn; vector = (uint32_t)&uart1_irq; +#if DEVICE_SERIAL_ASYNCH_DMA + if (irq == RxIrq) { + irqn_dma = DMA2_Stream5_IRQn; + vector_dma = (uint32_t)&dma2_stream5_irq; + } else { + irqn_dma = DMA2_Stream7_IRQn; + vector_dma = (uint32_t)&dma2_stream7_irq; + } +#endif break; - case UART_2: + case 1: irq_n = USART2_IRQn; vector = (uint32_t)&uart2_irq; +#if DEVICE_SERIAL_ASYNCH_DMA + if (irq == RxIrq) { + irqn_dma = DMA1_Stream5_IRQn; + vector_dma = (uint32_t)&dma1_stream5_irq; + } else { + irqn_dma = DMA1_Stream6_IRQn; + vector_dma = (uint32_t)&dma1_stream6_irq; + } +#endif break; #if defined(USART3_BASE) - case UART_3: + case 2: irq_n = USART3_IRQn; vector = (uint32_t)&uart3_irq; +#if DEVICE_SERIAL_ASYNCH_DMA + if (irq == RxIrq) { + irqn_dma = DMA1_Stream1_IRQn; + vector_dma = (uint32_t)&dma1_stream1_irq; + } else { + irqn_dma = DMA1_Stream3_IRQn; + vector_dma = (uint32_t)&dma1_stream3_irq; + } +#endif break; #endif #if defined(UART4_BASE) - case UART_4: + case 3: irq_n = UART4_IRQn; vector = (uint32_t)&uart4_irq; #if DEVICE_SERIAL_ASYNCH_DMA @@ -510,25 +691,43 @@ break; #endif #if defined(UART5_BASE) - case UART_5: + case 4: irq_n = UART5_IRQn; vector = (uint32_t)&uart5_irq; +#if DEVICE_SERIAL_ASYNCH_DMA + if (irq == RxIrq) { + irqn_dma = DMA1_Stream0_IRQn; + vector_dma = (uint32_t)&dma1_stream0_irq; + } else { + irqn_dma = DMA1_Stream4_IRQn; + vector_dma = (uint32_t)&dma1_stream7_irq; + } +#endif break; #endif #if defined(USART6_BASE) - case UART_6: + case 5: irq_n = USART6_IRQn; vector = (uint32_t)&uart6_irq; +#if DEVICE_SERIAL_ASYNCH_DMA + if (irq == RxIrq) { + irqn_dma = DMA2_Stream1_IRQn; + vector_dma = (uint32_t)&dma2_stream1_irq; + } else { + irqn_dma = DMA2_Stream6_IRQn; + vector_dma = (uint32_t)&dma2_stream6_irq; + } +#endif break; #endif #if defined(UART7_BASE) - case UART_7: + case 6: irq_n = UART7_IRQn; vector = (uint32_t)&uart7_irq; break; #endif #if defined(UART8_BASE) - case UART_8: + case 7: irq_n = UART8_IRQn; vector = (uint32_t)&uart8_irq; break; @@ -538,7 +737,7 @@ if (enable) { if (irq == RxIrq) { - __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); + __HAL_UART_ENABLE_IT(handle, UART_IT_RXNE); #if DEVICE_SERIAL_ASYNCH_DMA NVIC_SetVector(irq_n, vector_dma); NVIC_EnableIRQ(irq_n); @@ -549,7 +748,7 @@ NVIC_EnableIRQ(irq_n); #endif } else { // TxIrq - __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC); + __HAL_UART_ENABLE_IT(handle, UART_IT_TC); NVIC_SetVector(irq_n, vector); NVIC_EnableIRQ(irq_n); #if DEVICE_SERIAL_ASYNCH_DMA @@ -562,13 +761,13 @@ int all_disabled = 0; if (irq == RxIrq) { - __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE); + __HAL_UART_DISABLE_IT(handle, UART_IT_RXNE); // Check if TxIrq is disabled too - if ((UartHandle.Instance->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1; + if ((handle->Instance->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1; } else { // TxIrq - __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TXE); + __HAL_UART_DISABLE_IT(handle, UART_IT_TXE); // Check if RxIrq is disabled too - if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; + if ((handle->Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; } if (all_disabled) { @@ -587,41 +786,41 @@ int serial_getc(serial_t *obj) { - USART_TypeDef *uart = (USART_TypeDef *)(SERIAL_OBJ(uart)); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; while (!serial_readable(obj)); - return (int)(uart->DR & 0x1FF); + return (int)(handle->Instance->DR & 0x1FF); } void serial_putc(serial_t *obj, int c) { - USART_TypeDef *uart = (USART_TypeDef *)(SERIAL_OBJ(uart)); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; while (!serial_writable(obj)); - uart->DR = (uint32_t)(c & 0x1FF); + handle->Instance->DR = (uint32_t)(c & 0x1FF); } int serial_readable(serial_t *obj) { int status; - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; // Check if data is received - status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0); + status = ((__HAL_UART_GET_FLAG(handle, UART_FLAG_RXNE) != RESET) ? 1 : 0); return status; } int serial_writable(serial_t *obj) { int status; - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; // Check if data is transmitted - status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0); + status = ((__HAL_UART_GET_FLAG(handle, UART_FLAG_TXE) != RESET) ? 1 : 0); return status; } void serial_clear(serial_t *obj) { - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); - __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TXE); - __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_RXNE); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_TXE); + __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_RXNE); } void serial_pinout_tx(PinName tx) @@ -631,12 +830,13 @@ void serial_break_set(serial_t *obj) { - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); - HAL_LIN_SendBreak(&UartHandle); + UART_HandleTypeDef *uart = &UartHandle[SERIAL_OBJ(index)]; + HAL_LIN_SendBreak(uart); } void serial_break_clear(serial_t *obj) { + (void)obj; } //######################################################################################## @@ -657,7 +857,6 @@ { // We only support byte buffers for now MBED_ASSERT(width == 8); - UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); // Exit if a transmit is already on-going if (serial_tx_active(obj)) return; @@ -729,46 +928,44 @@ { IRQn_Type irq_n = (IRQn_Type)0; - UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); - - switch (SERIAL_OBJ(uart)) { + switch (SERIAL_OBJ(index)) { #if defined(USART1_BASE) - case UART_1: + case 0: irq_n = USART1_IRQn; break; #endif #if defined(USART2_BASE) - case UART_2: + case 1: irq_n = USART2_IRQn; break; #endif #if defined(USART3_BASE) - case UART_3: + case 2: irq_n = USART3_IRQn; break; #endif #if defined(UART4_BASE) - case UART_4: + case 3: irq_n = UART4_IRQn; break; #endif -#if defined(UART5_BASE) - case UART_5: +#if defined(USART5_BASE) + case 4: irq_n = UART5_IRQn; break; #endif #if defined(USART6_BASE) - case UART_6: + case 5: irq_n = USART6_IRQn; break; #endif #if defined(UART7_BASE) - case UART_7: + case 6: irq_n = UART7_IRQn; break; #endif #if defined(UART8_BASE) - case UART_8: + case 7: irq_n = UART8_IRQn; break; #endif @@ -781,24 +978,177 @@ #if DEVICE_SERIAL_ASYNCH_DMA -/** 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 - */ -static void h_serial_txdma_irq_handler_asynch() +/** + * @brief Start the DMA Transfer with interrupt enabled. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param SrcAddress: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param DataLength: The length of data to be transferred from source to destination + * @retval HAL status + */ +static HAL_StatusTypeDef MBED_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { - HAL_DMA_IRQHandler(UartHandle.hdmatx); + /* Process locked */ + __HAL_LOCK(hdma); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Disable the peripheral */ + __HAL_DMA_DISABLE(hdma); + + /* Configure the source, destination address and the data length */ + /* Clear DBM bit */ + hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM); + + /* Configure DMA Stream data length */ + hdma->Instance->NDTR = DataLength; + + /* Peripheral to Memory */ + if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) { + /* Configure DMA Stream destination address */ + hdma->Instance->PAR = DstAddress; + + /* Configure DMA Stream source address */ + hdma->Instance->M0AR = SrcAddress; + } else { + /* Memory to Peripheral */ + /* Configure DMA Stream source address */ + hdma->Instance->PAR = SrcAddress; + + /* Configure DMA Stream destination address */ + hdma->Instance->M0AR = DstAddress; + } + + /* Enable all interrupts EXCEPT HALF TRANSFER COMPLETE */ + hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME; + hdma->Instance->FCR |= DMA_IT_FE; + + /* Enable the Peripheral */ + __HAL_DMA_ENABLE(hdma); + + return HAL_OK; +} +/** + * @brief DMA UART receive process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void h_UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_UART_RxHalfCpltCallback(huart); } -/** 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 - */ -void h_serial_rxdma_irq_handler_asynch(serial_t *obj) + +/** + * @brief DMA UART receive process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void h_UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode*/ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + huart->RxXferCount = 0; + + /* Disable the DMA transfer for the receiver request by setting the DMAR bit + in the UART CR3 register */ + huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); + + /* Check if a transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + else + { + huart->State = HAL_UART_STATE_READY; + } + } + HAL_UART_RxCpltCallback(huart); +} +/** + * @brief DMA UART communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void h_UART_DMAError(DMA_HandleTypeDef *hdma) { -// UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); - HAL_DMA_IRQHandler(UartHandle.hdmarx); + UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + huart->RxXferCount = 0; + huart->TxXferCount = 0; + huart->State= HAL_UART_STATE_READY; + huart->ErrorCode |= HAL_UART_ERROR_DMA; + HAL_UART_ErrorCallback(huart); +} + +/** + * @brief Receives an amount of data in non blocking mode. + * @note This function differs from HAL's function as it does not enable HalfTranferComplete + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit. + * @retval HAL status + */ +static HAL_StatusTypeDef MBED_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0; + + tmp1 = huart->State; + if((tmp1 == HAL_UART_STATE_READY) || (tmp1 == HAL_UART_STATE_BUSY_TX)) { + if((pData == NULL ) || (Size == 0)) { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + /* Check if a transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX) { + huart->State = HAL_UART_STATE_BUSY_TX_RX; + } else { + huart->State = HAL_UART_STATE_BUSY_RX; + } + + /* Set the UART DMA transfer complete callback */ + huart->hdmarx->XferCpltCallback = h_UART_DMAReceiveCplt; + + /* Set the UART DMA Half transfer complete callback */ + huart->hdmarx->XferHalfCpltCallback = h_UART_DMARxHalfCplt; + + /* Set the DMA error callback */ + huart->hdmarx->XferErrorCallback = h_UART_DMAError; + + /* Enable the DMA Stream */ + tmp = (uint32_t*)&pData; + MBED_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the UART CR3 register */ + huart->Instance->CR3 |= USART_CR3_DMAR; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; + } else { + return HAL_BUSY; + } } /** @@ -811,49 +1161,37 @@ { IRQn_Type irq_n = (IRQn_Type)0; - UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); - - switch (SERIAL_OBJ(uart)) { + switch (SERIAL_OBJ(index)) { #if defined(USART1_BASE) - case UART_1: + case 0: irq_n = DMA2_Stream7_IRQn; break; #endif #if defined(USART2_BASE) - case UART_2: + case 1: irq_n = DMA1_Stream6_IRQn; break; #endif #if defined(USART3_BASE) - case UART_3: + case 2: irq_n = DMA1_Stream3_IRQn; break; #endif #if defined(UART4_BASE) - case UART_4: + case 3: irq_n = DMA1_Stream4_IRQn; break; #endif #if defined(UART5_BASE) - case UART_5: + case 4: irq_n = DMA1_Stream7_IRQn; break; #endif #if defined(USART6_BASE) - case UART_6: + case 5: irq_n = DMA2_Stream6_IRQn; break; #endif -#if defined(UART7_BASE) - case UART_7: - irq_n = DMA1_Stream1_IRQn; - break; -#endif -#if defined(UART8_BASE) - case UART_8: - irq_n = DMA1_Stream0_IRQn; - break; -#endif default: irq_n = (IRQn_Type)0; } @@ -870,47 +1208,35 @@ { IRQn_Type irq_n = (IRQn_Type)0; - UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); - - switch (SERIAL_OBJ(uart)) { + switch (SERIAL_OBJ(index)) { #if defined(USART1_BASE) - case UART_1: + case 0: irq_n = DMA2_Stream5_IRQn; break; #endif #if defined(USART2_BASE) - case UART_2: + case 1: irq_n = DMA1_Stream5_IRQn; break; #endif #if defined(USART3_BASE) - case UART_3: + case 2: irq_n = DMA1_Stream1_IRQn; break; #endif #if defined(UART4_BASE) - case UART_4: + case 3: irq_n = DMA1_Stream2_IRQn; break; #endif #if defined(UART5_BASE) - case UART_5: + case 4: irq_n = DMA1_Stream0_IRQn; break; #endif #if defined(USART6_BASE) - case UART_6: - irq_n = DMA2_Stream2_IRQn; - break; -#endif -#if defined(UART7_BASE) - case UART_7: - irq_n = DMA1_Stream3_IRQn; - break; -#endif -#if defined(UART8_BASE) - case UART_8: - irq_n = DMA1_Stream6_IRQn; + case 5: + irq_n = DMA2_Stream1_IRQn; break; #endif default: @@ -936,9 +1262,15 @@ * @param hint A suggestion for how to use DMA with this transfer * @return Returns number of data transfered, or 0 otherwise */ +#ifdef YOTTA_CFG_MBED_OS +int serial_tx_asynch(serial_t *obj, void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint) +#else 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) +#endif { - + // 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 @@ -952,13 +1284,13 @@ h_serial_tx_enable_event(obj, SERIAL_EVENT_TX_ALL, 0); // Clear all events h_serial_tx_enable_event(obj, event, 1); // Set only the wanted events + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; // Enable interrupt IRQn_Type irqn = h_serial_get_irq_index(obj); NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); NVIC_SetVector(irqn, (uint32_t)handler); - UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); NVIC_EnableIRQ(irqn); #if DEVICE_SERIAL_ASYNCH_DMA @@ -967,25 +1299,26 @@ NVIC_ClearPendingIRQ(irqn); NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); -// NVIC_SetVector(irqn, (uint32_t)&h_serial_txdma_irq_handler_asynch); NVIC_SetVector(irqn, (uint32_t)handler); NVIC_EnableIRQ(irqn); // the following function will enable program and enable the DMA transfer - if (HAL_UART_Transmit_DMA(&UartHandle, (uint8_t*)tx, tx_length) != HAL_OK) + if (HAL_UART_Transmit_DMA(handle, (uint8_t*)tx, tx_length) != HAL_OK) { /* Transfer error in transmission process */ return 0; } #else // the following function will enable UART_IT_TXE and error interrupts - if (HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)tx, tx_length) != HAL_OK) + if (HAL_UART_Transmit_IT(handle, (uint8_t*)tx, tx_length) != HAL_OK) { /* Transfer error in transmission process */ return 0; } #endif - + + DEBUG_PRINTF("UART%u: Tx: 0=(%u, %u) %x\n", obj->serial.module+1, tx_length, tx_width, HAL_UART_GetState(handle)); + return tx_length; } @@ -1004,6 +1337,9 @@ */ 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) { + // DMA usage is currently ignored + (void) hint; + /* Sanity check arguments */ MBED_ASSERT(obj); MBED_ASSERT(rx != (void*)0); @@ -1024,9 +1360,10 @@ NVIC_SetVector(irqn, (uint32_t)handler); NVIC_EnableIRQ(irqn); - UartHandle.Instance = (USART_TypeDef *)SERIAL_OBJ(uart); + + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; // flush current data + error flags - __HAL_UART_CLEAR_PEFLAG(&UartHandle); + __HAL_UART_CLEAR_PEFLAG(handle); #if DEVICE_SERIAL_ASYNCH_DMA // Enable DMA interrupt irqn = h_serial_rx_get_irqdma_index(obj); @@ -1034,17 +1371,17 @@ NVIC_DisableIRQ(irqn); NVIC_SetPriority(irqn, 1); NVIC_SetVector(irqn, (uint32_t)handler); - NVIC_EnableIRQ(irqn); // following HAL function will program and enable the DMA transfer - HAL_UART_Receive_DMA(&UartHandle, (uint8_t*)rx, rx_length); + MBED_UART_Receive_DMA(handle, (uint8_t*)rx, rx_length); #else // following HAL function will enable the RXNE interrupt + error interrupts - HAL_UART_Receive_IT(&UartHandle, (uint8_t*)rx, rx_length); + HAL_UART_Receive_IT(handle, (uint8_t*)rx, rx_length); #endif /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_ERR); + __HAL_UART_ENABLE_IT(handle, UART_IT_ERR); + DEBUG_PRINTF("UART%u: Rx: 0=(%u, %u, %u) %x\n", obj->serial.module+1, rx_length, rx_width, char_match, HAL_UART_GetState(handle)); return; } @@ -1056,8 +1393,8 @@ uint8_t serial_tx_active(serial_t *obj) { MBED_ASSERT(obj); - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); - return ((HAL_UART_GetState(&UartHandle) & UART_STATE_TX_ACTIVE) ? 1 : 0); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + return ((HAL_UART_GetState(handle) & UART_STATE_TX_ACTIVE) ? 1 : 0); } /** Attempts to determine if the serial peripheral is already in use for RX @@ -1068,8 +1405,8 @@ uint8_t serial_rx_active(serial_t *obj) { MBED_ASSERT(obj); - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); - return ((HAL_UART_GetState(&UartHandle) & UART_STATE_RX_ACTIVE) ? 1 : 0); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + return ((HAL_UART_GetState(handle) & UART_STATE_RX_ACTIVE) ? 1 : 0); } @@ -1085,62 +1422,62 @@ uint8_t i = 0; // Irq handler is common to Tx and Rx - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; #if DEVICE_SERIAL_ASYNCH_DMA - if ((UartHandle.Instance->CR3 & USART_CR3_DMAT) !=0) { + if ((handle->Instance->CR3 & USART_CR3_DMAT) !=0) { // call dma tx interrupt - HAL_DMA_IRQHandler(UartHandle.hdmatx); + HAL_DMA_IRQHandler(handle->hdmatx); } - if ((UartHandle.Instance->CR3 & USART_CR3_DMAR) !=0) { + if ((handle->Instance->CR3 & USART_CR3_DMAR) !=0) { // call dma rx interrupt - HAL_DMA_IRQHandler(UartHandle.hdmarx); + HAL_DMA_IRQHandler(handle->hdmarx); } #endif - HAL_UART_IRQHandler(&UartHandle); + HAL_UART_IRQHandler(handle); // TX PART: - if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) { - __HAL_UART_CLEAR_FLAG(&UartHandle, UART_FLAG_TC); + if (__HAL_UART_GET_FLAG(handle, UART_FLAG_TC) != RESET) { + __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_TC); // return event SERIAL_EVENT_TX_COMPLETE if requested if ((SERIAL_OBJ(events) & SERIAL_EVENT_TX_COMPLETE ) != 0){ return_event |= SERIAL_EVENT_TX_COMPLETE & obj->serial.events; } } // handle error events: - if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_PE)) { - __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_PE); + if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_PE)) { + __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_PE); return_event |= SERIAL_EVENT_RX_PARITY_ERROR & obj->serial.events; } - if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_NE)||(UartHandle.ErrorCode & HAL_UART_ERROR_NE)!=0) { - __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_NE); + if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_NE)||(handle->ErrorCode & HAL_UART_ERROR_NE)!=0) { + __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_NE); // not supported by mbed } - if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_FE)||(UartHandle.ErrorCode & HAL_UART_ERROR_FE)!=0) { - __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_FE); - return_event |= SERIAL_EVENT_RX_FRAMING_ERROR & obj->serial.events; + if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_FE)||(handle->ErrorCode & HAL_UART_ERROR_FE)!=0) { + __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_FE); + return_event |= SERIAL_EVENT_RX_FRAMING_ERROR & SERIAL_OBJ(events); } - if (__HAL_UART_GET_FLAG(&UartHandle, HAL_UART_ERROR_ORE)||(UartHandle.ErrorCode & HAL_UART_ERROR_ORE)!=0) { - __HAL_UART_CLEAR_FLAG(&UartHandle, HAL_UART_ERROR_ORE); - return_event |= SERIAL_EVENT_RX_OVERRUN_ERROR & obj->serial.events; + if (__HAL_UART_GET_FLAG(handle, HAL_UART_ERROR_ORE)||(handle->ErrorCode & HAL_UART_ERROR_ORE)!=0) { + __HAL_UART_CLEAR_FLAG(handle, HAL_UART_ERROR_ORE); + return_event |= SERIAL_EVENT_RX_OVERRUN_ERROR & SERIAL_OBJ(events); } //RX PART // increment rx_buff.pos - if (UartHandle.RxXferSize !=0) { - obj->rx_buff.pos = UartHandle.RxXferSize - UartHandle.RxXferCount; + if (handle->RxXferSize !=0) { + obj->rx_buff.pos = handle->RxXferSize - handle->RxXferCount; } - if ((UartHandle.RxXferCount==0)&&(obj->rx_buff.pos >= (obj->rx_buff.length - 1))) { - return_event |= SERIAL_EVENT_RX_COMPLETE & obj->serial.events; + if ((handle->RxXferCount==0)&&(obj->rx_buff.pos >= (obj->rx_buff.length - 1))) { + return_event |= SERIAL_EVENT_RX_COMPLETE & SERIAL_OBJ(events); } // Chek if Char_match is present if (SERIAL_OBJ(events) & SERIAL_EVENT_RX_CHARACTER_MATCH) { if (buf != NULL){ - while((buf[i] != obj->char_match)&&(i<UartHandle.RxXferSize)){//for (i=0;i<UartHandle.RxXferSize;i++){ + while((buf[i] != obj->char_match)&&(i<handle->RxXferSize)){//for (i=0;i<UartHandle.RxXferSize;i++){ i++;//if (buf[i] == obj->char_match{ //} } - if (i<UartHandle.RxXferSize){ + if (i<handle->RxXferSize){ obj->rx_buff.pos = i; - return_event |= SERIAL_EVENT_RX_CHARACTER_MATCH & obj->serial.events; + return_event |= SERIAL_EVENT_RX_CHARACTER_MATCH & SERIAL_OBJ(events); } } } @@ -1154,13 +1491,18 @@ */ void serial_tx_abort_asynch(serial_t *obj) { - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); - __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC|UART_IT_TXE); - UartHandle.Instance = 0; - - obj->tx_buff.buffer = 0; - obj->tx_buff.length = 0; - + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + __HAL_UART_DISABLE_IT(handle, UART_IT_TC|UART_IT_TXE); + // clear flags + __HAL_UART_CLEAR_PEFLAG(handle); + // reset states + handle->TxXferCount = 0; + // update handle state + if (handle->State == HAL_UART_STATE_BUSY_TX_RX) { + handle->State = HAL_UART_STATE_BUSY_RX; + } else { + handle->State = HAL_UART_STATE_READY; + } } /** Abort the ongoing RX transaction It disables the enabled interrupt for RX and @@ -1170,13 +1512,18 @@ */ void serial_rx_abort_asynch(serial_t *obj) { - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); - __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE); - UartHandle.Instance = 0; - - obj->rx_buff.buffer = 0; - obj->rx_buff.length = 0; - + UART_HandleTypeDef *handle = &UartHandle[SERIAL_OBJ(index)]; + __HAL_UART_DISABLE_IT(handle, UART_IT_RXNE); + // clear flags + __HAL_UART_CLEAR_PEFLAG(handle); + // reset states + handle->RxXferCount = 0; + // update handle state + if (handle->State == HAL_UART_STATE_BUSY_TX_RX) { + handle->State = HAL_UART_STATE_BUSY_TX; + } else { + handle->State = HAL_UART_STATE_READY; + } } #endif @@ -1196,10 +1543,9 @@ 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 - SERIAL_OBJ(uart) = (UARTName)pinmap_merge(uart_cts, uart_rts); + UARTName instance = (UARTName)pinmap_merge(uart_cts, uart_rts); - MBED_ASSERT(SERIAL_OBJ(uart) != (UARTName)NC); - UartHandle.Instance = (USART_TypeDef *)(SERIAL_OBJ(uart)); + MBED_ASSERT(instance != (UARTName)NC); if(type == FlowControlNone) { // Disable hardware flow control @@ -1233,7 +1579,7 @@ // Enable the pin for RTS function pinmap_pinout(rxflow, PinMap_UART_RTS); } - init_uart(obj); + init_uart(obj, instance); } #endif #endif