diff options
Diffstat (limited to 'cc3200/mods/pybuart.c')
-rw-r--r-- | cc3200/mods/pybuart.c | 366 |
1 files changed, 149 insertions, 217 deletions
diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c index 4af9de61d7..cb010395bd 100644 --- a/cc3200/mods/pybuart.c +++ b/cc3200/mods/pybuart.c @@ -52,51 +52,30 @@ #include "py/mpstate.h" #include "osi.h" #include "utils.h" +#include "pin.h" +#include "pybpin.h" +#include "pins.h" /// \moduleref pyb /// \class UART - duplex serial communication bus -/// -/// UART implements the standard UART/USART duplex serial communications protocol. At -/// the physical level it consists of 2 lines: RX and TX. -/// -/// UART objects can be created and initialised using: -/// -/// from pyb import UART -/// -/// uart = UART(1, 9600) # init with given baudrate -/// uart.init(9600, bits=8, stop=1, parity=None) # init with given parameters -/// -/// Bits can be 5, 6, 7, 8, parity can be None, 0 (even), 1 (odd). Stop can be 1 or 2. -/// -/// A UART object acts like a stream object and reading and writing is done -/// using the standard stream methods: -/// -/// uart.read(10) # read 10 characters, returns a bytes object -/// uart.readall() # read all available characters -/// uart.readline() # read a line -/// uart.readinto(buf) # read and store into the given buffer -/// uart.write('abc') # write the 3 characters -/// -/// Individual characters can be read/written using: -/// -/// uart.readchar() # read 1 character and returns it as an integer -/// uart.writechar(42) # write 1 character -/// -/// To check if there is anything to be read, use: -/// -/// uart.any() # returns True if any characters waiting /****************************************************************************** DEFINE CONSTANTS - ******************************************************************************/ -#define PYBUART_TX_WAIT_US (50) + *******-***********************************************************************/ +#define PYBUART_FRAME_TIME_US(baud) ((11 * 1000000) / baud) +#define PYBUART_2_FRAMES_TIME_US(baud) (PYBUART_FRAME_TIME_US(baud) * 2) +#define PYBUART_RX_TIMEOUT_US(baud) (PYBUART_2_FRAMES_TIME_US(baud)) + +#define PYBUART_TX_WAIT_US(baud) ((PYBUART_FRAME_TIME_US(baud)) + 1) #define PYBUART_TX_MAX_TIMEOUT_MS (5) +#define PYBUART_RX_BUFFER_LEN (128) + /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ STATIC void uart_init (pyb_uart_obj_t *self); -STATIC bool uart_rx_wait (pyb_uart_obj_t *self, uint32_t timeout); +STATIC bool uart_rx_wait (pyb_uart_obj_t *self); STATIC void UARTGenericIntHandler(uint32_t uart_id); STATIC void UART0IntHandler(void); STATIC void UART1IntHandler(void); @@ -115,36 +94,45 @@ struct _pyb_uart_obj_t { uint config; uint flowcontrol; byte *read_buf; // read buffer pointer - uint16_t timeout; // timeout waiting for first char - uint16_t timeout_char; // timeout waiting between chars - uint16_t read_buf_len; // len in chars; buf can hold len-1 chars volatile uint16_t read_buf_head; // indexes first empty slot uint16_t read_buf_tail; // indexes first full slot (not full if equals head) byte peripheral; + byte irq_trigger; }; /****************************************************************************** DECLARE PRIVATE DATA ******************************************************************************/ -STATIC pyb_uart_obj_t pyb_uart_obj[PYB_NUM_UARTS] = {{.reg = UARTA0_BASE, .baudrate = 0, .peripheral = PRCM_UARTA0}, - {.reg = UARTA1_BASE, .baudrate = 0, .peripheral = PRCM_UARTA1}}; +STATIC pyb_uart_obj_t pyb_uart_obj[PYB_NUM_UARTS] = { {.reg = UARTA0_BASE, .baudrate = 0, .read_buf = NULL, .peripheral = PRCM_UARTA0}, + {.reg = UARTA1_BASE, .baudrate = 0, .read_buf = NULL, .peripheral = PRCM_UARTA1} }; STATIC const mp_cb_methods_t uart_cb_methods; +STATIC const pin_fn_t pyb_uart_def_pin[PYB_NUM_UARTS][2] = { {{.pin = &pin_GP1, .af_idx = 3}, {.pin = &pin_GP2, .af_idx = 3}}, + {{.pin = &pin_GP3, .af_idx = 6}, {.pin = &pin_GP4, .af_idx = 6}} }; + /****************************************************************************** DEFINE PUBLIC FUNCTIONS ******************************************************************************/ void uart_init0 (void) { + // save references of the UART objects, to prevent the read buffers from being trashed by the gc + MP_STATE_PORT(pyb_uart_objs)[0] = &pyb_uart_obj[0]; + MP_STATE_PORT(pyb_uart_objs)[1] = &pyb_uart_obj[1]; } -bool uart_rx_any(pyb_uart_obj_t *self) { - return (self->read_buf_tail != self->read_buf_head || MAP_UARTCharsAvail(self->reg)); +uint32_t uart_rx_any(pyb_uart_obj_t *self) { + if (self->read_buf_tail != self->read_buf_head) { + // buffering via irq + return (self->read_buf_head > self->read_buf_tail) ? self->read_buf_head - self->read_buf_tail : + PYBUART_RX_BUFFER_LEN - self->read_buf_tail + self->read_buf_head; + } + return MAP_UARTCharsAvail(self->reg) ? 1 : 0; } int uart_rx_char(pyb_uart_obj_t *self) { if (self->read_buf_tail != self->read_buf_head) { - // buffering via IRQ + // buffering via irq int data = self->read_buf[self->read_buf_tail]; - self->read_buf_tail = (self->read_buf_tail + 1) % self->read_buf_len; + self->read_buf_tail = (self->read_buf_tail + 1) % PYBUART_RX_BUFFER_LEN; return data; } else { // no buffering @@ -154,12 +142,11 @@ int uart_rx_char(pyb_uart_obj_t *self) { bool uart_tx_char(pyb_uart_obj_t *self, int c) { uint32_t timeout = 0; - while (!MAP_UARTCharPutNonBlocking(self->reg, c)) { - if (timeout++ > ((PYBUART_TX_MAX_TIMEOUT_MS * 1000) / PYBUART_TX_WAIT_US)) { + if (timeout++ > ((PYBUART_TX_MAX_TIMEOUT_MS * 1000) / PYBUART_TX_WAIT_US(self->baudrate))) { return false; } - UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_TX_WAIT_US)); + UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_TX_WAIT_US(self->baudrate))); } return true; } @@ -182,43 +169,28 @@ void uart_tx_strn_cooked(pyb_uart_obj_t *self, const char *str, uint len) { } } -mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, uint rxbuffer_size, mp_int_t priority) { +mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, mp_int_t priority, byte trigger) { // disable the uart interrupts before updating anything uart_callback_disable (self); if (self->uart_id == PYB_UART_0) { MAP_IntPrioritySet(INT_UARTA0, priority); MAP_UARTIntRegister(self->reg, UART0IntHandler); - } - else { + } else { MAP_IntPrioritySet(INT_UARTA1, priority); MAP_UARTIntRegister(self->reg, UART1IntHandler); } - // check the rx buffer size - if (rxbuffer_size > 0) { - // allocate the read buffer - self->read_buf_len = rxbuffer_size; - self->read_buf = m_new(byte, rxbuffer_size); - } - // create the callback mp_obj_t _callback = mpcallback_new ((mp_obj_t)self, handler, &uart_cb_methods, true); // enable the interrupts now + self->irq_trigger = trigger; uart_callback_enable (self); return _callback; } -void uart_disable_all (void) { - for (int i = 0; i < PYB_NUM_UARTS; i++) { - // in case it's not clocked - MAP_PRCMPeripheralClkEnable(pyb_uart_obj[i].peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); - pyb_uart_deinit(&pyb_uart_obj[i]); - } -} - /****************************************************************************** DEFINE PRIVATE FUNCTIONS ******************************************************************************/ @@ -230,6 +202,12 @@ STATIC void uart_init (pyb_uart_obj_t *self) { // Reset the uart MAP_PRCMPeripheralReset(self->peripheral); + // re-allocate the read buffer after resetting the uart (which automatically disables any irqs) + self->read_buf_head = 0; + self->read_buf_tail = 0; + self->read_buf = MP_OBJ_NULL; // free the read buffer before allocating again + self->read_buf = m_new(byte, PYBUART_RX_BUFFER_LEN); + // Initialize the UART MAP_UARTConfigSetExpClk(self->reg, MAP_PRCMPeripheralClockGet(self->peripheral), self->baudrate, self->config); @@ -244,16 +222,17 @@ STATIC void uart_init (pyb_uart_obj_t *self) { UARTFlowControlSet(self->reg, self->flowcontrol); } -// Waits at most timeout milliseconds for at least 1 char to become ready for +// Waits at most timeout microseconds for at least 1 char to become ready for // reading (from buf or for direct reading). // Returns true if something available, false if not. -STATIC bool uart_rx_wait (pyb_uart_obj_t *self, uint32_t timeout) { +STATIC bool uart_rx_wait (pyb_uart_obj_t *self) { + int timeout = PYBUART_RX_TIMEOUT_US(self->baudrate); for ( ; ; ) { if (uart_rx_any(self)) { - return true; // have at least 1 char ready for reading + return true; // we have at least 1 char ready for reading } if (timeout > 0) { - HAL_Delay (1); + UtilsDelay(UTILS_DELAY_US_TO_COUNT(1)); timeout--; } else { @@ -277,8 +256,9 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) { // raise an exception when interrupts are finished mpexception_keyboard_nlr_jump(); } - else if (self->read_buf_len != 0) { - uint16_t next_head = (self->read_buf_head + 1) % self->read_buf_len; + // there's always a read buffer available + else { + uint16_t next_head = (self->read_buf_head + 1) % PYBUART_RX_BUFFER_LEN; if (next_head != self->read_buf_tail) { // only store data if room in buf self->read_buf[self->read_buf_head] = data; @@ -302,8 +282,11 @@ STATIC void UART1IntHandler(void) { STATIC void uart_callback_enable (mp_obj_t self_in) { pyb_uart_obj_t *self = self_in; - MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT); - MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT); + // check for any of the rx interrupt types + if (self->irq_trigger & (E_UART_TRIGGER_RX_ANY | E_UART_TRIGGER_RX_HALF | E_UART_TRIGGER_RX_FULL)) { + MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT); + MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT); + } } STATIC void uart_callback_disable (mp_obj_t self_in) { @@ -317,7 +300,7 @@ STATIC void uart_callback_disable (mp_obj_t self_in) { STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_uart_obj_t *self = self_in; if (self->baudrate > 0) { - mp_printf(print, "<UART%u, baudrate=%u, bits=", (self->uart_id + 1), self->baudrate); + mp_printf(print, "UART(%u, baudrate=%u, bits=", self->uart_id, self->baudrate); switch (self->config & UART_CONFIG_WLEN_MASK) { case UART_CONFIG_WLEN_5: mp_print_str(print, "5"); @@ -339,94 +322,102 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k } else { mp_printf(print, ", parity=%u", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? 0 : 1); } - mp_printf(print, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u>", - (self->config & UART_CONFIG_STOP_MASK) == UART_CONFIG_STOP_ONE ? 1 : 2, - self->timeout, self->timeout_char, self->read_buf_len); + mp_printf(print, ", stop=%u)", (self->config & UART_CONFIG_STOP_MASK) == UART_CONFIG_STOP_ONE ? 1 : 2); } else { - mp_printf(print, "<UART%u>", (self->uart_id + 1)); + mp_printf(print, "UART(%u)", self->uart_id); } } -/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0) -/// -/// Initialise the UART bus with the given parameters: -/// -/// - `baudrate` is the clock rate. -/// - `bits` is the number of bits per byte, 5, 6, 7, 8 -/// - `parity` is the parity, `None`, 0 (even) or 1 (odd). -/// - `stop` is the number of stop bits, 1 or 2. -/// - `flow` is the flow control mode, `None`, `UART.RTS`, -/// `UART.CTS', or `UART.CTS | UART.RTS` -/// - `timeout` is the timeout (in milliseconds) when waiting for the first character. -/// - `timeout_char` is the timeout (in milliseconds) between characters. STATIC const mp_arg_t pyb_uart_init_args[] = { { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, }, { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, { MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, - { MP_QSTR_flow, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_int = UART_FLOWCONTROL_NONE} }, - { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, - { MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; - STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // parse args mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(pyb_uart_init_args), pyb_uart_init_args, args); - // set timeouts - self->timeout = args[5].u_int; - self->timeout_char = args[6].u_int; - - // no read buffer for the moment - self->read_buf_head = 0; - self->read_buf_tail = 0; - self->read_buf_len = 0; - self->read_buf = NULL; - // get the baudrate - self->baudrate = args[0].u_int; - - // set the UART configuration values - if (n_args > 1) { - switch (args[1].u_int) { - case 5: - self->config = UART_CONFIG_WLEN_5; - break; - case 6: - self->config = UART_CONFIG_WLEN_6; - break; - case 7: - self->config = UART_CONFIG_WLEN_7; - break; - case 8: - self->config = UART_CONFIG_WLEN_8; - break; - default: - goto error; - break; - } - // Parity - if (args[2].u_obj == mp_const_none) { - self->config |= UART_CONFIG_PAR_NONE; + if (args[0].u_int <= 0) { + goto error; + } + uint baudrate = args[0].u_int; + uint config; + switch (args[1].u_int) { + case 5: + config = UART_CONFIG_WLEN_5; + break; + case 6: + config = UART_CONFIG_WLEN_6; + break; + case 7: + config = UART_CONFIG_WLEN_7; + break; + case 8: + config = UART_CONFIG_WLEN_8; + break; + default: + goto error; + break; + } + // parity + if (args[2].u_obj == mp_const_none) { + config |= UART_CONFIG_PAR_NONE; + } else { + config |= ((mp_obj_get_int(args[2].u_obj) & 1) ? UART_CONFIG_PAR_ODD : UART_CONFIG_PAR_EVEN); + } + // stop bits + config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO); + + mp_obj_t pins_o = args[4].u_obj; + uint flowcontrol = UART_FLOWCONTROL_NONE; + if (pins_o != mp_const_none) { + if (pins_o == MP_OBJ_NULL) { + // use the default pins + pin_config (pyb_uart_def_pin[self->uart_id][PIN_TYPE_UART_TX].pin, pyb_uart_def_pin[self->uart_id][PIN_TYPE_UART_TX].af_idx, + 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_2MA); + pin_config (pyb_uart_def_pin[self->uart_id][PIN_TYPE_UART_RX].pin, pyb_uart_def_pin[self->uart_id][PIN_TYPE_UART_RX].af_idx, + 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_2MA); } else { - self->config |= ((mp_obj_get_int(args[2].u_obj) & 1) ? UART_CONFIG_PAR_ODD : UART_CONFIG_PAR_EVEN); - } - // Stop bits - self->config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO); - // Flow control - if (args[4].u_int != UART_FLOWCONTROL_NONE || args[4].u_int != UART_FLOWCONTROL_TX || - args[4].u_int != UART_FLOWCONTROL_RX || args[4].u_int != (UART_FLOWCONTROL_TX | UART_FLOWCONTROL_RX)) { - goto error; + mp_obj_t *pins_t; + mp_uint_t n_pins; + mp_obj_get_array(pins_o, &n_pins, &pins_t); + if (n_pins != 2 && n_pins != 4) { + goto error; + } + if (n_pins == 4) { + if (pins_t[PIN_TYPE_UART_RTS] != mp_const_none && pins_t[PIN_TYPE_UART_RX] == mp_const_none) { + goto error; // RTS pin given in TX only mode + } else if (pins_t[PIN_TYPE_UART_CTS] != mp_const_none && pins_t[PIN_TYPE_UART_TX] == mp_const_none) { + goto error; // CTS pin given in RX only mode + } else { + if (pins_t[PIN_TYPE_UART_RTS] != mp_const_none) { + flowcontrol |= UART_FLOWCONTROL_RX; + } + if (pins_t[PIN_TYPE_UART_CTS] != mp_const_none) { + flowcontrol |= UART_FLOWCONTROL_TX; + } + } + } + // the pins tuple passed looks good so far + for (int i = 0; i < n_pins; i++) { + if (pins_t[i] != mp_const_none) { + pin_obj_t *pin = pin_find(pins_t[i]); + pin_config (pin, pin_find_af_index(pin, PIN_FN_UART, self->uart_id, i), + 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_2MA); + } + } } - self->flowcontrol = args[4].u_int; - } - else { - self->config = UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE; - self->flowcontrol = UART_FLOWCONTROL_NONE; } + self->baudrate = baudrate; + self->config = config; + self->flowcontrol = flowcontrol; + // initialize and enable the uart uart_init (self); // register it with the sleep module @@ -438,25 +429,12 @@ error: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } -/// \classmethod \constructor(bus, ...) -/// -/// Construct a UART object on the given bus id. `bus id` can be 1 or 2 -/// With no additional parameters, the UART object is created but not -/// initialised (it has the settings from the last initialisation of -/// the bus, if any). -/// When only the baud rate is given the UART object is created and -/// initialized with the default configuration of: 8 bit transfers, -/// 1 stop bit, no parity and flow control disabled. -/// See `init` for parameters of initialisation. -/// If extra arguments are given, the bus is initialised with these arguments -/// See `init` for parameters of initialisation. -/// STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, MP_ARRAY_SIZE(pyb_uart_init_args), true); // work out the uart id - int32_t uart_id = mp_obj_get_int(args[0]) - 1; + int32_t uart_id = mp_obj_get_int(args[0]); if (uart_id < PYB_UART_0 || uart_id > PYB_UART_1) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable)); @@ -482,8 +460,6 @@ STATIC mp_obj_t pyb_uart_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t * } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init); -/// \method deinit() -/// Turn off the UART bus. STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) { pyb_uart_obj_t *self = self_in; @@ -491,6 +467,8 @@ STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) { pybsleep_remove (self); // invalidate the baudrate self->baudrate = 0; + // free the read buffer + m_del(byte, self->read_buf, PYBUART_RX_BUFFER_LEN); MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT); MAP_UARTDisable(self->reg); MAP_PRCMPeripheralClkDisable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); @@ -498,21 +476,22 @@ STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit); -/// \method any() -/// Return `True` if any characters waiting, else `False`. STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) { pyb_uart_obj_t *self = self_in; - if (uart_rx_any(self)) { - return mp_const_true; - } else { - return mp_const_false; - } + return mp_obj_new_int(uart_rx_any(self)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any); -/// \method callback(handler, value, priority) -/// Creates a callback object associated with the uart -/// min num of arguments is 1 (value). The value is the size of the rx buffer +STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) { + pyb_uart_obj_t *self = self_in; + // send a break signal for at least 2 complete frames + MAP_UARTBreakCtl(self->reg, true); + UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_2_FRAMES_TIME_US(self->baudrate))); + MAP_UARTBreakCtl(self->reg, false); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak); + STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_arg_val_t args[mpcallback_INIT_NUM_ARGS]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args); @@ -531,6 +510,7 @@ STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, m } // register a new callback + // FIXME triggers!! return uart_callback_new (self, args[1].u_obj, mp_obj_get_int(args[3].u_obj), priority); } else if (!_callback) { _callback = mpcallback_new (self, mp_const_none, &uart_cb_methods, false); @@ -539,55 +519,12 @@ STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, m } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_callback_obj, 1, pyb_uart_callback); -/// \method writechar(char) -/// Write a single character on the bus. `char` is an integer to write. -/// Return value: `None`. -STATIC mp_obj_t pyb_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) { - pyb_uart_obj_t *self = self_in; - - // get the character to write - uint8_t data = mp_obj_get_int(char_in); - - // send the character - if (!uart_tx_char(self, data)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_uart_writechar_obj, pyb_uart_writechar); - -/// \method readchar() -/// Receive a single character on the bus. -/// Return value: The character read, as an integer. Returns -1 on timeout. -STATIC mp_obj_t pyb_uart_readchar(mp_obj_t self_in) { - pyb_uart_obj_t *self = self_in; - if (uart_rx_wait(self, self->timeout)) { - return mp_obj_new_int(uart_rx_char(self)); - } else { - // return -1 on timeout - return MP_OBJ_NEW_SMALL_INT(-1); - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_readchar_obj, pyb_uart_readchar); - -/// \method sendbreak() -STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) { - pyb_uart_obj_t *self = self_in; - // send a break signal for at least 2 complete frames - MAP_UARTBreakCtl(self->reg, true); - UtilsDelay(UTILS_DELAY_US_TO_COUNT((22 * 1000000) / self->baudrate)); - MAP_UARTBreakCtl(self->reg, false); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak); - - STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = { // instance methods { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_uart_init_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_uart_deinit_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_uart_any_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak), (mp_obj_t)&pyb_uart_sendbreak_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_uart_callback_obj }, /// \method read([nbytes]) @@ -601,13 +538,8 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = { /// \method write(buf) { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_writechar), (mp_obj_t)&pyb_uart_writechar_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readchar), (mp_obj_t)&pyb_uart_readchar_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak), (mp_obj_t)&pyb_uart_sendbreak_obj }, - // class constants - { MP_OBJ_NEW_QSTR(MP_QSTR_CTS), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_TX) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RTS), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_RX) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX_ANY), MP_OBJ_NEW_SMALL_INT(E_UART_TRIGGER_RX_ANY) }, }; STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table); @@ -622,7 +554,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i } // wait for first char to become available - if (!uart_rx_wait(self, self->timeout)) { + if (!uart_rx_wait(self)) { // we can either return 0 to indicate EOF (then read() method returns b'') // or return EAGAIN error to indicate non-blocking (then read() method returns None) return 0; @@ -632,7 +564,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i byte *orig_buf = buf; for ( ; ; ) { *buf++ = uart_rx_char(self); - if (--size == 0 || !uart_rx_wait(self, self->timeout_char)) { + if (--size == 0 || !uart_rx_wait(self)) { // return number of bytes read return buf - orig_buf; } |