summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucian Copeland <hierophect@gmail.com>2020-11-25 10:43:35 -0500
committerLucian Copeland <hierophect@gmail.com>2020-11-25 10:43:35 -0500
commitc9bc87768322c97e3536ec5d9592f97d54277235 (patch)
tree23481ef245827dc30a017de6704f9574b495d244
parent59458a9013786f79c78a36ce5d6298f16fdd6a1a (diff)
parente778fc1f876116fd8f07b95f9eb8439745988fba (diff)
Merge remote-tracking branch 'upstream/main' into esp-spi-pinclaim
-rw-r--r--.github/workflows/build.yml1
m---------lib/tinyusb0
-rw-r--r--locale/circuitpython.pot6
-rw-r--r--ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c40
-rw-r--r--ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.h62
-rw-r--r--ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.mk33
-rw-r--r--ports/atmel-samd/boards/cp_sapling_m0_spiflash/pins.c38
-rw-r--r--ports/atmel-samd/mpconfigport.mk4
-rw-r--r--ports/esp32s2/Makefile2
-rw-r--r--ports/esp32s2/common-hal/microcontroller/__init__.c12
-rw-r--r--ports/esp32s2/common-hal/nvm/ByteArray.c97
-rw-r--r--ports/esp32s2/common-hal/nvm/ByteArray.h38
-rw-r--r--ports/esp32s2/common-hal/nvm/__init__.c1
-rw-r--r--ports/esp32s2/common-hal/ps2io/Ps2.c392
-rw-r--r--ports/esp32s2/common-hal/ps2io/Ps2.h60
-rw-r--r--ports/esp32s2/common-hal/ps2io/__init__.c1
-rw-r--r--ports/esp32s2/mpconfigport.h7
-rw-r--r--ports/esp32s2/mpconfigport.mk6
-rw-r--r--ports/esp32s2/supervisor/port.c14
-rw-r--r--py/circuitpy_mpconfig.h2
-rw-r--r--py/circuitpy_mpconfig.mk3
-rw-r--r--shared-bindings/ps2io/Ps2.c5
22 files changed, 817 insertions, 7 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 046598a6e..2378a0965 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -199,6 +199,7 @@ jobs:
- "clue_nrf52840_express"
- "cp32-m4"
- "cp_sapling_m0"
+ - "cp_sapling_m0_spiflash"
- "datalore_ip_m4"
- "datum_distance"
- "datum_imu"
diff --git a/lib/tinyusb b/lib/tinyusb
-Subproject 8b2c82255750488232eae72f3d5dcbacfd6227f
+Subproject 218b80e63ab6ff87c1851e403f08b3d716d68f5
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index c184d6931..e8a9e412f 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-11-23 10:10-0600\n"
+"POT-Creation-Date: 2020-11-11 16:30+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1262,6 +1262,10 @@ msgstr ""
msgid "Must use a multiple of 6 rgb pins, not %d"
msgstr ""
+#: ports/esp32s2/common-hal/nvm/ByteArray.c
+msgid "NVS Error"
+msgstr ""
+
#: py/parse.c
msgid "Name too long"
msgstr ""
diff --git a/ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c
new file mode 100644
index 000000000..ce5636676
--- /dev/null
+++ b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 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 "boards/board.h"
+#include "common-hal/microcontroller/Pin.h"
+#include "supervisor/shared/board.h"
+#include "hal/include/hal_gpio.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.h b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.h
new file mode 100644
index 000000000..9c69c4802
--- /dev/null
+++ b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.h
@@ -0,0 +1,62 @@
+#define MICROPY_HW_BOARD_NAME "CP Sapling M0 w/ SPI Flash"
+#define MICROPY_HW_MCU_NAME "samd21e18"
+
+#define MICROPY_HW_NEOPIXEL (&pin_PA15)
+
+#define MICROPY_PORT_A (0)
+#define MICROPY_PORT_B (0)
+#define MICROPY_PORT_C (0)
+
+#define SPI_FLASH_MOSI_PIN &pin_PA18
+#define SPI_FLASH_MISO_PIN &pin_PA17
+#define SPI_FLASH_SCK_PIN &pin_PA19
+#define SPI_FLASH_CS_PIN &pin_PA22
+
+#define IGNORE_PIN_PA02 1
+#define IGNORE_PIN_PA03 1
+#define IGNORE_PIN_PA04 1
+#define IGNORE_PIN_PA05 1
+#define IGNORE_PIN_PA06 1
+#define IGNORE_PIN_PA07 1
+#define IGNORE_PIN_PA12 1
+#define IGNORE_PIN_PA13 1
+#define IGNORE_PIN_PA14 1
+#define IGNORE_PIN_PA20 1
+#define IGNORE_PIN_PA21 1
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
+#define IGNORE_PIN_PA27 1
+#define IGNORE_PIN_PA28 1
+#define IGNORE_PIN_PA30 1
+#define IGNORE_PIN_PA31 1
+#define IGNORE_PIN_PB01 1
+#define IGNORE_PIN_PB02 1
+#define IGNORE_PIN_PB03 1
+#define IGNORE_PIN_PB04 1
+#define IGNORE_PIN_PB05 1
+#define IGNORE_PIN_PB06 1
+#define IGNORE_PIN_PB07 1
+#define IGNORE_PIN_PB08 1
+#define IGNORE_PIN_PB09 1
+#define IGNORE_PIN_PB10 1
+#define IGNORE_PIN_PB11 1
+#define IGNORE_PIN_PB12 1
+#define IGNORE_PIN_PB13 1
+#define IGNORE_PIN_PB14 1
+#define IGNORE_PIN_PB15 1
+#define IGNORE_PIN_PB16 1
+#define IGNORE_PIN_PB17 1
+#define IGNORE_PIN_PB22 1
+#define IGNORE_PIN_PB23 1
+#define IGNORE_PIN_PB30 1
+#define IGNORE_PIN_PB31 1
+#define IGNORE_PIN_PB00 1
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PA09)
+#define DEFAULT_I2C_BUS_SDA (&pin_PA08)
+
+#define DEFAULT_SPI_BUS_SS (&pin_PA22)
+#define DEFAULT_SPI_BUS_SCK (&pin_PA19)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PA18)
+#define DEFAULT_SPI_BUS_MISO (&pin_PA17)
diff --git a/ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.mk b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.mk
new file mode 100644
index 000000000..99e13f791
--- /dev/null
+++ b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/mpconfigboard.mk
@@ -0,0 +1,33 @@
+USB_VID = 0x1209
+USB_PID = 0x4DDE
+USB_PRODUCT = "CP Sapling M0 w/ SPI Flash"
+USB_MANUFACTURER = "Oak Development Technologies"
+
+CHIP_VARIANT = SAMD21E18A
+CHIP_FAMILY = samd21
+
+INTERNAL_FLASH_FILESYSTEM = 0
+LONGINT_IMPL = MPZ
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = AT25DF081A
+
+CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_AUDIOBUSIO = 0
+CIRCUITPY_BITBANGIO = 0
+CIRCUITPY_COUNTIO = 0
+CIRCUITPY_FREQUENCYIO = 0
+CIRCUITPY_I2CPERIPHERAL = 0
+
+SUPEROPT_GC = 0
+
+CFLAGS_BOARD = --param max-inline-insns-auto=15
+ifeq ($(TRANSLATION), zh_Latn_pinyin)
+RELEASE_NEEDS_CLEAN_BUILD = 1
+CFLAGS_INLINE_LIMIT = 35
+endif
+ifeq ($(TRANSLATION), de_DE)
+RELEASE_NEEDS_CLEAN_BUILD = 1
+CFLAGS_INLINE_LIMIT = 35
+SUPEROPT_VM = 0
+endif
diff --git a/ports/atmel-samd/boards/cp_sapling_m0_spiflash/pins.c b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/pins.c
new file mode 100644
index 000000000..d527aaddc
--- /dev/null
+++ b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/pins.c
@@ -0,0 +1,38 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) },
+
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA00) },
+
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA01) },
+
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA09) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) },
+
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PA22) },
+
+ { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA19) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA19) },
+
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA17) },
+
+ { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA18) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index 1929e146d..17e3995bf 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -29,6 +29,10 @@ ifndef CIRCUITPY_AUDIOMP3
CIRCUITPY_AUDIOMP3 = 0
endif
+ifndef CIRCUITPY_BUILTINS_POW3
+CIRCUITPY_BUILTINS_POW3 = 0
+endif
+
ifndef CIRCUITPY_FREQUENCYIO
CIRCUITPY_FREQUENCYIO = 0
endif
diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile
index 931e4d063..0b5aa448a 100644
--- a/ports/esp32s2/Makefile
+++ b/ports/esp32s2/Makefile
@@ -104,6 +104,8 @@ INC += -isystem esp-idf/components/soc/soc/include
INC += -isystem esp-idf/components/soc/soc/esp32s2/include
INC += -isystem esp-idf/components/heap/include
INC += -isystem esp-idf/components/esp_system/include
+INC += -isystem esp-idf/components/spi_flash/include
+INC += -isystem esp-idf/components/nvs_flash/include
INC += -I$(BUILD)/esp-idf/config
CFLAGS += -DHAVE_CONFIG_H \
diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c
index dba12b88b..05f26c3fe 100644
--- a/ports/esp32s2/common-hal/microcontroller/__init__.c
+++ b/ports/esp32s2/common-hal/microcontroller/__init__.c
@@ -35,6 +35,7 @@
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/Processor.h"
+#include "shared-bindings/nvm/ByteArray.h"
#include "supervisor/filesystem.h"
#include "supervisor/shared/safe_mode.h"
@@ -85,6 +86,17 @@ const mcu_processor_obj_t common_hal_mcu_processor_obj = {
},
};
+#if CIRCUITPY_INTERNAL_NVM_SIZE > 0
+// The singleton nvm.ByteArray object.
+const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
+ .base = {
+ .type = &nvm_bytearray_type,
+ },
+ .start_address = (uint8_t*) CIRCUITPY_INTERNAL_NVM_START_ADDR,
+ .len = CIRCUITPY_INTERNAL_NVM_SIZE,
+};
+#endif
+
#if CIRCUITPY_WATCHDOG
// The singleton watchdog.WatchDogTimer object.
watchdog_watchdogtimer_obj_t common_hal_mcu_watchdogtimer_obj = {
diff --git a/ports/esp32s2/common-hal/nvm/ByteArray.c b/ports/esp32s2/common-hal/nvm/ByteArray.c
new file mode 100644
index 000000000..71321e7e6
--- /dev/null
+++ b/ports/esp32s2/common-hal/nvm/ByteArray.c
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 microDev
+ *
+ * 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/nvm/ByteArray.h"
+
+#include "py/runtime.h"
+#include "nvs_flash.h"
+
+uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) {
+ return self->len;
+}
+
+static void get_nvs_handle(nvs_handle_t * nvs_handle) {
+ // Initialize NVS
+ esp_err_t err = nvs_flash_init();
+ if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
+ // NVS partition was truncated and needs to be erased
+ // Retry nvs_flash_init
+ ESP_ERROR_CHECK(nvs_flash_erase());
+ err = nvs_flash_init();
+ }
+ ESP_ERROR_CHECK(err);
+
+ // Open NVS handle
+ if (nvs_open("CPY", NVS_READWRITE, nvs_handle) != ESP_OK) {
+ mp_raise_RuntimeError(translate("NVS Error"));
+ }
+}
+
+bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
+ uint32_t start_index, uint8_t* values, uint32_t len) {
+ char index[9];
+
+ // start nvs
+ nvs_handle_t handle;
+ get_nvs_handle(&handle);
+
+ // stage flash changes
+ for (uint32_t i = 0; i < len; i++) {
+ sprintf(index, "%i", start_index + i);
+ if (nvs_set_u8(handle, (const char *)index, values[i]) != ESP_OK) {
+ return false;
+ }
+ }
+
+ // commit flash changes
+ if (nvs_commit(handle) != ESP_OK) {
+ return false;
+ }
+
+ // close nvs
+ nvs_close(handle);
+ return true;
+}
+
+void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self,
+ uint32_t start_index, uint32_t len, uint8_t* values) {
+ char index[9];
+
+ // start nvs
+ nvs_handle_t handle;
+ get_nvs_handle(&handle);
+
+ // get from flash
+ for (uint32_t i = 0; i < len; i++) {
+ sprintf(index, "%i", start_index + i);
+ if (nvs_get_u8(handle, (const char *)index, &values[i]) != ESP_OK) {
+ mp_raise_RuntimeError(translate("NVS Error"));
+ }
+ }
+
+ // close nvs
+ nvs_close(handle);
+}
diff --git a/ports/esp32s2/common-hal/nvm/ByteArray.h b/ports/esp32s2/common-hal/nvm/ByteArray.h
new file mode 100644
index 000000000..44b63d724
--- /dev/null
+++ b/ports/esp32s2/common-hal/nvm/ByteArray.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 microDev
+ *
+ * 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_ESP32S2_COMMON_HAL_NVM_BYTEARRAY_H
+#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_NVM_BYTEARRAY_H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t* start_address;
+ uint32_t len;
+} nvm_bytearray_obj_t;
+
+#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_NVM_BYTEARRAY_H
diff --git a/ports/esp32s2/common-hal/nvm/__init__.c b/ports/esp32s2/common-hal/nvm/__init__.c
new file mode 100644
index 000000000..1b702a158
--- /dev/null
+++ b/ports/esp32s2/common-hal/nvm/__init__.c
@@ -0,0 +1 @@
+// No nvm module functions.
diff --git a/ports/esp32s2/common-hal/ps2io/Ps2.c b/ports/esp32s2/common-hal/ps2io/Ps2.c
new file mode 100644
index 000000000..003f0d827
--- /dev/null
+++ b/ports/esp32s2/common-hal/ps2io/Ps2.c
@@ -0,0 +1,392 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 microDev
+ *
+ * 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/ps2io/Ps2.h"
+
+#include "supervisor/port.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
+#define STATE_IDLE 0
+#define STATE_RECV 1
+#define STATE_RECV_PARITY 2
+#define STATE_RECV_STOP 3
+#define STATE_RECV_ERR 10
+
+#define ERROR_STARTBIT 0x01
+#define ERROR_TIMEOUT 0x02
+#define ERROR_PARITY 0x04
+#define ERROR_STOPBIT 0x08
+#define ERROR_BUFFER 0x10
+
+#define ERROR_TX_CLKLO 0x100
+#define ERROR_TX_CLKHI 0x200
+#define ERROR_TX_ACKDATA 0x400
+#define ERROR_TX_ACKCLK 0x800
+#define ERROR_TX_RTS 0x1000
+#define ERROR_TX_NORESP 0x2000
+
+void ps2_reset(void) {
+ gpio_uninstall_isr_service();
+}
+
+static void delay_us(uint32_t t) {
+ common_hal_mcu_delay_us(t);
+}
+
+/* interrupt handling */
+
+static void IRAM_ATTR ps2_interrupt_handler(void *self_in) {
+ // Grab the current time first.
+ uint64_t current_tick = port_get_raw_ticks(NULL);
+
+ ps2io_ps2_obj_t * self = self_in;
+ int data_bit = gpio_get_level(self->data_pin) ? 1 : 0;
+
+ // test for timeout
+ if (self->state != STATE_IDLE) {
+ int64_t diff_ms = current_tick - self->last_raw_ticks;
+ if (diff_ms > 1) { // a.k.a. > 1.001ms
+ self->last_errors |= ERROR_TIMEOUT;
+ self->state = STATE_IDLE;
+ }
+ }
+
+ self->last_raw_ticks = current_tick;
+
+ if (self->state == STATE_IDLE) {
+ self->bits = 0;
+ self->parity = false;
+ self->bitcount = 0;
+ self->state = STATE_RECV;
+ if (data_bit) {
+ // start bit should be 0
+ self->last_errors |= ERROR_STARTBIT;
+ self->state = STATE_RECV_ERR;
+ } else {
+ self->state = STATE_RECV;
+ }
+
+ } else if (self->state == STATE_RECV) {
+ if (data_bit) {
+ self->bits |= data_bit << self->bitcount;
+ self->parity = !self->parity;
+ }
+ ++self->bitcount;
+ if (self->bitcount >= 8) {
+ self->state = STATE_RECV_PARITY;
+ }
+
+ } else if (self->state == STATE_RECV_PARITY) {
+ ++self->bitcount;
+ if (data_bit) {
+ self->parity = !self->parity;
+ }
+ if (!self->parity) {
+ self->last_errors |= ERROR_PARITY;
+ self->state = STATE_RECV_ERR;
+ } else {
+ self->state = STATE_RECV_STOP;
+ }
+
+ } else if (self->state == STATE_RECV_STOP) {
+ ++self->bitcount;
+ if (! data_bit) {
+ self->last_errors |= ERROR_STOPBIT;
+ } else if (self->waiting_cmd_response) {
+ self->cmd_response = self->bits;
+ self->waiting_cmd_response = false;
+ } else if (self->bufcount >= sizeof(self->buffer)) {
+ self->last_errors |= ERROR_BUFFER;
+ } else {
+ self->buffer[self->bufposw] = self->bits;
+ self->bufposw = (self->bufposw + 1) % sizeof(self->buffer);
+ self->bufcount++;
+ }
+ self->state = STATE_IDLE;
+
+ } else if (self->state == STATE_RECV_ERR) {
+ // just count the bits until idle
+ if (++self->bitcount >= 10) {
+ self->state = STATE_IDLE;
+ }
+ }
+}
+
+static void enable_interrupt(ps2io_ps2_obj_t* self) {
+ // turn on falling edge interrupt
+ gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
+ gpio_set_intr_type(self->clk_pin, GPIO_INTR_NEGEDGE);
+ gpio_isr_handler_add(self->clk_pin, ps2_interrupt_handler, (void*)self);
+}
+
+static void disable_interrupt(ps2io_ps2_obj_t* self) {
+ // turn off fallling edge interrupt
+ gpio_isr_handler_remove(self->clk_pin);
+}
+
+static void resume_interrupt(ps2io_ps2_obj_t* self) {
+ self->state = STATE_IDLE;
+ gpio_isr_handler_add(self->clk_pin, ps2_interrupt_handler, (void*)self);
+}
+
+/* gpio handling */
+
+static void clk_hi(ps2io_ps2_obj_t* self) {
+ // external pull-up
+ gpio_set_direction(self->clk_pin, GPIO_MODE_INPUT);
+}
+
+static bool wait_clk_lo(ps2io_ps2_obj_t* self, uint32_t us) {
+ clk_hi(self);
+ delay_us(1);
+ while (gpio_get_level(self->clk_pin) && us) {
+ --us;
+ delay_us(1);
+ }
+ return us;
+}
+
+static bool wait_clk_hi(ps2io_ps2_obj_t* self, uint32_t us) {
+ clk_hi(self);
+ delay_us(1);
+ while (!gpio_get_level(self->clk_pin) && us) {
+ --us;
+ delay_us(1);
+ }
+ return us;
+}
+
+static void clk_lo(ps2io_ps2_obj_t* self) {
+ gpio_set_direction(self->clk_pin, GPIO_MODE_OUTPUT);
+ gpio_set_level(self->clk_pin, 0);
+}
+
+static void data_hi(ps2io_ps2_obj_t* self) {
+ // external pull-up
+ gpio_set_direction(self->data_pin, GPIO_MODE_INPUT);
+}
+
+static bool wait_data_lo(ps2io_ps2_obj_t* self, uint32_t us) {
+ data_hi(self);
+ delay_us(1);
+ while (gpio_get_level(self->data_pin) && us) {
+ --us;
+ delay_us(1);
+ }
+ return us;
+}
+
+static bool wait_data_hi(ps2io_ps2_obj_t* self, uint32_t us) {
+ data_hi(self);
+ delay_us(1);
+ while (!gpio_get_level(self->data_pin) && us) {
+ --us;
+ delay_us(1);
+ }
+ return us;
+}
+
+static void data_lo(ps2io_ps2_obj_t* self) {
+ gpio_set_direction(self->data_pin, GPIO_MODE_OUTPUT);
+ gpio_set_level(self->data_pin, 0);
+}
+
+static void idle(ps2io_ps2_obj_t* self) {
+ clk_hi(self);
+ data_hi(self);
+}
+
+static void inhibit(ps2io_ps2_obj_t* self) {
+ clk_lo(self);
+ data_hi(self);
+}
+
+/* ps2io module functions */
+
+void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self,
+ const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin) {
+ self->clk_pin = (gpio_num_t)clk_pin->number;
+ self->data_pin = (gpio_num_t)data_pin->number;
+ self->state = STATE_IDLE;
+ self->bufcount = 0;
+ self->bufposr = 0;
+ self->bufposw = 0;
+ self->waiting_cmd_response = false;
+
+ idle(self);
+ enable_interrupt(self);
+
+ claim_pin(clk_pin);
+ claim_pin(data_pin);
+}
+
+bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self) {
+ return self->clk_pin == GPIO_NUM_MAX;
+}
+
+void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self) {
+ if (common_hal_ps2io_ps2_deinited(self)) {
+ return;
+ }
+ gpio_uninstall_isr_service();
+ reset_pin_number(self->clk_pin);
+ reset_pin_number(self->data_pin);
+ self->clk_pin = GPIO_NUM_MAX;
+ self->data_pin = GPIO_NUM_MAX;
+}
+
+uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self) {
+ return self->bufcount;
+}
+
+int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self) {
+ common_hal_mcu_disable_interrupts();
+ if (self->bufcount <= 0) {
+ common_hal_mcu_enable_interrupts();
+ return -1;
+ }
+ uint8_t b = self->buffer[self->bufposr];
+ self->bufposr = (self->bufposr + 1) % sizeof(self->buffer);
+ self->bufcount -= 1;
+ common_hal_mcu_enable_interrupts();
+ return b;
+}
+
+uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self) {
+ common_hal_mcu_disable_interrupts();
+ uint16_t errors = self->last_errors;
+ self->last_errors = 0;
+ common_hal_mcu_enable_interrupts();
+ return errors;
+}
+
+// Based upon TMK implementation of PS/2 protocol
+// https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/protocol/ps2_interrupt.c
+
+int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b) {
+ disable_interrupt(self);
+
+ /* terminate a transmission if we have */
+ inhibit(self);
+ delay_us(100);
+
+ /* RTS and start bit */
+ data_lo(self);
+ clk_hi(self);
+ if (!wait_clk_lo(self, 10000)) {
+ self->last_errors |= ERROR_TX_RTS;
+ goto ERROR;
+ }
+
+ bool parity = true;
+ for (uint8_t i = 0; i < 8; i++) {
+ delay_us(15);
+ if (b & (1 << i)) {
+ parity = !parity;
+ data_hi(self);
+ } else {
+ data_lo(self);
+ }
+ if (!wait_clk_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKHI;
+ goto ERROR;
+ }
+ if (!wait_clk_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKLO;
+ goto ERROR;
+ }
+ }
+
+ /* Parity bit */
+ delay_us(15);
+ if (parity) {
+ data_hi(self);
+ } else {
+ data_lo(self);
+ }
+ if (!wait_clk_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKHI;
+ goto ERROR;
+ }
+ if (!wait_clk_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_CLKLO;
+ goto ERROR;
+ }
+
+ /* Stop bit */
+ delay_us(15);
+ data_hi(self);
+
+ /* Ack */
+ if (!wait_data_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKDATA;
+ goto ERROR;
+ }
+ if (!wait_clk_lo(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKCLK;
+ goto ERROR;
+ }
+
+ /* wait for idle state */
+ if (!wait_clk_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKCLK;
+ goto ERROR;
+ }
+ if (!wait_data_hi(self, 50)) {
+ self->last_errors |= ERROR_TX_ACKDATA;
+ goto ERROR;
+ }
+
+ /* Wait for response byte */
+ self->waiting_cmd_response = true;
+ idle(self);
+ resume_interrupt(self);
+
+ for (int i = 0; i < 25; ++i) {
+ delay_us(1000);
+ common_hal_mcu_disable_interrupts();
+ bool has_response = !self->waiting_cmd_response;
+ uint8_t response = self->cmd_response;
+ common_hal_mcu_enable_interrupts();
+
+ if (has_response) {
+ return response;
+ }
+ }
+
+ /* No response */
+ common_hal_mcu_disable_interrupts();
+ self->waiting_cmd_response = false;
+ self->last_errors |= ERROR_TX_NORESP;
+ common_hal_mcu_enable_interrupts();
+ return -1;
+
+ /* Other errors */
+ERROR:
+ idle(self);
+ resume_interrupt(self);
+ return -1;
+}
diff --git a/ports/esp32s2/common-hal/ps2io/Ps2.h b/ports/esp32s2/common-hal/ps2io/Ps2.h
new file mode 100644
index 000000000..497952b25
--- /dev/null
+++ b/ports/esp32s2/common-hal/ps2io/Ps2.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 microDev
+ *
+ * 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_ESP32S2_COMMON_HAL_PS2IO_PS2_H
+#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_PS2IO_PS2_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+#include "driver/gpio.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ gpio_num_t clk_pin;
+ gpio_num_t data_pin;
+
+ uint8_t state;
+ uint64_t last_raw_ticks;
+
+ uint16_t bits;
+ bool parity;
+ uint8_t bitcount;
+
+ uint8_t buffer[16];
+ uint8_t bufcount;
+ uint8_t bufposr;
+ uint8_t bufposw;
+
+ uint16_t last_errors;
+
+ bool waiting_cmd_response;
+ uint8_t cmd_response;
+} ps2io_ps2_obj_t;
+
+void ps2_reset(void);
+
+#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_PS2IO_PS2_H
diff --git a/ports/esp32s2/common-hal/ps2io/__init__.c b/ports/esp32s2/common-hal/ps2io/__init__.c
new file mode 100644
index 000000000..ba4b4249f
--- /dev/null
+++ b/ports/esp32s2/common-hal/ps2io/__init__.c
@@ -0,0 +1 @@
+// No ps2io module functions.
diff --git a/ports/esp32s2/mpconfigport.h b/ports/esp32s2/mpconfigport.h
index cec8dd35d..db7393d8e 100644
--- a/ports/esp32s2/mpconfigport.h
+++ b/ports/esp32s2/mpconfigport.h
@@ -28,7 +28,6 @@
#ifndef ESP32S2_MPCONFIGPORT_H__
#define ESP32S2_MPCONFIGPORT_H__
-#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
#define MICROPY_NLR_THUMB (0)
#define MICROPY_PY_UJSON (1)
@@ -36,11 +35,15 @@
#include "py/circuitpy_mpconfig.h"
-
#define MICROPY_PORT_ROOT_POINTERS \
CIRCUITPY_COMMON_ROOT_POINTERS
#define MICROPY_NLR_SETJMP (1)
#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
+#define CIRCUITPY_INTERNAL_NVM_START_ADDR (0x9000)
+
+#ifndef CIRCUITPY_INTERNAL_NVM_SIZE
+#define CIRCUITPY_INTERNAL_NVM_SIZE (20 * 1024)
+#endif
#endif // __INCLUDED_ESP32S2_MPCONFIGPORT_H
diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk
index 52b9ac286..8ba5b0f99 100644
--- a/ports/esp32s2/mpconfigport.mk
+++ b/ports/esp32s2/mpconfigport.mk
@@ -21,13 +21,17 @@ CIRCUITPY_COUNTIO = 1
CIRCUITPY_FREQUENCYIO = 1
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_ROTARYIO = 1
-CIRCUITPY_NVM = 0
+CIRCUITPY_NVM = 1
# We don't have enough endpoints to include MIDI.
CIRCUITPY_USB_MIDI = 0
CIRCUITPY_WIFI = 1
CIRCUITPY_WATCHDOG ?= 1
CIRCUITPY_ESPIDF = 1
+ifndef CIRCUITPY_PS2IO
+CIRCUITPY_PS2IO = 1
+endif
+
ifndef CIRCUITPY_TOUCHIO_USE_NATIVE
CIRCUITPY_TOUCHIO_USE_NATIVE = 1
endif
diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c
index 71afded5a..aff7dbda4 100644
--- a/ports/esp32s2/supervisor/port.c
+++ b/ports/esp32s2/supervisor/port.c
@@ -41,6 +41,7 @@
#include "common-hal/busio/I2C.h"
#include "common-hal/busio/SPI.h"
#include "common-hal/busio/UART.h"
+#include "common-hal/ps2io/Ps2.h"
#include "common-hal/pulseio/PulseIn.h"
#include "common-hal/pwmio/PWMOut.h"
#include "common-hal/watchdog/WatchDogTimer.h"
@@ -105,6 +106,19 @@ void reset_port(void) {
analogout_reset();
#endif
+#if CIRCUITPY_PS2IO
+ ps2_reset();
+#endif
+
+#if CIRCUITPY_PULSEIO
+ esp32s2_peripherals_rmt_reset();
+ pulsein_reset();
+#endif
+
+#if CIRCUITPY_PWMIO
+ pwmout_reset();
+#endif
+
#if CIRCUITPY_BUSIO
i2c_reset();
spi_reset();
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index 85e152670..28fd4095c 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -184,7 +184,7 @@ typedef long mp_off_t;
// Turning off FULL_BUILD removes some functionality to reduce flash size on tiny SAMD21s
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD)
#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD)
-#define MICROPY_PY_BUILTINS_POW3 (CIRCUITPY_FULL_BUILD)
+#define MICROPY_PY_BUILTINS_POW3 (CIRCUITPY_BUILTINS_POW3)
#define MICROPY_COMP_FSTRING_LITERAL (MICROPY_CPYTHON_COMPAT)
#define MICROPY_MODULE_WEAK_LINKS (0)
#define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD)
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index a6aabec33..08e773718 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -90,6 +90,9 @@ CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO)
CIRCUITPY_BOARD ?= 1
CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
+CIRCUITPY_BUILTINS_POW3 ?= $(CIRCUITPY_FULL_BUILD)
+CFLAGS += -DCIRCUITPY_BUILTINS_POW3=$(CIRCUITPY_BUILTINS_POW3)
+
CIRCUITPY_BUSIO ?= 1
CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO)
diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c
index 0977e08ff..07fa5cebb 100644
--- a/shared-bindings/ps2io/Ps2.c
+++ b/shared-bindings/ps2io/Ps2.c
@@ -116,8 +116,9 @@ STATIC void check_for_deinit(ps2io_ps2_obj_t *self) {
//| ...
//|
STATIC mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) {
- (void)n_args;
- common_hal_ps2io_ps2_deinit(args[0]);
+ mp_check_self(MP_OBJ_IS_TYPE(args[0], &ps2io_ps2_type));
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+ common_hal_ps2io_ps2_deinit(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ps2io_ps2___exit___obj, 4, 4, ps2io_ps2_obj___exit__);