Browse Source

cc3200: New UART API plus related test.

pull/1458/head
Daniel Campora 9 years ago
parent
commit
f91f212d9f
  1. 7
      cc3200/boards/LAUNCHXL/mpconfigboard.h
  2. 8
      cc3200/misc/mpcallback.c
  3. 1
      cc3200/misc/mpcallback.h
  4. 59
      cc3200/mods/pybpin.c
  5. 5
      cc3200/mods/pybpin.h
  6. 20
      cc3200/mods/pybtimer.c
  7. 1
      cc3200/mods/pybtimer.h
  8. 366
      cc3200/mods/pybuart.c
  9. 11
      cc3200/mods/pybuart.h
  10. 1
      cc3200/mpconfigport.h
  11. 16
      cc3200/mptask.c
  12. 22
      cc3200/qstrdefsport.h
  13. 75
      docs/library/pyb.UART.rst
  14. 3
      tests/wipy/pin.py
  15. 87
      tests/wipy/uart.py
  16. 28
      tests/wipy/uart.py.exp

7
cc3200/boards/LAUNCHXL/mpconfigboard.h

@ -35,13 +35,8 @@
#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_ANTENNA_DIVERSITY (0)
#define MICROPY_STDIO_UART 1
#define MICROPY_STDIO_UART 0
#define MICROPY_STDIO_UART_BAUD 115200
#define MICROPY_STDIO_UART_RX_BUF_SIZE 128
#define MICROPY_STDIO_UART_TX_PIN (pin_GP1)
#define MICROPY_STDIO_UART_RX_PIN (pin_GP2)
#define MICROPY_STDIO_UART_TX_PIN_AF PIN_MODE_3
#define MICROPY_STDIO_UART_RX_PIN_AF PIN_MODE_3
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA1
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA2

8
cc3200/misc/mpcallback.c

