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) {

Reply via email to