From d5e256486eafab543c3e24850fe87136c2f0575d Mon Sep 17 00:00:00 2001 From: Daniel Campora Date: Thu, 3 Sep 2015 11:25:44 +0200 Subject: [PATCH] cc3200: Re-work Pin class according to the new API. Also add relevant test. --- cc3200/boards/cc3200_af.csv | 52 ++++----- cc3200/mods/pybpin.c | 205 +++++++++++++++++----------------- cc3200/mods/pybrtc.c | 2 +- cc3200/mods/pybrtc.h | 2 +- cc3200/mods/pybsd.c | 2 +- cc3200/mods/pybsd.h | 2 +- cc3200/mptask.c | 7 +- cc3200/qstrdefsport.h | 9 +- docs/library/pyb.Pin.rst | 215 ++++++++++++++++-------------------- docs/wipy/quickref.rst | 7 +- tests/run-tests | 2 +- tests/wipy/pin.py | 182 ++++++++++++++++++++++++++++++ tests/wipy/pin.py.exp | 64 +++++++++++ 13 files changed, 485 insertions(+), 266 deletions(-) create mode 100644 tests/wipy/pin.py create mode 100644 tests/wipy/pin.py.exp diff --git a/cc3200/boards/cc3200_af.csv b/cc3200/boards/cc3200_af.csv index 557dcfe92c..fcb41cbf09 100644 --- a/cc3200/boards/cc3200_af.csv +++ b/cc3200/boards/cc3200_af.csv @@ -1,25 +1,25 @@ Pin,Name,Default,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15,ADC -1,GP10,GP10,GP10,I2C_SCL,,GT_PWM06,,,SDCARD_CLK,UART1_TX,,,,,GT_CCP01,,,, -2,GP11,GP11,GP11,I2C_SDA,,GT_PWM07,pXCLK(XVCLK),,SDCARD_CMD,UART1_RX,,,,,GT_CCP02,McAFSX,,, -3,GP12,GP12,GP12,,,McACLK,pVS(VSYNC),I2C_SCL,,UART0_TX,,,,,GT_CCP03,,,, -4,GP13,GP13,GP13,,,,pHS(HSYNC),I2C_SDA,,UART0_RX,,,,,GT_CCP04,,,, -5,GP14,GP14,GP14,,,,pDATA8(CAM_D4),2C_SCL,,GSPI_CLK,,,,,GT_CCP05,,,, -6,GP15,GP15,GP15,,,,pDATA9(CAM_D5),I2C_SDA,,GSPI_MISO,,,,,,GT_CCP06,,, -7,GP16,GP16,GP16,,,,pDATA10(CAM_D6),UART1_TX,,GSPI_MOSI,,,,,,GT_CCP07,,, -8,GP17,GP17,GP17,,,,pDATA11(CAM_D7),UART1_RX,,GSPI_CS,,,,,,,,, +1,GP10,GP10,GP10,I2C0_SCL,,TIM3_PWM0,,,SD0_CLK,UART1_TX,,,,,TIM0_CC1,,,, +2,GP11,GP11,GP11,I2C0_SDA,,TIM3_PWM1,pXCLK(XVCLK),,SD0_CMD,UART1_RX,,,,,TIM1_CC0,I2S0_FS,,, +3,GP12,GP12,GP12,,,I2S0_CLK,pVS(VSYNC),I2C0_SCL,,UART0_TX,,,,,TIM1_CC1,,,, +4,GP13,GP13,GP13,,,,pHS(HSYNC),I2C0_SDA,,UART0_RX,,,,,TIM2_CC0,,,, +5,GP14,GP14,GP14,,,,pDATA8(CAM_D4),I2C0_SCL,,SPI0_CLK,,,,,TIM2_CC1,,,, +6,GP15,GP15,GP15,,,,pDATA9(CAM_D5),I2C0_SDA,,SPI0_MISO,,,,,,TIM3_CC0,,, +7,GP16,GP16,GP16,,,,pDATA10(CAM_D6),UART1_TX,,SPI0_MOSI,,,,,,TIM3_CC1,,, +8,GP17,GP17,GP17,,,,pDATA11(CAM_D7),UART1_RX,,SPI0_CS0,,,,,,,,, 9,VDD_DIG1,VDD_DIG1,VDD_DIG1,,,,,,,,,,,,,,,, 10,VIN_IO1,VIN_IO1,VIN_IO1,,,,,,,,,,,,,,,, 11,FLASH_SPI_CLK,FLASH_SPI_CLK,FLASH_SPI_CLK,,,,,,,,,,,,,,,, 12,FLASH_SPI_DOUT,FLASH_SPI_DOUT,FLASH_SPI_DOUT,,,,,,,,,,,,,,,, 13,FLASH_SPI_DIN,FLASH_SPI_DIN,FLASH_SPI_DIN,,,,,,,,,,,,,,,, 14,FLASH_SPI_CS,FLASH_SPI_CS,FLASH_SPI_CS,,,,,,,,,,,,,,,, -15,GP22,GP22,GP22,,,,,GT_CCP04,,McAFSX,,,,,,,,, -16,GP23,TDI,GP23,TDI,UART1_TX,,,,,,,2C_SCL,,,,,,, -17,GP24,TDO,GP24,TDO,UART1_RX,,GT_CCP06,PWM0,McAFSX,,,I2C_SDA,,,,,,, +15,GP22,GP22,GP22,,,,,TIM2_CC0,,I2S0_FS,,,,,,,,, +16,GP23,TDI,GP23,TDI,UART1_TX,,,,,,,I2C0_SCL,,,,,,, +17,GP24,TDO,GP24,TDO,UART1_RX,,TIM3_CC0,TIM0_PWM0,I2S0_FS,,,I2C0_SDA,,,,,,, 18,GP28,GP28,GP28,,,,,,,,,,,,,,,, -19,TCK,TCK,,TCK,,,,,,,GT_PWM03,,,,,,,, +19,TCK,TCK,,TCK,,,,,,,TIM1_PWM2,,,,,,,, 20,GP29,TMS,GP29,TMS,,,,,,,,,,,,,,, -21,GP25,SOP2,GP25,,McAFSX,,,,,,,GT_PWM02,,,,,,, +21,GP25,SOP2,GP25,,I2S0_FS,,,,,,,TIM1_PWM0,,,,,,, 22,WLAN_XTAL_N,WLAN_XTAL_N,WLAN_XTAL_N,,,,,,,,,,,,,,,, 23,WLAN_XTAL_P,WLAN_XTAL_P,WLAN_XTAL_P,,,,,,,,,,,,,,,, 24,VDD_PLL,VDD_PLL,VDD_PLL,,,,,,,,,,,,,,,, @@ -43,24 +43,24 @@ Pin,Name,Default,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF1 42,DCDC_PA_OUT,DCDC_PA_O UT,DCDC_PA_O UT,,,,,,,,,,,,,,,, 43,DCDC_DIG_SW,DCDC_DIG_ SW,DCDC_DIG_ SW,,,,,,,,,,,,,,,, 44,VIN_DCDC_DIG,VIN_DCDC_ DIG,VIN_DCDC_ DIG,,,,,,,,,,,,,,,, -45,GP31,DCDC_ANA2_SW_P,GP31,,UART1_RX,,,,McAXR0,GSPI_CLK,,UART0_RX,,,McAFSX,,,, +45,GP31,DCDC_ANA2_SW_P,GP31,,UART1_RX,,,,I2S0_DAT0,SPI0_CLK,,UART0_RX,,,I2S0_FS,,,, 46,DCDC_ANA2_SW_N,DCDC_ANA2_SW_N,DCDC_ANA2_SW_N,,,,,,,,,,,,,,,, 47,VDD_ANA2,VDD_ANA2,VDD_ANA2,,,,,,,,,,,,,,,, 48,VDD_ANA1,VDD_ANA1,VDD_ANA1,,,,,,,,,,,,,,,, 49,VDD_RAM,VDD_RAM,VDD_RAM,,,,,,,,,,,,,,,, -50,GP0,GP0,GP0,,,UART0_RTS,McAXR0,,McAXR1,GT_CCP00,,GSPI_CS,UART1_RTS,,UART0_CTS,,,, +50,GP0,GP0,GP0,,,UART0_RTS,I2S0_DAT0,,I2S0_DAT1,TIM0_CC0,,SPI0_CS0,UART1_RTS,,UART0_CTS,,,, 51,RTC_XTAL_P,RTC_XTAL_P,RTC_XTAL_P,,,,,,,,,,,,,,,, -52,RTC_XTAL_N,RTC_XTAL_N,GP32,,McACLK,,McAXR0,,UART0_RTS,,GSPI_MOSI,,,,,,,, -53,GP30,GP30,GP30,,McACLK,McAFSX,GT_CCP05,,,GSPI_MISO,,UART0_TX,,,,,,, +52,RTC_XTAL_N,RTC_XTAL_N,GP32,,I2S0_CLK,,I2S0_DAT0,,UART0_RTS,,SPI0_MOSI,,,,,,,, +53,GP30,GP30,GP30,,I2S0_CLK,I2S0_FS,TIM2_CC1,,,SPI0_MISO,,UART0_TX,,,,,,, 54,VIN_IO2,VIN_IO2,VIN_IO2,,,,,,,,,,,,,,,, -55,GP1,GP1,GP1,,,GSPI_MISO,pCLK (PIXCLK),,UART1_TX,GT_CCP01,,,,,,,,, +55,GP1,GP1,GP1,,,SPI0_MISO,pCLK (PIXCLK),,UART1_TX,TIM0_CC1,,,,,,,,, 56,VDD_DIG2,VDD_DIG2,VDD_DIG2,,,,,,,,,,,,,,,, -57,GP2,GP2,GP2,,,UART0_RX,,,UART1_RX,GT_CCP02,,,,,,,,,ADC_CH0 -58,GP3,GP3,GP3,,,,pDATA7(CAM_D3),,UART1_TX,,,,,,,,,,ADC_CH1 -59,GP4,GP4,GP4,,,,pDATA6(CAM_D2),,UART1_RX,,,,,,,,,,ADC_CH2 -60,GP5,GP5,GP5,,,,pDATA5(CAM_D1),,McAXR1,GT_CCP05,,,,,,,,,ADC_CH3 -61,GP6,GP6,GP6,,,UART1_CTS,pDATA4(CAM_D0),UART0_RTS,UART0_CTS,GT_CCP06,,,,,,,,, -62,GP7,GP7,GP7,,,UART1_RTS,,,,,,,UART0_RTS,UART0_TX,,McACLKX,,, -63,GP8,GP8,GP8,,,,,,SDCARD_IRQ,McAFSX,,,,,GT_CCP06,,,, -64,GP9,GP9,GP9,,,GT_PWM05,,,SDCARD_DATA,McAXR0,,,,,GT_CCP00,,,, +57,GP2,GP2,GP2,,,UART0_RX,,,UART1_RX,TIM1_CC0,,,,,,,,,ADC0_CH0 +58,GP3,GP3,GP3,,,,pDATA7(CAM_D3),,UART1_TX,,,,,,,,,,ADC0_CH1 +59,GP4,GP4,GP4,,,,pDATA6(CAM_D2),,UART1_RX,,,,,,,,,,ADC0_CH2 +60,GP5,GP5,GP5,,,,pDATA5(CAM_D1),,I2S0_DAT1,TIM2_CC1,,,,,,,,,ADC0_CH3 +61,GP6,GP6,GP6,,,UART1_CTS,pDATA4(CAM_D0),UART0_RTS,UART0_CTS,TIM3_CC0,,,,,,,,, +62,GP7,GP7,GP7,,,UART1_RTS,,,,,,,UART0_RTS,UART0_TX,,I2S0_CLK,,, +63,GP8,GP8,GP8,,,,,,SDCARD_IRQ,I2S0_FS,,,,,TIM3_CC0,,,, +64,GP9,GP9,GP9,,,TIM2_PWM1,,,SD0_DAT0,I2S0_DAT0,,,,,TIM0_CC0,,,, 65,GND_TAB,GND_TAB,GND_TAB,,,,,,,,,,,,,,,, diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c index bbf40b5859..81385afd8b 100644 --- a/cc3200/mods/pybpin.c +++ b/cc3200/mods/pybpin.c @@ -55,43 +55,11 @@ /// \moduleref pyb /// \class Pin - control I/O pins /// -/// A pin is the basic object to control I/O pins. It has methods to set -/// the mode of the pin (input or output) and methods to get and set the -/// digital logic level. For analog control of a pin, see the ADC class. -/// -/// Usage Model: -/// -/// g = pyb.Pin('GPIO9', af=0, mode=pyb.Pin.IN, type=pyb.Pin.STD, strength=pyb.Pin.S2MA) -/// -/// \Interrupts: -//// You can also configure the Pin to generate interrupts -/// -/// Example callback: -/// -/// def pincb(pin): -/// print(pin.name()) -/// -/// extint = pyb.Pin('GPIO10', 0, pyb.Pin.INT_RISING, pyb.GPIO.STD_PD, pyb.S2MA) -/// extint.callback (mode=pyb.Pin.INT_RISING, handler=pincb) -/// # the callback can be triggered manually -/// extint.callback()() -/// # to disable the callback -/// extint.callback().disable() -/// -/// Now every time a falling edge is seen on the gpio pin, the callback will be -/// called. Caution: mechanical pushbuttons have "bounce" and pushing or -/// releasing a switch will often generate multiple edges. -/// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed -/// explanation, along with various techniques for debouncing. -/// -/// All pin objects go through the pin mapper to come up with one of the -/// gpio pins. -/// -/// There is also a C API, so that drivers which require Pin interrupts -/// can also use this code. See pybextint.h for the available functions. /****************************************************************************** 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 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); @@ -140,11 +108,19 @@ STATIC pybpin_wake_pin_t pybpin_wake_pin[PYBPIN_NUM_WAKE_PINS] = DEFINE PUBLIC FUNCTIONS ******************************************************************************/ void pin_init0(void) { - // assign GP10 and GP11 to the GPIO peripheral (the default is I2C), so that the I2C bus can - // be assigned safely to any other pins (as recomended by the SDK release notes). Make them - // inputs with pull-downs enabled to ensure they are not floating during LDPS and hibernate. - pin_config ((pin_obj_t *)&pin_GP10, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, -1, PIN_STRENGTH_2MA); - pin_config ((pin_obj_t *)&pin_GP11, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, -1, PIN_STRENGTH_2MA); +// 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 + 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; + } +#endif } // C API used to convert a user-supplied pin name into an ordinal pin number. @@ -176,16 +152,46 @@ void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint if (value != -1) { self->value = value; } - pin_obj_configure ((const pin_obj_t *)self); // mark the pin as used - self->isused = true; + self->used = true; + pin_obj_configure ((const pin_obj_t *)self); + // register it with the sleep module pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pin_obj_configure); } +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; + } + } + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); +} + /****************************************************************************** DEFINE PRIVATE FUNCTIONS ******************************************************************************/ +STATIC pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { + mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins); + mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP); + if (named_elem != NULL && named_elem->value != NULL) { + return named_elem->value; + } + return NULL; +} + +STATIC pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit) { + mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins); + for (uint i = 0; i < named_map->used; i++) { + if ((((pin_obj_t *)named_map->table[i].value)->port == port) && + (((pin_obj_t *)named_map->table[i].value)->bit == bit)) { + return named_map->table[i].value; + } + } + return NULL; +} + STATIC void pin_obj_configure (const pin_obj_t *self) { uint32_t type; if (self->mode == PIN_TYPE_ANALOG) { @@ -402,25 +408,6 @@ STATIC void EXTI_Handler(uint port) { /******************************************************************************/ // Micro Python bindings -/// \method init(mode, pull=Pin.PULL_NONE, af=-1) -/// Initialise the pin: -/// -/// - `mode` can be one of: -/// - `Pin.IN` - configure the pin for input -/// - `Pin.OUT` - configure the pin for output -/// - `Pin.OPEN_DRAIN` - open drain output -/// - `pull` can be one of: -/// - `Pin.PULL_UP` - pull-up enabled -/// - `Pin.PULL_DOWN` - pull-down enabled -/// - `Pin.PULL_NONE` - no internal pull-up/down resistor -/// - `value` can take 1, 0, True or False to set the initial value of the pin -/// - `drive` can be one of: -/// - `Pin.LOW_POWER` - 2ma drive strength -/// - `Pin.MED_POWER` - 4ma drive strength -/// - `Pin.HIGH_POWER` - 6ma drive strength -/// - `alt` selects the alternate function (a number from 0 to 15). -/// -/// Returns: `None`. STATIC const mp_arg_t pin_init_args[] = { { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_pull, MP_ARG_INT, {.u_int = PIN_TYPE_STD} }, @@ -457,26 +444,33 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_ uint strength = args[3].u_int; pin_validate_drive(strength); + // get the alternate function int af = args[4].u_int; - if ((af > 0 && (mode != GPIO_DIR_MODE_ALT || mode != GPIO_DIR_MODE_ALT_OD)) || af > 15) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); + if (mode != GPIO_DIR_MODE_ALT && mode != GPIO_DIR_MODE_ALT_OD) { + if (af == -1) { + af = 0; + } else { + goto invalid_args; + } + } else if (af < -1 || af > 15) { + goto invalid_args; } - // configure the pin as requested pin_config (self, af, mode, pull, value, strength); return mp_const_none; + +invalid_args: + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } -/// \method print() -/// Return a string describing the pin object. STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pin_obj_t *self = self_in; uint32_t pull = self->pull; uint32_t drive = self->strength; // pin name - mp_printf(print, "name); + mp_printf(print, "Pin('%q'", self->name); // pin mode qstr mode_qst; @@ -514,12 +508,13 @@ STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t } else { drv_qst = MP_QSTR_HIGH_POWER; } - mp_printf(print, ", drive=Pin.%q>", drv_qst); + mp_printf(print, ", drive=Pin.%q", drv_qst); + + // pin af + int alt = (self->af == 0) ? -1 : self->af; + mp_printf(print, ", alt=%d)", alt); } -/// \classmethod \constructor(id, ...) -/// Create a new Pin object associated with the id. If additional arguments are given, -/// they are used to initialise the pin. See `init`. STATIC mp_obj_t pin_make_new(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, 1, MP_OBJ_FUN_ARGS_MAX, true); @@ -541,13 +536,6 @@ STATIC mp_obj_t pin_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *k } MP_DEFINE_CONST_FUN_OBJ_KW(pin_init_obj, 1, pin_obj_init); -/// \method value([value]) -/// Get or set the digital logic level of the pin: -/// -/// - With no arguments, return 0 or 1 depending on the logic level of the pin. -/// - With `value` given, set the logic level of the pin. `value` can be -/// anything that converts to a boolean. If it converts to `True`, the pin -/// is set high, otherwise it is set low. STATIC mp_obj_t pin_value(mp_uint_t n_args, const mp_obj_t *args) { pin_obj_t *self = args[0]; if (n_args == 1) { @@ -567,8 +555,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); -/// \method low() -/// Set the pin to a low logic level. STATIC mp_obj_t pin_low(mp_obj_t self_in) { pin_obj_t *self = self_in; MAP_GPIOPinWrite(self->port, self->bit, 0); @@ -576,8 +562,6 @@ STATIC mp_obj_t pin_low(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low); -/// \method high() -/// Set the pin to a high logic level. 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); @@ -585,8 +569,6 @@ STATIC mp_obj_t pin_high(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high); -/// \method toggle() -/// Toggles the value of the pin 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)); @@ -594,16 +576,12 @@ STATIC mp_obj_t pin_toggle(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_toggle_obj, pin_toggle); -/// \method id() -/// Returns the qstr name of the pin STATIC mp_obj_t pin_id(mp_obj_t self_in) { pin_obj_t *self = self_in; return MP_OBJ_NEW_QSTR(self->name); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_id_obj, pin_id); -/// \method mode() -/// Get or set the mode of the pin STATIC mp_obj_t pin_mode(mp_uint_t n_args, const mp_obj_t *args) { pin_obj_t *self = args[0]; if (n_args == 1) { @@ -618,8 +596,6 @@ STATIC mp_obj_t pin_mode(mp_uint_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_mode_obj, 1, 2, pin_mode); -/// \method pull() -/// Get or set the pull of the pin STATIC mp_obj_t pin_pull(mp_uint_t n_args, const mp_obj_t *args) { pin_obj_t *self = args[0]; if (n_args == 1) { @@ -634,8 +610,6 @@ STATIC mp_obj_t pin_pull(mp_uint_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_pull_obj, 1, 2, pin_pull); -/// \method drive() -/// Get or set the drive of the pin STATIC mp_obj_t pin_drive(mp_uint_t n_args, const mp_obj_t *args) { pin_obj_t *self = args[0]; if (n_args == 1) { @@ -650,10 +624,6 @@ 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); - -/// \method callback(method, mode, priority, pwrmode) -/// Creates a callback object associated to a pin -/// min num of arguments is 1 (mode) 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); @@ -666,8 +636,11 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map uint priority = mpcallback_translate_priority (args[2].u_int); // verify the interrupt mode uint intmode = args[0].u_int; - if (intmode != GPIO_FALLING_EDGE && intmode != GPIO_RISING_EDGE && intmode != GPIO_BOTH_EDGES && - intmode != GPIO_LOW_LEVEL && intmode != GPIO_HIGH_LEVEL) { + if (intmode == (GPIO_FALLING_EDGE | GPIO_RISING_EDGE)) { + intmode = GPIO_BOTH_EDGES; + } + else if (intmode != GPIO_FALLING_EDGE && intmode != GPIO_RISING_EDGE && + intmode != GPIO_LOW_LEVEL && intmode != GPIO_HIGH_LEVEL) { goto invalid_args; } @@ -782,14 +755,26 @@ invalid_args: } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_callback_obj, 1, pin_callback); -/// \method \call() -/// Get or set the value of the pin 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 }, @@ -801,6 +786,7 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_mode), (mp_obj_t)&pin_mode_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_pull), (mp_obj_t)&pin_pull_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_drive), (mp_obj_t)&pin_drive_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_alt_list), (mp_obj_t)&pin_alt_list_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pin_callback_obj }, // class attributes @@ -818,11 +804,10 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_LOW_POWER), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_2MA) }, { MP_OBJ_NEW_QSTR(MP_QSTR_MED_POWER), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_4MA) }, { MP_OBJ_NEW_QSTR(MP_QSTR_HIGH_POWER), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_6MA) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_INT_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_FALLING_EDGE) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_INT_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_RISING_EDGE) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_INT_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_BOTH_EDGES) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_INT_LOW_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_LOW_LEVEL) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_INT_HIGH_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_HIGH_LEVEL) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_FALLING_EDGE) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_RISING_EDGE) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_LOW_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_LOW_LEVEL) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_HIGH_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_HIGH_LEVEL) }, }; STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table); @@ -842,3 +827,15 @@ STATIC const mp_cb_methods_t pin_cb_methods = { .disable = pin_extint_disable, }; +STATIC void pin_named_pins_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + pin_named_pins_obj_t *self = self_in; + mp_printf(print, "", self->name); +} + +const mp_obj_type_t pin_board_pins_obj_type = { + { &mp_type_type }, + .name = MP_QSTR_board, + .print = pin_named_pins_obj_print, + .locals_dict = (mp_obj_t)&pin_board_pins_locals_dict, +}; + diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c index 1644d8aa80..14a610a673 100644 --- a/cc3200/mods/pybrtc.c +++ b/cc3200/mods/pybrtc.c @@ -80,7 +80,7 @@ STATIC const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type}; DECLARE PUBLIC FUNCTIONS ******************************************************************************/ __attribute__ ((section (".boot"))) -void pybrtc_init(void) { +void pybrtc_pre_init(void) { // if the RTC was previously set, leave it alone if (MAP_PRCMSysResetCauseGet() == PRCM_POWER_ON) { // fresh reset; configure the RTC Calendar diff --git a/cc3200/mods/pybrtc.h b/cc3200/mods/pybrtc.h index 8184683d2c..55d695a9a0 100644 --- a/cc3200/mods/pybrtc.h +++ b/cc3200/mods/pybrtc.h @@ -33,7 +33,7 @@ extern const mp_obj_type_t pyb_rtc_type; -extern void pybrtc_init(void); +extern void pybrtc_pre_init(void); extern void pyb_rtc_callback_disable (mp_obj_t self_in); extern uint32_t pybrtc_get_seconds (void); diff --git a/cc3200/mods/pybsd.c b/cc3200/mods/pybsd.c index a527bdc039..052a6b51e6 100644 --- a/cc3200/mods/pybsd.c +++ b/cc3200/mods/pybsd.c @@ -80,7 +80,7 @@ STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in); DEFINE PUBLIC FUNCTIONS ******************************************************************************/ __attribute__ ((section (".boot"))) -void pybsd_init0 (void) { +void pybsd_pre_init (void) { // allocate memory for the sd file system ASSERT ((pybsd_obj.fatfs = mem_Malloc(sizeof(FATFS))) != NULL); } diff --git a/cc3200/mods/pybsd.h b/cc3200/mods/pybsd.h index 5004441f38..145c7dc411 100644 --- a/cc3200/mods/pybsd.h +++ b/cc3200/mods/pybsd.h @@ -29,7 +29,7 @@ #if MICROPY_HW_HAS_SDCARD extern const mp_obj_type_t pyb_sd_type; -void pybsd_init0 (void); +void pybsd_pre_init (void); void pybsd_disable (void); bool pybsd_is_mounted (void); #endif diff --git a/cc3200/mptask.c b/cc3200/mptask.c index d5c0818e7d..a96bd1b93d 100644 --- a/cc3200/mptask.c +++ b/cc3200/mptask.c @@ -128,9 +128,9 @@ soft_reset: mpexception_init0(); mpcallback_init0(); pybsleep_init0(); + pin_init0(); mperror_init0(); uart_init0(); - pin_init0(); timer_init0(); readline_init0(); mod_network_init0(); @@ -266,7 +266,7 @@ soft_reset_exit: __attribute__ ((section (".boot"))) STATIC void mptask_pre_init (void) { #if MICROPY_HW_ENABLE_RTC - pybrtc_init(); + pybrtc_pre_init(); #endif // Create the simple link spawn task @@ -288,7 +288,8 @@ STATIC void mptask_pre_init (void) { modusocket_pre_init(); #if MICROPY_HW_HAS_SDCARD - pybsd_init0(); + // this one allocates memory for the SD file system + pybsd_pre_init(); #endif CRYPTOHASH_Init(); diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h index ff0d26d9d2..e50105b4cc 100644 --- a/cc3200/qstrdefsport.h +++ b/cc3200/qstrdefsport.h @@ -132,11 +132,10 @@ Q(PULL_NONE) Q(LOW_POWER) Q(MED_POWER) Q(HIGH_POWER) -Q(INT_RISING) -Q(INT_FALLING) -Q(INT_RISING_FALLING) -Q(INT_LOW_LEVEL) -Q(INT_HIGH_LEVEL) +Q(IRQ_RISING) +Q(IRQ_FALLING) +Q(IRQ_LOW_LEVEL) +Q(IRQ_HIGH_LEVEL) // for UART class Q(UART) diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index 90de1f6f81..1676f23d97 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -65,21 +65,21 @@ Usage Model: .. only:: port_wipy - Board pins are identified by their string name:: + Board pins are identified by their string id:: - g = pyb.Pin('GP9', af=0, mode=pyb.Pin.IN, type=pyb.Pin.STD, strength=pyb.Pin.S2MA) + g = pyb.Pin('GP9', mode=pyb.Pin.OUT, pull=pyb.Pin.PULL_NONE, drive=pyb.Pin.MED_POWER, alt=-1) You can also configure the Pin to generate interrupts. For instance:: def pincb(pin): - print(pin.name()) + print(pin.id()) - pin_int = pyb.Pin('GP10', af=0, mode=Pin.IN, type=pyb.Pin.STD_PD, strength=pyb.Pin.S2MA) - pin_int.callback (mode=pyb.Pin.INT_RISING, handler=pincb) + pin_int = pyb.Pin('GP10', mode=Pin.IN, pull=pyb.Pin.PULL_DOWN) + pin_int.irq(mode=pyb.Pin.IRQ_RISING, handler=pincb) # the callback can be triggered manually - pin_int.callback()() + pin_int.irq()() # to disable the callback - pin_int.callback().disable() + pin_int.irq().disable() Now every time a falling edge is seen on the gpio pin, the callback will be executed. Caution: mechanical push buttons have "bounce" and pushing or @@ -93,19 +93,10 @@ Usage Model: Constructors ------------ -.. only:: port_pyboard +.. class:: pyb.Pin(id, ...) - .. class:: pyb.Pin(id, ...) - - Create a new Pin object associated with the id. If additional arguments are given, - they are used to initialise the pin. See :meth:`pin.init`. - -.. only:: port_wipy - - .. class:: pyb.Pin(name, ...) - - Create a new Pin object associated with the name. If additional arguments are given, - they are used to initialise the pin. See :meth:`pin.init`. + Create a new Pin object associated with the id. If additional arguments are given, + they are used to initialise the pin. See :meth:`pin.init`. .. only:: port_pyboard @@ -160,36 +151,40 @@ Methods .. only:: port_wipy - .. method:: pin.init(af, mode, type, strength) + .. method:: pin.init(mode, pull, \*, drive, alt) Initialise the pin: - - - ``af`` is the number of the alternate function. Please refer to the - `pinout and alternate functions table. `_ - for the specific alternate functions that each pin supports. - ``mode`` can be one of: - - ``Pin.OUT`` - no pull up or down resistors. - - ``Pin.IN`` - enable the pull-up resistor. + - ``Pin.IN`` - input pin. + - ``Pin.OUT`` - output pin in push-pull mode. + - ``Pin.OPEN_DRAIN`` - output pin in open-drain mode. + - ``Pin.ALT`` - pin mapped to an alternate function. + - ``Pin.ALT_OPEN_DRAIN`` - pin mapped to an alternate function in open-drain mode. - - ``type`` can be one of: + - ``pull`` can be one of: - - ``Pin.STD`` - push-pull pin. - - ``Pin.STD_PU`` - push-pull pin with pull-up resistor. - - ``Pin.STD_PD`` - push-pull pin with pull-down resistor. - - ``Pin.OD`` - open drain pin. - - ``Pin.OD_PU`` - open drain pin with pull-up resistor. - - ``Pin.OD_PD`` - open drain pin with pull-down resistor. + - ``Pin.PULL_NONE`` - no pull up or down resistor. + - ``Pin.PULL_UP`` - pull up resistor enabled. + - ``Pin.PULL_DOWN`` - pull down resitor enabled. - - ``strength`` can be one of: + - ``drive`` can be one of: - - ``Pin.S2MA`` - 2mA drive capability. - - ``Pin.S4MA`` - 4mA drive capability. - - ``Pin.S6MA`` - 6mA drive capability. + - ``Pin.LOW_POWER`` - 2mA drive capability. + - ``Pin.MED_POWER`` - 4mA drive capability. + - ``Pin.HIGH_POWER`` - 6mA drive capability. + + - ``alt`` is the number of the alternate function. Please refer to the + `pinout and alternate functions table. `_ + for the specific alternate functions that each pin supports. Returns: ``None``. + .. method:: pin.id() + + Get the pin id. + .. method:: pin.high() Set the pin to a high logic level. @@ -229,11 +224,9 @@ Methods will match one of the allowed constants for the mode argument to the init function. -.. method:: pin.name() + .. method:: pin.name() - Get the pin name. - -.. only:: port_pyboard + Get the pin name. .. method:: pin.names() @@ -247,44 +240,52 @@ Methods Get the pin port. - .. method:: pin.pull() - - Returns the currently configured pull of the pin. The integer returned - will match one of the allowed constants for the pull argument to the init - function. +.. method:: pin.pull() + + Returns the currently configured pull of the pin. The integer returned + will match one of the allowed constants for the pull argument to the init + function. .. only:: port_wipy + .. method:: pin([value]) + + Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin. + See **pin.value** for more details. + .. method:: pin.toggle() Toggle the value of the pin. - .. method:: pin.info() + .. method:: pin.mode([mode]) - Return a 5-tuple with the configuration of the pin: - ``(name, alternate-function, mode, type, strength)`` + Get or set the pin mode. - .. warning:: - This method cannot be called within a callback (interrupt-context) - because it needs to allocate memory to return the tuple and memory - allocations are disabled while interrupts are being serviced. + .. method:: pin.pull([pull]) - .. method:: pin.callback(\*, mode, priority=1, handler=None, wakes=pyb.Sleep.ACTIVE) + Get or set the pin pull. + + .. method:: pin.drive([drive]) + + Get or set the pin drive strength. + + .. method:: pin.irq(\*, trigger, priority=1, handler=None, wake=None) Create a callback to be triggered when the input level at the pin changes. - - ``mode`` configures the pin level which can generate an interrupt. Possible values are: + - ``trigger`` configures the pin level which can generate an interrupt. Possible values are: - - ``Pin.INT_FALLING`` interrupt on falling edge. - - ``Pin.INT_RISING`` interrupt on rising edge. - - ``Pin.INT_RISING_FALLING`` interrupt on rising and falling edge. - - ``Pin.INT_LOW_LEVEL`` interrupt on low level. - - ``Pin.INT_HIGH_LEVEL`` interrupt on high level. + - ``Pin.IRQ_FALLING`` interrupt on falling edge. + - ``Pin.IRQ_RISING`` interrupt on rising edge. + - ``Pin.IRQ_LOW_LEVEL`` interrupt on low level. + - ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level. + + The values can be *ORed* together, for instance mode=Pin.IRQ_FALLING | Pin.IRQ_RISING - ``priority`` level of the interrupt. Can take values in the range 1-7. Higher values represent higher priorities. - ``handler`` is an optional function to be called when new characters arrive. - - ``wake_from`` selects the power mode in which this interrupt can wake up the + - ``wakes`` selects the power mode in which this interrupt can wake up the board. Please note: - If ``wake_from=pyb.Sleep.ACTIVE`` any pin can wake the board. @@ -345,68 +346,42 @@ Constants .. only:: port_wipy .. data:: Pin.IN - - input pin mode - + .. data:: Pin.OUT - output pin mode + .. data:: Pin.OPEN_DRAIN + + .. data:: Pin.ALT + + .. data:: Pin.ALT_OPEN_DRAIN + + Selects the pin mode. + + .. data:: Pin.PULL_NONE + + .. data:: Pin.PULL_UP + + .. data:: Pin.PULL_DOWN - .. data:: Pin.STD - - push-pull pin type - - .. data:: Pin.STD_PU - - push-pull pin with internall pull-up resistor - - .. data:: Pin.STD_PD - - push-pull pin with internall pull-down resistor - - .. data:: Pin.OD - - open-drain pin - - .. data:: Pin.OD_PU - - open-drain pin with pull-up resistor - - .. data:: Pin.OD_PD - - open-drain pin with pull-down resistor - - .. data:: Pin.INT_FALLING - - interrupt on falling edge - - .. data:: Pin.INT_RISING - - interrupt on rising edge - - .. data:: Pin.INT_RISING_FALLING - - interrupt on rising and falling edge - - .. data:: Pin.INT_LOW_LEVEL - - interrupt on low level - - .. data:: Pin.INT_HIGH_LEVEL - - interrupt on high level - - .. data:: Pin.S2MA - - 2mA drive strength - - .. data:: Pin.S4MA - - 4mA drive strength - - .. data:: Pin.S6MA - - 6mA drive strength + Selectes the wether there's pull up/down resistor, or none. + + .. data:: Pin.LOW_POWER + + .. data:: Pin.MED_POWER + + .. data:: Pin.HIGH_POWER + + Selects the drive strength. + + .. data:: Pin.IRQ_FALLING + + .. data:: Pin.IRQ_RISING + + .. data:: Pin.IRQ_LOW_LEVEL + + .. data:: Pin.IRQ_HIGH_LEVEL + + Selects the IRQ trigger type. .. only:: port_pyboard diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst index 358020d94e..da895d7b30 100644 --- a/docs/wipy/quickref.rst +++ b/docs/wipy/quickref.rst @@ -28,14 +28,15 @@ See :ref:`pyb.Pin `. :: from pyb import Pin # initialize GP2 in gpio mode (af=0) and make it an output - p_out = Pin('GP2', af=0, mode=Pin.OUT) + p_out = Pin('GP2', mode=Pin.OUT) p_out.high() p_out.low() p_out.toggle() + p_out(True) # make GP1 an input with the pull-up enabled - p_in = Pin('GP1', af = 0, mode=Pin.IN, type = Pin.STD_PU) - p_in.value() # get value, 0 or 1 + p_in = Pin('GP1', mode=Pin.IN, pull = Pin.PULL_UP) + p_in() # get value, 0 or 1 Timers ------ diff --git a/tests/run-tests b/tests/run-tests index 2229cd46fb..ff1de6aae0 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -335,7 +335,7 @@ def main(): test_dirs = ('basics', 'micropython', 'float', 'misc', 'extmod', 'pyb', 'pybnative', 'inlineasm') elif args.target == 'wipy': # run WiPy tests - test_dirs = ('basics', 'micropython', 'misc', 'extmod') + test_dirs = ('basics', 'micropython', 'misc', 'extmod', 'wipy') else: # run PC tests test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc', 'unicode', 'extmod', 'unix', 'cmdline') diff --git a/tests/wipy/pin.py b/tests/wipy/pin.py new file mode 100644 index 0000000000..cfbe283082 --- /dev/null +++ b/tests/wipy/pin.py @@ -0,0 +1,182 @@ +""" This test need a set of pins which can be set as inputs and have no external + pull up or pull down connected. +""" +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) +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) +else: + raise Exception('Board not supported!') + +def test_noinit(): + for p in pin_map: + pin = Pin(p) + pin.value() + +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 + print(pin()) + +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) + +# test un-initialized pins +test_noinit() +# test with pull-up and pull-down +test_pin_read(Pin.PULL_UP) +test_pin_read(Pin.PULL_DOWN) + +# test all constructor combinations +pin = Pin(pin_map[0]) +pin = Pin(pin_map[0], mode=Pin.IN) +pin = Pin(pin_map[0], mode=Pin.OUT) +pin = Pin(pin_map[0], mode=Pin.IN, pull=Pin.PULL_DOWN) +pin = Pin(pin_map[0], mode=Pin.IN, pull=Pin.PULL_UP) +pin = Pin(pin_map[0], mode=Pin.OPEN_DRAIN, pull=Pin.PULL_UP) +pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_DOWN) +pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_NONE) +pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP) +pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.LOW_POWER) +pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.MED_POWER) +pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.HIGH_POWER) +pin = Pin(pin_map[0], mode=Pin.OUT, drive=pin.LOW_POWER) +pin = Pin(pin_map[0], Pin.OUT, Pin.PULL_DOWN) +pin = Pin(pin_map[0], Pin.ALT, Pin.PULL_UP) +pin = Pin(pin_map[0], Pin.ALT_OPEN_DRAIN, Pin.PULL_UP) +test_pin_af() # try the entire af range on all pins + +# test pin init and printing +pin = Pin(pin_map[0]) +pin.init(mode=Pin.IN) +print(pin) +pin.init(Pin.IN, Pin.PULL_DOWN) +print(pin) +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) +pin.high() # test high +print(pin.value()) +print(pin()) +pin.low() # test low +print(pin.value()) +print(pin()) +pin.toggle() # test toggle +print(pin()) +pin.toggle() # test toggle again +print(pin()) +# test different value settings +pin(1) +print(pin.value()) +pin(0) +print(pin.value()) +pin.value(1) +print(pin()) +pin.value(0) +print(pin()) + +# test all getters and setters +pin = Pin(pin_map[0], mode=Pin.OUT) +# mode +print(pin.mode() == Pin.OUT) +pin.mode(Pin.IN) +print(pin.mode() == Pin.IN) +# pull +pin.pull(Pin.PULL_NONE) +print(pin.pull() == Pin.PULL_NONE) +pin.pull(Pin.PULL_DOWN) +print(pin.pull() == Pin.PULL_DOWN) +# drive +pin.drive(Pin.MED_POWER) +print(pin.drive() == Pin.MED_POWER) +pin.drive(Pin.HIGH_POWER) +print(pin.drive() == Pin.HIGH_POWER) +# id +print(pin.id() == pin_map[0]) + +# all the next ones MUST raise +try: + pin = Pin(pin_map[0], mode=Pin.OUT, pull=Pin.PULL_UP, drive=pin.IN) # incorrect drive value +except Exception: + print('Exception') + +try: + pin = Pin(pin_map[0], mode=Pin.LOW_POWER, pull=Pin.PULL_UP) # incorrect mode value +except Exception: + print('Exception') + +try: + pin = Pin(pin_map[0], mode=Pin.IN, pull=Pin.HIGH_POWER) # incorrect pull value +except Exception: + print('Exception') + +try: + pin = Pin('A0', Pin.OUT, Pin.PULL_DOWN) # incorrect pin id +except Exception: + print('Exception') + +try: + pin = Pin(pin_map[0], Pin.IN, Pin.PULL_UP, alt=0) # af specified in GPIO mode +except Exception: + print('Exception') + +try: + pin = Pin(pin_map[0], Pin.OUT, Pin.PULL_UP, alt=7) # af specified in GPIO mode +except Exception: + print('Exception') + +try: + pin = Pin(pin_map[0], Pin.ALT, Pin.PULL_UP, alt=0) # incorrect af +except Exception: + print('Exception') + +try: + pin = Pin(pin_map[0], Pin.ALT_OPEN_DRAIN, Pin.PULL_UP, alt=-1) # incorrect af +except Exception: + print('Exception') + +try: + pin = Pin(pin_map[0], Pin.ALT_OPEN_DRAIN, Pin.PULL_UP, alt=16) # incorrect af +except Exception: + print('Exception') + +try: + pin.mode(Pin.PULL_UP) # incorrect pin mode +except Exception: + print('Exception') + +try: + pin.pull(Pin.OUT) # incorrect pull +except Exception: + print('Exception') + +try: + pin.drive(Pin.IN) # incorrect drive strength +except Exception: + print('Exception') + +try: + pin.id('ABC') # id cannot be set +except Exception: + print('Exception') + diff --git a/tests/wipy/pin.py.exp b/tests/wipy/pin.py.exp new file mode 100644 index 0000000000..8c824abe0c --- /dev/null +++ b/tests/wipy/pin.py.exp @@ -0,0 +1,64 @@ +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +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 +1 +0 +0 +1 +0 +1 +0 +1 +0 +True +True +True +True +True +True +True +Exception +Exception +Exception +Exception +Exception +Exception +Exception +Exception +Exception +Exception +Exception