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.