Commit f91f212d authored by Daniel Campora's avatar Daniel Campora

cc3200: New UART API plus related test.

parent 36821d09
......@@ -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
......
......@@ -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))) {
......
......@@ -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);
......
......@@ -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 },
......
......@@ -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 {
......
......@@ -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);
......
......@@ -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);
This diff is collapsed.
......@@ -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_
......@@ -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
......
......@@ -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();
......
......@@ -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)
......
......@@ -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
......@@ -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():
......
'''
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')
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
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