Skip to content

Commit 4efc5e1

Browse files
ennyKeydpgeorge
authored andcommitted
stm32/machine_uart: Implement TX/RX inversion parameter for UART on H7.
Implemented the keyword-only parameter `invert` for the `UART.init` method in accordance with the docs: - added constants `UART.INV_TX` and `UART.INV_RX` - added the new `invert` keyword parameter to the `uart_init` function - adapted the `uart_init` call - added invert setting to `uart_print` output The feature applies only to STM32H7. Signed-off-by: ennyKey <[email protected]>
1 parent e58425a commit 4efc5e1

File tree

5 files changed

+59
-6
lines changed

5 files changed

+59
-6
lines changed

ports/stm32/machine_uart.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,20 @@
3737
#include "irq.h"
3838
#include "pendsv.h"
3939

40+
#if defined(STM32H7)
41+
#define MICROPY_PY_MACHINE_UART_INV_ENTRY \
42+
{ MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_ADVFEATURE_TXINVERT_INIT) }, \
43+
{ MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_ADVFEATURE_RXINVERT_INIT) },
44+
#else
45+
#define MICROPY_PY_MACHINE_UART_INV_ENTRY
46+
#endif
47+
4048
#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \
4149
{ MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, \
4250
{ MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) }, \
4351
{ MP_ROM_QSTR(MP_QSTR_IRQ_RXIDLE), MP_ROM_INT(UART_FLAG_IDLE) }, \
4452
{ MP_ROM_QSTR(MP_QSTR_IRQ_RX), MP_ROM_INT(UART_FLAG_RXNE) }, \
53+
MICROPY_PY_MACHINE_UART_INV_ENTRY \
4554

4655
static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
4756
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -125,11 +134,27 @@ static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_
125134
if (self->mp_irq_trigger != 0) {
126135
mp_printf(print, "; irq=0x%x", self->mp_irq_trigger);
127136
}
137+
#if defined(STM32H7)
138+
mp_print_str(print, ", invert=");
139+
if (!(cr2 & (USART_CR2_TXINV | USART_CR2_RXINV))) {
140+
mp_print_str(print, "0");
141+
} else {
142+
if (cr2 & USART_CR2_TXINV) {
143+
mp_print_str(print, "INV_TX");
144+
if (cr2 & USART_CR2_RXINV) {
145+
mp_print_str(print, "|");
146+
}
147+
}
148+
if (cr2 & USART_CR2_RXINV) {
149+
mp_print_str(print, "INV_RX");
150+
}
151+
}
152+
#endif
128153
mp_print_str(print, ")");
129154
}
130155
}
131156

