From e59863f128654cff82c0fe0f66d9091db486bc1a Mon Sep 17 00:00:00 2001 From: Jani Pellikka Date: Tue, 23 Feb 2016 15:54:00 +0200 Subject: [PATCH 1/7] Query if error occurred on serial. --- source/serial_api.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/source/serial_api.c b/source/serial_api.c index b77dd30..f3d1b35 100644 --- a/source/serial_api.c +++ b/source/serial_api.c @@ -233,6 +233,32 @@ int serial_readable(serial_t *obj) { return !UART_HAL_IsRxFifoEmpty(obj->serial.address); } +int serial_error(serial_t *obj) { + int error = 0; + uint8_t overrun = UART_HAL_GetStatusFlag(obj->serial.address, kUartRxOverrun); + uint8_t parity = UART_HAL_GetStatusFlag(obj->serial.address, kUartParityErr); + uint8_t framing = UART_HAL_GetStatusFlag(obj->serial.address, kUartFrameErr); + uint8_t overflow = (HW_UART_SFIFO_RD(obj->serial.address) >> (uint8_t)(BP_UART_SFIFO_RXOF)) & 1U; + + if (overrun) { + UART_HAL_ClearStatusFlag(obj->serial.address, kUartRxOverrun); + error |= SERIAL_ERROR_RX_OVERRUN; + } + if (parity) { + UART_HAL_ClearStatusFlag(obj->serial.address, kUartParityErr); + error |= SERIAL_ERROR_RX_PARITY; + } + if (framing) { + UART_HAL_ClearStatusFlag(obj->serial.address, kUartFrameErr); + error |= SERIAL_ERROR_RX_FRAMING; + } + if (overflow) { + error |= SERIAL_ERROR_RX_OVERFLOW; + HW_UART_SFIFO_SET(obj->serial.address, BM_UART_SFIFO_RXOF); + } + return error; +} + int serial_writable(serial_t *obj) { return obj->serial.entry_count - UART_HAL_GetTxDatawordCountInFifo(obj->serial.address); } From 598ad5eca9d31323e4e39c52dc4ac8e3c885ba17 Mon Sep 17 00:00:00 2001 From: Jani Pellikka Date: Tue, 1 Mar 2016 15:45:05 +0200 Subject: [PATCH 2/7] Workaround for FIFO out-of-sync HW bug. --- source/serial_api.c | 49 +++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/source/serial_api.c b/source/serial_api.c index f3d1b35..7719ae3 100644 --- a/source/serial_api.c +++ b/source/serial_api.c @@ -51,6 +51,7 @@ static uint8_t serial_is_tx_complete(serial_t *obj); static void serial_tx_buffer_set(serial_t *obj, void *tx, size_t length, uint8_t width); static void serial_rx_buffer_set(serial_t *obj, void *rx, size_t length, uint8_t width); static void serial_rx_set_char_match(serial_t *obj, uint8_t char_match); +static void serial_overrun_reset(uint32_t addr); /* TODO: putchar/getchar 9 and 10 bits support @@ -150,37 +151,43 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b /****************************************************************************** * INTERRUPTS HANDLING ******************************************************************************/ -static inline void uart_irq(uint32_t transmit_empty, uint32_t receive_full, uint32_t index) { +static inline void uart_irq(uint32_t base, uint32_t index) { + bool transmit_empty, receive_full; + transmit_empty = UART_HAL_GetTxDataRegEmptyIntCmd(base) && UART_HAL_IsTxDataRegEmpty(base); + receive_full = UART_HAL_GetRxDataRegFullIntCmd(base) && UART_HAL_IsRxDataRegFull(base); + if (serial_irq_ids[index] != 0) { if (transmit_empty) irq_handler(serial_irq_ids[index], TxIrq); - if (receive_full) - irq_handler(serial_irq_ids[index], RxIrq); + if (receive_full) + irq_handler(serial_irq_ids[index], RxIrq); + } + + if (UART_HAL_GetStatusFlag(base, kUartRxOverrun)) { + serial_overrun_reset(base); } } void uart0_irq() { - uart_irq(UART_HAL_GetTxDataRegEmptyIntCmd(UART0_BASE) && UART_HAL_IsTxDataRegEmpty(UART0_BASE), UART_HAL_GetRxDataRegFullIntCmd(UART0_BASE) && UART_HAL_IsRxDataRegFull(UART0_BASE), 0); - if (UART_HAL_GetStatusFlag(UART0_BASE, kUartRxOverrun)) - UART_HAL_ClearStatusFlag(UART0_BASE, kUartRxOverrun); + uart_irq(UART0_BASE, 0); } void uart1_irq() { - uart_irq(UART_HAL_GetTxDataRegEmptyIntCmd(UART1_BASE) && UART_HAL_IsTxDataRegEmpty(UART1_BASE), UART_HAL_GetRxDataRegFullIntCmd(UART1_BASE) && UART_HAL_IsRxDataRegFull(UART1_BASE), 1); + uart_irq(UART1_BASE, 1); } void uart2_irq() { - uart_irq(UART_HAL_GetTxDataRegEmptyIntCmd(UART2_BASE) && UART_HAL_IsTxDataRegEmpty(UART2_BASE), UART_HAL_GetRxDataRegFullIntCmd(UART2_BASE) && UART_HAL_IsRxDataRegFull(UART2_BASE), 2); + uart_irq(UART2_BASE, 2); } #if (UART_NUM > 3) void uart3_irq() { - uart_irq(UART_HAL_GetTxDataRegEmptyIntCmd(UART3_BASE) && UART_HAL_IsTxDataRegEmpty(UART3_BASE), UART_HAL_GetRxDataRegFullIntCmd(UART3_BASE) && UART_HAL_IsRxDataRegFull(UART3_BASE), 3); + uart_irq(UART3_BASE, 3); } void uart4_irq() { - uart_irq(UART_HAL_GetTxDataRegEmptyIntCmd(UART4_BASE) && UART_HAL_IsTxDataRegEmpty(UART4_BASE), UART_HAL_GetRxDataRegFullIntCmd(UART4_BASE) && UART_HAL_IsRxDataRegFull(UART4_BASE), 4); + uart_irq(UART4_BASE, 4); } #endif @@ -227,9 +234,25 @@ void serial_putc(serial_t *obj, int c) { UART_HAL_Putchar(obj->serial.address, (uint8_t)c); } +/** This function has been introduced due to a HW bug + * in the Kinetis UART module: after an overrun in the + * FIFO occurs (a character isn't fetched by IRQ when + * it is already full and a new one arrives), the FIFO + * stops working; write and read pointers of the FIFO + * will have an offset afterwards. + */ +static void serial_overrun_reset(uint32_t addr) +{ + HW_UART_PFIFO_CLR(addr, UART_PFIFO_RXFE_MASK); + HW_UART_CFIFO_SET(addr, UART_CFIFO_RXFLUSH_MASK); + HW_UART_D_RD(addr); /* Dummy data read */ + HW_UART_PFIFO_SET(addr, UART_PFIFO_RXFE_MASK); +} + int serial_readable(serial_t *obj) { - if (UART_HAL_GetStatusFlag(obj->serial.address, kUartRxOverrun)) - UART_HAL_ClearStatusFlag(obj->serial.address, kUartRxOverrun); + if (UART_HAL_GetStatusFlag(obj->serial.address, kUartRxOverrun)) { + serial_overrun_reset(obj->serial.address); + } return !UART_HAL_IsRxFifoEmpty(obj->serial.address); } @@ -318,7 +341,7 @@ static uint32_t serial_rx_error_event_check(serial_t *obj) if ((event & SERIAL_EVENT_RX_OVERRUN_ERROR) && overrun) { result |= SERIAL_EVENT_RX_OVERRUN_ERROR; - UART_HAL_ClearStatusFlag(obj->serial.address, kUartRxOverrun); + serial_overrun_reset(obj->serial.address); } if ((event & SERIAL_EVENT_RX_FRAMING_ERROR) && framing) { result |= SERIAL_EVENT_RX_FRAMING_ERROR; From fa7f91f24dff8455f8839557234ccdc931929b88 Mon Sep 17 00:00:00 2001 From: Jani Pellikka Date: Wed, 2 Mar 2016 16:34:04 +0200 Subject: [PATCH 3/7] Disable/enable receiver; flush after RXFIFO sets. --- source/serial_api.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/serial_api.c b/source/serial_api.c index 7719ae3..9b041c1 100644 --- a/source/serial_api.c +++ b/source/serial_api.c @@ -243,10 +243,13 @@ void serial_putc(serial_t *obj, int c) { */ static void serial_overrun_reset(uint32_t addr) { - HW_UART_PFIFO_CLR(addr, UART_PFIFO_RXFE_MASK); - HW_UART_CFIFO_SET(addr, UART_CFIFO_RXFLUSH_MASK); - HW_UART_D_RD(addr); /* Dummy data read */ - HW_UART_PFIFO_SET(addr, UART_PFIFO_RXFE_MASK); + UART_HAL_DisableReceiver(addr); + UART_HAL_SetRxFifoCmd(addr, false); + UART_HAL_FlushRxFifo(addr); + UART_HAL_ClearStatusFlag(addr, kUartRxOverrun); + UART_HAL_SetRxFifoCmd(addr, true); + UART_HAL_FlushRxFifo(addr); + UART_HAL_EnableReceiver(addr); } int serial_readable(serial_t *obj) { From 62934ec5510f11ad09957640bf5360606e4660ed Mon Sep 17 00:00:00 2001 From: Martin Kojtal Date: Thu, 3 Mar 2016 09:04:46 +0100 Subject: [PATCH 4/7] version v1.0.9 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index 38024f9..9a1b65c 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "mbed-hal-ksdk-mcu", - "version": "1.0.8", + "version": "1.0.9", "description": "mbed HAL for Freescale KSDK MCUs", "keywords": [ "mbed", From b9cddac0cb27a149ffb6f60d2c778d1d941239c7 Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Tue, 8 Mar 2016 12:22:51 +0200 Subject: [PATCH 5/7] Updated dependency on latest uvisor-lib uvisor-lib 2.0.0 was just released. This commit updates the dependency on uvisor-lib to take into account this version. --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index 9a1b65c..6e8747b 100644 --- a/module.json +++ b/module.json @@ -64,7 +64,7 @@ "mbed-hal-ksdk-mcu/TARGET_KSDK_CODE/utilities" ], "dependencies": { - "uvisor-lib": "^1.0.0", + "uvisor-lib": ">=1.0.0,<3.0.0", "mbed-hal": "*" }, "targetDependencies": { From 89c7d1c14227083096dcd834d2af7298136c9543 Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Tue, 8 Mar 2016 15:29:56 +0200 Subject: [PATCH 6/7] version v1.1.0 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index 6e8747b..55ce842 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "mbed-hal-ksdk-mcu", - "version": "1.0.9", + "version": "1.1.0", "description": "mbed HAL for Freescale KSDK MCUs", "keywords": [ "mbed", From e447b8db8789688c27317dcce45e4200ebfeb07f Mon Sep 17 00:00:00 2001 From: Jani Pellikka Date: Wed, 23 Mar 2016 11:02:58 +0200 Subject: [PATCH 7/7] Updated to use overrun reset function. --- source/serial_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/serial_api.c b/source/serial_api.c index 9b041c1..1307e1b 100644 --- a/source/serial_api.c +++ b/source/serial_api.c @@ -267,7 +267,7 @@ int serial_error(serial_t *obj) { uint8_t overflow = (HW_UART_SFIFO_RD(obj->serial.address) >> (uint8_t)(BP_UART_SFIFO_RXOF)) & 1U; if (overrun) { - UART_HAL_ClearStatusFlag(obj->serial.address, kUartRxOverrun); + serial_overrun_reset(obj->serial.address); error |= SERIAL_ERROR_RX_OVERRUN; } if (parity) {