3636#include "py/stream.h"
3737#include "modpyb.h"
3838
39+ // baudrate is currently fixed to this value
40+ #define UART_BAUDRATE (115200)
41+
3942typedef struct _pyb_uart_obj_t {
4043 mp_obj_base_t base ;
4144 uint8_t uart_id ;
45+ uint16_t timeout ; // timeout waiting for first char (in ms)
46+ uint16_t timeout_char ; // timeout waiting between chars (in ms)
4247} pyb_uart_obj_t ;
4348
4449/******************************************************************************/
4550// MicroPython bindings for UART
4651
4752STATIC void pyb_uart_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
4853 pyb_uart_obj_t * self = MP_OBJ_TO_PTR (self_in );
49- mp_printf (print , "UART(%u)" , self -> uart_id );
54+ mp_printf (print , "UART(%u, baudrate=%u, timeout=%u, timeout_char=%u)" ,
55+ self -> uart_id , UART_BAUDRATE , self -> timeout , self -> timeout_char );
5056}
5157
5258STATIC void pyb_uart_init_helper (pyb_uart_obj_t * self , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
53- /*
54- enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop };
59+ enum { ARG_timeout , ARG_timeout_char };
5560 static const mp_arg_t allowed_args [] = {
56- { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} },
57- { MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
58- { MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = mp_const_none} },
59- { MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
60- { MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
61- { MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
61+ //{ MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} },
62+ //{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
63+ //{ MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = mp_const_none} },
64+ //{ MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
65+ //{ MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
66+ //{ MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
67+ { MP_QSTR_timeout , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
68+ { MP_QSTR_timeout_char , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
6269 };
6370 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
6471 mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
65- */
66- // not implemented
72+
73+ // set timeout
74+ self -> timeout = args [ARG_timeout ].u_int ;
75+
76+ // set timeout_char
77+ // make sure it is at least as long as a whole character (13 bits to be safe)
78+ self -> timeout_char = args [ARG_timeout_char ].u_int ;
79+ uint32_t min_timeout_char = 13000 / UART_BAUDRATE + 1 ;
80+ if (self -> timeout_char < min_timeout_char ) {
81+ self -> timeout_char = min_timeout_char ;
82+ }
6783}
6884
6985STATIC mp_obj_t pyb_uart_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
@@ -80,12 +96,10 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
8096 self -> base .type = & pyb_uart_type ;
8197 self -> uart_id = uart_id ;
8298
83- if (n_args > 1 || n_kw > 0 ) {
84- // init the peripheral
85- mp_map_t kw_args ;
86- mp_map_init_fixed_table (& kw_args , n_kw , args + n_args );
87- pyb_uart_init_helper (self , n_args - 1 , args + 1 , & kw_args );
88- }
99+ // init the peripheral
100+ mp_map_t kw_args ;
101+ mp_map_init_fixed_table (& kw_args , n_kw , args + n_args );
102+ pyb_uart_init_helper (self , n_args - 1 , args + 1 , & kw_args );
89103
90104 return MP_OBJ_FROM_PTR (self );
91105}
@@ -109,7 +123,32 @@ STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
109123STATIC MP_DEFINE_CONST_DICT (pyb_uart_locals_dict , pyb_uart_locals_dict_table );
110124
111125STATIC mp_uint_t pyb_uart_read (mp_obj_t self_in , void * buf_in , mp_uint_t size , int * errcode ) {
112- mp_not_implemented ("reading from UART" );
126+ pyb_uart_obj_t * self = MP_OBJ_TO_PTR (self_in );
127+
128+ if (self -> uart_id == 1 ) {
129+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_OSError , "UART(1) can't read" ));
130+ }
131+
132+ // make sure we want at least 1 char
133+ if (size == 0 ) {
134+ return 0 ;
135+ }
136+
137+ // wait for first char to become available
138+ if (!uart_rx_wait (self -> timeout * 1000 )) {
139+ * errcode = EAGAIN ;
140+ return MP_STREAM_ERROR ;
141+ }
142+
143+ // read the data
144+ uint8_t * buf = buf_in ;
145+ for (;;) {
146+ * buf ++ = uart_rx_char ();
147+ if (-- size == 0 || !uart_rx_wait (self -> timeout_char * 1000 )) {
148+ // return number of bytes read
149+ return buf - (uint8_t * )buf_in ;
150+ }
151+ }
113152}
114153
115154STATIC mp_uint_t pyb_uart_write (mp_obj_t self_in , const void * buf_in , mp_uint_t size , int * errcode ) {
0 commit comments