@ -91,6 +91,14 @@ void mpcallback_wake_all (void) {
}
}
void mpcallback_disable_all (void) {
// re-enable all active callback objects one by one
for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
callback_obj->methods->disable(callback_obj->parent);
}
}
void mpcallback_remove (const mp_obj_t parent) {
mpcallback_obj_t *callback_obj;
if ((callback_obj = mpcallback_find(parent))) {

1
cc3200/misc/mpcallback.h

@ -65,6 +65,7 @@ void mpcallback_init0 (void);
mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods, bool enable);
mpcallback_obj_t *mpcallback_find (mp_obj_t parent);
void mpcallback_wake_all (void);
void mpcallback_disable_all (void);
void mpcallback_remove (const mp_obj_t parent);
void mpcallback_handler (mp_obj_t self_in);
uint mpcallback_translate_priority (uint priority);

59
cc3200/mods/pybpin.c

@ -110,9 +110,8 @@ STATIC pybpin_wake_pin_t pybpin_wake_pin[PYBPIN_NUM_WAKE_PINS] =
void pin_init0(void) {
// this initalization also reconfigures the JTAG/SWD pins
#ifndef DEBUG
// GP10 and GP11 must be assigned to the GPIO peripheral (the default is I2C), so that the I2C bus
// can then be assigned safely to any other pins (as recomended by the SDK release notes).
// Anyway, we initialize all pins here, as inputs WITHOUT any pull resistor enabled
// assign all pins to the GPIO module so that peripherals can be connected to any
// pins without conflicts after a soft reset
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
for (uint i = 0; i < named_map->used - 1; i++) {
pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
@ -555,20 +554,6 @@ STATIC mp_obj_t pin_value(mp_uint_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
STATIC mp_obj_t pin_low(mp_obj_t self_in) {
pin_obj_t *self = self_in;
MAP_GPIOPinWrite(self->port, self->bit, 0);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low);
STATIC mp_obj_t pin_high(mp_obj_t self_in) {
pin_obj_t *self = self_in;
MAP_GPIOPinWrite(self->port, self->bit, self->bit);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high);
STATIC mp_obj_t pin_toggle(mp_obj_t self_in) {
pin_obj_t *self = self_in;
MAP_GPIOPinWrite(self->port, self->bit, ~MAP_GPIOPinRead(self->port, self->bit));
@ -624,6 +609,26 @@ STATIC mp_obj_t pin_drive(mp_uint_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_drive_obj, 1, 2, pin_drive);
STATIC mp_obj_t pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_t _args[2] = {self_in, *args};
return pin_value (n_args + 1, _args);
}
STATIC mp_obj_t pin_alt_list(mp_obj_t self_in) {
pin_obj_t *self = self_in;
mp_obj_t af[2];
mp_obj_t afs = mp_obj_new_list(0, NULL);
for (int i = 0; i < self->num_afs; i++) {
af[0] = MP_OBJ_NEW_QSTR(self->af_list[i].name);
af[1] = mp_obj_new_int(self->af_list[i].idx);
mp_obj_list_append(afs, mp_obj_new_tuple(MP_ARRAY_SIZE(af), af));
}
return afs;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_alt_list_obj, pin_alt_list);
STATIC mp_obj_t pin_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);
@ -755,26 +760,6 @@ invalid_args:
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_callback_obj, 1, pin_callback);
STATIC mp_obj_t pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_t _args[2] = {self_in, *args};
return pin_value (n_args + 1, _args);
}
STATIC mp_obj_t pin_alt_list(mp_obj_t self_in) {
pin_obj_t *self = self_in;
mp_obj_t af[2];
mp_obj_t afs = mp_obj_new_list(0, NULL);
for (int i = 0; i < self->num_afs; i++) {
af[0] = MP_OBJ_NEW_QSTR(self->af_list[i].name);
af[1] = mp_obj_new_int(self->af_list[i].idx);
mp_obj_list_append(afs, mp_obj_new_tuple(MP_ARRAY_SIZE(af), af));
}
return afs;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_alt_list_obj, pin_alt_list);
STATIC const mp_map_elem_t pin_locals_dict_table[] = {
// instance methods
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pin_init_obj },

5
cc3200/mods/pybpin.h

@ -115,6 +115,11 @@ typedef struct {
uint8_t used : 1;
} pin_obj_t;
typedef struct {
pin_obj_t *pin;
uint8_t af_idx;
} pin_fn_t;
extern const mp_obj_type_t pin_type;
typedef struct {

20
cc3200/mods/pybtimer.c

@ -142,26 +142,6 @@ void timer_init0 (void) {
mp_obj_list_init(&MP_STATE_PORT(pyb_timer_channel_obj_list), 0);
}
void timer_disable_all (void) {
pyb_timer_obj_t timer = {
.timer = TIMERA0_BASE,
.intflags = TIMER_CAPB_EVENT | TIMER_CAPB_MATCH |
TIMER_TIMB_TIMEOUT | TIMER_CAPA_EVENT |
TIMER_CAPA_MATCH | TIMER_TIMA_TIMEOUT,
.peripheral = PRCM_TIMERA0
};
for (uint32_t i = 0; i < PYBTIMER_NUM_TIMERS; i++) {
// in case it's not clocked
MAP_PRCMPeripheralClkEnable(timer.peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
timer_disable(&timer);
// timer base offset according to hw_memmap.h
timer.timer += 0x1000;
// peripheral offset according to prcm.h
timer.peripheral++;
}
}
void pyb_timer_channel_callback_enable (mp_obj_t self_in) {
pyb_timer_channel_obj_t *self = self_in;
MAP_TimerIntClear(self->timer->timer, self->timer->intflags & self->channel);

1
cc3200/mods/pybtimer.h

@ -34,5 +34,4 @@ extern const mp_obj_type_t pyb_timer_type;
DECLARE PUBLIC FUNCTIONS
******************************************************************************/
void timer_init0 (void);
void timer_disable_all (void);

366
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;
}

11
cc3200/mods/pybuart.h

@ -28,6 +28,12 @@
#ifndef PYBUART_H_
#define PYBUART_H_
// interrupt triggers
#define E_UART_TRIGGER_RX_ANY (0x01)
#define E_UART_TRIGGER_RX_HALF (0x02)
#define E_UART_TRIGGER_RX_FULL (0x04)
#define E_UART_TRIGGER_TX_DONE (0x08)
typedef enum {
PYB_UART_0 = 0,
PYB_UART_1 = 1,
@ -38,12 +44,11 @@ typedef struct _pyb_uart_obj_t pyb_uart_obj_t;
extern const mp_obj_type_t pyb_uart_type;
void uart_init0(void);
bool uart_rx_any(pyb_uart_obj_t *uart_obj);
uint32_t uart_rx_any(pyb_uart_obj_t *uart_obj);
int uart_rx_char(pyb_uart_obj_t *uart_obj);
bool uart_tx_char(pyb_uart_obj_t *self, int c);
bool uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, 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);
void uart_disable_all (void);
mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, mp_int_t priority, byte trigger);
#endif // PYBUART_H_

1
cc3200/mpconfigport.h

@ -148,6 +148,7 @@ extern const struct _mp_obj_module_t mp_module_ussl;
mp_obj_list_t pybsleep_obj_list; \
mp_obj_list_t mpcallback_obj_list; \
mp_obj_list_t pyb_timer_channel_obj_list; \
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \
// type definitions for the specific machine

16
cc3200/mptask.c

@ -139,18 +139,13 @@ soft_reset:
#endif
#ifdef LAUNCHXL
// configure the stdio uart pins with the correct alternate functions
// param 3 ("mode") is DON'T CARE" for AFs others than GPIO
pin_config ((pin_obj_t *)&MICROPY_STDIO_UART_TX_PIN, MICROPY_STDIO_UART_TX_PIN_AF, 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_2MA);
pin_config ((pin_obj_t *)&MICROPY_STDIO_UART_RX_PIN, MICROPY_STDIO_UART_RX_PIN_AF, 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_2MA);
// instantiate the stdio uart
// instantiate the stdio uart on the default pins
mp_obj_t args[2] = {
mp_obj_new_int(MICROPY_STDIO_UART),
mp_obj_new_int(MICROPY_STDIO_UART_BAUD),
};
pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args);
// create a callback for the uart, in order to enable the rx interrupts
uart_callback_new (pyb_stdio_uart, mp_const_none, MICROPY_STDIO_UART_RX_BUF_SIZE, INT_PRIORITY_LVL_3);
uart_callback_new (pyb_stdio_uart, mp_const_none, INT_PRIORITY_LVL_3, E_UART_TRIGGER_RX_ANY);
#else
pyb_stdio_uart = MP_OBJ_NULL;
#endif
@ -239,10 +234,9 @@ soft_reset_exit:
pybsleep_signal_soft_reset();
mp_printf(&mp_plat_print, "PYB: soft reboot\n");
// disable all peripherals that could trigger a callback
pyb_rtc_callback_disable(NULL);
timer_disable_all();
uart_disable_all();
// disable all callbacks to avoid undefined behaviour
// when coming out of a soft reset
mpcallback_disable_all();
// flush the serial flash buffer
sflash_disk_flush();

22
cc3200/qstrdefsport.h

@ -61,6 +61,7 @@ Q(flush)
Q(FileIO)
Q(enable)
Q(disable)
Q(repl_uart)
// Entries for sys.path
Q(/flash)
Q(/flash/lib)
@ -119,6 +120,7 @@ Q(mode)
Q(pull)
Q(drive)
Q(alt)
Q(alt_list)
Q(IN)
Q(OUT)
Q(OPEN_DRAIN)
@ -137,24 +139,16 @@ Q(IRQ_HIGH_LEVEL)
// for UART class
Q(UART)
Q(init)
Q(deinit)
Q(any)
Q(sendbreak)
Q(baudrate)
Q(bits)
Q(stop)
Q(parity)
Q(init)
Q(deinit)
Q(all)
Q(writechar)
Q(readchar)
Q(sendbreak)
Q(readinto)
Q(read_buf_len)
Q(timeout)
Q(timeout_char)
Q(repl_uart)
Q(flow)
Q(RTS)
Q(CTS)
Q(pins)
Q(RX_ANY)
// for I2C class
Q(I2C)

75
docs/library/pyb.UART.rst

@ -36,17 +36,25 @@ using the standard stream methods::
uart.readinto(buf) # read and store into the given buffer
uart.write('abc') # write the 3 characters
Individual characters can be read/written using::
.. only:: port_pyboard
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.readchar() # read 1 character and returns it as an integer
uart.writechar(42) # write 1 character
uart.any() # returns True if any characters waiting
To check if there is anything to be read, use::
*Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4.
Earlier versions use ``uart.send`` and ``uart.recv``.
uart.any() # returns True if any characters waiting
.. only:: port_wipy
To check if there is anything to be read, use::
*Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4.
Earlier versions use ``uart.send`` and ``uart.recv``.
uart.any() # returns the number of characters available for reading
Constructors
------------
@ -73,7 +81,7 @@ Constructors
.. class:: pyb.UART(bus, ...)
Construct a UART object on the given bus. ``bus`` can be 1 or 2.
Construct a UART object on the given bus. ``bus`` can be 0 or 1.
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). If extra arguments are given, the bus is initialised.
@ -110,7 +118,7 @@ Methods
.. only:: port_wipy
.. method:: uart.init(baudrate, bits=8, parity=None, stop=1, \*, timeout=1000, flow=None, timeout_char=0)
.. method:: uart.init(baudrate, bits=8, parity=None, stop=1, \*, pins=(TX, RX, RTS, CTS))
Initialise the UART bus with the given parameters:
@ -118,18 +126,27 @@ Methods
- ``bits`` is the number of bits per character, 7, 8 or 9.
- ``parity`` is the parity, ``None``, 0 (even) or 1 (odd).
- ``stop`` is the number of stop bits, 1 or 2.
- ``flow`` sets the flow control type. Can be None, ``UART.RTS``, ``UART.CTS``
or ``UART.RTS | UART.CTS``.
- ``timeout`` is the timeout in milliseconds to wait for the first character.
- ``timeout_char`` is the timeout in milliseconds to wait between characters.
- ``pins`` is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
Any of the pins can be None if one wants the UART to operate with limited functionality.
If the RTS pin is given the the RX pin must be given as well. The same applies to CTS.
When no pins are given, then the default set of TX and RX pins is taken, and hardware
flow control will be disabled. If pins=None, no pin assignment will be made.
.. method:: uart.deinit()
Turn off the UART bus.
.. method:: uart.any()
.. only:: port_pyboard
.. method:: uart.any()
Return ``True`` if any characters waiting, else ``False``.
.. only:: port_wipy
.. method:: uart.any()
Return ``True`` if any characters waiting, else ``False``.
Return the number of characters available for reading.
.. method:: uart.read([nbytes])
@ -144,7 +161,7 @@ Methods
on timeout.
.. only:: port_wipy
Return value: a bytes object containing the bytes read in. Returns ``b''``
on timeout.
@ -184,17 +201,17 @@ Methods
Return value: number of bytes written.
.. method:: uart.writechar(char)
Write a single character on the bus. ``char`` is an integer to write.
Return value: ``None``.
.. only:: port_wipy
Write the buffer of bytes to the bus.
Return value: number of bytes written.
.. method:: uart.writechar(char)
Write a single character on the bus. ``char`` is an integer to write.
Return value: ``None``.
.. method:: uart.sendbreak()
Send a break condition on the bus. This drives the bus low for a duration
@ -229,7 +246,15 @@ Methods
Constants
---------
.. data:: UART.RTS
.. data:: UART.CTS
to select the flow control type
.. only:: port_pyboard
.. data:: UART.RTS
.. data:: UART.CTS
to select the flow control type
.. only:: port_wipy
.. data:: UART.RX_ANY
IRQ trigger sources

