diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c index cae2f68942..debce55288 100644 --- a/cc3200/mods/pybpin.c +++ b/cc3200/mods/pybpin.c @@ -60,6 +60,8 @@ DECLARE PRIVATE FUNCTIONS ******************************************************************************/ STATIC pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name); STATIC pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit); +STATIC int8_t pin_obj_find_af (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type); +STATIC void pin_deassign (pin_obj_t* pin); STATIC void pin_obj_configure (const pin_obj_t *self); STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *wake_pin, uint *idx); STATIC void pin_extint_enable (mp_obj_t self_in); @@ -68,6 +70,7 @@ STATIC void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t prio STATIC void pin_validate_mode (uint mode); STATIC void pin_validate_pull (uint pull); STATIC void pin_validate_drive (uint strength); +STATIC void pin_validate_af(const pin_obj_t* pin, int8_t idx, uint8_t *fn, uint8_t *unit, uint8_t *type); STATIC void GPIOA0IntHandler (void); STATIC void GPIOA1IntHandler (void); STATIC void GPIOA2IntHandler (void); @@ -115,9 +118,7 @@ void pin_init0(void) { 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; - pin_config (pin, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD, -1, PIN_STRENGTH_2MA); - // mark it as unused again - pin->used = false; + pin_deassign (pin); } #endif } @@ -147,10 +148,12 @@ void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint if (af != -1) { self->af = af; } + // if value is -1, then we want to keep it as it is if (value != -1) { self->value = value; } + // mark the pin as used self->used = true; pin_obj_configure ((const pin_obj_t *)self); @@ -160,12 +163,27 @@ void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint } int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) { - for (int i = 0; i < pin->num_afs; i++) { - if (pin->af_list[i].fn == fn && pin->af_list[i].unit == unit && pin->af_list[i].type == type) { - return pin->af_list[i].idx; + int8_t af = pin_obj_find_af(pin, fn, unit, type); + if (af < 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); + } + return af; +} + +void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type) { + 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; + // af is different than GPIO + if (pin->af > PIN_MODE_0) { + // check if the pin supports the target af + int af = pin_obj_find_af(pin, fn, unit, type); + if (af > 0 && af == pin->af) { + // the pin is assigned to the target af, de-assign it + pin_deassign (pin); + } } } - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } /****************************************************************************** @@ -191,6 +209,20 @@ STATIC pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uin return NULL; } +STATIC int8_t pin_obj_find_af (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) { + for (int i = 0; i < pin->num_afs; i++) { + if (pin->af_list[i].fn == fn && pin->af_list[i].unit == unit && pin->af_list[i].type == type) { + return pin->af_list[i].idx; + } + } + return -1; +} + +STATIC void pin_deassign (pin_obj_t* pin) { + pin_config (pin, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD, -1, PIN_STRENGTH_4MA); + pin->used = false; +} + STATIC void pin_obj_configure (const pin_obj_t *self) { uint32_t type; if (self->mode == PIN_TYPE_ANALOG) { @@ -370,6 +402,18 @@ STATIC void pin_validate_drive(uint strength) { } } +STATIC void pin_validate_af(const pin_obj_t* pin, int8_t idx, uint8_t *fn, uint8_t *unit, uint8_t *type) { + for (int i = 0; i < pin->num_afs; i++) { + if (pin->af_list[i].idx == idx) { + *fn = pin->af_list[i].fn; + *unit = pin->af_list[i].unit; + *type = pin->af_list[i].type; + return; + } + } + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); +} + STATIC void GPIOA0IntHandler (void) { EXTI_Handler(GPIOA0_BASE); } @@ -455,6 +499,12 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_ goto invalid_args; } + // check for a valid af and then free it from any other pins + if (af > PIN_MODE_0) { + uint8_t fn, unit, type; + pin_validate_af (self, af, &fn, &unit, &type); + pin_free_af_from_pins(fn, unit, type); + } pin_config (self, af, mode, pull, value, strength); return mp_const_none; diff --git a/cc3200/mods/pybpin.h b/cc3200/mods/pybpin.h index 4c49e63ab5..f03a998f53 100644 --- a/cc3200/mods/pybpin.h +++ b/cc3200/mods/pybpin.h @@ -140,5 +140,6 @@ void pin_init0(void); void pin_config(pin_obj_t *self, int af, uint mode, uint type, int value, uint strength); pin_obj_t *pin_find(mp_obj_t user_obj); int8_t pin_find_af_index(const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type); +void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type); #endif // PYBPIN_H_ diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c index cb010395bd..00f009ce67 100644 --- a/cc3200/mods/pybuart.c +++ b/cc3200/mods/pybuart.c @@ -71,11 +71,18 @@ #define PYBUART_RX_BUFFER_LEN (128) +// 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) + /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ STATIC void uart_init (pyb_uart_obj_t *self); STATIC bool uart_rx_wait (pyb_uart_obj_t *self); +STATIC void uart_check_init(pyb_uart_obj_t *self); STATIC void UARTGenericIntHandler(uint32_t uart_id); STATIC void UART0IntHandler(void); STATIC void UART1IntHandler(void); @@ -98,6 +105,7 @@ struct _pyb_uart_obj_t { uint16_t read_buf_tail; // indexes first full slot (not full if equals head) byte peripheral; byte irq_trigger; + bool callback_enabled; }; /****************************************************************************** @@ -244,6 +252,7 @@ STATIC bool uart_rx_wait (pyb_uart_obj_t *self) { STATIC void UARTGenericIntHandler(uint32_t uart_id) { pyb_uart_obj_t *self; uint32_t status; + bool exec_callback = false; self = &pyb_uart_obj[uart_id]; status = MAP_UARTIntStatus(self->reg, true); @@ -266,9 +275,23 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) { } } } - // call the user defined handler - mp_obj_t _callback = mpcallback_find(self); - mpcallback_handler(_callback); + + if (self->irq_trigger & E_UART_TRIGGER_RX_ANY) { + exec_callback = true; + } + + if (exec_callback && self->callback_enabled) { + // call the user defined handler + mp_obj_t _callback = mpcallback_find(self); + mpcallback_handler(_callback); + } + } +} + +STATIC void uart_check_init(pyb_uart_obj_t *self) { + // not initialized + if (!self->baudrate) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); } } @@ -287,11 +310,12 @@ STATIC void uart_callback_enable (mp_obj_t self_in) { MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT); MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT); } + self->callback_enabled = true; } STATIC void uart_callback_disable (mp_obj_t self_in) { pyb_uart_obj_t *self = self_in; - MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT); + self->callback_enabled = false; } /******************************************************************************/ @@ -405,6 +429,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con } // the pins tuple passed looks good so far for (int i = 0; i < n_pins; i++) { + pin_free_af_from_pins(PIN_FN_UART, self->uart_id, 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), @@ -422,6 +447,8 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con uart_init (self); // register it with the sleep module pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)uart_init); + // enable the callback + uart_callback_new (self, mp_const_none, INT_PRIORITY_LVL_3, E_UART_TRIGGER_RX_ANY); return mp_const_none; @@ -478,12 +505,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit); STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) { pyb_uart_obj_t *self = self_in; + uart_check_init(self); return mp_obj_new_int(uart_rx_any(self)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any); STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) { pyb_uart_obj_t *self = self_in; + uart_check_init(self); // 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))); @@ -498,6 +527,7 @@ STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, m // check if any parameters were passed pyb_uart_obj_t *self = pos_args[0]; + uart_check_init(self); mp_obj_t _callback = mpcallback_find((mp_obj_t)self); if (kw_args->used > 0) { @@ -547,6 +577,7 @@ STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table); STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { pyb_uart_obj_t *self = self_in; byte *buf = buf_in; + uart_check_init(self); // make sure we want at least 1 char if (size == 0) { @@ -574,6 +605,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { pyb_uart_obj_t *self = self_in; const char *buf = buf_in; + uart_check_init(self); // write the data if (!uart_tx_strn(self, buf, size)) { @@ -585,6 +617,8 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { pyb_uart_obj_t *self = self_in; mp_uint_t ret; + uart_check_init(self); + if (request == MP_IOCTL_POLL) { mp_uint_t flags = arg; ret = 0; diff --git a/cc3200/mods/pybuart.h b/cc3200/mods/pybuart.h index 476fc11a4e..89f3edc0ed 100644 --- a/cc3200/mods/pybuart.h +++ b/cc3200/mods/pybuart.h @@ -28,12 +28,6 @@ #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, diff --git a/cc3200/mptask.c b/cc3200/mptask.c index 87990b43c2..dd3a762244 100644 --- a/cc3200/mptask.c +++ b/cc3200/mptask.c @@ -145,7 +145,6 @@ soft_reset: 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); - 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 diff --git a/tests/wipy/pin.py b/tests/wipy/pin.py index 20bea3e5a7..ae0fa82b19 100644 --- a/tests/wipy/pin.py +++ b/tests/wipy/pin.py @@ -7,10 +7,10 @@ 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) + max_af_idx = 15 elif 'WiPy' in machine: pin_map = ['GP23', 'GP24', 'GP12', 'GP13', 'GP14', 'GP9', 'GP17', 'GP28', 'GP22', 'GP8', 'GP30', 'GP31', 'GP0', 'GP4', 'GP5'] - af_range = range(1, 16) + max_af_idx = 15 else: raise Exception('Board not supported!') @@ -28,9 +28,10 @@ def test_pin_read(pull): def test_pin_af(): for p in pin_map: - for n in af_range: - Pin(p, mode=Pin.ALT, alt=n) - Pin(p, mode=Pin.ALT_OPEN_DRAIN, alt=n) + for af in Pin(p).alt_list(): + if af[1] <= max_af_idx: + Pin(p, mode=Pin.ALT, alt=af[1]) + Pin(p, mode=Pin.ALT_OPEN_DRAIN, alt=af[1]) # test un-initialized pins test_noinit() @@ -67,10 +68,6 @@ pin.init(mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.LOW_POWER) print(pin) pin.init(mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.HIGH_POWER) print(pin) -pin = Pin(pin_map[0], Pin.ALT, Pin.PULL_NONE, alt=1) -print(pin) -pin = Pin(pin_map[0], Pin.ALT_OPEN_DRAIN, Pin.PULL_NONE, alt=15) -print(pin) # test value in OUT mode pin = Pin(pin_map[0], mode=Pin.OUT) diff --git a/tests/wipy/pin.py.exp b/tests/wipy/pin.py.exp index 87b4d3ef85..4fc60b5d79 100644 --- a/tests/wipy/pin.py.exp +++ b/tests/wipy/pin.py.exp @@ -32,8 +32,6 @@ Pin('GP23', mode=Pin.IN, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=-1) Pin('GP23', mode=Pin.IN, pull=Pin.PULL_DOWN, drive=Pin.MED_POWER, alt=-1) Pin('GP23', mode=Pin.OUT, pull=Pin.PULL_UP, drive=Pin.LOW_POWER, alt=-1) Pin('GP23', mode=Pin.OUT, pull=Pin.PULL_UP, drive=Pin.HIGH_POWER, alt=-1) -Pin('GP23', mode=Pin.ALT, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=1) -Pin('GP23', mode=Pin.ALT_OPEN_DRAIN, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=15) 1 0 1 diff --git a/tests/wipy/uart.py b/tests/wipy/uart.py index a483891ad8..31a2c3a0ab 100644 --- a/tests/wipy/uart.py +++ b/tests/wipy/uart.py @@ -6,6 +6,7 @@ UART0 and UART1 must be connected together for this test to pass. from pyb import UART from pyb import Pin import os +import pyb machine = os.uname().machine if 'LaunchPad' in machine: @@ -25,12 +26,6 @@ for uart_id in uart_id_range: 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) @@ -52,16 +47,16 @@ print(buf) print(uart1.readinto(buf) == 2) print(buf) -uart0.write(b'123') -print(uart1.any() > 0) -print(uart1.readline() == b'123') +uart0.write(b'1234567890') +pyb.delay(2) # because of the fifo interrupt levels +print(uart1.any() == 10) +print(uart1.readline() == b'1234567890') 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') @@ -69,17 +64,21 @@ 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') -Pin('GP13', mode=Pin.IN) -Pin('GP12', mode=Pin.IN) -# no pin assignemnt +# leave pins as they were (rx only mode) uart0 = UART(0, 1000000, pins=None) +print(uart0.write(b'123456') == 6) +print(uart1.read() == b'') +print(uart1.write(b'123') == 3) +print(uart0.read() == b'123') + +# no pin assignemnt +uart0 = UART(0, 1000000, pins=(None, None)) print(uart0.write(b'123456789') == 9) print(uart1.read() == b'') print(uart1.write(b'123456789') == 9) @@ -87,12 +86,46 @@ print(uart0.read() == b'') print(Pin.board.GP12) print(Pin.board.GP13) +# check for memory leaks... +for i in range (0, 1000): + uart0 = UART(0, 1000000) + uart1 = UART(1, 1000000) + # 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') + +uart0 = UART(0, 1000000) +uart0.deinit() +try: + uart0.any() +except Exception: + print('Exception') + +uart0 = UART(0, 1000000) +uart0.deinit() +try: + uart0.read() +except Exception: + print('Exception') + +uart0 = UART(0, 1000000) +uart0.deinit() +try: + uart0.write('abc') +except Exception: + print('Exception') + +uart0 = UART(0, 1000000) +uart0.deinit() +try: + uart0.sendbreak('abc') +except Exception: + print('Exception') diff --git a/tests/wipy/uart.py.exp b/tests/wipy/uart.py.exp index a5c6da1e8f..7234b35190 100644 --- a/tests/wipy/uart.py.exp +++ b/tests/wipy/uart.py.exp @@ -28,7 +28,15 @@ True True True True +True +True +True +True Pin('GP12', mode=Pin.IN, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=-1) Pin('GP13', mode=Pin.IN, pull=Pin.PULL_NONE, drive=Pin.MED_POWER, alt=-1) Exception Exception +Exception +Exception +Exception +Exception