132-
/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0, flow=0, read_buf_len=64)
157+
/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0, flow=0, read_buf_len=64, invert=0)
133158
///
134159
/// Initialise the UART bus with the given parameters:
135160
///
@@ -141,6 +166,7 @@ static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_
141166
/// - `timeout_char` is the timeout in milliseconds to wait between characters.
142167
/// - `flow` is RTS | CTS where RTS == 256, CTS == 512
143168
/// - `read_buf_len` is the character length of the read buffer (0 to disable).
169+
/// - `invert` specifies which lines to invert. INV_TX | INV_RX (0 to disable). --> Only for STM32H7
144170
static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
145171
static const mp_arg_t allowed_args[] = {
146172
{ MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} },
@@ -152,11 +178,17 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
152178
{ MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
153179
{ MP_QSTR_rxbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
154180
{ MP_QSTR_read_buf_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, // legacy
181+
#if defined(STM32H7)
182+
{ MP_QSTR_invert, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
183+
#endif
155184
};
156185

157186
// parse args
158187
struct {
159188
mp_arg_val_t baudrate, bits, parity, stop, flow, timeout, timeout_char, rxbuf, read_buf_len;
189+
#if defined(STM32H7)
190+
mp_arg_val_t invert;
191+
#endif
160192
} args;
161193
mp_arg_parse_all(n_args, pos_args, kw_args,
162194
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
@@ -202,11 +234,18 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
202234
// flow control
203235
uint32_t flow = args.flow.u_int;
204236

237+
// inverted
238+
#if defined(STM32H7)
239+
uint32_t invert = args.invert.u_int;
240+
#else
241+
uint32_t invert = 0;
242+
#endif
243+
205244
// Save attach_to_repl setting because uart_init will disable it.
206245
bool attach_to_repl = self->attached_to_repl;
207246

208247
// init UART (if it fails, it's because the port doesn't exist)
209-
if (!uart_init(self, baudrate, bits, parity, stop, flow)) {
248+
if (!uart_init(self, baudrate, bits, parity, stop, flow, invert)) {
210249
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) doesn't exist"), self->uart_id);
211250
}
212251

ports/stm32/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ void stm32_main(uint32_t reset_mode) {
502502
pyb_uart_repl_obj.is_static = true;
503503
pyb_uart_repl_obj.timeout = 0;
504504
pyb_uart_repl_obj.timeout_char = 2;
505-
uart_init(&pyb_uart_repl_obj, MICROPY_HW_UART_REPL_BAUD, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, 0);
505+
uart_init(&pyb_uart_repl_obj, MICROPY_HW_UART_REPL_BAUD, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, 0, 0);
506506
uart_set_rxbuf(&pyb_uart_repl_obj, sizeof(pyb_uart_repl_rxbuf), pyb_uart_repl_rxbuf);
507507
uart_attach_to_repl(&pyb_uart_repl_obj, true);
508508
MP_STATE_PORT(machine_uart_obj_all)[MICROPY_HW_UART_REPL - 1] = &pyb_uart_repl_obj;

ports/stm32/mpbthciport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) {
184184
MP_STATE_PORT(machine_uart_obj_all)[mp_bluetooth_hci_uart_obj.uart_id - 1] = &mp_bluetooth_hci_uart_obj;
185185

186186
// Initialise the UART.
187-
uart_init(&mp_bluetooth_hci_uart_obj, baudrate, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, UART_HWCONTROL_RTS | UART_HWCONTROL_CTS);
187+
uart_init(&mp_bluetooth_hci_uart_obj, baudrate, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, UART_HWCONTROL_RTS | UART_HWCONTROL_CTS, 0);
188188
uart_set_rxbuf(&mp_bluetooth_hci_uart_obj, sizeof(hci_uart_rxbuf), hci_uart_rxbuf);
189189

190190
// Add IRQ handler for IDLE (i.e. packet finished).

ports/stm32/uart.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ bool uart_exists(int uart_id) {
265265

266266
// assumes Init parameters have been set up correctly
267267
bool uart_init(machine_uart_obj_t *uart_obj,
268-
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow) {
268+
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow, uint32_t invert) {
269269
USART_TypeDef *UARTx;
270270
IRQn_Type irqn;
271271
uint8_t uart_fn = AF_FN_UART;
@@ -677,6 +677,20 @@ bool uart_init(machine_uart_obj_t *uart_obj,
677677
huart.Init.ClockPrescaler = UART_PRESCALER_DIV16;
678678
#endif
679679

680+
#if defined(STM32H7)
681+
huart.AdvancedInit.AdvFeatureInit = (UART_ADVFEATURE_TXINVERT_INIT | UART_ADVFEATURE_RXINVERT_INIT);
682+
if (invert & UART_ADVFEATURE_RXINVERT_INIT) {
683+
huart.AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_ENABLE;
684+
} else {
685+
huart.AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_DISABLE;
686+
}
687+
if (invert & UART_ADVFEATURE_TXINVERT_INIT) {
688+
huart.AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_ENABLE;
689+
} else {
690+
huart.AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_DISABLE;
691+
}
692+
#endif
693+
680694
#if defined(STM32G4) || defined(STM32H7) || defined(STM32N6) // WB also has a fifo..
681695
huart.FifoMode = UART_FIFOMODE_ENABLE;
682696
#endif

ports/stm32/uart.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ void uart_init0(void);
8787
void uart_deinit_all(void);
8888
bool uart_exists(int uart_id);
8989
bool uart_init(machine_uart_obj_t *uart_obj,
90-
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow);
90+
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow, uint32_t invert);
9191
void uart_irq_config(machine_uart_obj_t *self, bool enable);
9292
void uart_set_rxbuf(machine_uart_obj_t *self, size_t len, void *buf);
9393
void uart_deinit(machine_uart_obj_t *uart_obj);

0 commit comments

Comments
 (0)