Commit d5e25648 authored by Daniel Campora's avatar Daniel Campora
Browse files

cc3200: Re-work Pin class according to the new API.

Also add relevant test.
parent 42054c3c
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,,,,,,,,,,,,,,,,
......@@ -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,
};
......@@ -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
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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();
......
......@@ -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)
......
......@@ -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.