You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2018/04/20 18:52:39 UTC

[mynewt-core] 03/06: Add stm32f3xx common hal_uart

This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 4fe83465f84d29da6c52437b0d2e5c5fa2f56263
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Mon Apr 16 15:13:42 2018 -0300

    Add stm32f3xx common hal_uart
---
 hw/bsp/nucleo-f303k8/src/hal_bsp.c             |   4 +-
 hw/bsp/nucleo-f303re/src/hal_bsp.c             |   4 +-
 hw/bsp/stm32f3discovery/src/hal_bsp.c          |   4 +-
 hw/mcu/stm/stm32_common/src/hal_uart.c         |  61 +++-
 hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h   |   3 +
 hw/mcu/stm/stm32f3xx/include/mcu/stm32f3_bsp.h |   2 +-
 hw/mcu/stm/stm32f3xx/src/hal_uart.c            | 374 -------------------------
 7 files changed, 57 insertions(+), 395 deletions(-)

diff --git a/hw/bsp/nucleo-f303k8/src/hal_bsp.c b/hw/bsp/nucleo-f303k8/src/hal_bsp.c
index 916d19e..24f3daa 100644
--- a/hw/bsp/nucleo-f303k8/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f303k8/src/hal_bsp.c
@@ -45,7 +45,7 @@
 #if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
 static struct uart_dev hal_uart[2];
 
