summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2016-12-06 10:31:38 -0800
committerScott Shawcroft <scott.shawcroft@gmail.com>2016-12-07 15:21:14 -0800
commit0ae344841ff048424b886e1f386b16c0c9ba4ee2 (patch)
tree358f0e2044672d38dc863b243aea734b2e41337c
parentbb9c751b502a7bda49027d5ee195f8110b1493f9 (diff)
atmel-samd & esp8266: Make sure pins are not already in use.
This prevents corrupting previous functional objects by stealing their pins out from under them. It prevents this by ensuring that pins are in default state before claiming them. It also verifies pins are released correctly and reset on soft reset. Fixes #4, instantiating a second class will fail. Fixes #29, pins are now reset too.
-rw-r--r--atmel-samd/boards/arduino_zero/mpconfigboard.h3
-rw-r--r--atmel-samd/boards/cplay_m0_flash/mpconfigboard.h3
-rw-r--r--atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h5
-rw-r--r--atmel-samd/boards/feather_m0_basic/mpconfigboard.h5
-rw-r--r--atmel-samd/boards/feather_m0_flash/mpconfigboard.h3
-rw-r--r--atmel-samd/boards/gemma_m0/mpconfigboard.h8
-rw-r--r--atmel-samd/boards/metro_m0_flash/mpconfigboard.h3
-rw-r--r--atmel-samd/boards/trinket_m0/mpconfigboard.h8
-rw-r--r--atmel-samd/common-hal/microcontroller/Pin.c37
-rw-r--r--atmel-samd/common-hal/nativeio/AnalogIn.c8
-rw-r--r--atmel-samd/common-hal/nativeio/AnalogOut.c2
-rw-r--r--atmel-samd/common-hal/nativeio/I2C.c5
-rw-r--r--atmel-samd/common-hal/nativeio/PWMOut.c1
-rw-r--r--atmel-samd/common-hal/nativeio/SPI.c8
-rw-r--r--atmel-samd/common-hal/nativeio/types.h7
-rw-r--r--atmel-samd/main.c14
-rw-r--r--atmel-samd/samd21_pins.c7
-rw-r--r--atmel-samd/samd21_pins.h2
-rw-r--r--esp8266/common-hal/microcontroller/Pin.c52
-rw-r--r--esp8266/common-hal/microcontroller/Pin.h32
-rw-r--r--esp8266/common-hal/nativeio/AnalogIn.c11
-rw-r--r--esp8266/common-hal/nativeio/DigitalInOut.c8
-rw-r--r--esp8266/common-hal/nativeio/PWMOut.c11
-rw-r--r--esp8266/common-hal/nativeio/SPI.c10
-rw-r--r--esp8266/common-hal/nativeio/types.h1
-rw-r--r--esp8266/main.c2
-rw-r--r--shared-bindings/microcontroller/Pin.c6
-rw-r--r--shared-bindings/microcontroller/Pin.h4
-rw-r--r--shared-bindings/nativeio/AnalogIn.c35
-rw-r--r--shared-bindings/nativeio/AnalogIn.h1
-rw-r--r--shared-bindings/nativeio/AnalogOut.c26
-rw-r--r--shared-bindings/nativeio/DigitalInOut.c1
-rw-r--r--shared-bindings/nativeio/I2C.c2
-rw-r--r--shared-bindings/nativeio/PWMOut.c3
-rw-r--r--shared-bindings/nativeio/SPI.c3
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;
}