summaryrefslogtreecommitdiff
path: root/ports/stm32/uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/uart.c')
-rw-r--r--ports/stm32/uart.c98
1 files changed, 84 insertions, 14 deletions
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index 13e1667d2..adcbe8836 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -41,13 +41,13 @@
#if defined(STM32F4)
#define UART_RXNE_IS_SET(uart) ((uart)->SR & USART_SR_RXNE)
#else
-#if defined(STM32H7) || defined(STM32WL)
+#if defined(STM32G0) || defined(STM32H7) || defined(STM32WL)
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#endif
#define UART_RXNE_IS_SET(uart) ((uart)->ISR & USART_ISR_RXNE)
#endif
-#if defined(STM32WL)
+#if defined(STM32G0) || defined(STM32WL)
#define UART_RXNE_IT_EN(uart) do { (uart)->CR1 |= USART_CR1_RXNEIE_RXFNEIE; } while (0)
#define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE_RXFNEIE; } while (0)
#else
@@ -55,7 +55,7 @@
#define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE; } while (0)
#endif
-#if defined(STM32WL)
+#if defined(STM32G0) || defined(STM32WL)
#define USART_CR1_IE_BASE (USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | USART_CR1_IDLEIE)
#else
#define USART_CR1_IE_BASE (USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | USART_CR1_IDLEIE)
@@ -82,7 +82,7 @@
#define USART_CR3_IE_ALL (USART_CR3_IE_BASE)
#endif
-#elif defined(STM32G4)
+#elif defined(STM32G0) || defined(STM32G4)
#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE)
#define USART_CR2_IE_ALL (USART_CR2_IE_BASE)
#if defined(USART_CR3_TCBGTIE)
@@ -122,13 +122,13 @@ typedef struct _pyb_uart_irq_map_t {
STATIC const pyb_uart_irq_map_t mp_uart_irq_map[] = {
{ USART_CR1_IDLEIE, UART_FLAG_IDLE}, // RX idle
{ USART_CR1_PEIE, UART_FLAG_PE}, // parity error
- #if defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32WL)
{ USART_CR1_TXEIE_TXFNFIE, UART_FLAG_TXE}, // TX register empty
#else
{ USART_CR1_TXEIE, UART_FLAG_TXE}, // TX register empty
#endif
{ USART_CR1_TCIE, UART_FLAG_TC}, // TX complete
- #if defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32WL)
{ USART_CR1_RXNEIE_RXFNEIE, UART_FLAG_RXNE}, // RX register not empty
#else
{ USART_CR1_RXNEIE, UART_FLAG_RXNE}, // RX register not empty
@@ -229,6 +229,11 @@ bool uart_exists(int uart_id) {
return true;
#endif
+ #if defined(MICROPY_HW_LPUART2_TX) && defined(MICROPY_HW_LPUART2_RX)
+ case PYB_LPUART_2:
+ return true;
+ #endif
+
default:
return false;
}
@@ -270,7 +275,11 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
case PYB_UART_2:
uart_unit = 2;
UARTx = USART2;
+ #if defined(STM32G0)
+ irqn = USART2_LPUART2_IRQn;
+ #else
irqn = USART2_IRQn;
+ #endif
pins[0] = MICROPY_HW_UART2_TX;
pins[1] = MICROPY_HW_UART2_RX;
#if defined(MICROPY_HW_UART2_RTS)
@@ -293,6 +302,8 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART3;
#if defined(STM32F0)
irqn = USART3_8_IRQn;
+ #elif defined(STM32G0)
+ irqn = USART3_4_5_6_LPUART1_IRQn;
#else
irqn = USART3_IRQn;
#endif
@@ -323,6 +334,10 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART4;
irqn = USART4_5_IRQn;
__HAL_RCC_USART4_CLK_ENABLE();
+ #elif defined(STM32G0)
+ UARTx = USART4;
+ irqn = USART3_4_5_6_LPUART1_IRQn;
+ __HAL_RCC_USART4_CLK_ENABLE();
#else
UARTx = UART4;
irqn = UART4_IRQn;
@@ -354,6 +369,10 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART5;
irqn = USART4_5_IRQn;
__HAL_RCC_USART5_CLK_ENABLE();
+ #elif defined(STM32G0)
+ UARTx = USART5;
+ irqn = USART3_4_5_6_LPUART1_IRQn;
+ __HAL_RCC_USART5_CLK_ENABLE();
#else
UARTx = UART5;
irqn = UART5_IRQn;
@@ -380,6 +399,8 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART6;
#if defined(STM32F0)
irqn = USART3_8_IRQn;
+ #elif defined(STM32G0)
+ irqn = USART3_4_5_6_LPUART1_IRQn;
#else
irqn = USART6_IRQn;
#endif
@@ -480,7 +501,11 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
uart_fn = AF_FN_LPUART;
uart_unit = 1;
UARTx = LPUART1;
+ #if defined(STM32G0)
+ irqn = USART3_4_5_6_LPUART1_IRQn;
+ #else
irqn = LPUART1_IRQn;
+ #endif
pins[0] = MICROPY_HW_LPUART1_TX;
pins[1] = MICROPY_HW_LPUART1_RX;
#if defined(MICROPY_HW_LPUART1_RTS)
@@ -497,6 +522,30 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
break;
#endif
+ #if defined(MICROPY_HW_LPUART2_TX) && defined(MICROPY_HW_LPUART2_RX)
+ case PYB_LPUART_2:
+ uart_fn = AF_FN_LPUART;
+ uart_unit = 2;
+ UARTx = LPUART2;
+ #if defined(STM32G0)
+ irqn = USART2_LPUART2_IRQn;
+ #endif
+ pins[0] = MICROPY_HW_LPUART2_TX;
+ pins[1] = MICROPY_HW_LPUART2_RX;
+ #if defined(MICROPY_HW_LPUART2_RTS)
+ if (flow & UART_HWCONTROL_RTS) {
+ pins[2] = MICROPY_HW_LPUART2_RTS;
+ }
+ #endif
+ #if defined(MICROPY_HW_LPUART2_CTS)
+ if (flow & UART_HWCONTROL_CTS) {
+ pins[3] = MICROPY_HW_LPUART2_CTS;
+ }
+ #endif
+ __HAL_RCC_LPUART2_CLK_ENABLE();
+ break;
+ #endif
+
default:
// UART does not exist or is not configured for this board
return false;
@@ -626,14 +675,20 @@ void uart_deinit(pyb_uart_obj_t *self) {
__HAL_RCC_USART1_CLK_DISABLE();
#if defined(USART2)
} else if (self->uart_id == 2) {
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART2_LPUART2_IRQn);
+ #else
HAL_NVIC_DisableIRQ(USART2_IRQn);
+ #endif
__HAL_RCC_USART2_FORCE_RESET();
__HAL_RCC_USART2_RELEASE_RESET();
__HAL_RCC_USART2_CLK_DISABLE();
#endif
#if defined(USART3)
} else if (self->uart_id == 3) {
- #if !defined(STM32F0)
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART3_4_5_6_LPUART1_IRQn);
+ #elif !defined(STM32F0)
HAL_NVIC_DisableIRQ(USART3_IRQn);
#endif
__HAL_RCC_USART3_FORCE_RESET();
@@ -715,11 +770,26 @@ void uart_deinit(pyb_uart_obj_t *self) {
#endif
#if defined(LPUART1)
} else if (self->uart_id == PYB_LPUART_1) {
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART3_4_5_6_LPUART1_IRQn);
+ #else
HAL_NVIC_DisableIRQ(LPUART1_IRQn);
+ #endif
__HAL_RCC_LPUART1_FORCE_RESET();
__HAL_RCC_LPUART1_RELEASE_RESET();
__HAL_RCC_LPUART1_CLK_DISABLE();
#endif
+ #if defined(LPUART2)
+ } else if (self->uart_id == PYB_LPUART_2) {
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART2_LPUART2_IRQn);
+ #else
+ HAL_NVIC_DisableIRQ(LPUART2_IRQn);
+ #endif
+ __HAL_RCC_LPUART2_FORCE_RESET();
+ __HAL_RCC_LPUART2_RELEASE_RESET();
+ __HAL_RCC_LPUART2_CLK_DISABLE();
+ #endif
}
}
@@ -730,7 +800,7 @@ void uart_attach_to_repl(pyb_uart_obj_t *self, bool attached) {
uint32_t uart_get_source_freq(pyb_uart_obj_t *self) {
uint32_t uart_clk = 0;
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
uart_clk = HAL_RCC_GetPCLK1Freq();
#elif defined(STM32F7)
switch ((RCC->DCKCFGR2 >> ((self->uart_id - 1) * 2)) & 3) {
@@ -830,14 +900,14 @@ uint32_t uart_get_baudrate(pyb_uart_obj_t *self) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
return LL_LPUART_GetBaudRate(self->uartx, uart_get_source_freq(self)
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
, self->uartx->PRESC
#endif
);
}
#endif
return LL_USART_GetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
self->uartx->PRESC,
#endif
LL_USART_OVERSAMPLING_16);
@@ -847,7 +917,7 @@ void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
LL_LPUART_SetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
LL_LPUART_PRESCALER_DIV1,
#endif
baudrate);
@@ -855,7 +925,7 @@ void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
}
#endif
LL_USART_SetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
LL_USART_PRESCALER_DIV1,
#endif
LL_USART_OVERSAMPLING_16, baudrate);
@@ -906,7 +976,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
return data;
} else {
// no buffering
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
int data = self->uartx->RDR & self->char_mask;
self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set
return data;
@@ -1056,7 +1126,7 @@ void uart_irq_handler(mp_uint_t uart_id) {
uint16_t next_head = (self->read_buf_head + 1) % self->read_buf_len;
if (next_head != self->read_buf_tail) {
// only read data if room in buf
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
int data = self->uartx->RDR; // clears UART_FLAG_RXNE
#else
self->mp_irq_flags = self->uartx->SR; // resample to get any new flags since next read of DR will clear SR