8080
8181struct _pyb_uart_obj_t {
8282 mp_obj_base_t base ;
83- pyb_uart_t uart_id ;
84- bool is_enabled ;
85- UART_HandleTypeDef uart ;
83+ UART_HandleTypeDef uart ; // this is 17 words big
8684 IRQn_Type irqn ;
85+ pyb_uart_t uart_id : 8 ;
86+ bool is_enabled : 1 ;
87+ byte char_width ; // 0 for 7,8 bit chars, 1 for 9 bit chars
88+ uint16_t char_mask ; // 0x7f for 7 bit, 0xff for 8 bit, 0x1ff for 9 bit
8789 uint16_t timeout ; // timeout waiting for first char
8890 uint16_t timeout_char ; // timeout waiting between chars
89- uint16_t char_width ; // 0 for 7,8 bit chars, 1 for 9 bit chars
9091 uint16_t read_buf_len ; // len in chars; buf can hold len-1 chars
9192 volatile uint16_t read_buf_head ; // indexes first empty slot
9293 uint16_t read_buf_tail ; // indexes first full slot (not full if equals head)
@@ -280,7 +281,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
280281 return data ;
281282 } else {
282283 // no buffering
283- return self -> uart .Instance -> DR ;
284+ return self -> uart .Instance -> DR & self -> char_mask ;
284285 }
285286}
286287
@@ -315,6 +316,7 @@ void uart_irq_handler(mp_uint_t uart_id) {
315316
316317 if (__HAL_UART_GET_FLAG (& self -> uart , UART_FLAG_RXNE ) != RESET ) {
317318 int data = self -> uart .Instance -> DR ; // clears UART_FLAG_RXNE
319+ data &= self -> char_mask ;
318320 if (self -> read_buf_len != 0 ) {
319321 uint16_t next_head = (self -> read_buf_head + 1 ) % self -> read_buf_len ;
320322 if (next_head != self -> read_buf_tail ) {
@@ -340,9 +342,12 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
340342 if (!self -> is_enabled ) {
341343 print (env , "UART(%u)" , self -> uart_id );
342344 } else {
345+ mp_int_t bits = (self -> uart .Init .WordLength == UART_WORDLENGTH_8B ? 8 : 9 );
346+ if (self -> uart .Init .Parity != UART_PARITY_NONE ) {
347+ bits -= 1 ;
348+ }
343349 print (env , "UART(%u, baudrate=%u, bits=%u, parity=" ,
344- self -> uart_id , self -> uart .Init .BaudRate ,
345- self -> uart .Init .WordLength == UART_WORDLENGTH_8B ? 8 : 9 );
350+ self -> uart_id , self -> uart .Init .BaudRate , bits );
346351 if (self -> uart .Init .Parity == UART_PARITY_NONE ) {
347352 print (env , "None" );
348353 } else {
@@ -359,7 +364,7 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
359364/// Initialise the UART bus with the given parameters:
360365///
361366/// - `baudrate` is the clock rate.
362- /// - `bits` is the number of bits per byte, 8 or 9.
367+ /// - `bits` is the number of bits per byte, 7, 8 or 9.
363368/// - `parity` is the parity, `None`, 0 (even) or 1 (odd).
364369/// - `stop` is the number of stop bits, 1 or 2.
365370/// - `timeout` is the timeout in milliseconds to wait for the first character.
@@ -384,20 +389,40 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
384389 // set the UART configuration values
385390 memset (& self -> uart , 0 , sizeof (self -> uart ));
386391 UART_InitTypeDef * init = & self -> uart .Init ;
392+
393+ // baudrate
387394 init -> BaudRate = args [0 ].u_int ;
388- init -> WordLength = args [1 ].u_int == 8 ? UART_WORDLENGTH_8B : UART_WORDLENGTH_9B ;
395+
396+ // parity
397+ mp_int_t bits = args [1 ].u_int ;
389398 if (args [2 ].u_obj == mp_const_none ) {
390399 init -> Parity = UART_PARITY_NONE ;
391400 } else {
392401 mp_int_t parity = mp_obj_get_int (args [2 ].u_obj );
393402 init -> Parity = (parity & 1 ) ? UART_PARITY_ODD : UART_PARITY_EVEN ;
403+ bits += 1 ; // STs convention has bits including parity
394404 }
405+
406+ // number of bits
407+ if (bits == 8 ) {
408+ init -> WordLength = UART_WORDLENGTH_8B ;
409+ } else if (bits == 9 ) {
410+ init -> WordLength = UART_WORDLENGTH_9B ;
411+ } else {
412+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "unsupported combination of bits and parity" ));
413+ }
414+
415+ // stop bits
395416 switch (args [3 ].u_int ) {
396417 case 1 : init -> StopBits = UART_STOPBITS_1 ; break ;
397418 default : init -> StopBits = UART_STOPBITS_2 ; break ;
398419 }
399- init -> Mode = UART_MODE_TX_RX ;
420+
421+ // flow control
400422 init -> HwFlowCtl = args [4 ].u_int ;
423+
424+ // extra config (not yet configurable)
425+ init -> Mode = UART_MODE_TX_RX ;
401426 init -> OverSampling = UART_OVERSAMPLING_16 ;
402427
403428 // init UART (if it fails, it's because the port doesn't exist)
@@ -412,8 +437,14 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
412437 // setup the read buffer
413438 m_del (byte , self -> read_buf , self -> read_buf_len << self -> char_width );
414439 if (init -> WordLength == UART_WORDLENGTH_9B && init -> Parity == UART_PARITY_NONE ) {
440+ self -> char_mask = 0x1ff ;
415441 self -> char_width = CHAR_WIDTH_9BIT ;
416442 } else {
443+ if (init -> WordLength == UART_WORDLENGTH_9B || init -> Parity == UART_PARITY_NONE ) {
444+ self -> char_mask = 0xff ;
445+ } else {
446+ self -> char_mask = 0x7f ;
447+ }
417448 self -> char_width = CHAR_WIDTH_8BIT ;
418449 }
419450 self -> read_buf_head = 0 ;
0 commit comments