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>
This commit is contained in:
parent
1342debb9b
commit
9d674cf7ab
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]; \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue