Commit 6ea45277 authored by Damien George's avatar Damien George

stm32/uart: For UART init, pass in params directly, not via HAL struct.

To provide a cleaner and more abstract C-level interface to the UART.
parent e0c24325
...@@ -161,52 +161,45 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const ...@@ -161,52 +161,45 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
mp_arg_parse_all(n_args, pos_args, kw_args, mp_arg_parse_all(n_args, pos_args, kw_args,
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args);
// set the UART configuration values
UART_InitTypeDef init_struct;
memset(&init_struct, 0, sizeof(init_struct));
UART_InitTypeDef *init = &init_struct;
// baudrate // baudrate
init->BaudRate = args.baudrate.u_int; uint32_t baudrate = args.baudrate.u_int;
// parity // parity
mp_int_t bits = args.bits.u_int; uint32_t bits = args.bits.u_int;
uint32_t parity;
if (args.parity.u_obj == mp_const_none) { if (args.parity.u_obj == mp_const_none) {
init->Parity = UART_PARITY_NONE; parity = UART_PARITY_NONE;
} else { } else {
mp_int_t parity = mp_obj_get_int(args.parity.u_obj); mp_int_t p = mp_obj_get_int(args.parity.u_obj);
init->Parity = (parity & 1) ? UART_PARITY_ODD : UART_PARITY_EVEN; parity = (p & 1) ? UART_PARITY_ODD : UART_PARITY_EVEN;
bits += 1; // STs convention has bits including parity bits += 1; // STs convention has bits including parity
} }
// number of bits // number of bits
if (bits == 8) { if (bits == 8) {
init->WordLength = UART_WORDLENGTH_8B; bits = UART_WORDLENGTH_8B;
} else if (bits == 9) { } else if (bits == 9) {
init->WordLength = UART_WORDLENGTH_9B; bits = UART_WORDLENGTH_9B;
#ifdef UART_WORDLENGTH_7B #ifdef UART_WORDLENGTH_7B
} else if (bits == 7) { } else if (bits == 7) {
init->WordLength = UART_WORDLENGTH_7B; bits = UART_WORDLENGTH_7B;
#endif #endif
} else { } else {
mp_raise_ValueError("unsupported combination of bits and parity"); mp_raise_ValueError("unsupported combination of bits and parity");
} }
// stop bits // stop bits
uint32_t stop;
switch (args.stop.u_int) { switch (args.stop.u_int) {
case 1: init->StopBits = UART_STOPBITS_1; break; case 1: stop = UART_STOPBITS_1; break;
default: init->StopBits = UART_STOPBITS_2; break; default: stop = UART_STOPBITS_2; break;
} }
// flow control // flow control
init->HwFlowCtl = args.flow.u_int; uint32_t flow = args.flow.u_int;
// extra config (not yet configurable)
init->Mode = UART_MODE_TX_RX;
init->OverSampling = UART_OVERSAMPLING_16;
// init UART (if it fails, it's because the port doesn't exist) // init UART (if it fails, it's because the port doesn't exist)
if (!uart_init2(self, init)) { if (!uart_init(self, baudrate, bits, parity, stop, flow)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART(%d) doesn't exist", self->uart_id)); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART(%d) doesn't exist", self->uart_id));
} }
...@@ -217,18 +210,18 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const ...@@ -217,18 +210,18 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
// make sure it is at least as long as a whole character (13 bits to be safe) // make sure it is at least as long as a whole character (13 bits to be safe)
// minimum value is 2ms because sys-tick has a resolution of only 1ms // minimum value is 2ms because sys-tick has a resolution of only 1ms
self->timeout_char = args.timeout_char.u_int; self->timeout_char = args.timeout_char.u_int;
uint32_t min_timeout_char = 13000 / init->BaudRate + 2; uint32_t min_timeout_char = 13000 / baudrate + 2;
if (self->timeout_char < min_timeout_char) { if (self->timeout_char < min_timeout_char) {
self->timeout_char = min_timeout_char; self->timeout_char = min_timeout_char;
} }
// setup the read buffer // setup the read buffer
m_del(byte, self->read_buf, self->read_buf_len << self->char_width); m_del(byte, self->read_buf, self->read_buf_len << self->char_width);
if (init->WordLength == UART_WORDLENGTH_9B && init->Parity == UART_PARITY_NONE) { if (bits == UART_WORDLENGTH_9B && parity == UART_PARITY_NONE) {
self->char_mask = 0x1ff; self->char_mask = 0x1ff;
self->char_width = CHAR_WIDTH_9BIT; self->char_width = CHAR_WIDTH_9BIT;
} else { } else {
if (init->WordLength == UART_WORDLENGTH_9B || init->Parity == UART_PARITY_NONE) { if (bits == UART_WORDLENGTH_9B || parity == UART_PARITY_NONE) {
self->char_mask = 0xff; self->char_mask = 0xff;
} else { } else {
self->char_mask = 0x7f; self->char_mask = 0x7f;
...@@ -254,10 +247,10 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const ...@@ -254,10 +247,10 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
// check we could set the baudrate within 5% // check we could set the baudrate within 5%
uint32_t baudrate_diff; uint32_t baudrate_diff;
if (actual_baudrate > init->BaudRate) { if (actual_baudrate > baudrate) {
baudrate_diff = actual_baudrate - init->BaudRate; baudrate_diff = actual_baudrate - baudrate;
} else { } else {
baudrate_diff = init->BaudRate - actual_baudrate; baudrate_diff = baudrate - actual_baudrate;
} }
if (20 * baudrate_diff > actual_baudrate) { if (20 * baudrate_diff > actual_baudrate) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "set baudrate %d is not within 5%% of desired value", actual_baudrate)); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "set baudrate %d is not within 5%% of desired value", actual_baudrate));
......
...@@ -123,7 +123,8 @@ bool uart_exists(int uart_id) { ...@@ -123,7 +123,8 @@ bool uart_exists(int uart_id) {
} }
// assumes Init parameters have been set up correctly // assumes Init parameters have been set up correctly
bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) { 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; USART_TypeDef *UARTx;
IRQn_Type irqn; IRQn_Type irqn;
int uart_unit; int uart_unit;
...@@ -150,12 +151,12 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) { ...@@ -150,12 +151,12 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) {
pins[0] = MICROPY_HW_UART2_TX; pins[0] = MICROPY_HW_UART2_TX;
pins[1] = MICROPY_HW_UART2_RX; pins[1] = MICROPY_HW_UART2_RX;
#if defined(MICROPY_HW_UART2_RTS) #if defined(MICROPY_HW_UART2_RTS)
if (init->HwFlowCtl & UART_HWCONTROL_RTS) { if (flow & UART_HWCONTROL_RTS) {
pins[2] = MICROPY_HW_UART2_RTS; pins[2] = MICROPY_HW_UART2_RTS;
} }
#endif #endif
#if defined(MICROPY_HW_UART2_CTS) #if defined(MICROPY_HW_UART2_CTS)
if (init->HwFlowCtl & UART_HWCONTROL_CTS) { if (flow & UART_HWCONTROL_CTS) {
pins[3] = MICROPY_HW_UART2_CTS; pins[3] = MICROPY_HW_UART2_CTS;
} }
#endif #endif
...@@ -175,12 +176,12 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) { ...@@ -175,12 +176,12 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) {
pins[0] = MICROPY_HW_UART3_TX; pins[0] = MICROPY_HW_UART3_TX;
pins[1] = MICROPY_HW_UART3_RX; pins[1] = MICROPY_HW_UART3_RX;
#if defined(MICROPY_HW_UART3_RTS) #if defined(MICROPY_HW_UART3_RTS)
if (init->HwFlowCtl & UART_HWCONTROL_RTS) { if (flow & UART_HWCONTROL_RTS) {
pins[2] = MICROPY_HW_UART3_RTS; pins[2] = MICROPY_HW_UART3_RTS;
} }
#endif #endif
#if defined(MICROPY_HW_UART3_CTS) #if defined(MICROPY_HW_UART3_CTS)
if (init->HwFlowCtl & UART_HWCONTROL_CTS) { if (flow & UART_HWCONTROL_CTS) {
pins[3] = MICROPY_HW_UART3_CTS; pins[3] = MICROPY_HW_UART3_CTS;
} }
#endif #endif
...@@ -234,12 +235,12 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) { ...@@ -234,12 +235,12 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) {
pins[0] = MICROPY_HW_UART6_TX; pins[0] = MICROPY_HW_UART6_TX;
pins[1] = MICROPY_HW_UART6_RX; pins[1] = MICROPY_HW_UART6_RX;
#if defined(MICROPY_HW_UART6_RTS) #if defined(MICROPY_HW_UART6_RTS)
if (init->HwFlowCtl & UART_HWCONTROL_RTS) { if (flow & UART_HWCONTROL_RTS) {
pins[2] = MICROPY_HW_UART6_RTS; pins[2] = MICROPY_HW_UART6_RTS;
} }
#endif #endif
#if defined(MICROPY_HW_UART6_CTS) #if defined(MICROPY_HW_UART6_CTS)
if (init->HwFlowCtl & UART_HWCONTROL_CTS) { if (flow & UART_HWCONTROL_CTS) {
pins[3] = MICROPY_HW_UART6_CTS; pins[3] = MICROPY_HW_UART6_CTS;
} }
#endif #endif
...@@ -305,7 +306,13 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) { ...@@ -305,7 +306,13 @@ bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init) {
UART_HandleTypeDef huart; UART_HandleTypeDef huart;
memset(&huart, 0, sizeof(huart)); memset(&huart, 0, sizeof(huart));
huart.Instance = UARTx; huart.Instance = UARTx;
huart.Init = *init; huart.Init.BaudRate = baudrate;
huart.Init.WordLength = bits;
huart.Init.StopBits = stop;
huart.Init.Parity = parity;
huart.Init.Mode = UART_MODE_TX_RX;
huart.Init.HwFlowCtl = flow;
huart.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart); HAL_UART_Init(&huart);
uart_obj->is_enabled = true; uart_obj->is_enabled = true;
...@@ -421,21 +428,6 @@ void uart_attach_to_repl(pyb_uart_obj_t *self, bool attached) { ...@@ -421,21 +428,6 @@ void uart_attach_to_repl(pyb_uart_obj_t *self, bool attached) {
self->attached_to_repl = attached; self->attached_to_repl = attached;
} }
/* obsolete and unused
bool uart_init(pyb_uart_obj_t *uart_obj, uint32_t baudrate) {
UART_HandleTypeDef *uh = &uart_obj->uart;
memset(uh, 0, sizeof(*uh));
uh->Init.BaudRate = baudrate;
uh->Init.WordLength = UART_WORDLENGTH_8B;
uh->Init.StopBits = UART_STOPBITS_1;
uh->Init.Parity = UART_PARITY_NONE;
uh->Init.Mode = UART_MODE_TX_RX;
uh->Init.HwFlowCtl = UART_HWCONTROL_NONE;
uh->Init.OverSampling = UART_OVERSAMPLING_16;
return uart_init2(uart_obj);
}
*/
uint32_t uart_get_baudrate(pyb_uart_obj_t *self) { uint32_t uart_get_baudrate(pyb_uart_obj_t *self) {
uint32_t uart_clk = 0; uint32_t uart_clk = 0;
......
...@@ -63,7 +63,8 @@ extern const mp_obj_type_t pyb_uart_type; ...@@ -63,7 +63,8 @@ extern const mp_obj_type_t pyb_uart_type;
void uart_init0(void); void uart_init0(void);
void uart_deinit_all(void); void uart_deinit_all(void);
bool uart_exists(int uart_id); bool uart_exists(int uart_id);
bool uart_init2(pyb_uart_obj_t *uart_obj, UART_InitTypeDef *init); bool uart_init(pyb_uart_obj_t *uart_obj,
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow);
void uart_set_rxbuf(pyb_uart_obj_t *self, size_t len, void *buf); void uart_set_rxbuf(pyb_uart_obj_t *self, size_t len, void *buf);
void uart_deinit(pyb_uart_obj_t *uart_obj); void uart_deinit(pyb_uart_obj_t *uart_obj);
void uart_irq_handler(mp_uint_t uart_id); void uart_irq_handler(mp_uint_t uart_id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment