summaryrefslogtreecommitdiffstatshomepage
path: root/ports/stm32/uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/uart.c')
-rw-r--r--ports/stm32/uart.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index 55fa622142..9354af4a29 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -91,7 +91,7 @@
#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_WUFIE)
#endif
-#elif defined(STM32H7)
+#elif defined(STM32H7) || defined(STM32N6)
#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_RXFFIE | USART_CR1_TXFEIE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE)
#define USART_CR2_IE_ALL (USART_CR2_IE_BASE)
#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_RXFTIE | USART_CR3_TCBGTIE | USART_CR3_TXFTIE | USART_CR3_WUFIE)
@@ -157,6 +157,18 @@ void uart_init0(void) {
if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) {
MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig");
}
+ #elif defined(STM32N6)
+ // UART clock configuration, IC14 (max 100MHz).
+ LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_IC14);
+ LL_RCC_SetUSARTClockSource(LL_RCC_USART2_CLKSOURCE_IC14);
+ LL_RCC_SetUSARTClockSource(LL_RCC_USART3_CLKSOURCE_IC14);
+ LL_RCC_SetUARTClockSource(LL_RCC_UART4_CLKSOURCE_IC14);
+ LL_RCC_SetUARTClockSource(LL_RCC_UART5_CLKSOURCE_IC14);
+ LL_RCC_SetUSARTClockSource(LL_RCC_USART6_CLKSOURCE_IC14);
+ LL_RCC_SetUARTClockSource(LL_RCC_UART7_CLKSOURCE_IC14);
+ LL_RCC_SetUARTClockSource(LL_RCC_UART8_CLKSOURCE_IC14);
+ LL_RCC_SetUARTClockSource(LL_RCC_UART9_CLKSOURCE_IC14);
+ LL_RCC_SetUSARTClockSource(LL_RCC_USART10_CLKSOURCE_IC14);
#endif
}
@@ -661,7 +673,7 @@ bool uart_init(machine_uart_obj_t *uart_obj,
huart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
#endif
- #if defined(STM32H7) || defined(STM32WB)
+ #if defined(STM32H7) || defined(STM32N6) || defined(STM32WB)
// Compute the smallest prescaler that will allow the given baudrate.
uint32_t presc = UART_PRESCALER_DIV1;
if (uart_obj->uart_id == PYB_LPUART_1) {
@@ -689,6 +701,10 @@ bool uart_init(machine_uart_obj_t *uart_obj,
uart_obj->is_enabled = true;
uart_obj->attached_to_repl = false;
+ #if defined(STM32F4) || defined(STM32L1)
+ uart_obj->suppress_idle_irq = true;
+ #endif
+
if (bits == UART_WORDLENGTH_9B && parity == UART_PARITY_NONE) {
uart_obj->char_mask = 0x1ff;
uart_obj->char_width = CHAR_WIDTH_9BIT;
@@ -972,6 +988,29 @@ uint32_t uart_get_source_freq(machine_uart_obj_t *self) {
default:
break;
}
+
+ #elif defined(STM32N6)
+
+ static const uint16_t is_usart = 1 << 10 | 1 << 6 | 1 << 3 | 1 << 2 | 1 << 1;
+ static const uint32_t clksource[] = {
+ LL_RCC_USART1_CLKSOURCE,
+ LL_RCC_USART2_CLKSOURCE,
+ LL_RCC_USART3_CLKSOURCE,
+ LL_RCC_UART4_CLKSOURCE,
+ LL_RCC_UART5_CLKSOURCE,
+ LL_RCC_USART6_CLKSOURCE,
+ LL_RCC_UART7_CLKSOURCE,
+ LL_RCC_UART8_CLKSOURCE,
+ LL_RCC_UART9_CLKSOURCE,
+ LL_RCC_USART10_CLKSOURCE,
+ };
+
+ if (is_usart & (1 << self->uart_id)) {
+ uart_clk = LL_RCC_GetUSARTClockFreq(clksource[self->uart_id - 1]);
+ } else {
+ uart_clk = LL_RCC_GetUARTClockFreq(clksource[self->uart_id - 1]);
+ }
+
#else
if (self->uart_id == 1
#if defined(USART6)
@@ -997,14 +1036,14 @@ uint32_t uart_get_baudrate(machine_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(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL)
, self->uartx->PRESC
#endif
);
}
#endif
return LL_USART_GetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL)
self->uartx->PRESC,
#endif
LL_USART_OVERSAMPLING_16);
@@ -1014,7 +1053,7 @@ void uart_set_baudrate(machine_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(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL)
LL_LPUART_PRESCALER_DIV1,
#endif
baudrate);
@@ -1022,7 +1061,7 @@ void uart_set_baudrate(machine_uart_obj_t *self, uint32_t baudrate) {
}
#endif
LL_USART_SetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL)
LL_USART_PRESCALER_DIV1,
#endif
LL_USART_OVERSAMPLING_16, baudrate);
@@ -1073,7 +1112,7 @@ int uart_rx_char(machine_uart_obj_t *self) {
return data;
} else {
// no buffering
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32N6) || 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;
@@ -1228,7 +1267,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(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || 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
@@ -1274,6 +1313,9 @@ void uart_irq_handler(mp_uint_t uart_id) {
self->uartx->CR1 &= ~USART_CR1_RXNEIE;
}
}
+ if (self->suppress_idle_irq) {
+ self->mp_irq_flags &= ~USART_SR_IDLE;
+ }
#else
self->uartx->ICR = self->mp_irq_flags & (USART_ICR_IDLECF | USART_ICR_ORECF);
#endif
@@ -1282,6 +1324,14 @@ void uart_irq_handler(mp_uint_t uart_id) {
if (self->mp_irq_trigger & self->mp_irq_flags) {
mp_irq_handler(self->mp_irq_obj);
}
+
+ #if defined(STM32F4) || defined(STM32L1)
+ if (did_clear_sr) {
+ self->suppress_idle_irq = false;
+ } else {
+ self->suppress_idle_irq = true;
+ }
+ #endif
}
static mp_uint_t uart_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) {