Repository: incubator-mynewt-core Updated Branches: refs/heads/develop c98ff85f7 -> 4609cd2eb
MK64F12; uart rx interrupts now deliver data. Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/cd187c1e Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/cd187c1e Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/cd187c1e Branch: refs/heads/develop Commit: cd187c1e4263991fd0dac8ea7aba8b8b2ee46139 Parents: c98ff85 Author: Marko Kiiskila <ma...@runtime.io> Authored: Mon Jan 30 16:52:53 2017 -0800 Committer: Marko Kiiskila <ma...@runtime.io> Committed: Mon Jan 30 16:52:53 2017 -0800 ---------------------------------------------------------------------- hw/mcu/nxp/MK64F12/src/hal_uart.c | 119 +++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cd187c1e/hw/mcu/nxp/MK64F12/src/hal_uart.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nxp/MK64F12/src/hal_uart.c b/hw/mcu/nxp/MK64F12/src/hal_uart.c index 823d8c1..d429ab6 100644 --- a/hw/mcu/nxp/MK64F12/src/hal_uart.c +++ b/hw/mcu/nxp/MK64F12/src/hal_uart.c @@ -64,6 +64,7 @@ struct hal_uart { uint8_t u_configured:1; uint8_t u_open:1; uint8_t u_tx_started:1; + uint8_t u_rx_stall:1; struct uart_ring ur_tx; uint8_t tx_buffer[TX_BUF_SZ]; struct uart_ring ur_rx; @@ -83,6 +84,16 @@ static clock_ip_name_t const s_uartPortClocks[] = NXP_UART_PORT_CLOCKS; static uint8_t const s_uartPIN_RX[] = NXP_UART_PIN_RX; static uint8_t const s_uartPIN_TX[] = NXP_UART_PIN_TX; +static void uart_irq0(void); +static void uart_irq1(void); +static void uart_irq2(void); +static void uart_irq3(void); +static void uart_irq4(void); +static void uart_irq5(void); +static void (*s_uartirqs[])(void) = { + uart_irq0, uart_irq1, uart_irq2, uart_irq3, uart_irq4, uart_irq5 +}; + /* * RING BUFFER FUNCTIONS */ @@ -167,8 +178,9 @@ hal_uart_tx_fill_buf(struct hal_uart *u) OS_ENTER_CRITICAL(sr); while (!ur_is_full(&u->ur_tx)) { - if (u->u_tx_func) + if (u->u_tx_func) { data = u->u_tx_func(u->u_func_arg); + } if (data <= 0) { break; } @@ -199,29 +211,31 @@ void hal_uart_start_tx(int port) /* add data to TX ring buffer */ if (u->u_tx_started == 0) { rc = hal_uart_tx_fill_buf(u); - if (rc > 0) + if (rc > 0) { u->u_tx_started = 1; + } } /* Send data only when UART TX register is empty and TX ring buffer has data to send out. */ while (!ur_is_empty(&u->ur_tx) && - (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(u->u_base))) - { + (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(u->u_base))) { data = ur_read(&u->ur_tx); UART_WriteByte(u->u_base, data); ur_bump(&u->ur_tx); } if (ur_is_empty(&u->ur_tx)) { - if (u->u_tx_done) + if (u->u_tx_done) { u->u_tx_done(u->u_func_arg); + } u->u_tx_started = 0; break; } } } -void hal_uart_start_rx(int port) +void +hal_uart_start_rx(int port) { struct hal_uart *u; os_sr_t sr; @@ -235,46 +249,93 @@ void hal_uart_start_rx(int port) return; } - /* Send back what's in the RX ring buffer until it's empty or we get an error */ - while ((rc >= 0) && !ur_is_empty(&u->ur_rx)) - { + u->u_rx_stall = 0; + + /* Send back what's in the RX ring buffer until it's empty or we get an + * error */ + while ((rc >= 0) && !ur_is_empty(&u->ur_rx)) { OS_ENTER_CRITICAL(sr); rc = u->u_rx_func(u->u_func_arg, ur_read(&u->ur_rx)); - if (rc >= 0) + if (rc >= 0) { ur_bump(&u->ur_rx); + } else { + u->u_rx_stall = 1; + } OS_EXIT_CRITICAL(sr); } } -void uart_irq_handler(void) +static void +uart_irq_handler(int port) { struct hal_uart *u; - int port; + uint32_t status; uint8_t data; - for (port = 0; port < FSL_FEATURE_SOC_UART_COUNT; port++) { - u = &uarts[port]; - if (u->u_configured && u->u_open) { - /* Check for RX data */ - if ((kUART_RxDataRegFullFlag | kUART_RxOverrunFlag) & - UART_GetStatusFlags(u->u_base)) { - data = UART_ReadByte(u->u_base); + u = &uarts[port]; + if (u->u_configured && u->u_open) { + status = UART_GetStatusFlags(u->u_base); + /* Check for RX data */ + if (status & (kUART_RxDataRegFullFlag | kUART_RxOverrunFlag)) { + data = UART_ReadByte(u->u_base); + if (u->u_rx_stall || u->u_rx_func(u->u_func_arg, data) < 0) { + /* + * RX queue full. + */ + u->u_rx_stall = 1; ur_queue(&u->ur_rx, data); } - /* Check for TX complete */ - if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(u->u_base)) { - if (u->u_tx_started) { - u->u_tx_started = 0; - if (u->u_tx_done) - u->u_tx_done(u->u_func_arg); - } + } + /* Check for TX complete */ + if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(u->u_base)) { + if (u->u_tx_started) { + u->u_tx_started = 0; + if (u->u_tx_done) + u->u_tx_done(u->u_func_arg); } } } } -int hal_uart_config(int port, int32_t speed, uint8_t databits, uint8_t stopbits, - enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) +static void +uart_irq0(void) +{ + uart_irq_handler(0); +} + +static void +uart_irq1(void) +{ + uart_irq_handler(1); +} + +static void +uart_irq2(void) +{ + uart_irq_handler(2); +} + +static void +uart_irq3(void) +{ + uart_irq_handler(3); +} + +static void +uart_irq4(void) +{ + uart_irq_handler(4); +} + +static void +uart_irq5(void) +{ + uart_irq_handler(5); +} + +int +hal_uart_config(int port, int32_t speed, uint8_t databits, uint8_t stopbits, + enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) { struct hal_uart *u; uart_config_t uconfig; @@ -327,7 +388,7 @@ int hal_uart_config(int port, int32_t speed, uint8_t databits, uint8_t stopbits, u->u_open = 1; u->u_tx_started = 0; - NVIC_SetVector(u->u_irq, (uint32_t)uart_irq_handler); + NVIC_SetVector(u->u_irq, (uint32_t)s_uartirqs[port]); /* Initialize UART device */ if (port != 0) {