diff options
35 files changed, 322 insertions, 15 deletions
diff --git a/atmel-samd/boards/arduino_zero/mpconfigboard.h b/atmel-samd/boards/arduino_zero/mpconfigboard.h index 2cfa2c173..50ab4c51c 100644 --- a/atmel-samd/boards/arduino_zero/mpconfigboard.h +++ b/atmel-samd/boards/arduino_zero/mpconfigboard.h @@ -7,6 +7,9 @@ #define MICROPY_HW_LED_TX PIN_PA27 #define MICROPY_HW_LED_RX PIN_PB03 +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25 | PORT_PA27) +#define MICROPY_PORT_B (PORT_PB03) + #define AUTORESET_DELAY_MS 500 #include "internal_flash.h" diff --git a/atmel-samd/boards/cplay_m0_flash/mpconfigboard.h b/atmel-samd/boards/cplay_m0_flash/mpconfigboard.h index 47c23bbe0..1db6c4b74 100644 --- a/atmel-samd/boards/cplay_m0_flash/mpconfigboard.h +++ b/atmel-samd/boards/cplay_m0_flash/mpconfigboard.h @@ -17,6 +17,9 @@ #define SPI_FLASH_CS PIN_PB08 #define SPI_FLASH_SERCOM SERCOM4 +#define MICROPY_PORT_A (PORT_PA12 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (PORT_PB08 | PORT_PB10 | PORT_PB11) + #define AUTORESET_DELAY_MS 500 #include "spi_flash.h" diff --git a/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h b/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h index e92b8842a..9ed6daf66 100644 --- a/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h +++ b/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h @@ -1,5 +1,5 @@ // LEDs -#define MICROPY_HW_LED_MSC PIN_PA17 // red +//#define MICROPY_HW_LED_MSC PIN_PA17 // red // #define UART_REPL #define USB_REPL @@ -8,6 +8,9 @@ #define AUTORESET_DELAY_MS 500 +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) + #include "internal_flash.h" #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/atmel-samd/boards/feather_m0_basic/mpconfigboard.h b/atmel-samd/boards/feather_m0_basic/mpconfigboard.h index 3dc84dddc..10693934a 100644 --- a/atmel-samd/boards/feather_m0_basic/mpconfigboard.h +++ b/atmel-samd/boards/feather_m0_basic/mpconfigboard.h @@ -1,5 +1,5 @@ // LEDs -#define MICROPY_HW_LED_MSC PIN_PA17 // red +//#define MICROPY_HW_LED_MSC PIN_PA17 // red // #define UART_REPL #define USB_REPL @@ -8,6 +8,9 @@ #define AUTORESET_DELAY_MS 500 +#define MICROPY_PORT_A (PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) + #include "internal_flash.h" #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/atmel-samd/boards/feather_m0_flash/mpconfigboard.h b/atmel-samd/boards/feather_m0_flash/mpconfigboard.h index c7ecd5346..68c2a72e4 100644 --- a/atmel-samd/boards/feather_m0_flash/mpconfigboard.h +++ b/atmel-samd/boards/feather_m0_flash/mpconfigboard.h @@ -18,6 +18,9 @@ #define SPI_FLASH_CS PIN_PA13 #define SPI_FLASH_SERCOM SERCOM4 +#define MICROPY_PORT_A (PORT_PA12 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11) + #define AUTORESET_DELAY_MS 500 #include "spi_flash.h" diff --git a/atmel-samd/boards/gemma_m0/mpconfigboard.h b/atmel-samd/boards/gemma_m0/mpconfigboard.h index 9b461b452..998e895ff 100644 --- a/atmel-samd/boards/gemma_m0/mpconfigboard.h +++ b/atmel-samd/boards/gemma_m0/mpconfigboard.h @@ -3,8 +3,12 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Gemma M0 (Experimental)" #define MICROPY_HW_MCU_NAME "samd21e18" -#define MICROPY_HW_APA102_MOSI &pin_PA04 -#define MICROPY_HW_APA102_SCK &pin_PA05 +#define MICROPY_HW_APA102_SERCOM SERCOM0 +#define MICROPY_HW_APA102_MOSI &pin_PA04 +#define MICROPY_HW_APA102_SCK &pin_PA05 + +#define MICROPY_PORT_A (PORT_PA04 | PORT_PA05 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) #define AUTORESET_DELAY_MS 500 diff --git a/atmel-samd/boards/metro_m0_flash/mpconfigboard.h b/atmel-samd/boards/metro_m0_flash/mpconfigboard.h index 0c82d80e5..f3afe90a5 100644 --- a/atmel-samd/boards/metro_m0_flash/mpconfigboard.h +++ b/atmel-samd/boards/metro_m0_flash/mpconfigboard.h @@ -32,6 +32,9 @@ #define SPI_FLASH_CS PIN_PA13 #define SPI_FLASH_SERCOM SERCOM4 +#define MICROPY_PORT_A (PORT_PA12 | PORT_PA13 |PORT_PA24 | PORT_PA25 | PORT_PA27 | PORT_PA30) +#define MICROPY_PORT_B (PORT_PB03 | PORT_PB10 | PORT_PB11) + #define AUTORESET_DELAY_MS 500 #include "spi_flash.h" diff --git a/atmel-samd/boards/trinket_m0/mpconfigboard.h b/atmel-samd/boards/trinket_m0/mpconfigboard.h index d7c494821..e7282c3a6 100644 --- a/atmel-samd/boards/trinket_m0/mpconfigboard.h +++ b/atmel-samd/boards/trinket_m0/mpconfigboard.h @@ -3,8 +3,12 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Trinket M0 (Experimental)" #define MICROPY_HW_MCU_NAME "samd21e18" -#define MICROPY_HW_APA102_MOSI &pin_PA04 -#define MICROPY_HW_APA102_SCK &pin_PA05 +#define MICROPY_HW_APA102_SERCOM SERCOM0 +#define MICROPY_HW_APA102_MOSI &pin_PA04 +#define MICROPY_HW_APA102_SCK &pin_PA05 + +#define MICROPY_PORT_A (PORT_PA04 | PORT_PA05 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B (0) #define AUTORESET_DELAY_MS 500 diff --git a/atmel-samd/common-hal/microcontroller/Pin.c b/atmel-samd/common-hal/microcontroller/Pin.c index 2e8b72a2c..cfe8762bd 100644 --- a/atmel-samd/common-hal/microcontroller/Pin.c +++ b/atmel-samd/common-hal/microcontroller/Pin.c @@ -1 +1,36 @@ -// Pins have no behavior. +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/microcontroller/Pin.h" + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { + PortGroup *const port = system_pinmux_get_group_from_gpio_pin(pin->pin); + uint32_t pin_index = (pin->pin); + PORT_PINCFG_Type state = port->PINCFG[pin_index]; + + return state.bit.PMUXEN == 0 && state.bit.INEN == 0 && + state.bit.PULLEN == 0 && (port->DIR.reg & (1 << pin_index)) == 0; +} diff --git a/atmel-samd/common-hal/nativeio/AnalogIn.c b/atmel-samd/common-hal/nativeio/AnalogIn.c index faf63265f..592ba4ca8 100644 --- a/atmel-samd/common-hal/nativeio/AnalogIn.c +++ b/atmel-samd/common-hal/nativeio/AnalogIn.c @@ -33,6 +33,7 @@ #include "shared-bindings/nativeio/AnalogIn.h" #include "asf/sam0/drivers/adc/adc.h" +#include "samd21_pins.h" void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self, const mcu_pin_obj_t *pin) { @@ -55,6 +56,13 @@ void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self, adc_init(&self->adc_instance, ADC, &config_adc); } +void common_hal_nativeio_analogin_deinit(nativeio_analogin_obj_t *self) { + // TODO(tannewt): Count how many pins are in use and only reset the ADC when + // none are used. + adc_reset(&self->adc_instance); + reset_pin(self->pin->pin); +} + // TODO(tannewt): Don't turn it all on just for one read. This simplifies // handling of reading multiple inputs and surviving sleep though so for now its // ok. diff --git a/atmel-samd/common-hal/nativeio/AnalogOut.c b/atmel-samd/common-hal/nativeio/AnalogOut.c index ac2eada42..958eb7e6a 100644 --- a/atmel-samd/common-hal/nativeio/AnalogOut.c +++ b/atmel-samd/common-hal/nativeio/AnalogOut.c @@ -32,6 +32,7 @@ #include "shared-bindings/nativeio/AnalogOut.h" #include "asf/sam0/drivers/dac/dac.h" +#include "samd21_pins.h" void common_hal_nativeio_analogout_construct(nativeio_analogout_obj_t* self, const mcu_pin_obj_t *pin) { @@ -61,6 +62,7 @@ void common_hal_nativeio_analogout_construct(nativeio_analogout_obj_t* self, void common_hal_nativeio_analogout_deinit(nativeio_analogout_obj_t *self) { dac_disable(&self->dac_instance); dac_chan_disable(&self->dac_instance, DAC_CHANNEL_0); + reset_pin(PIN_PA02); } void common_hal_nativeio_analogout_set_value(nativeio_analogout_obj_t *self, diff --git a/atmel-samd/common-hal/nativeio/I2C.c b/atmel-samd/common-hal/nativeio/I2C.c index aee5728ca..07e367baa 100644 --- a/atmel-samd/common-hal/nativeio/I2C.c +++ b/atmel-samd/common-hal/nativeio/I2C.c @@ -77,6 +77,9 @@ void common_hal_nativeio_i2c_construct(nativeio_i2c_obj_t *self, config_i2c_master.pinmux_pad1 = scl_pinmux; // SCL config_i2c_master.buffer_timeout = 10000; + self->sda_pin = sda->pin; + self->scl_pin = scl->pin; + enum status_code status = i2c_master_init(&self->i2c_master_instance, sercom, &config_i2c_master); if (status != STATUS_OK) { @@ -88,6 +91,8 @@ void common_hal_nativeio_i2c_construct(nativeio_i2c_obj_t *self, void common_hal_nativeio_i2c_deinit(nativeio_i2c_obj_t *self) { i2c_master_disable(&self->i2c_master_instance); + reset_pin(self->sda_pin); + reset_pin(self->scl_pin); } bool common_hal_nativeio_i2c_probe(nativeio_i2c_obj_t *self, uint8_t addr) { diff --git a/atmel-samd/common-hal/nativeio/PWMOut.c b/atmel-samd/common-hal/nativeio/PWMOut.c index 4a21201f9..82833fbba 100644 --- a/atmel-samd/common-hal/nativeio/PWMOut.c +++ b/atmel-samd/common-hal/nativeio/PWMOut.c @@ -88,6 +88,7 @@ extern void common_hal_nativeio_pwmout_deinit(nativeio_pwmout_obj_t* self) { } else { tcc_disable(&self->tcc_instance); } + reset_pin(self->pin->pin); } extern void common_hal_nativeio_pwmout_set_duty_cycle(nativeio_pwmout_obj_t* self, uint16_t duty) { diff --git a/atmel-samd/common-hal/nativeio/SPI.c b/atmel-samd/common-hal/nativeio/SPI.c index ab7e80b58..f31bae1e1 100644 --- a/atmel-samd/common-hal/nativeio/SPI.c +++ b/atmel-samd/common-hal/nativeio/SPI.c @@ -124,11 +124,16 @@ void common_hal_nativeio_spi_construct(nativeio_spi_obj_t *self, &config_spi_master.pinmux_pad2, &config_spi_master.pinmux_pad3}; *pinmuxes[clock_pad] = clock_pinmux; + self->clock_pin = clock->pin; + self->MOSI_pin = 0; if (!mosi_none) { *pinmuxes[mosi_pad] = mosi_pinmux; + self->MOSI_pin = mosi->pin; } + self->MISO_pin = 0; if (!miso_none) { *pinmuxes[miso_pad] = miso_pinmux; + self->MISO_pin = miso->pin; } spi_init(&self->spi_master_instance, sercom, &config_spi_master); @@ -138,6 +143,9 @@ void common_hal_nativeio_spi_construct(nativeio_spi_obj_t *self, void common_hal_nativeio_spi_deinit(nativeio_spi_obj_t *self) { spi_disable(&self->spi_master_instance); + reset_pin(self->clock_pin); + reset_pin(self->MOSI_pin); + reset_pin(self->MISO_pin); } bool common_hal_nativeio_spi_configure(nativeio_spi_obj_t *self, diff --git a/atmel-samd/common-hal/nativeio/types.h b/atmel-samd/common-hal/nativeio/types.h index f811b0c2a..0a34fe209 100644 --- a/atmel-samd/common-hal/nativeio/types.h +++ b/atmel-samd/common-hal/nativeio/types.h @@ -69,12 +69,17 @@ typedef struct { mp_obj_base_t base; struct i2c_master_module i2c_master_instance; bool has_lock; + uint8_t scl_pin; + uint8_t sda_pin; } nativeio_i2c_obj_t; -typedef struct _machine_spi_obj_t { +typedef struct { mp_obj_base_t base; struct spi_module spi_master_instance; bool has_lock; + uint8_t clock_pin; + uint8_t MOSI_pin; + uint8_t MISO_pin; } nativeio_spi_obj_t; typedef struct { diff --git a/atmel-samd/main.c b/atmel-samd/main.c index 014ff950b..adbca42ea 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -163,10 +163,22 @@ void reset_samd21(void) { continue; } #endif + #ifdef MICROPY_HW_APA102_SERCOM + if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) { + continue; + } + #endif sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1; } - // TODO(tannewt): Reset all of the pins too. + struct system_pinmux_config config; + system_pinmux_get_config_defaults(&config); + config.powersave = true; + + uint32_t pin_mask[2] = PORT_OUT_IMPLEMENTED; + + system_pinmux_group_set_config(&(PORT->Group[0]), pin_mask[0] & ~MICROPY_PORT_A, &config); + system_pinmux_group_set_config(&(PORT->Group[1]), pin_mask[1] & ~MICROPY_PORT_B, &config); } bool maybe_run(const char* filename, int* ret) { diff --git a/atmel-samd/samd21_pins.c b/atmel-samd/samd21_pins.c index 83989780e..00cf2049d 100644 --- a/atmel-samd/samd21_pins.c +++ b/atmel-samd/samd21_pins.c @@ -44,6 +44,13 @@ const mcu_pin_obj_t pin_## p_name = { \ #define NO_ADC_INPUT (0) +void reset_pin(uint8_t pin) { + struct system_pinmux_config config; + system_pinmux_get_config_defaults(&config); + config.powersave = true; + system_pinmux_pin_set_config(pin, &config); +} + // Pins in datasheet order. #ifdef PIN_PA00 PIN(PA00, false, NO_ADC_INPUT, \ diff --git a/atmel-samd/samd21_pins.h b/atmel-samd/samd21_pins.h index 614a2183e..ab34d8929 100644 --- a/atmel-samd/samd21_pins.h +++ b/atmel-samd/samd21_pins.h @@ -3,6 +3,8 @@ #include "common-hal/microcontroller/types.h" +void reset_pin(uint8_t pin); + #define MUX_C 2 #define MUX_D 3 #define MUX_E 4 diff --git a/esp8266/common-hal/microcontroller/Pin.c b/esp8266/common-hal/microcontroller/Pin.c index 2e8b72a2c..23524e2ca 100644 --- a/esp8266/common-hal/microcontroller/Pin.c +++ b/esp8266/common-hal/microcontroller/Pin.c @@ -1 +1,51 @@ -// Pins have no behavior. +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "eagle_soc.h" + +extern volatile bool adc_in_use; + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { + return (pin == &pin_TOUT && adc_in_use) || + ((READ_PERI_REG(pin->peripheral) & + (PERIPHS_IO_MUX_FUNC<<PERIPHS_IO_MUX_FUNC_S)) == 0 && + (GPIO_REG_READ(GPIO_ENABLE_ADDRESS) & (1 << pin->gpio_number)) == 0 && + (READ_PERI_REG(pin->peripheral) & PERIPHS_IO_MUX_PULLUP) == 0 ); +} + +void reset_pins(void) { + for (int i = 0; i < 17; i++) { + if (i == 0 || (i > 6 && i < 13) || i == 12) { + continue; + } + uint32_t peripheral = PERIPHS_IO_MUX + i * 4; + PIN_FUNC_SELECT(peripheral, 0); + PIN_PULLUP_DIS(peripheral); + } +} diff --git a/esp8266/common-hal/microcontroller/Pin.h b/esp8266/common-hal/microcontroller/Pin.h new file mode 100644 index 000000000..428ece1c2 --- /dev/null +++ b/esp8266/common-hal/microcontroller/Pin.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H__ + +void reset_pins(void); + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H__ diff --git a/esp8266/common-hal/nativeio/AnalogIn.c b/esp8266/common-hal/nativeio/AnalogIn.c index efdd2d2ac..bf46e930d 100644 --- a/esp8266/common-hal/nativeio/AnalogIn.c +++ b/esp8266/common-hal/nativeio/AnalogIn.c @@ -31,12 +31,23 @@ #include "py/runtime.h" #include "py/binary.h" #include "py/mphal.h" +#include "common-hal/microcontroller/__init__.h" #include "shared-bindings/nativeio/AnalogIn.h" #include "user_interface.h" +volatile bool adc_in_use = false; + void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self, const mcu_pin_obj_t *pin) { + if (pin != &pin_TOUT) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin %q does not have ADC capabilities", pin->name)); + } + adc_in_use = true; +} + +void common_hal_nativeio_analogin_deinit(nativeio_analogin_obj_t* self) { + adc_in_use = false; } uint16_t common_hal_nativeio_analogin_get_value(nativeio_analogin_obj_t *self) { diff --git a/esp8266/common-hal/nativeio/DigitalInOut.c b/esp8266/common-hal/nativeio/DigitalInOut.c index 04428c64f..e6a28ed75 100644 --- a/esp8266/common-hal/nativeio/DigitalInOut.c +++ b/esp8266/common-hal/nativeio/DigitalInOut.c @@ -42,8 +42,12 @@ digitalinout_result_t common_hal_nativeio_digitalinout_construct( } void common_hal_nativeio_digitalinout_deinit(nativeio_digitalinout_obj_t* self) { - uint32_t pin_mask = 1 << self->pin->gpio_number; - gpio_output_set(0x0, 0x0, 0x0, pin_mask); + if (self->pin->gpio_number < 16) { + uint32_t pin_mask = 1 << self->pin->gpio_number; + gpio_output_set(0x0, 0x0, 0x0, pin_mask); + PIN_FUNC_SELECT(self->pin->peripheral, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } } void common_hal_nativeio_digitalinout_switch_to_input( diff --git a/esp8266/common-hal/nativeio/PWMOut.c b/esp8266/common-hal/nativeio/PWMOut.c index c12bc7cf2..ce40b6c36 100644 --- a/esp8266/common-hal/nativeio/PWMOut.c +++ b/esp8266/common-hal/nativeio/PWMOut.c @@ -32,6 +32,10 @@ #include "py/runtime.h" #include "shared-bindings/nativeio/PWMOut.h" +#include "eagle_soc.h" +#include "c_types.h" +#include "gpio.h" + // Shared with pybpwm extern bool pwm_inited; @@ -45,6 +49,7 @@ void common_hal_nativeio_pwmout_construct(nativeio_pwmout_obj_t* self, const mcu self->channel = pwm_add(pin->gpio_number, pin->peripheral, pin->gpio_function); + self->pin = pin; if (self->channel == -1) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "PWM not supported on pin %d", pin->gpio_number)); @@ -54,6 +59,12 @@ void common_hal_nativeio_pwmout_construct(nativeio_pwmout_obj_t* self, const mcu extern void common_hal_nativeio_pwmout_deinit(nativeio_pwmout_obj_t* self) { pwm_delete(self->channel); pwm_start(); + if (self->pin->gpio_number < 16) { + uint32_t pin_mask = 1 << self->pin->gpio_number; + gpio_output_set(0x0, 0x0, 0x0, pin_mask); + PIN_FUNC_SELECT(self->pin->peripheral, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } } extern void common_hal_nativeio_pwmout_set_duty_cycle(nativeio_pwmout_obj_t* self, uint16_t duty) { diff --git a/esp8266/common-hal/nativeio/SPI.c b/esp8266/common-hal/nativeio/SPI.c index 6559c894e..444483eb3 100644 --- a/esp8266/common-hal/nativeio/SPI.c +++ b/esp8266/common-hal/nativeio/SPI.c @@ -31,6 +31,8 @@ #include "py/nlr.h" #include "eagle_soc.h" +#include "c_types.h" +#include "gpio.h" extern const mcu_pin_obj_t pin_MTMS; extern const mcu_pin_obj_t pin_MTCK; @@ -48,8 +50,16 @@ void common_hal_nativeio_spi_construct(nativeio_spi_obj_t *self, void common_hal_nativeio_spi_deinit(nativeio_spi_obj_t *self) { PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U); + + // Turn off outputs 12 - 14. + gpio_output_set(0x0, 0x0, 0x0, 0x7 << 12); } bool common_hal_nativeio_spi_configure(nativeio_spi_obj_t *self, diff --git a/esp8266/common-hal/nativeio/types.h b/esp8266/common-hal/nativeio/types.h index 4dd7dc6a8..7c263faeb 100644 --- a/esp8266/common-hal/nativeio/types.h +++ b/esp8266/common-hal/nativeio/types.h @@ -64,6 +64,7 @@ typedef struct { typedef struct { mp_obj_base_t base; int channel; + const mcu_pin_obj_t* pin; } nativeio_pwmout_obj_t; #endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__ diff --git a/esp8266/main.c b/esp8266/main.c index a2e747d21..160d8e415 100644 --- a/esp8266/main.c +++ b/esp8266/main.c @@ -38,6 +38,7 @@ #include "lib/utils/pyexec.h" #include "gccollect.h" #include "user_interface.h" +#include "common-hal/microcontroller/Pin.h" STATIC char heap[36 * 1024]; @@ -58,6 +59,7 @@ STATIC void mp_reset(void) { MP_STATE_PORT(mp_kbd_exception) = mp_obj_new_exception(&mp_type_KeyboardInterrupt); MP_STATE_PORT(term_obj) = MP_OBJ_NULL; MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL; + reset_pins(); pin_init0(); readline_init0(); dupterm_task_init(); diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index c691a9a17..d564d6d10 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -53,3 +53,9 @@ void assert_pin(mp_obj_t obj, bool none_ok) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Expected a Pin")); } } + +void assert_pin_free(const mcu_pin_obj_t* pin) { + if (pin != NULL && !common_hal_mcu_pin_is_free(pin)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin %q in use", pin->name)); + } +} diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index d31ba040c..46a531a6d 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -27,11 +27,15 @@ #ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H__ #define __MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H__ +#include "common-hal/microcontroller/types.h" #include "py/obj.h" // Type object used in Python. Should be shared between ports. extern const mp_obj_type_t mcu_pin_type; void assert_pin(mp_obj_t obj, bool none_ok); +void assert_pin_free(const mcu_pin_obj_t* pin); + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin); #endif // __MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H__ diff --git a/shared-bindings/nativeio/AnalogIn.c b/shared-bindings/nativeio/AnalogIn.c index fb3d1c5b2..14e7efe1c 100644 --- a/shared-bindings/nativeio/AnalogIn.c +++ b/shared-bindings/nativeio/AnalogIn.c @@ -66,11 +66,43 @@ STATIC mp_obj_t nativeio_analogin_make_new(const mp_obj_type_t *type, nativeio_analogin_obj_t *self = m_new_obj(nativeio_analogin_obj_t); self->base.type = &nativeio_analogin_type; const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); common_hal_nativeio_analogin_construct(self, pin); return (mp_obj_t) self; } +//| .. method:: deinit() +//| +//| Turn off the AnalogIn and release the pin for other use. +//| +STATIC mp_obj_t nativeio_analogin_deinit(mp_obj_t self_in) { + nativeio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_nativeio_analogin_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogin_deinit_obj, nativeio_analogin_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +STATIC mp_obj_t nativeio_analogin___enter__(mp_obj_t self_in) { + return self_in; +} +MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogin___enter___obj, nativeio_analogin___enter__); + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t nativeio_analogin___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_nativeio_analogin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_analogin___exit___obj, 4, 4, nativeio_analogin___exit__); + //| .. attribute:: value //| //| Read the value on the analog pin and return it. The returned value @@ -95,6 +127,9 @@ mp_obj_property_t nativeio_analogin_value_obj = { }; STATIC const mp_rom_map_elem_t nativeio_analogin_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_analogin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&nativeio_analogin___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_analogin___exit___obj) }, { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&nativeio_analogin_value_obj)}, }; diff --git a/shared-bindings/nativeio/AnalogIn.h b/shared-bindings/nativeio/AnalogIn.h index e901aa3b7..781cd465c 100644 --- a/shared-bindings/nativeio/AnalogIn.h +++ b/shared-bindings/nativeio/AnalogIn.h @@ -33,6 +33,7 @@ extern const mp_obj_type_t nativeio_analogin_type; void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self, const mcu_pin_obj_t *pin); +void common_hal_nativeio_analogin_deinit(nativeio_analogin_obj_t* self); uint16_t common_hal_nativeio_analogin_get_value(nativeio_analogin_obj_t *self); #endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ diff --git a/shared-bindings/nativeio/AnalogOut.c b/shared-bindings/nativeio/AnalogOut.c index 7ea767843..3e80b943d 100644 --- a/shared-bindings/nativeio/AnalogOut.c +++ b/shared-bindings/nativeio/AnalogOut.c @@ -63,7 +63,7 @@ STATIC mp_obj_t nativeio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t nativeio_analogout_obj_t *self = m_new_obj(nativeio_analogout_obj_t); self->base.type = &nativeio_analogout_type; - + assert_pin_free(pin); common_hal_nativeio_analogout_construct(self, pin); return self; @@ -82,6 +82,26 @@ STATIC mp_obj_t nativeio_analogout_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogout_deinit_obj, nativeio_analogout_deinit); +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +STATIC mp_obj_t nativeio_analogout___enter__(mp_obj_t self_in) { + return self_in; +} +MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogout___enter___obj, nativeio_analogout___enter__); + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t nativeio_analogout___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_nativeio_analogout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_analogout___exit___obj, 4, 4, nativeio_analogout___exit__); + //| .. attribute:: value //| //| The value on the analog pin. The value must be between 0 and 65535 @@ -107,7 +127,9 @@ mp_obj_property_t nativeio_analogout_value_obj = { STATIC const mp_rom_map_elem_t nativeio_analogout_locals_dict_table[] = { // instance methods - { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&nativeio_analogout_deinit_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_analogout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&nativeio_analogout___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_analogout___exit___obj) }, // Properties { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&nativeio_analogout_value_obj }, diff --git a/shared-bindings/nativeio/DigitalInOut.c b/shared-bindings/nativeio/DigitalInOut.c index 7ef06152a..1ffb5c7f3 100644 --- a/shared-bindings/nativeio/DigitalInOut.c +++ b/shared-bindings/nativeio/DigitalInOut.c @@ -63,6 +63,7 @@ STATIC mp_obj_t nativeio_digitalinout_make_new(const mp_obj_type_t *type, assert_pin(args[0], false); mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); + assert_pin_free(pin); common_hal_nativeio_digitalinout_construct(self, pin); return (mp_obj_t)self; diff --git a/shared-bindings/nativeio/I2C.c b/shared-bindings/nativeio/I2C.c index a29d2b275..2aca80cf6 100644 --- a/shared-bindings/nativeio/I2C.c +++ b/shared-bindings/nativeio/I2C.c @@ -63,7 +63,9 @@ STATIC mp_obj_t nativeio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, assert_pin(args[ARG_scl].u_obj, false); assert_pin(args[ARG_sda].u_obj, false); const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); + assert_pin_free(scl); const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); + assert_pin_free(sda); common_hal_nativeio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int); return (mp_obj_t)self; } diff --git a/shared-bindings/nativeio/PWMOut.c b/shared-bindings/nativeio/PWMOut.c index b60d75fef..10c7e8641 100644 --- a/shared-bindings/nativeio/PWMOut.c +++ b/shared-bindings/nativeio/PWMOut.c @@ -51,6 +51,7 @@ STATIC mp_obj_t nativeio_pwmout_make_new(const mp_obj_type_t *type, size_t n_arg mp_obj_t pin_obj = args[0]; assert_pin(pin_obj, false); const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); // create PWM object from the given pin nativeio_pwmout_obj_t *self = m_new_obj(nativeio_pwmout_obj_t); @@ -135,9 +136,9 @@ mp_obj_property_t nativeio_pwmout_duty_cycle_obj = { STATIC const mp_rom_map_elem_t nativeio_pwmout_locals_dict_table[] = { // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_pwmout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&nativeio_pwmout___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_pwmout___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_pwmout_deinit_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_duty_cycle), MP_ROM_PTR(&nativeio_pwmout_duty_cycle_obj) }, diff --git a/shared-bindings/nativeio/SPI.c b/shared-bindings/nativeio/SPI.c index d27059001..df17b5c63 100644 --- a/shared-bindings/nativeio/SPI.c +++ b/shared-bindings/nativeio/SPI.c @@ -77,8 +77,11 @@ STATIC mp_obj_t nativeio_spi_make_new(const mp_obj_type_t *type, size_t n_args, assert_pin(args[ARG_MOSI].u_obj, true); assert_pin(args[ARG_MISO].u_obj, true); const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); + assert_pin_free(clock); const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); + assert_pin_free(mosi); const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); + assert_pin_free(miso); common_hal_nativeio_spi_construct(self, clock, mosi, miso); return (mp_obj_t)self; } |