3
tests/wipy/pin.py

@ -5,7 +5,6 @@ from pyb import Pin
import os
machine = os.uname().machine
if 'LaunchPad' in machine:
pin_map = ['GP24', 'GP12', 'GP14', 'GP15', 'GP16', 'GP17', 'GP28', 'GP8', 'GP6', 'GP30', 'GP31', 'GP3', 'GP0', 'GP4', 'GP5']
af_range = range(1, 16)
@ -24,7 +23,7 @@ def test_pin_read(pull):
# enable the pull resistor on all pins, then read the value
for p in pin_map:
pin = Pin(p, mode=Pin.IN, pull=pull)
# read the pin value
for p in pin_map:
print(pin())
def test_pin_af():

87
tests/wipy/uart.py

@ -0,0 +1,87 @@
'''
UART test fro the CC3200 based boards.
UART0 and UART1 must be connected together for this test to pass.
'''
from pyb import UART
from pyb import Pin
import os
machine = os.uname().machine
if 'LaunchPad' in machine:
uart_id_range = range(0, 2)
uart_pins = [[('GP12', 'GP13'), ('GP12', 'GP13', 'GP7', 'GP6')], [('GP16', 'GP17'), ('GP16', 'GP17', 'GP7', 'GP6')]]
elif 'WiPy' in machine:
uart_id_range = range(0, 2)
uart_pins = [[('GP12', 'GP13'), ('GP12', 'GP13', 'GP7', 'GP6')], [('GP16', 'GP17'), ('GP16', 'GP17', 'GP7', 'GP6')]]
else:
raise Exception('Board not supported!')
for uart_id in uart_id_range:
uart = UART(uart_id, 38400)
print(uart)
uart.init(baudrate=57600, stop=1, parity=None, pins=uart_pins[uart_id][0])
uart.init(baudrate=9600, stop=2, parity=0, pins=uart_pins[uart_id][1])
uart.init(baudrate=115200, parity=1, pins=uart_pins[uart_id][0])
uart.sendbreak()
# assign GP1, GP2, GP3 and GP4 back to GPIO mode
Pin('GP1', mode=Pin.IN)
Pin('GP2', mode=Pin.IN)
Pin('GP3', mode=Pin.IN)
Pin('GP4', mode=Pin.IN)
# now it's time for some loopback tests between the uarts
uart0 = UART(0, 1000000, pins=uart_pins[0][0])
print(uart0)
uart1 = UART(1, 1000000, pins=uart_pins[1][0])
print(uart1)
print(uart0.write(b'123456') == 6)
print(uart1.read() == b'123456')
print(uart1.write(b'123') == 3)
print(uart0.read(1) == b'1')
print(uart0.read(2) == b'23')
print(uart0.read() == b'')
uart0.write(b'123')
buf = bytearray(3)
print(uart1.readinto(buf, 1) == 1)
print(buf)
print(uart1.readinto(buf) == 2)
print(buf)
uart0.write(b'123')
print(uart1.any() > 0)
print(uart1.readline() == b'123')
print(uart1.any() == 0)
uart0.write(b'1234567890')
print(uart1.readall() == b'1234567890')
# tx only mode
Pin('GP13', mode=Pin.IN)
uart0 = UART(0, 1000000, pins=('GP12', None))
print(uart0.write(b'123456') == 6)
print(uart1.read() == b'123456')
print(uart1.write(b'123') == 3)
print(uart0.read() == b'')
# rx only mode
Pin('GP12', mode=Pin.IN)
uart0 = UART(0, 1000000, pins=(None, 'GP13'))
print(uart0.write(b'123456') == 6)
print(uart1.read() == b'')
print(uart1.write(b'123') == 3)
print(uart0.read() == b'123')
# next ones must raise
try:
UART(0, 9600, parity=2, pins=('GP12', 'GP13', 'GP7'))
except Exception:
print('Exception')
try:
UART(0, 9600, parity=2, pins=('GP12', 'GP7'))
except Exception:
print('Exception')

28
tests/wipy/uart.py.exp

@ -0,0 +1,28 @@
UART(0, baudrate=38400, bits=8, parity=None, stop=1)
UART(1, baudrate=38400, bits=8, parity=None, stop=1)
UART(0, baudrate=1000000, bits=8, parity=None, stop=1)
UART(1, baudrate=1000000, bits=8, parity=None, stop=1)
True
True
True
True
True
True
True
bytearray(b'1\x00\x00')
True
bytearray(b'23\x00')
True
True
True
True
True
True
True
True
True
True
True
True
Exception
Exception
Loading…
Cancel
Save