-static const struct stm32f3_uart_cfg uart_cfg[UART_CNT] = {
+static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
 #if MYNEWT_VAL(UART_0)
     {
         .suc_uart    = USART2,
@@ -74,7 +74,7 @@ static const struct stm32f3_uart_cfg uart_cfg[UART_CNT] = {
 #endif
 };
 
-const struct stm32f3_uart_cfg *
+const struct stm32_uart_cfg *
 bsp_uart_config(int port)
 {
     assert(port < UART_CNT);
diff --git a/hw/bsp/nucleo-f303re/src/hal_bsp.c b/hw/bsp/nucleo-f303re/src/hal_bsp.c
index dcd562f..42c50fd 100644
--- a/hw/bsp/nucleo-f303re/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f303re/src/hal_bsp.c
@@ -45,7 +45,7 @@
 #if MYNEWT_VAL(UART_0) || MYNEWT_VAL(UART_1)
 static struct uart_dev hal_uart[2];
 
-static const struct stm32f3_uart_cfg uart_cfg[UART_CNT] = {
+static const struct stm32_uart_cfg uart_cfg[UART_CNT] = {
 #if MYNEWT_VAL(UART_0)
     {
         .suc_uart    = USART2,
@@ -74,7 +74,7 @@ static const struct stm32f3_uart_cfg uart_cfg[UART_CNT] = {
 #endif
 };
 
-const struct stm32f3_uart_cfg *
+const struct stm32_uart_cfg *
 bsp_uart_config(int port)
 {
     assert(port < UART_CNT);
diff --git a/hw/bsp/stm32f3discovery/src/hal_bsp.c b/hw/bsp/stm32f3discovery/src/hal_bsp.c
index cd6f5b7..687f920 100644
--- a/hw/bsp/stm32f3discovery/src/hal_bsp.c
+++ b/hw/bsp/stm32f3discovery/src/hal_bsp.c
@@ -53,7 +53,7 @@
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev hal_uart[1];
 
-static const struct stm32f3_uart_cfg uart_cfg[1] = {
+static const struct stm32_uart_cfg uart_cfg[1] = {
     {
         .suc_uart    = USART1,
         .suc_rcc_reg = &RCC->APB2ENR,
@@ -67,7 +67,7 @@ static const struct stm32f3_uart_cfg uart_cfg[1] = {
     },
 };
 
-const struct stm32f3_uart_cfg *
+const struct stm32_uart_cfg *
 bsp_uart_config(int port)
 {
     assert(port == 0);
diff --git a/hw/mcu/stm/stm32_common/src/hal_uart.c b/hw/mcu/stm/stm32_common/src/hal_uart.c
index d5af720..b4e8b2e 100644
--- a/hw/mcu/stm/stm32_common/src/hal_uart.c
+++ b/hw/mcu/stm/stm32_common/src/hal_uart.c
@@ -43,7 +43,34 @@ struct hal_uart_irq {
     struct hal_uart *ui_uart;
     volatile uint32_t ui_cnt;
 };
+
+#if defined(USART6_BASE)
 static struct hal_uart_irq uart_irqs[6];
+#elif defined(USART5_BASE)
+static struct hal_uart_irq uart_irqs[5];
+#elif defined(USART4_BASE)
+static struct hal_uart_irq uart_irqs[4];
+#else
+static struct hal_uart_irq uart_irqs[3];
+#endif
+
+#if defined(STM32F3) || defined(STM32F7)
+#  define STATUS(x)     ((x)->ISR)
+#  define RXNE          USART_ISR_RXNE
+#  define TXE           USART_ISR_TXE
+#  define TC            USART_ISR_TC
+#  define RXDR(x)       ((x)->RDR)
+#  define TXDR(x)       ((x)->TDR)
+#  define BAUD(x,y)     UART_DIV_SAMPLING16((x), (y))
+#else
+#  define STATUS(x)     ((x)->SR)
+#  define RXNE          USART_SR_RXNE
+#  define TXE           USART_SR_TXE
+#  define TC            USART_SR_TC
+#  define RXDR(x)       ((x)->DR)
+#  define TXDR(x)       ((x)->DR)
+#  define BAUD(x,y)     UART_BRR_SAMPLING16((x), (y))
+#endif
 
 int
 hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done,
@@ -78,9 +105,9 @@ uart_irq_handler(int num)
     u = ui->ui_uart;
     regs = u->u_regs;
 
-    isr = regs->SR;
-    if (isr & USART_SR_RXNE) {
-        data = regs->DR;
+    isr = STATUS(regs);
+    if (isr & RXNE) {
+        data = RXDR(regs);
         rc = u->u_rx_func(u->u_func_arg, data);
         if (rc < 0) {
             regs->CR1 &= ~USART_CR1_RXNEIE;
@@ -88,19 +115,19 @@ uart_irq_handler(int num)
             u->u_rx_stall = 1;
         }
     }
-    if (isr & (USART_SR_TXE | USART_SR_TC)) {
+    if (isr & (TXE | TC)) {
         cr1 = regs->CR1;
-        if (isr & USART_SR_TXE) {
+        if (isr & TXE) {
             data = u->u_tx_func(u->u_func_arg);
             if (data < 0) {
                 cr1 &= ~USART_CR1_TXEIE;
                 cr1 |= USART_CR1_TCIE;
                 u->u_tx_end = 1;
             } else {
-                regs->DR = data;
+                TXDR(regs) = data;
             }
         }
-        if (u->u_tx_end == 1 && isr & USART_SR_TC) {
+        if (u->u_tx_end == 1 && isr & TC) {
             if (u->u_tx_done) {
                 u->u_tx_done(u->u_func_arg);
             }
@@ -109,6 +136,12 @@ uart_irq_handler(int num)
         }
         regs->CR1 = cr1;
     }
+#if defined(STM32F3) || defined(STM32F7)
+    /* clear overrun */
+    if (isr & USART_ISR_ORE) {
+        regs->ICR |= USART_ICR_ORECF;
+    }
+#endif
 }
 
 void
@@ -156,14 +189,14 @@ hal_uart_blocking_tx(int port, uint8_t data)
     }
     regs = u->u_regs;
 
-    while (!(regs->SR & USART_SR_TXE));
+    while (!(STATUS(regs) & TXE));
 
-    regs->DR = data;
+    TXDR(regs) = data;
 
     /*
      * Waits for TX to complete.
      */
-    while (!(regs->SR & USART_SR_TC));
+    while (!(STATUS(regs) & TC));
 }
 
 static void
@@ -374,13 +407,13 @@ hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
 #else
     if (cfg->suc_uart == USART1) {
 #endif
-        u->u_regs->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), baudrate);
+        u->u_regs->BRR = BAUD(HAL_RCC_GetPCLK2Freq(), baudrate);
     } else {
-        u->u_regs->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), baudrate);
+        u->u_regs->BRR = BAUD(HAL_RCC_GetPCLK1Freq(), baudrate);
     }
 
-    (void)u->u_regs->DR;
-    (void)u->u_regs->SR;
+    (void)RXDR(u->u_regs);
+    (void)STATUS(u->u_regs);
     hal_uart_set_nvic(cfg->suc_irqn, u);
 
     u->u_regs->CR1 |= (USART_CR1_RXNEIE | USART_CR1_UE);
diff --git a/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h
index 98d1a5e..01c64f1 100644
--- a/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f3xx/include/mcu/stm32_hal.h
@@ -63,6 +63,9 @@ struct stm32_hal_spi_cfg {
 /* hal_i2c */
 #include "stm32f3xx_hal_i2c.h"
 #include "mcu/stm32f3xx_mynewt_hal.h"
+
+/* hal_uart */
+#include "stm32f3xx_hal_uart.h"
 #include "mcu/stm32f3_bsp.h"
 
 #ifdef __cplusplus
diff --git a/hw/mcu/stm/stm32f3xx/include/mcu/stm32f3_bsp.h b/hw/mcu/stm/stm32f3xx/include/mcu/stm32f3_bsp.h
index ec5a83f..f04ce09 100644
--- a/hw/mcu/stm/stm32f3xx/include/mcu/stm32f3_bsp.h
+++ b/hw/mcu/stm/stm32f3xx/include/mcu/stm32f3_bsp.h
@@ -30,7 +30,7 @@ extern "C" {
 /**
  * BSP specific UART settings.
  */
-struct stm32f3_uart_cfg {
+struct stm32_uart_cfg {
     USART_TypeDef *suc_uart;            /* UART dev registers */
     volatile uint32_t *suc_rcc_reg;     /* RCC register to modify */
     uint32_t suc_rcc_dev;               /* RCC device ID */
diff --git a/hw/mcu/stm/stm32f3xx/src/hal_uart.c b/hw/mcu/stm/stm32f3xx/src/hal_uart.c
deleted file mode 100644
index 2d1f3c5..0000000
--- a/hw/mcu/stm/stm32f3xx/src/hal_uart.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "hal/hal_uart.h"
-#include "hal/hal_gpio.h"
-#include "mcu/cmsis_nvic.h"
-#include "bsp/bsp.h"
-#include "stm32f3xx.h"
-#include "stm32f3xx_hal_dma.h"
-#include "stm32f3xx_hal_uart.h"
-#include "stm32f3xx_hal_rcc.h"
-#include "mcu/stm32f3_bsp.h"
-#include "mcu/stm32f3xx_mynewt_hal.h"
-#include <assert.h>
-#include <stdlib.h>
-
-struct hal_uart {
-    USART_TypeDef *u_regs;
-    uint8_t u_open:1;
-    uint8_t u_rx_stall:1;
-    uint8_t u_tx_end:1;
-    uint8_t u_rx_data;
-    hal_uart_rx_char u_rx_func;
-    hal_uart_tx_char u_tx_func;
-    hal_uart_tx_done u_tx_done;
-    void *u_func_arg;
-    const struct stm32f3_uart_cfg *u_cfg;
-};
-static struct hal_uart uarts[UART_CNT];
-
-struct hal_uart_irq {
-    struct hal_uart *ui_uart;
-    volatile uint32_t ui_cnt;
-};
-static struct hal_uart_irq uart_irqs[3];
-
-int
-hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done,
-  hal_uart_rx_char rx_func, void *arg)
-{
-    struct hal_uart *u;
-
-    u = &uarts[port];
-    if (port >= UART_CNT || u->u_open) {
-        return -1;
-    }
-    u->u_rx_func = rx_func;
-    u->u_tx_func = tx_func;
-    u->u_tx_done = tx_done;
-    u->u_func_arg = arg;
-    return 0;
-}
-
-static void
-uart_irq_handler(int num)
-{
-    struct hal_uart_irq *ui;
-    struct hal_uart *u;
-    USART_TypeDef *regs;
-    uint32_t isr;
-    uint32_t cr1;
-    int data;
-    int rc;
-
-    ui = &uart_irqs[num];
-    ++ui->ui_cnt;
-    u = ui->ui_uart;
-    regs = u->u_regs;
-
-    isr = regs->ISR;
-    if (isr & USART_ISR_RXNE) {
-        data = regs->RDR;
-        rc = u->u_rx_func(u->u_func_arg, data);
-        if (rc < 0) {
-            regs->CR1 &= ~USART_CR1_RXNEIE;
-            u->u_rx_data = data;
-            u->u_rx_stall = 1;
-        }
-    }
-    if (isr & (USART_ISR_TXE | USART_ISR_TC)) {
-        cr1 = regs->CR1;
-        if (isr & USART_ISR_TXE) {
-            data = u->u_tx_func(u->u_func_arg);
-            if (data < 0) {
-                cr1 &= ~USART_CR1_TXEIE;
-                cr1 |= USART_CR1_TCIE;
-                u->u_tx_end = 1;
-            } else {
-                regs->TDR = data;
-            }
-        }
-        if (u->u_tx_end == 1 && isr & USART_ISR_TC) {
-            if (u->u_tx_done) {
-                u->u_tx_done(u->u_func_arg);
-            }
-            u->u_tx_end = 0;
-            cr1 &= ~USART_CR1_TCIE;
-        }
-        regs->CR1 = cr1;
-    }
-    if (isr & USART_ISR_ORE) {
-        regs->ICR |= USART_ICR_ORECF;
-    }
-}
-
-void
-hal_uart_start_rx(int port)
-{
-    struct hal_uart *u;
-    int sr;
-    int rc;
-
-    u = &uarts[port];
-    if (u->u_rx_stall) {
-        __HAL_DISABLE_INTERRUPTS(sr);
-        rc = u->u_rx_func(u->u_func_arg, u->u_rx_data);
-        if (rc == 0) {
-            u->u_rx_stall = 0;
-            u->u_regs->CR1 |= USART_CR1_RXNEIE;
-        }
-        __HAL_ENABLE_INTERRUPTS(sr);
-    }
-}
-
-void
-hal_uart_start_tx(int port)
-{
-    struct hal_uart *u;
-    int sr;
-
-    u = &uarts[port];
-    __HAL_DISABLE_INTERRUPTS(sr);
-    u->u_regs->CR1 &= ~USART_CR1_TCIE;
-    u->u_regs->CR1 |= USART_CR1_TXEIE;
-    u->u_tx_end = 0;
-    __HAL_ENABLE_INTERRUPTS(sr);
-}
-
-void
-hal_uart_blocking_tx(int port, uint8_t data)
-{
-    struct hal_uart *u;
-    USART_TypeDef *regs;
-
-    u = &uarts[port];
-    if (port >= UART_CNT || !u->u_open) {
-        return;
-    }
-    regs = u->u_regs;
-
-    while (!(regs->ISR & USART_ISR_TXE));
-
-    regs->TDR = data;
-
-    /*
-     * Waits for TX to complete.
-     */
-    while (!(regs->ISR & USART_ISR_TC));
-}
-
-static void
-uart_irq1(void)
-{
-    uart_irq_handler(0);
-}
-
-static void
-uart_irq2(void)
-{
-    uart_irq_handler(1);
-}
-
-static void
-uart_irq3(void)
-{
-    uart_irq_handler(2);
-}
-
-static void
-hal_uart_set_nvic(IRQn_Type irqn, struct hal_uart *uart)
-{
-    uint32_t isr;
-    struct hal_uart_irq *ui = NULL;
-
-    switch (irqn) {
-    case USART1_IRQn:
-        isr = (uint32_t)&uart_irq1;
-        ui = &uart_irqs[0];
-        break;
-    case USART2_IRQn:
-        isr = (uint32_t)&uart_irq2;
-        ui = &uart_irqs[1];
-        break;
-    case USART3_IRQn:
-        isr = (uint32_t)&uart_irq3;
-        ui = &uart_irqs[2];
-        break;
-    default:
-        assert(0);
-        break;
-    }
-
-    if (ui) {
-        ui->ui_uart = uart;
-
-        NVIC_SetVector(irqn, isr);
-        NVIC_EnableIRQ(irqn);
-    }
-}
-
-int
-hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
-  enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl)
-{
-    struct hal_uart *u;
-    const struct stm32f3_uart_cfg *cfg;
-    uint32_t cr1, cr2, cr3;
-
-    if (port >= UART_CNT) {
-        return -1;
-    }
-
-    u = &uarts[port];
-    if (u->u_open) {
-        return -1;
-    }
-    cfg = u->u_cfg;
-    assert(cfg);
-
-    /*
-     * RCC
-     * pin config
-     * UART config
-     * nvic config
-     * enable uart
-     */
-    cr1 = cfg->suc_uart->CR1;
-    cr2 = cfg->suc_uart->CR2;
-    cr3 = cfg->suc_uart->CR3;
-
-    cr1 &= ~(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_RE |
-      USART_CR1_OVER8);
-    cr2 &= ~(USART_CR2_STOP);
-    cr3 &= ~(USART_CR3_RTSE | USART_CR3_CTSE);
-
-    switch (databits) {
-        case 8:
-            cr1 |= UART_WORDLENGTH_8B;
-            break;
-        case 9:
-            cr1 |= UART_WORDLENGTH_9B;
-            break;
-        default:
-            assert(0);
-            return -1;
-    }
-
-    switch (stopbits) {
-        case 1:
-            cr2 |= UART_STOPBITS_1;
-            break;
-        case 2:
-            cr2 |= UART_STOPBITS_2;
-            break;
-        default:
-            return -1;
-    }
-
-    switch (parity) {
-        case HAL_UART_PARITY_NONE:
-            cr1 |= UART_PARITY_NONE;
-            break;
-        case HAL_UART_PARITY_ODD:
-            cr1 |= UART_PARITY_ODD;
-            break;
-        case HAL_UART_PARITY_EVEN:
-            cr1 |= UART_PARITY_EVEN;
-            break;
-    }
-
-    switch (flow_ctl) {
-        case HAL_UART_FLOW_CTL_NONE:
-            cr3 |= UART_HWCONTROL_NONE;
-            break;
-        case HAL_UART_FLOW_CTL_RTS_CTS:
-            cr3 |= UART_HWCONTROL_RTS_CTS;
-            if (cfg->suc_pin_rts < 0 || cfg->suc_pin_cts < 0) {
-                /*
-                 * Can't turn on HW flow control if pins to do that are not
-                 * defined.
-                 */
-                assert(0);
-                return -1;
-            }
-            break;
-    }
-
-    cr1 |= (UART_MODE_RX | UART_MODE_TX | UART_OVERSAMPLING_16);
-
-    *cfg->suc_rcc_reg |= cfg->suc_rcc_dev;
-
-    hal_gpio_init_af(cfg->suc_pin_tx, cfg->suc_pin_af, 0, 0);
-    hal_gpio_init_af(cfg->suc_pin_rx, cfg->suc_pin_af, 0, 0);
-    if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) {
-        hal_gpio_init_af(cfg->suc_pin_rts, cfg->suc_pin_af, 0, 0);
-        hal_gpio_init_af(cfg->suc_pin_cts, cfg->suc_pin_af, 0, 0);
-    }
-
-    u->u_regs = cfg->suc_uart;
-    u->u_regs->CR3 = cr3;
-    u->u_regs->CR2 = cr2;
-    u->u_regs->CR1 = cr1;
-
-    if (cfg->suc_uart == USART1) {
-        u->u_regs->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), baudrate));
-    } else {
-        u->u_regs->BRR = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), baudrate));
-    }
-
-    (void)u->u_regs->RDR;
-    (void)u->u_regs->ISR;
-    hal_uart_set_nvic(cfg->suc_irqn, u);
-
-    u->u_regs->CR1 |= (USART_CR1_RXNEIE | USART_CR1_UE);
-    u->u_open = 1;
-
-    return 0;
-}
-
-int
-hal_uart_init(int port, void *arg)
-{
-    struct hal_uart *u;
-
-    if (port >= UART_CNT) {
-        return -1;
-    }
-    u = &uarts[port];
-    u->u_cfg = (const struct stm32f3_uart_cfg *)arg;
-
-    return 0;
-}
-
-int
-hal_uart_close(int port)
-{
-    struct hal_uart *u;
-
-    if (port >= UART_CNT) {
-        return -1;
-    }
-    u = &uarts[port];
-
-    u->u_open = 0;
-    u->u_regs->CR1 = 0;
-
-    return 0;
-}

-- 
To stop receiving notification emails like this one, please contact
utzig@apache.org.