summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--cc3200/boards/cc3200_af.csv52
-rw-r--r--cc3200/mods/pybpin.c205
-rw-r--r--cc3200/mods/pybrtc.c2
-rw-r--r--cc3200/mods/pybrtc.h2
-rw-r--r--cc3200/mods/pybsd.c2
-rw-r--r--cc3200/mods/pybsd.h2
-rw-r--r--cc3200/mptask.c7
-rw-r--r--cc3200/qstrdefsport.h9
-rw-r--r--docs/library/pyb.Pin.rst215
-rw-r--r--docs/wipy/quickref.rst7
-rwxr-xr-xtests/run-tests2
-rw-r--r--tests/wipy/pin.py182
-rw-r--r--tests/wipy/pin.py.exp64
13 files changed, 485 insertions, 266 deletions
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, "<Pin.board.%q", self->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, "<Pin.%q>", 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, ...)
-
- 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(id, ...)
- .. 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. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
- 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. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
+ 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()
-
- Get the pin name.
+ .. method:: 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])
+
+ Get or set the pin mode.
- Return a 5-tuple with the configuration of the pin:
- ``(name, alternate-function, mode, type, strength)``
+ .. method:: pin.pull([pull])
- .. 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.
+ Get or set the pin pull.
- .. method:: pin.callback(\*, mode, priority=1, handler=None, wakes=pyb.Sleep.ACTIVE)
+ .. 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.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
+ .. 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
- 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 <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