summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Mason <c.mason@inchipdesign.com.au>2021-02-17 11:07:34 +1100
committerDamien George <damien@micropython.org>2021-02-21 15:49:32 +1100
commit9d674cf7ab8570637dfab23811800e3b98babad9 (patch)
treec9a3b89e1da78298579209027d4a1057d301680e
parent1342debb9b419f78566e173b55b67b15f0a89ee4 (diff)
stm32/uart: Add support for LPUART1 on L0, L4, H7 and WB MCUs.
Add LPUART1 as a standard UART. No low power features are supported, yet. LPUART1 is enabled as the next available UART after the standard U(S)ARTs: STM32WB: LPUART1 = UART(2) STM32L0: LPUART1 = UART(6) STM32L4: LPUART1 = UART(6) STM32H7: LPUART1 = UART(9) On all ports: LPUART1 = machine.UART('LP1') LPUART1 is enabled by defining MICROPY_HW_LPUART1_TX and MICROPY_HW_LPUART1_RX in mpconfigboard.h. Signed-off-by: Chris Mason <c.mason@inchipdesign.com.au>
-rwxr-xr-xports/stm32/boards/make-pins.py2
-rw-r--r--ports/stm32/machine_uart.c29
-rw-r--r--ports/stm32/mpconfigboard_common.h9
-rw-r--r--ports/stm32/mpconfigport.h2
-rw-r--r--ports/stm32/pin_defs_stm32.h5
-rw-r--r--ports/stm32/stm32_it.c18
-rw-r--r--ports/stm32/uart.c47
-rw-r--r--ports/stm32/uart.h3
8 files changed, 108 insertions, 7 deletions
diff --git a/ports/stm32/boards/make-pins.py b/ports/stm32/boards/make-pins.py
index a91ed8a2c..a19532331 100755
--- a/ports/stm32/boards/make-pins.py
+++ b/ports/stm32/boards/make-pins.py
@@ -14,6 +14,7 @@ SUPPORTED_FN = {
"I2S": ["CK", "MCK", "SD", "WS", "EXTSD"],
"USART": ["RX", "TX", "CTS", "RTS", "CK"],
"UART": ["RX", "TX", "CTS", "RTS"],
+ "LPUART": ["RX", "TX", "CTS", "RTS"],
"SPI": ["NSS", "SCK", "MISO", "MOSI"],
"SDMMC": ["CK", "CMD", "D0", "D1", "D2", "D3"],
"CAN": ["TX", "RX"],
@@ -24,6 +25,7 @@ CONDITIONAL_VAR = {
"I2S": "MICROPY_HW_ENABLE_I2S{num}",
"SPI": "MICROPY_HW_SPI{num}_SCK",
"UART": "MICROPY_HW_UART{num}_TX",
+ "LPUART": "MICROPY_HW_LPUART{num}_TX",
"USART": "MICROPY_HW_UART{num}_TX",
"SDMMC": "MICROPY_HW_SDMMC{num}_CK",
"CAN": "MICROPY_HW_CAN{num}_TX",
diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c
index 31e6a1789..eceb5b6e7 100644
--- a/ports/stm32/machine_uart.c
+++ b/ports/stm32/machine_uart.c
@@ -76,7 +76,14 @@
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!self->is_enabled) {
- mp_printf(print, "UART(%u)", self->uart_id);
+ #ifdef LPUART1
+ if (self->uart_id == PYB_LPUART_1) {
+ mp_printf(print, "UART('LP1')");
+ } else
+ #endif
+ {
+ mp_printf(print, "UART(%u)", self->uart_id);
+ }
} else {
mp_int_t bits;
uint32_t cr1 = self->uartx->CR1;
@@ -98,8 +105,16 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
if (cr1 & USART_CR1_PCE) {
bits -= 1;
}
- mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=",
- self->uart_id, uart_get_baudrate(self), bits);
+ #ifdef LPUART1
+ if (self->uart_id == PYB_LPUART_1) {
+ mp_printf(print, "UART('LP1', baudrate=%u, bits=%u, parity=",
+ uart_get_baudrate(self), bits);
+ } else
+ #endif
+ {
+ mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=",
+ self->uart_id, uart_get_baudrate(self), bits);
+ }
if (!(cr1 & USART_CR1_PCE)) {
mp_print_str(print, "None");
} else if (!(cr1 & USART_CR1_PS)) {
@@ -335,6 +350,14 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
} else if (strcmp(port, MICROPY_HW_UART10_NAME) == 0) {
uart_id = PYB_UART_10;
#endif
+ #ifdef MICROPY_HW_LPUART1_NAME
+ } else if (strcmp(port, MICROPY_HW_LPUART1_NAME) == 0) {
+ uart_id = PYB_LPUART_1;
+ #endif
+ #ifdef LPUART1
+ } else if (strcmp(port, "LP1") == 0 && uart_exists(PYB_LPUART_1)) {
+ uart_id = PYB_LPUART_1;
+ #endif
} else {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%s) doesn't exist"), port);
}
diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h
index 615310e51..ed30d17bd 100644
--- a/ports/stm32/mpconfigboard_common.h
+++ b/ports/stm32/mpconfigboard_common.h
@@ -181,6 +181,7 @@
#define MICROPY_HW_MAX_I2C (2)
#define MICROPY_HW_MAX_TIMER (17)
#define MICROPY_HW_MAX_UART (8)
+#define MICROPY_HW_MAX_LPUART (0)
// Configuration for STM32F4 series
#elif defined(STM32F4)
@@ -200,6 +201,7 @@
#else
#define MICROPY_HW_MAX_UART (6)
#endif
+#define MICROPY_HW_MAX_LPUART (0)
// Configuration for STM32F7 series
#elif defined(STM32F7)
@@ -214,6 +216,7 @@
#define MICROPY_HW_MAX_I2C (4)
#define MICROPY_HW_MAX_TIMER (17)
#define MICROPY_HW_MAX_UART (8)
+#define MICROPY_HW_MAX_LPUART (0)
// Configuration for STM32H7 series
#elif defined(STM32H7)
@@ -223,6 +226,7 @@
#define MICROPY_HW_MAX_I2C (4)
#define MICROPY_HW_MAX_TIMER (17)
#define MICROPY_HW_MAX_UART (8)
+#define MICROPY_HW_MAX_LPUART (1)
// Configuration for STM32L0 series
#elif defined(STM32L0)
@@ -232,6 +236,7 @@
#define MICROPY_HW_MAX_I2C (3)
#define MICROPY_HW_MAX_TIMER (22)
#define MICROPY_HW_MAX_UART (5)
+#define MICROPY_HW_MAX_LPUART (1)
// Configuration for STM32L4 series
#elif defined(STM32L4)
@@ -240,7 +245,8 @@
#define PYB_EXTI_NUM_VECTORS (23)
#define MICROPY_HW_MAX_I2C (4)
#define MICROPY_HW_MAX_TIMER (17)
-#define MICROPY_HW_MAX_UART (6)
+#define MICROPY_HW_MAX_UART (5)
+#define MICROPY_HW_MAX_LPUART (1)
// Configuration for STM32WB series
#elif defined(STM32WB)
@@ -250,6 +256,7 @@
#define MICROPY_HW_MAX_I2C (3)
#define MICROPY_HW_MAX_TIMER (17)
#define MICROPY_HW_MAX_UART (1)
+#define MICROPY_HW_MAX_LPUART (1)
#ifndef MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
#define MICROPY_HW_STM32WB_FLASH_SYNCRONISATION (1)
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index 407a3e6c6..5998cd908 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -375,7 +375,7 @@ struct _mp_bluetooth_btstack_root_pointers_t;
struct _pyb_uart_obj_t *pyb_stdio_uart; \
\
/* pointers to all UART objects (if they have been created) */ \
- struct _pyb_uart_obj_t *pyb_uart_obj_all[MICROPY_HW_MAX_UART]; \
+ struct _pyb_uart_obj_t *pyb_uart_obj_all[MICROPY_HW_MAX_UART + MICROPY_HW_MAX_LPUART]; \
\
/* pointers to all CAN objects (if they have been created) */ \
struct _pyb_can_obj_t *pyb_can_obj_all[MICROPY_HW_MAX_CAN]; \
diff --git a/ports/stm32/pin_defs_stm32.h b/ports/stm32/pin_defs_stm32.h
index 33a179080..9285c190a 100644
--- a/ports/stm32/pin_defs_stm32.h
+++ b/ports/stm32/pin_defs_stm32.h
@@ -47,6 +47,7 @@ enum {
AF_FN_I2C,
AF_FN_USART,
AF_FN_UART = AF_FN_USART,
+ AF_FN_LPUART,
AF_FN_SPI,
AF_FN_I2S,
AF_FN_SDMMC,
@@ -77,6 +78,10 @@ enum {
AF_PIN_TYPE_UART_RX = AF_PIN_TYPE_USART_RX,
AF_PIN_TYPE_UART_CTS = AF_PIN_TYPE_USART_CTS,
AF_PIN_TYPE_UART_RTS = AF_PIN_TYPE_USART_RTS,
+ AF_PIN_TYPE_LPUART_TX = AF_PIN_TYPE_USART_TX,
+ AF_PIN_TYPE_LPUART_RX = AF_PIN_TYPE_USART_RX,
+ AF_PIN_TYPE_LPUART_CTS = AF_PIN_TYPE_USART_CTS,
+ AF_PIN_TYPE_LPUART_RTS = AF_PIN_TYPE_USART_RTS,
AF_PIN_TYPE_SPI_MOSI = 0,
AF_PIN_TYPE_SPI_MISO,
diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c
index 8e96da177..dc96e2dd6 100644
--- a/ports/stm32/stm32_it.c
+++ b/ports/stm32/stm32_it.c
@@ -742,11 +742,13 @@ void USART1_IRQHandler(void) {
IRQ_EXIT(USART1_IRQn);
}
+#if defined(USART2)
void USART2_IRQHandler(void) {
IRQ_ENTER(USART2_IRQn);
uart_irq_handler(2);
IRQ_EXIT(USART2_IRQn);
}
+#endif
#if defined(STM32F0)
@@ -772,29 +774,37 @@ void USART4_5_IRQHandler(void) {
#else
+#if defined(USART3)
void USART3_IRQHandler(void) {
IRQ_ENTER(USART3_IRQn);
uart_irq_handler(3);
IRQ_EXIT(USART3_IRQn);
}
+#endif
+#if defined(UART4)
void UART4_IRQHandler(void) {
IRQ_ENTER(UART4_IRQn);
uart_irq_handler(4);
IRQ_EXIT(UART4_IRQn);
}
+#endif
+#if defined(UART5)
void UART5_IRQHandler(void) {
IRQ_ENTER(UART5_IRQn);
uart_irq_handler(5);
IRQ_EXIT(UART5_IRQn);
}
+#endif
+#if defined(USART6)
void USART6_IRQHandler(void) {
IRQ_ENTER(USART6_IRQn);
uart_irq_handler(6);
IRQ_EXIT(USART6_IRQn);
}
+#endif
#if defined(UART7)
void UART7_IRQHandler(void) {
@@ -830,6 +840,14 @@ void UART10_IRQHandler(void) {
#endif
+#if defined(LPUART1)
+void LPUART1_IRQHandler(void) {
+ IRQ_ENTER(LPUART1_IRQn);
+ uart_irq_handler(PYB_LPUART_1);
+ IRQ_EXIT(LPUART1_IRQn);
+}
+#endif
+
#if MICROPY_PY_PYB_LEGACY
#if defined(MICROPY_HW_I2C1_SCL)
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index 8091ba05f..d40a883c5 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -201,6 +201,11 @@ bool uart_exists(int uart_id) {
return true;
#endif
+ #if defined(MICROPY_HW_LPUART1_TX) && defined(MICROPY_HW_LPUART1_RX)
+ case PYB_LPUART_1:
+ return true;
+ #endif
+
default:
return false;
}
@@ -211,6 +216,7 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow) {
USART_TypeDef *UARTx;
IRQn_Type irqn;
+ uint8_t uart_fn = AF_FN_UART;
int uart_unit;
const pin_obj_t *pins[4] = {0};
@@ -406,6 +412,28 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
break;
#endif
+ #if defined(MICROPY_HW_LPUART1_TX) && defined(MICROPY_HW_LPUART1_RX)
+ case PYB_LPUART_1:
+ uart_fn = AF_FN_LPUART;
+ uart_unit = 1;
+ UARTx = LPUART1;
+ irqn = LPUART1_IRQn;
+ pins[0] = MICROPY_HW_LPUART1_TX;
+ pins[1] = MICROPY_HW_LPUART1_RX;
+ #if defined(MICROPY_HW_LPUART1_RTS)
+ if (flow & UART_HWCONTROL_RTS) {
+ pins[2] = MICROPY_HW_LPUART1_RTS;
+ }
+ #endif
+ #if defined(MICROPY_HW_LPUART1_CTS)
+ if (flow & UART_HWCONTROL_CTS) {
+ pins[3] = MICROPY_HW_LPUART1_CTS;
+ }
+ #endif
+ __HAL_RCC_LPUART1_CLK_ENABLE();
+ break;
+ #endif
+
default:
// UART does not exist or is not configured for this board
return false;
@@ -416,7 +444,7 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
for (uint i = 0; i < 4; i++) {
if (pins[i] != NULL) {
- bool ret = mp_hal_pin_config_alt(pins[i], mode, pull, AF_FN_UART, uart_unit);
+ bool ret = mp_hal_pin_config_alt(pins[i], mode, pull, uart_fn, uart_unit);
if (!ret) {
return false;
}
@@ -596,6 +624,13 @@ void uart_deinit(pyb_uart_obj_t *self) {
__HAL_RCC_UART10_RELEASE_RESET();
__HAL_RCC_UART10_CLK_DISABLE();
#endif
+ #if defined(LPUART1)
+ } else if (self->uart_id == PYB_LPUART_1) {
+ HAL_NVIC_DisableIRQ(LPUART1_IRQn);
+ __HAL_RCC_LPUART1_FORCE_RESET();
+ __HAL_RCC_LPUART1_RELEASE_RESET();
+ __HAL_RCC_LPUART1_CLK_DISABLE();
+ #endif
}
}
@@ -677,7 +712,15 @@ uint32_t uart_get_source_freq(pyb_uart_obj_t *self) {
uint32_t uart_get_baudrate(pyb_uart_obj_t *self) {
// This formula assumes UART_OVERSAMPLING_16
- return uart_get_source_freq(self) / self->uartx->BRR;
+ uint32_t source_freq = uart_get_source_freq(self);
+ #if defined(LPUART1)
+ if (self->uart_id == PYB_LPUART_1) {
+ return source_freq / (self->uartx->BRR >> 8);
+ } else
+ #endif
+ {
+ return source_freq / self->uartx->BRR;
+ }
}
void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h
index 570a79c93..0490a617f 100644
--- a/ports/stm32/uart.h
+++ b/ports/stm32/uart.h
@@ -40,6 +40,9 @@ typedef enum {
PYB_UART_8 = 8,
PYB_UART_9 = 9,
PYB_UART_10 = 10,
+ #ifdef LPUART1
+ PYB_LPUART_1 = MICROPY_HW_MAX_UART + 1,
+ #endif
} pyb_uart_t;
#define CHAR_WIDTH_8BIT (0)