summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf.py1
-rw-r--r--ports/atmel-samd/Makefile25
-rw-r--r--ports/atmel-samd/audio_dma.c6
-rw-r--r--ports/atmel-samd/bindings/samd/Clock.c3
-rw-r--r--ports/atmel-samd/board_busses.c6
-rw-r--r--ports/atmel-samd/boards/arduino_zero/pins.c2
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/board.c1
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/pins.c3
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/board.c1
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c3
-rw-r--r--ports/atmel-samd/boards/feather_m0_adalogger/pins.c3
-rw-r--r--ports/atmel-samd/boards/feather_m0_basic/pins.c3
-rw-r--r--ports/atmel-samd/boards/feather_m0_express/pins.c3
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm69/pins.c3
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm9x/pins.c3
-rw-r--r--ports/atmel-samd/boards/feather_m0_supersized/pins.c3
-rw-r--r--ports/atmel-samd/boards/feather_m4_express/pins.c3
-rw-r--r--ports/atmel-samd/boards/gemma_m0/pins.c3
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m0_express/pins.c3
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m4_express/pins.c3
-rw-r--r--ports/atmel-samd/boards/metro_m0_express/pins.c3
-rw-r--r--ports/atmel-samd/boards/metro_m4_express/pins.c3
-rw-r--r--ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.h72
-rw-r--r--ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.mk11
-rw-r--r--ports/atmel-samd/boards/metro_m4_express_revb/pins.c48
-rw-r--r--ports/atmel-samd/boards/pirkey_m0/pins.c3
-rw-r--r--ports/atmel-samd/boards/trinket_m0/pins.c3
-rw-r--r--ports/atmel-samd/boards/trinket_m0_haxpress/pins.c3
-rw-r--r--ports/atmel-samd/boards/ugame10/pins.c3
-rw-r--r--ports/atmel-samd/common-hal/analogio/AnalogIn.c2
-rw-r--r--ports/atmel-samd/common-hal/analogio/AnalogOut.c6
-rw-r--r--ports/atmel-samd/common-hal/audiobusio/I2SOut.c13
-rw-r--r--ports/atmel-samd/common-hal/audiobusio/PDMIn.c11
-rw-r--r--ports/atmel-samd/common-hal/audioio/AudioOut.c9
-rw-r--r--ports/atmel-samd/common-hal/busio/I2C.c3
-rw-r--r--ports/atmel-samd/common-hal/busio/SPI.c6
-rw-r--r--ports/atmel-samd/common-hal/busio/UART.c3
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.c7
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.h2
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Processor.c2
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/__init__.c2
-rw-r--r--ports/atmel-samd/common-hal/pulseio/PWMOut.c4
-rw-r--r--ports/atmel-samd/common-hal/pulseio/PulseIn.c4
-rw-r--r--ports/atmel-samd/common-hal/pulseio/PulseOut.c4
-rw-r--r--ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c158
-rw-r--r--ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h40
-rw-r--r--ports/atmel-samd/common-hal/rotaryio/__init__.c1
-rw-r--r--ports/atmel-samd/common-hal/touchio/TouchIn.c6
-rw-r--r--ports/atmel-samd/external_flash/external_flash.c4
-rw-r--r--ports/atmel-samd/external_flash/qspi_flash.c4
-rw-r--r--ports/atmel-samd/external_flash/spi_flash.c4
-rw-r--r--ports/atmel-samd/mpconfigport.h4
-rw-r--r--ports/atmel-samd/peripherals/adc.h (renamed from ports/atmel-samd/samd21_peripherals.h)9
-rw-r--r--ports/atmel-samd/peripherals/cache.h (renamed from ports/atmel-samd/samd51_peripherals.h)8
-rw-r--r--ports/atmel-samd/peripherals/clocks.c (renamed from ports/atmel-samd/clocks.c)0
-rw-r--r--ports/atmel-samd/peripherals/clocks.h (renamed from ports/atmel-samd/clocks.h)0
-rw-r--r--ports/atmel-samd/peripherals/dma.c (renamed from ports/atmel-samd/shared_dma.c)164
-rw-r--r--ports/atmel-samd/peripherals/dma.h (renamed from ports/atmel-samd/shared_dma.h)9
-rw-r--r--ports/atmel-samd/peripherals/events.c62
-rw-r--r--ports/atmel-samd/peripherals/events.h (renamed from ports/atmel-samd/events.h)2
-rw-r--r--ports/atmel-samd/peripherals/i2s.c46
-rw-r--r--ports/atmel-samd/peripherals/i2s.h (renamed from ports/atmel-samd/i2s.h)0
-rw-r--r--ports/atmel-samd/peripherals/pins.h42
-rw-r--r--ports/atmel-samd/peripherals/samd21/adc.c47
-rw-r--r--ports/atmel-samd/peripherals/samd21/cache.c (renamed from ports/atmel-samd/pins.h)19
-rw-r--r--ports/atmel-samd/peripherals/samd21/clocks.c (renamed from ports/atmel-samd/samd21_clocks.c)2
-rw-r--r--ports/atmel-samd/peripherals/samd21/dma.c118
-rw-r--r--ports/atmel-samd/peripherals/samd21/events.c (renamed from ports/atmel-samd/events.c)107
-rw-r--r--ports/atmel-samd/peripherals/samd21/i2s.c (renamed from ports/atmel-samd/boards/metro_m4_express_revb/board.c)30
-rw-r--r--ports/atmel-samd/peripherals/samd21/pins.c (renamed from ports/atmel-samd/samd21_pins.c)2
-rw-r--r--ports/atmel-samd/peripherals/samd21/pins.h (renamed from ports/atmel-samd/samd21_pins.h)11
-rw-r--r--ports/atmel-samd/peripherals/samd21/sercom.c (renamed from ports/atmel-samd/samd21_peripherals.c)20
-rw-r--r--ports/atmel-samd/peripherals/samd21/timers.c75
-rw-r--r--ports/atmel-samd/peripherals/samd51/adc.c61
-rw-r--r--ports/atmel-samd/peripherals/samd51/cache.c39
-rw-r--r--ports/atmel-samd/peripherals/samd51/clocks.c (renamed from ports/atmel-samd/samd51_clocks.c)2
-rw-r--r--ports/atmel-samd/peripherals/samd51/dma.c94
-rw-r--r--ports/atmel-samd/peripherals/samd51/events.c88
-rw-r--r--ports/atmel-samd/peripherals/samd51/i2s.c (renamed from ports/atmel-samd/i2s.c)36
-rw-r--r--ports/atmel-samd/peripherals/samd51/pins.c (renamed from ports/atmel-samd/samd51_pins.c)2
-rw-r--r--ports/atmel-samd/peripherals/samd51/pins.h (renamed from ports/atmel-samd/samd51_pins.h)5
-rw-r--r--ports/atmel-samd/peripherals/samd51/sercom.c (renamed from ports/atmel-samd/samd51_peripherals.c)46
-rw-r--r--ports/atmel-samd/peripherals/samd51/timers.c (renamed from ports/atmel-samd/timers.c)166
-rw-r--r--ports/atmel-samd/peripherals/sercom.c (renamed from ports/atmel-samd/peripherals.c)2
-rw-r--r--ports/atmel-samd/peripherals/sercom.h (renamed from ports/atmel-samd/peripherals.h)17
-rw-r--r--ports/atmel-samd/peripherals/timers.c147
-rw-r--r--ports/atmel-samd/peripherals/timers.h (renamed from ports/atmel-samd/timers.h)0
-rw-r--r--ports/atmel-samd/supervisor/port.c8
-rw-r--r--shared-bindings/board/__init__.h2
-rw-r--r--shared-bindings/rotaryio/IncrementalEncoder.c159
-rw-r--r--shared-bindings/rotaryio/IncrementalEncoder.h41
-rw-r--r--shared-bindings/rotaryio/__init__.c75
-rw-r--r--shared-bindings/rotaryio/__init__.h34
-rw-r--r--supervisor/shared/rgb_led_status.c1
94 files changed, 1504 insertions, 823 deletions
diff --git a/conf.py b/conf.py
index eb4b1490f..03d100f12 100644
--- a/conf.py
+++ b/conf.py
@@ -101,6 +101,7 @@ exclude_patterns = ["**/build*",
"ports/atmel-samd/asf4_conf",
"ports/atmel-samd/external_flash",
"ports/atmel-samd/freetouch",
+ "ports/atmel-samd/peripherals",
"ports/atmel-samd/QTouch",
"ports/atmel-samd/tools",
"ports/bare-arm",
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index d627e7641..162e6b3e6 100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -242,19 +242,24 @@ SRC_C = \
audio_dma.c \
board_busses.c \
background.c \
- clocks.c \
- $(CHIP_FAMILY)_clocks.c \
- events.c \
fatfs_port.c \
flash_api.c \
mphalport.c \
reset.c \
- $(CHIP_FAMILY)_peripherals.c \
- peripherals.c \
- $(CHIP_FAMILY)_pins.c \
- shared_dma.c \
+ peripherals/clocks.c \
+ peripherals/dma.c \
+ peripherals/events.c \
+ peripherals/sercom.c \
+ peripherals/timers.c \
+ peripherals/$(CHIP_FAMILY)/adc.c \
+ peripherals/$(CHIP_FAMILY)/cache.c \
+ peripherals/$(CHIP_FAMILY)/clocks.c \
+ peripherals/$(CHIP_FAMILY)/dma.c \
+ peripherals/$(CHIP_FAMILY)/events.c \
+ peripherals/$(CHIP_FAMILY)/pins.c \
+ peripherals/$(CHIP_FAMILY)/sercom.c \
+ peripherals/$(CHIP_FAMILY)/timers.c \
tick.c \
- timers.c \
usb.c \
usb_mass_storage.c \
bindings/samd/__init__.c \
@@ -301,6 +306,8 @@ SRC_COMMON_HAL = \
microcontroller/Processor.c \
neopixel_write/__init__.c \
os/__init__.c \
+ rotaryio/__init__.c \
+ rotaryio/IncrementalEncoder.c \
rtc/__init__.c \
rtc/RTC.c \
storage/__init__.c \
@@ -391,7 +398,7 @@ ifneq ($(CHIP_VARIANT),SAMD51G18A)
audiobusio/__init__.c \
audiobusio/I2SOut.c \
audiobusio/PDMIn.c
- SRC_C += i2s.c
+ SRC_C += peripherals/i2s.c peripherals/$(CHIP_FAMILY)/i2s.c
endif
endif
diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c
index e8dbdc61d..5a572e9d1 100644
--- a/ports/atmel-samd/audio_dma.c
+++ b/ports/atmel-samd/audio_dma.c
@@ -25,9 +25,9 @@
*/
#include "audio_dma.h"
-#include "clocks.h"
-#include "events.h"
-#include "shared_dma.h"
+#include "peripherals/clocks.h"
+#include "peripherals/events.h"
+#include "peripherals/dma.h"
#include "shared-bindings/audioio/RawSample.h"
#include "shared-bindings/audioio/WaveFile.h"
diff --git a/ports/atmel-samd/bindings/samd/Clock.c b/ports/atmel-samd/bindings/samd/Clock.c
index 81e8fb1ce..3c87177a4 100644
--- a/ports/atmel-samd/bindings/samd/Clock.c
+++ b/ports/atmel-samd/bindings/samd/Clock.c
@@ -24,9 +24,8 @@
* THE SOFTWARE.
*/
-#include "clocks.h"
#include "bindings/samd/Clock.h"
-
+#include "peripherals/clocks.h"
#include "py/obj.h"
#include "py/objproperty.h"
#include "py/runtime.h"
diff --git a/ports/atmel-samd/board_busses.c b/ports/atmel-samd/board_busses.c
index 02d08133c..008391bf0 100644
--- a/ports/atmel-samd/board_busses.c
+++ b/ports/atmel-samd/board_busses.c
@@ -30,11 +30,9 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "mpconfigboard.h"
-#include "pins.h"
+#include "peripherals/pins.h"
#include "py/runtime.h"
-
-
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
STATIC mp_obj_t board_i2c(void) {
mp_raise_NotImplementedError("No default I2C bus");
@@ -112,4 +110,4 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
return uart_singleton;
}
#endif
-MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart); \ No newline at end of file
+MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart);
diff --git a/ports/atmel-samd/boards/arduino_zero/pins.c b/ports/atmel-samd/boards/arduino_zero/pins.c
index 4fa417b37..8a7ff70e6 100644
--- a/ports/atmel-samd/boards/arduino_zero/pins.c
+++ b/ports/atmel-samd/boards/arduino_zero/pins.c
@@ -1,9 +1,7 @@
#include "shared-bindings/board/__init__.h"
-#include "samd21_pins.h"
#include "board_busses.h"
-
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) },
diff --git a/ports/atmel-samd/boards/circuitplayground_express/board.c b/ports/atmel-samd/boards/circuitplayground_express/board.c
index eb7ffab4a..5c5e9f7fa 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/board.c
+++ b/ports/atmel-samd/boards/circuitplayground_express/board.c
@@ -31,7 +31,6 @@
#include "hal/include/hal_gpio.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/neopixel_write/__init__.h"
-#include "samd21_pins.h"
void board_init(void)
{
diff --git a/ports/atmel-samd/boards/circuitplayground_express/pins.c b/ports/atmel-samd/boards/circuitplayground_express/pins.c
index f4540573a..14ae89c55 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/pins.c
+++ b/ports/atmel-samd/boards/circuitplayground_express/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c
index eb7ffab4a..5c5e9f7fa 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c
@@ -31,7 +31,6 @@
#include "hal/include/hal_gpio.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/neopixel_write/__init__.h"
-#include "samd21_pins.h"
void board_init(void)
{
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c
index f4540573a..14ae89c55 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c
index 7eff106e8..0754617dd 100644
--- a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c
+++ b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/feather_m0_basic/pins.c b/ports/atmel-samd/boards/feather_m0_basic/pins.c
index b3edabe81..4486d27ab 100644
--- a/ports/atmel-samd/boards/feather_m0_basic/pins.c
+++ b/ports/atmel-samd/boards/feather_m0_basic/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/feather_m0_express/pins.c b/ports/atmel-samd/boards/feather_m0_express/pins.c
index 6bd74f372..68666c273 100644
--- a/ports/atmel-samd/boards/feather_m0_express/pins.c
+++ b/ports/atmel-samd/boards/feather_m0_express/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c
index e6cede3dd..6055f8a1b 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c
+++ b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c
index 8f52a5767..7395c6e2f 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c
+++ b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/feather_m0_supersized/pins.c b/ports/atmel-samd/boards/feather_m0_supersized/pins.c
index 6bd74f372..68666c273 100644
--- a/ports/atmel-samd/boards/feather_m0_supersized/pins.c
+++ b/ports/atmel-samd/boards/feather_m0_supersized/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/feather_m4_express/pins.c b/ports/atmel-samd/boards/feather_m4_express/pins.c
index bc3cb1f47..5767f63fa 100644
--- a/ports/atmel-samd/boards/feather_m4_express/pins.c
+++ b/ports/atmel-samd/boards/feather_m4_express/pins.c
@@ -1,4 +1,5 @@
-#include "samd51_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/gemma_m0/pins.c b/ports/atmel-samd/boards/gemma_m0/pins.c
index 6d031c685..196e438e0 100644
--- a/ports/atmel-samd/boards/gemma_m0/pins.c
+++ b/ports/atmel-samd/boards/gemma_m0/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c
index 2b35c91aa..25407bc14 100644
--- a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c
+++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c
index fdcf039e6..3997ecda4 100644
--- a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c
+++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c
@@ -1,4 +1,5 @@
-#include "samd51_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
// This mapping only includes functional names because pins broken
diff --git a/ports/atmel-samd/boards/metro_m0_express/pins.c b/ports/atmel-samd/boards/metro_m0_express/pins.c
index 4cd8752be..13f0eb0ba 100644
--- a/ports/atmel-samd/boards/metro_m0_express/pins.c
+++ b/ports/atmel-samd/boards/metro_m0_express/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c
index 8dc0f25d6..0e66817f7 100644
--- a/ports/atmel-samd/boards/metro_m4_express/pins.c
+++ b/ports/atmel-samd/boards/metro_m4_express/pins.c
@@ -1,4 +1,5 @@
-#include "samd51_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
// This mapping only includes functional names because pins broken
diff --git a/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.h
deleted file mode 100644
index db51140d6..000000000
--- a/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// This is for Rev B which a larger run was done and sent to Adafruit community
-// members.
-
-#define MICROPY_HW_BOARD_NAME "Metro M4 Express Rev B (Black)"
-#define MICROPY_HW_MCU_NAME "samd51j19"
-
-#define CIRCUITPY_MCU_FAMILY samd51
-
-#define MICROPY_HW_LED_TX PIN_PA27
-#define MICROPY_HW_LED_RX PIN_PB06
-
-#define MICROPY_HW_NEOPIXEL (&pin_PB17)
-
-#define SPI_FLASH_BAUDRATE (60000000)
-
-// Rev B: single channel SPI
-// Rev C will be QSPI
-#define SPI_FLASH_MOSI_PIN PIN_PB08
-#define SPI_FLASH_MISO_PIN PIN_PB11
-#define SPI_FLASH_SCK_PIN PIN_PB09
-#define SPI_FLASH_CS_PIN PIN_PB10
-#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB08D_SERCOM4_PAD0
-#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PB11D_SERCOM4_PAD3
-#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB09D_SERCOM4_PAD1
-#define SPI_FLASH_SERCOM SERCOM4
-#define SPI_FLASH_SERCOM_INDEX 4
-#define SPI_FLASH_MOSI_PAD 0
-#define SPI_FLASH_MISO_PAD 3
-#define SPI_FLASH_SCK_PAD 1
-// <o> Transmit Data Pinout
-// <0x0=>PAD[0,1]_DO_SCK
-// <0x1=>PAD[2,3]_DO_SCK
-// <0x2=>PAD[3,1]_DO_SCK
-// <0x3=>PAD[0,3]_DO_SCK
-#define SPI_FLASH_DOPO 0
-#define SPI_FLASH_DIPO 3 // same as MISO pad
-
-// These are pins not to reset.
-// Pin for TX LED
-#define MICROPY_PORT_A (PORT_PA27)
-// Pins for RX LED, SPI flash and neopixel
-#define MICROPY_PORT_B (PORT_PB06 | PORT_PB08 | PORT_PB09 | PORT_PB10 | PORT_PB11 | PORT_PB17)
-#define MICROPY_PORT_C (0)
-#define MICROPY_PORT_D (0)
-
-#define AUTORESET_DELAY_MS 500
-
-#include "external_flash/external_flash.h"
-
-// If you change this, then make sure to update the linker scripts as well to
-// make sure you don't overwrite code
-#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
-
-#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
-
-#include "external_flash/devices.h"
-
-#define EXTERNAL_FLASH_DEVICE_COUNT 2
-#define EXTERNAL_FLASH_DEVICES S25FL216K, \
- GD25Q16C
-
-#include "external_flash/external_flash.h"
-
-#define DEFAULT_I2C_BUS_SCL (&pin_PB03)
-#define DEFAULT_I2C_BUS_SDA (&pin_PB02)
-
-#define DEFAULT_SPI_BUS_SCK (&pin_PA13)
-#define DEFAULT_SPI_BUS_MOSI (&pin_PA12)
-#define DEFAULT_SPI_BUS_MISO (&pin_PA15)
-
-#define DEFAULT_UART_BUS_RX (&pin_PA23)
-#define DEFAULT_UART_BUS_TX (&pin_PA22)
diff --git a/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.mk
deleted file mode 100644
index 9e6965063..000000000
--- a/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-LD_FILE = boards/samd51x19-bootloader-external-flash.ld
-USB_VID = 0x239A
-USB_PID = 0x8021
-USB_PRODUCT = "Metro M4 Express Rev B (Black)"
-USB_MANUFACTURER = "Adafruit Industries LLC"
-
-SPI_FLASH_FILESYSTEM = 1
-LONGINT_IMPL = MPZ
-
-CHIP_VARIANT = SAMD51J19A
-CHIP_FAMILY = samd51
diff --git a/ports/atmel-samd/boards/metro_m4_express_revb/pins.c b/ports/atmel-samd/boards/metro_m4_express_revb/pins.c
deleted file mode 100644
index 23e662f1c..000000000
--- a/ports/atmel-samd/boards/metro_m4_express_revb/pins.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "samd51_pins.h"
-#include "board_busses.h"
-
-// This mapping only includes functional names because pins broken
-// out on connectors are labeled with their MCU name available from
-// microcontroller.pin.
-STATIC const mp_map_elem_t board_global_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PA05 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PA06 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PA04 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PA11 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PA07 },
-
-
- { MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PA23 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PA23 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PA22 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PA22 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PA08 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PA10 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB12 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PB14 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D6), (mp_obj_t)&pin_PB15 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PA14 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA16 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA17 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D10), (mp_obj_t)&pin_PA18 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D11), (mp_obj_t)&pin_PA19 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA20 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA21 },
-
- { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 },
-
- { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB17 },
-
- { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA15 },
-
- { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PB06 },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PA27 },
- { 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_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
-};
-MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/atmel-samd/boards/pirkey_m0/pins.c b/ports/atmel-samd/boards/pirkey_m0/pins.c
index 7efc8eb33..e08302f14 100644
--- a/ports/atmel-samd/boards/pirkey_m0/pins.c
+++ b/ports/atmel-samd/boards/pirkey_m0/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/trinket_m0/pins.c b/ports/atmel-samd/boards/trinket_m0/pins.c
index 0fdcbc279..633017024 100644
--- a/ports/atmel-samd/boards/trinket_m0/pins.c
+++ b/ports/atmel-samd/boards/trinket_m0/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c
index 0fdcbc279..633017024 100644
--- a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c
+++ b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/boards/ugame10/pins.c b/ports/atmel-samd/boards/ugame10/pins.c
index acf73c9ff..87ace5e96 100644
--- a/ports/atmel-samd/boards/ugame10/pins.c
+++ b/ports/atmel-samd/boards/ugame10/pins.c
@@ -1,4 +1,5 @@
-#include "samd21_pins.h"
+#include "shared-bindings/board/__init__.h"
+
#include "board_busses.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
diff --git a/ports/atmel-samd/common-hal/analogio/AnalogIn.c b/ports/atmel-samd/common-hal/analogio/AnalogIn.c
index 02613ae07..e452eb030 100644
--- a/ports/atmel-samd/common-hal/analogio/AnalogIn.c
+++ b/ports/atmel-samd/common-hal/analogio/AnalogIn.c
@@ -34,7 +34,7 @@
#include "py/binary.h"
#include "py/mphal.h"
-#include "peripherals.h"
+#include "peripherals/adc.h"
#include "shared-bindings/analogio/AnalogIn.h"
#include "atmel_start_pins.h"
diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c
index 97299a863..9ceca3868 100644
--- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c
+++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c
@@ -42,10 +42,6 @@
#include "hpl/pm/hpl_pm_base.h"
#endif
-#ifdef SAMD51
-#include "samd51_pins.h"
-#endif
-
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
const mcu_pin_obj_t *pin) {
if (pin->pin != PIN_PA02
@@ -73,7 +69,7 @@ void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
#endif
// SAMD21: This clock should be <= 12 MHz, per datasheet section 47.6.3.
- // SAMD51: This clock should be <= 350kHz, per datasheet table 37-6.
+ // SAMD51: This clock should be <= 350kHz, per datasheet table 37-6.
_gclk_enable_channel(DAC_GCLK_ID, CONF_GCLK_DAC_SRC);
// Don't double init the DAC on the SAMD51 when both outputs are in use. We use the free state
diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c
index f4a8eb52e..27a7b9ee0 100644
--- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c
+++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c
@@ -45,13 +45,14 @@
#include "hpl/pm/hpl_pm_base.h"
#endif
+#include "peripherals/clocks.h"
+#include "peripherals/dma.h"
+#include "peripherals/events.h"
+#include "peripherals/i2s.h"
+#include "peripherals/pins.h"
+#include "peripherals/timers.h"
+
#include "audio_dma.h"
-#include "clocks.h"
-#include "events.h"
-#include "i2s.h"
-#include "pins.h"
-#include "shared_dma.h"
-#include "timers.h"
#ifdef SAMD21
#define SERCTRL(name) I2S_SERCTRL_ ## name
diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
index 44129eed1..5502fcd81 100644
--- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
+++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c
@@ -41,12 +41,13 @@
#include "hal/include/hal_gpio.h"
#include "hal/utils/include/utils.h"
+#include "peripherals/clocks.h"
+#include "peripherals/events.h"
+#include "peripherals/i2s.h"
+#include "peripherals/pins.h"
+#include "peripherals/dma.h"
+
#include "audio_dma.h"
-#include "clocks.h"
-#include "events.h"
-#include "i2s.h"
-#include "pins.h"
-#include "shared_dma.h"
#include "tick.h"
#define OVERSAMPLING 64
diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c
index 331ae9c9b..fc5c75673 100644
--- a/ports/atmel-samd/common-hal/audioio/AudioOut.c
+++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c
@@ -45,10 +45,11 @@
#endif
#include "audio_dma.h"
-#include "events.h"
-#include "samd21_pins.h"
-#include "shared_dma.h"
-#include "timers.h"
+
+#include "peripherals/dma.h"
+#include "peripherals/events.h"
+#include "peripherals/pins.h"
+#include "peripherals/timers.h"
void audioout_reset(void) {
}
diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c
index 347a2e349..66929beff 100644
--- a/ports/atmel-samd/common-hal/busio/I2C.c
+++ b/ports/atmel-samd/common-hal/busio/I2C.c
@@ -32,8 +32,7 @@
#include "hal/include/hal_i2c_m_sync.h"
#include "hal/include/hpl_i2c_m_sync.h"
-#include "peripherals.h"
-#include "pins.h"
+#include "peripherals/sercom.h"
#include "shared-bindings/microcontroller/__init__.h"
diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c
index a2bf30f05..a2ee93c6d 100644
--- a/ports/atmel-samd/common-hal/busio/SPI.c
+++ b/ports/atmel-samd/common-hal/busio/SPI.c
@@ -36,9 +36,9 @@
#include "hal/include/hpl_spi_m_sync.h"
#include "supervisor/shared/rgb_led_status.h"
-#include "peripherals.h"
-#include "pins.h"
-#include "shared_dma.h"
+#include "peripherals/dma.h"
+//#include "peripherals/pins.h"
+#include "peripherals/sercom.h"
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c
index 537677520..a95ccf3ac 100644
--- a/ports/atmel-samd/common-hal/busio/UART.c
+++ b/ports/atmel-samd/common-hal/busio/UART.c
@@ -42,8 +42,7 @@
#include "hal/include/hal_usart_async.h"
#include "hal/include/hpl_usart_async.h"
-#include "peripherals.h"
-#include "pins.h"
+#include "peripherals/sercom.h"
// Do-nothing callback needed so that usart_async code will enable rx interrupts.
// See comment below re usart_async_register_callback()
diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c
index e1ca5d622..ad97581e1 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Pin.c
+++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c
@@ -29,13 +29,8 @@
#include "atmel_start_pins.h"
#include "hal/include/hal_gpio.h"
+#include "peripherals/pins.h"
#include "supervisor/shared/rgb_led_status.h"
-#ifdef SAMD21
-#include "samd21_pins.h"
-#endif
-#ifdef SAMD51
-#include "samd51_pins.h"
-#endif
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h
index 4e21a14cd..4230246a5 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Pin.h
+++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h
@@ -81,4 +81,6 @@ void reset_all_pins(void);
void reset_pin(uint8_t pin);
void claim_pin(const mcu_pin_obj_t* pin);
+#include "peripherals/pins.h"
+
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H
diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.c b/ports/atmel-samd/common-hal/microcontroller/Processor.c
index e7f758cd1..a76ee2e78 100644
--- a/ports/atmel-samd/common-hal/microcontroller/Processor.c
+++ b/ports/atmel-samd/common-hal/microcontroller/Processor.c
@@ -63,7 +63,7 @@
#include "common-hal/microcontroller/Processor.h"
-#include "peripherals.h"
+#include "peripherals/adc.h"
#include "peripheral_clk_config.h"
diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c
index a9c83646f..fa057faca 100644
--- a/ports/atmel-samd/common-hal/microcontroller/__init__.c
+++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c
@@ -30,10 +30,10 @@
#include "py/runtime.h"
#include "reset.h"
-#include "samd21_pins.h"
#include "shared-bindings/nvm/ByteArray.h"
#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/Processor.h"
void common_hal_mcu_delay_us(uint32_t delay) {
diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c
index 24cd154c2..18d896686 100644
--- a/ports/atmel-samd/common-hal/pulseio/PWMOut.c
+++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c
@@ -34,9 +34,9 @@
#include "atmel_start_pins.h"
#include "hal/utils/include/utils_repeat_macro.h"
-#include "timers.h"
+#include "peripherals/timers.h"
-#include "samd21_pins.h"
+#include "peripherals/pins.h"
#undef ENABLE
diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c
index 6e3aa3abb..266a9251e 100644
--- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c
+++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2017-2018 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
@@ -34,7 +34,7 @@
#include "mpconfigport.h"
#include "py/gc.h"
#include "py/runtime.h"
-#include "samd21_pins.h"
+#include "peripherals/pins.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/pulseio/PulseIn.h"
diff --git a/ports/atmel-samd/common-hal/pulseio/PulseOut.c b/ports/atmel-samd/common-hal/pulseio/PulseOut.c
index 95b0bbee0..8e715d410 100644
--- a/ports/atmel-samd/common-hal/pulseio/PulseOut.c
+++ b/ports/atmel-samd/common-hal/pulseio/PulseOut.c
@@ -31,11 +31,11 @@
#include "hal/include/hal_gpio.h"
#include "mpconfigport.h"
+#include "peripherals/pins.h"
+#include "peripherals/timers.h"
#include "py/gc.h"
#include "py/runtime.h"
-#include "samd21_pins.h"
#include "shared-bindings/pulseio/PulseOut.h"
-#include "timers.h"
// This timer is shared amongst all PulseOut objects under the assumption that
// the code is single threaded.
diff --git a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
new file mode 100644
index 000000000..58119fa7e
--- /dev/null
+++ b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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/rotaryio/IncrementalEncoder.h"
+
+#include <stdint.h>
+
+#include "atmel_start_pins.h"
+#include "hal/include/hal_gpio.h"
+
+#include "mpconfigport.h"
+#include "peripherals/pins.h"
+#include "py/gc.h"
+#include "py/runtime.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
+#ifdef SAMD21
+#include "hpl/gclk/hpl_gclk_base.h"
+#endif
+
+void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self,
+ const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
+// if (!pin->has_extint) {
+// mp_raise_RuntimeError("No hardware support on pin");
+// }
+// uint32_t mask = 1 << pin->extint_channel;
+// if (active_incrementalencoders[pin->extint_channel] != NULL ||
+// (eic_get_enable() == 1 &&
+// #ifdef SAMD51
+// ((EIC->INTENSET.bit.EXTINT & mask) != 0 ||
+// (EIC->EVCTRL.bit.EXTINTEO & mask) != 0))) {
+// #endif
+// #ifdef SAMD21
+// ((EIC->INTENSET.vec.EXTINT & mask) != 0 ||
+// (EIC->EVCTRL.vec.EXTINTEO & mask) != 0))) {
+// #endif
+// mp_raise_RuntimeError("EXTINT channel already in use");
+// }
+//
+// self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false);
+// if (self->buffer == NULL) {
+// mp_raise_msg_varg(&mp_type_MemoryError, "Failed to allocate RX buffer of %d bytes", maxlen * sizeof(uint16_t));
+// }
+// self->channel = pin->extint_channel;
+// self->pin = pin->pin;
+// self->maxlen = maxlen;
+// self->idle_state = idle_state;
+// self->start = 0;
+// self->len = 0;
+// self->first_edge = true;
+//
+// active_incrementalencoders[pin->extint_channel] = self;
+//
+// // Check to see if the EIC is enabled and start it up if its not.'
+// // SAMD51 EIC can only be clocked up to 100mhz so we use the 48mhz clock.
+// if (eic_get_enable() == 0) {
+// #ifdef SAMD51
+// MCLK->APBAMASK.bit.EIC_ = true;
+// hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID,
+// GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
+// #endif
+//
+// #ifdef SAMD21
+// PM->APBAMASK.bit.EIC_ = true;
+// _gclk_enable_channel(EIC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
+// #endif
+//
+//
+// #ifdef SAMD21
+// NVIC_DisableIRQ(EIC_IRQn);
+// NVIC_ClearPendingIRQ(EIC_IRQn);
+// NVIC_EnableIRQ(EIC_IRQn);
+// #endif
+// }
+//
+// gpio_set_pin_function(pin->pin, GPIO_PIN_FUNCTION_A);
+//
+// #ifdef SAMD51
+// NVIC_DisableIRQ(EIC_0_IRQn + self->channel);
+// NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel);
+// NVIC_EnableIRQ(EIC_0_IRQn + self->channel);
+// #endif
+//
+// // Set config will enable the EIC.
+// incrementalencoder_set_config(self, true);
+// EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos;
+}
+
+bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t* self) {
+ //return self->pin == NO_PIN;
+ return true;
+}
+
+void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t* self) {
+ // if (common_hal_rotaryio_incrementalencoder_deinited(self)) {
+ // return;
+ // }
+ // uint32_t mask = 1 << self->channel;
+ // EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos;
+ // #ifdef SAMD51
+ // NVIC_DisableIRQ(EIC_0_IRQn + self->channel);
+ // NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel);
+ // #endif
+ // active_incrementalencoders[self->channel] = NULL;
+ // reset_pin(self->pin);
+ // self->pin = NO_PIN;
+ //
+ // bool all_null = true;
+ // for (uint8_t i = 0; all_null && i < 16; i++) {
+ // all_null = all_null && active_incrementalencoders[i] == NULL;
+ // }
+ // #ifdef SAMD21
+ // if (all_null && EIC->INTENSET.reg == 0) {
+ // NVIC_DisableIRQ(EIC_IRQn);
+ // NVIC_ClearPendingIRQ(EIC_IRQn);
+ // }
+ // #endif
+ // // Test if all channels are null and deinit everything if they are.
+ // if (all_null && EIC->EVCTRL.reg == 0 && EIC->INTENSET.reg == 0) {
+ // eic_set_enable(false);
+ // #ifdef SAMD51
+ // MCLK->APBAMASK.bit.EIC_ = false;
+ // hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID, 0);
+ // #endif
+ //
+ // #ifdef SAMD21
+ // PM->APBAMASK.bit.EIC_ = false;
+ // hri_gclk_write_CLKCTRL_reg(GCLK, GCLK_CLKCTRL_ID(EIC_GCLK_ID));
+ // #endif
+ // }
+}
+
+mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t* self) {
+ return 0;
+}
diff --git a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h
new file mode 100644
index 000000000..c878239bc
--- /dev/null
+++ b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t pin_a;
+ uint8_t pin_b;
+} rotaryio_incrementalencoder_obj_t;
+
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H
diff --git a/ports/atmel-samd/common-hal/rotaryio/__init__.c b/ports/atmel-samd/common-hal/rotaryio/__init__.c
new file mode 100644
index 000000000..2bee925bc
--- /dev/null
+++ b/ports/atmel-samd/common-hal/rotaryio/__init__.c
@@ -0,0 +1 @@
+// No pulseio module functions.
diff --git a/ports/atmel-samd/common-hal/touchio/TouchIn.c b/ports/atmel-samd/common-hal/touchio/TouchIn.c
index eda1b72c4..e39a091d7 100644
--- a/ports/atmel-samd/common-hal/touchio/TouchIn.c
+++ b/ports/atmel-samd/common-hal/touchio/TouchIn.c
@@ -37,10 +37,10 @@
#include "hpl/pm/hpl_pm_base.h"
#endif
-#include "clocks.h"
-#include "samd21_pins.h"
-#include "tick.h"
+#include "peripherals/clocks.h"
+#include "peripherals/pins.h"
+#include "tick.h"
#include "adafruit_ptc.h"
bool touch_enabled = false;
diff --git a/ports/atmel-samd/external_flash/external_flash.c b/ports/atmel-samd/external_flash/external_flash.c
index ccc47e5b1..b0e40fc70 100644
--- a/ports/atmel-samd/external_flash/external_flash.c
+++ b/ports/atmel-samd/external_flash/external_flash.c
@@ -36,12 +36,10 @@
#include "py/obj.h"
#include "py/runtime.h"
#include "lib/oofatfs/ff.h"
-#include "peripherals.h"
+//#include "peripherals.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "supervisor/shared/rgb_led_status.h"
-//#include "shared_dma.h"
-
#include "hal_gpio.h"
#include "hal_spi_m_sync.h"
diff --git a/ports/atmel-samd/external_flash/qspi_flash.c b/ports/atmel-samd/external_flash/qspi_flash.c
index 3fc9d31be..ec91c21e2 100644
--- a/ports/atmel-samd/external_flash/qspi_flash.c
+++ b/ports/atmel-samd/external_flash/qspi_flash.c
@@ -32,8 +32,8 @@
#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
#include "external_flash/common_commands.h"
-#include "peripherals.h"
-#include "shared_dma.h"
+#include "peripherals/cache.h"
+#include "peripherals/dma.h"
#include "atmel_start_pins.h"
#include "hal_gpio.h"
diff --git a/ports/atmel-samd/external_flash/spi_flash.c b/ports/atmel-samd/external_flash/spi_flash.c
index 8a8cbaef8..faad8d9e0 100644
--- a/ports/atmel-samd/external_flash/spi_flash.c
+++ b/ports/atmel-samd/external_flash/spi_flash.c
@@ -29,8 +29,8 @@
#include <string.h>
#include "external_flash/common_commands.h"
-#include "peripherals.h"
-#include "shared_dma.h"
+#include "peripherals/sercom.h"
+#include "py/mpconfig.h"
#include "hal_gpio.h"
#include "hal_spi_m_sync.h"
diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h
index cd05927b0..ee75a26c5 100644
--- a/ports/atmel-samd/mpconfigport.h
+++ b/ports/atmel-samd/mpconfigport.h
@@ -174,6 +174,7 @@ extern const struct _mp_obj_module_t board_module;
extern const struct _mp_obj_module_t math_module;
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t random_module;
+extern const struct _mp_obj_module_t rotaryio_module;
extern const struct _mp_obj_module_t rtc_module;
extern const struct _mp_obj_module_t samd_module;
extern const struct _mp_obj_module_t storage_module;
@@ -220,6 +221,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
{ MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \
AUDIOBUSIO_MODULE \
{ MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }
#endif
#define EXPRESS_BOARD
@@ -304,7 +306,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
#define MP_STATE_PORT MP_STATE_VM
-#include "shared_dma.h"
+#include "peripherals/dma.h"
#define MICROPY_PORT_ROOT_POINTERS \
const char *readline_hist[8]; \
diff --git a/ports/atmel-samd/samd21_peripherals.h b/ports/atmel-samd/peripherals/adc.h
index 805717695..6530b1dcd 100644
--- a/ports/atmel-samd/samd21_peripherals.h
+++ b/ports/atmel-samd/peripherals/adc.h
@@ -24,15 +24,12 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
#include "include/sam.h"
#include "hal/include/hal_adc_sync.h"
-void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
-uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
-bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance);
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
diff --git a/ports/atmel-samd/samd51_peripherals.h b/ports/atmel-samd/peripherals/cache.h
index 6643379a5..b260568a3 100644
--- a/ports/atmel-samd/samd51_peripherals.h
+++ b/ports/atmel-samd/peripherals/cache.h
@@ -27,14 +27,6 @@
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
-#include "sam.h"
-#include "hal/include/hal_adc_sync.h"
-
-void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
-uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
-bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
-void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance);
-
void samd_peripherals_disable_and_clear_cache(void);
void samd_peripherals_enable_cache(void);
diff --git a/ports/atmel-samd/clocks.c b/ports/atmel-samd/peripherals/clocks.c
index a890210bf..a890210bf 100644
--- a/ports/atmel-samd/clocks.c
+++ b/ports/atmel-samd/peripherals/clocks.c
diff --git a/ports/atmel-samd/clocks.h b/ports/atmel-samd/peripherals/clocks.h
index 6b7cfedce..6b7cfedce 100644
--- a/ports/atmel-samd/clocks.h
+++ b/ports/atmel-samd/peripherals/clocks.h
diff --git a/ports/atmel-samd/shared_dma.c b/ports/atmel-samd/peripherals/dma.c
index edc2d0f1a..664c6aea8 100644
--- a/ports/atmel-samd/shared_dma.c
+++ b/ports/atmel-samd/peripherals/dma.c
@@ -23,7 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "shared_dma.h"
+#include "peripherals/dma.h"
#include <string.h>
@@ -48,164 +48,6 @@ COMPILER_ALIGNED(16) static DmacDescriptor write_back_descriptors[DMA_CHANNEL_CO
#define FIRST_SERCOM_TX_TRIGSRC 0x05
#endif
-static uint8_t sercom_index(Sercom* sercom) {
- #ifdef SAMD21
- return ((uint32_t) sercom - (uint32_t) SERCOM0) / 0x400;
- #else
- const Sercom* sercoms[SERCOM_INST_NUM] = SERCOM_INSTS;
- for (uint8_t i = 0; i < SERCOM_INST_NUM; i++) {
- if (sercoms[i] == sercom) {
- return i;
- }
- }
- return 0;
- #endif
-}
-
-void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- /** Select the DMA channel and clear software trigger */
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- DMAC->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
- DMAC->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
- DMAC->SWTRIGCTRL.reg &= (uint32_t)(~(1 << channel_number));
- uint32_t event_output_enable = 0;
- if (output_event) {
- event_output_enable = DMAC_CHCTRLB_EVOE;
- }
- DMAC->CHCTRLB.reg = DMAC_CHCTRLB_LVL_LVL0 |
- DMAC_CHCTRLB_TRIGSRC(trigsrc) |
- DMAC_CHCTRLB_TRIGACT_BEAT |
- event_output_enable;
- common_hal_mcu_enable_interrupts();
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- channel->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
- channel->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
- if (output_event) {
- channel->CHEVCTRL.reg = DMAC_CHEVCTRL_EVOE;
- }
- channel->CHCTRLA.reg = DMAC_CHCTRLA_TRIGSRC(trigsrc) |
- DMAC_CHCTRLA_TRIGACT_BURST |
- DMAC_CHCTRLA_BURSTLEN_SINGLE;
- #endif
-}
-
-void dma_enable_channel(uint8_t channel_number) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- /** Select the DMA channel and clear software trigger */
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- // Clear any previous interrupts.
- DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
- DMAC->CHCTRLA.bit.ENABLE = true;
- common_hal_mcu_enable_interrupts();
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- channel->CHCTRLA.bit.ENABLE = true;
- // Clear any previous interrupts.
- channel->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
- #endif
-}
-
-void dma_disable_channel(uint8_t channel_number) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- /** Select the DMA channel and clear software trigger */
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- DMAC->CHCTRLA.bit.ENABLE = false;
- common_hal_mcu_enable_interrupts();
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- channel->CHCTRLA.bit.ENABLE = false;
- #endif
-}
-
-void dma_suspend_channel(uint8_t channel_number) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- /** Select the DMA channel and clear software trigger */
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_SUSPEND_Val;
- common_hal_mcu_enable_interrupts();
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_SUSPEND;
- #endif
-}
-
-void dma_resume_channel(uint8_t channel_number) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- /** Select the DMA channel and clear software trigger */
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_RESUME_Val;
- DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_SUSP;
- common_hal_mcu_enable_interrupts();
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_RESUME;
- #endif
-}
-
-bool dma_channel_enabled(uint8_t channel_number) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- /** Select the DMA channel and clear software trigger */
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- bool enabled = DMAC->CHCTRLA.bit.ENABLE;
- common_hal_mcu_enable_interrupts();
- return enabled;
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- return channel->CHCTRLA.bit.ENABLE;
- #endif
-}
-
-uint8_t dma_transfer_status(uint8_t channel_number) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- /** Select the DMA channel and clear software trigger */
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- uint8_t status = DMAC->CHINTFLAG.reg;
- common_hal_mcu_enable_interrupts();
- return status;
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- return channel->CHINTFLAG.reg;
- #endif
-}
-
-static bool channel_free(uint8_t channel_number) {
- #ifdef SAMD21
- common_hal_mcu_disable_interrupts();
- DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
- bool channel_free = DMAC->CHSTATUS.reg == 0;
- common_hal_mcu_enable_interrupts();
- return channel_free;
- #endif
-
- #ifdef SAMD51
- DmacChannel* channel = &DMAC->Channel[channel_number];
- return channel->CHSTATUS.reg == 0;
- #endif
-}
-
void init_shared_dma(void) {
// Turn on the clocks
#ifdef SAMD51
@@ -237,8 +79,8 @@ static int32_t shared_dma_transfer(void* peripheral,
const uint8_t* buffer_out, volatile uint32_t* dest,
volatile uint32_t* src, uint8_t* buffer_in,
uint32_t length, uint8_t tx) {
- if (!channel_free(SHARED_TX_CHANNEL) ||
- (buffer_in != NULL && !channel_free(SHARED_RX_CHANNEL))) {
+ if (!dma_channel_free(SHARED_TX_CHANNEL) ||
+ (buffer_in != NULL && !dma_channel_free(SHARED_RX_CHANNEL))) {
return -1;
}
diff --git a/ports/atmel-samd/shared_dma.h b/ports/atmel-samd/peripherals/dma.h
index 03e5b276c..cf256b962 100644
--- a/ports/atmel-samd/shared_dma.h
+++ b/ports/atmel-samd/peripherals/dma.h
@@ -24,8 +24,8 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
#include <stdbool.h>
#include <stdint.h>
@@ -49,6 +49,8 @@ int32_t qspi_dma_write(uint32_t address, const uint8_t* buffer, uint32_t length)
int32_t qspi_dma_read(uint32_t address, uint8_t* buffer, uint32_t length);
#endif
+uint8_t sercom_index(Sercom* sercom);
+
int32_t sercom_dma_write(Sercom* sercom, const uint8_t* buffer, uint32_t length);
int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_t tx);
int32_t sercom_dma_transfer(Sercom* sercom, const uint8_t* buffer_out, uint8_t* buffer_in, uint32_t length);
@@ -58,8 +60,9 @@ void dma_enable_channel(uint8_t channel_number);
void dma_disable_channel(uint8_t channel_number);
void dma_suspend_channel(uint8_t channel_number);
void dma_resume_channel(uint8_t channel_number);
+bool dma_channel_free(uint8_t channel_number);
bool dma_channel_enabled(uint8_t channel_number);
uint8_t dma_transfer_status(uint8_t channel_number);
DmacDescriptor* dma_descriptor(uint8_t channel_number);
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
diff --git a/ports/atmel-samd/peripherals/events.c b/ports/atmel-samd/peripherals/events.c
new file mode 100644
index 000000000..9a4ab3b0c
--- /dev/null
+++ b/ports/atmel-samd/peripherals/events.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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 <stdint.h>
+
+#include "peripherals/events.h"
+//
+// #include "clocks.h"
+//
+#include "py/runtime.h"
+
+uint8_t find_async_event_channel(void) {
+ int8_t channel;
+ for (channel = EVSYS_CHANNELS - 1; channel > 0; channel--) {
+ if (event_channel_free(channel)) {
+ break;
+ }
+ }
+ if (channel < 0) {
+ mp_raise_RuntimeError("All event channels in use");
+ }
+ return channel;
+}
+
+#ifdef SAMD21
+#define EVSYS_SYNCH_NUM EVSYS_CHANNELS
+#endif
+uint8_t find_sync_event_channel(void) {
+ uint8_t channel;
+ for (channel = 0; channel < EVSYS_SYNCH_NUM; channel++) {
+ if (event_channel_free(channel)) {
+ break;
+ }
+ }
+ if (channel >= EVSYS_SYNCH_NUM) {
+ mp_raise_RuntimeError("All sync event channels in use");
+ }
+ return channel;
+}
diff --git a/ports/atmel-samd/events.h b/ports/atmel-samd/peripherals/events.h
index 64093c0ab..0073142f1 100644
--- a/ports/atmel-samd/events.h
+++ b/ports/atmel-samd/peripherals/events.h
@@ -44,4 +44,6 @@ void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generat
bool event_interrupt_active(uint8_t channel);
bool event_interrupt_overflow(uint8_t channel);
+bool event_channel_free(uint8_t channel);
+
#endif // MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H
diff --git a/ports/atmel-samd/peripherals/i2s.c b/ports/atmel-samd/peripherals/i2s.c
new file mode 100644
index 000000000..4d99e7b5b
--- /dev/null
+++ b/ports/atmel-samd/peripherals/i2s.c
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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 "i2s.h"
+
+#include "clocks.h"
+
+#include "hpl/gclk/hpl_gclk_base.h"
+#ifdef SAMD21
+#include "hpl/pm/hpl_pm_base.h"
+#endif
+
+void i2s_set_enable(bool enable) {
+ while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
+ I2S->CTRLA.bit.ENABLE = enable;
+ while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
+}
+
+void i2s_set_clock_unit_enable(uint8_t clock_unit, bool enable) {
+ while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
+ I2S->CTRLA.vec.CKEN = 1 << clock_unit;
+ while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
+}
diff --git a/ports/atmel-samd/i2s.h b/ports/atmel-samd/peripherals/i2s.h
index 7df667b2a..7df667b2a 100644
--- a/ports/atmel-samd/i2s.h
+++ b/ports/atmel-samd/peripherals/i2s.h
diff --git a/ports/atmel-samd/peripherals/pins.h b/ports/atmel-samd/peripherals/pins.h
new file mode 100644
index 000000000..1ddbf3329
--- /dev/null
+++ b/ports/atmel-samd/peripherals/pins.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the Micro Python 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.
+ */
+
+// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
+// that all necessary includes are already included.
+
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
+
+#include "mpconfigport.h"
+
+#ifdef SAMD21
+#include "peripherals/samd21/pins.h"
+#endif
+#ifdef SAMD51
+#include "peripherals/samd51/pins.h"
+#endif
+
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
diff --git a/ports/atmel-samd/peripherals/samd21/adc.c b/ports/atmel-samd/peripherals/samd21/adc.c
new file mode 100644
index 000000000..3a7f1e811
--- /dev/null
+++ b/ports/atmel-samd/peripherals/samd21/adc.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Dan Halbert 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 "hal/include/hal_adc_sync.h"
+#include "hpl/gclk/hpl_gclk_base.h"
+#include "hpl/pm/hpl_pm_base.h"
+
+// Do initialization and calibration setup needed for any use of the ADC.
+// The reference and resolution should be set by the caller.
+void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
+ // Turn the clocks on.
+ _pm_enable_bus_clock(PM_BUS_APBC, ADC);
+ _gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
+
+ adc_sync_init(adc, instance, (void *)NULL);
+
+ // Load the factory calibration
+ hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos);
+ // Bits 7:5
+ uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
+ // Bits 4:0
+ linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
+ hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity);
+}
diff --git a/ports/atmel-samd/pins.h b/ports/atmel-samd/peripherals/samd21/cache.c
index 1842efbc0..641b5e115 100644
--- a/ports/atmel-samd/pins.h
+++ b/ports/atmel-samd/peripherals/samd21/cache.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2017 Dan Halbert 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
@@ -24,16 +24,9 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PINS_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_PINS_H
+// The SAMD21 doesn't have a cache so we have nothing to do.
+void samd_peripherals_disable_and_clear_cache(void) {
+}
-#include "mpconfigport.h"
-
-#ifdef SAMD21
-#include "samd21_pins.h"
-#endif
-#ifdef SAMD51
-#include "samd51_pins.h"
-#endif
-
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_PINS_H
+void samd_peripherals_enable_cache(void) {
+}
diff --git a/ports/atmel-samd/samd21_clocks.c b/ports/atmel-samd/peripherals/samd21/clocks.c
index 0fc4d63e5..94b515814 100644
--- a/ports/atmel-samd/samd21_clocks.c
+++ b/ports/atmel-samd/peripherals/samd21/clocks.c
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-#include "clocks.h"
+#include "peripherals/clocks.h"
#include "hpl_gclk_config.h"
diff --git a/ports/atmel-samd/peripherals/samd21/dma.c b/ports/atmel-samd/peripherals/samd21/dma.c
new file mode 100644
index 000000000..3a399745a
--- /dev/null
+++ b/ports/atmel-samd/peripherals/samd21/dma.c
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017-2018 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 "peripherals/dma.h"
+
+#include <string.h>
+
+#include "py/gc.h"
+#include "py/mpstate.h"
+
+#include "hal/utils/include/utils.h"
+
+#include "shared-bindings/microcontroller/__init__.h"
+
+uint8_t sercom_index(Sercom* sercom) {
+ return ((uint32_t) sercom - (uint32_t) SERCOM0) / 0x400;
+}
+
+void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
+ common_hal_mcu_disable_interrupts();
+ /** Select the DMA channel and clear software trigger */
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ DMAC->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
+ DMAC->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
+ DMAC->SWTRIGCTRL.reg &= (uint32_t)(~(1 << channel_number));
+ uint32_t event_output_enable = 0;
+ if (output_event) {
+ event_output_enable = DMAC_CHCTRLB_EVOE;
+ }
+ DMAC->CHCTRLB.reg = DMAC_CHCTRLB_LVL_LVL0 |
+ DMAC_CHCTRLB_TRIGSRC(trigsrc) |
+ DMAC_CHCTRLB_TRIGACT_BEAT |
+ event_output_enable;
+ common_hal_mcu_enable_interrupts();
+}
+
+void dma_enable_channel(uint8_t channel_number) {
+ common_hal_mcu_disable_interrupts();
+ /** Select the DMA channel and clear software trigger */
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ // Clear any previous interrupts.
+ DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
+ DMAC->CHCTRLA.bit.ENABLE = true;
+ common_hal_mcu_enable_interrupts();
+}
+
+void dma_disable_channel(uint8_t channel_number) {
+ common_hal_mcu_disable_interrupts();
+ /** Select the DMA channel and clear software trigger */
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ DMAC->CHCTRLA.bit.ENABLE = false;
+ common_hal_mcu_enable_interrupts();
+}
+
+void dma_suspend_channel(uint8_t channel_number) {
+ common_hal_mcu_disable_interrupts();
+ /** Select the DMA channel and clear software trigger */
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_SUSPEND_Val;
+ common_hal_mcu_enable_interrupts();
+}
+
+void dma_resume_channel(uint8_t channel_number) {
+ common_hal_mcu_disable_interrupts();
+ /** Select the DMA channel and clear software trigger */
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_RESUME_Val;
+ DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_SUSP;
+ common_hal_mcu_enable_interrupts();
+}
+
+bool dma_channel_enabled(uint8_t channel_number) {
+ common_hal_mcu_disable_interrupts();
+ /** Select the DMA channel and clear software trigger */
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ bool enabled = DMAC->CHCTRLA.bit.ENABLE;
+ common_hal_mcu_enable_interrupts();
+ return enabled;
+}
+
+uint8_t dma_transfer_status(uint8_t channel_number) {
+ common_hal_mcu_disable_interrupts();
+ /** Select the DMA channel and clear software trigger */
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ uint8_t status = DMAC->CHINTFLAG.reg;
+ common_hal_mcu_enable_interrupts();
+ return status;
+}
+
+bool dma_channel_free(uint8_t channel_number) {
+ common_hal_mcu_disable_interrupts();
+ DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
+ bool channel_free = DMAC->CHSTATUS.reg == 0;
+ common_hal_mcu_enable_interrupts();
+ return channel_free;
+}
diff --git a/ports/atmel-samd/events.c b/ports/atmel-samd/peripherals/samd21/events.c
index 05a2ae8a7..70dfa249d 100644
--- a/ports/atmel-samd/events.c
+++ b/ports/atmel-samd/peripherals/samd21/events.c
@@ -24,131 +24,52 @@
* THE SOFTWARE.
*/
-#include "events.h"
+#include "peripherals/events.h"
-#include "clocks.h"
+#include "peripherals/clocks.h"
#include "py/runtime.h"
-#ifdef SAMD21
#include "hpl/pm/hpl_pm_base.h"
-#endif
-
-#ifdef SAMD51
-#include "hri/hri_mclk_d51.h"
-#endif
void turn_on_event_system(void) {
- #ifdef SAMD51
- hri_mclk_set_APBBMASK_EVSYS_bit(MCLK);
- #endif
-
- #ifdef SAMD21
_pm_enable_bus_clock(PM_BUS_APBC, EVSYS);
- #endif
}
void reset_event_system(void) {
- #ifdef SAMD51
- EVSYS->CTRLA.bit.SWRST = true;
- hri_mclk_clear_APBBMASK_EVSYS_bit(MCLK);
- #endif
-
- #ifdef SAMD21
EVSYS->CTRL.bit.SWRST = true;
_pm_disable_bus_clock(PM_BUS_APBC, EVSYS);
- #endif
}
-static bool channel_free(int8_t channel) {
+bool event_channel_free(uint8_t channel) {
uint8_t generator;
- #ifdef SAMD51
- generator = EVSYS->Channel[channel].CHANNEL.bit.EVGEN;
- #endif
- #ifdef SAMD21
// Explicitly do a byte write so the peripheral knows we're just wanting to read the channel
// rather than write to it.
*((uint8_t*) &EVSYS->CHANNEL.reg) = channel;
generator = (EVSYS->CHANNEL.reg & EVSYS_CHANNEL_EVGEN_Msk) >> EVSYS_CHANNEL_EVGEN_Pos;
- #endif
return generator == 0;
}
-uint8_t find_async_event_channel(void) {
- int8_t channel;
- for (channel = EVSYS_CHANNELS - 1; channel > 0; channel--) {
- if (channel_free(channel)) {
- break;
- }
- }
- if (channel < 0) {
- mp_raise_RuntimeError("All event channels in use");
- }
- return channel;
-}
-
-#ifdef SAMD21
-#define EVSYS_SYNCH_NUM EVSYS_CHANNELS
-#endif
-uint8_t find_sync_event_channel(void) {
- uint8_t channel;
- for (channel = 0; channel < EVSYS_SYNCH_NUM; channel++) {
- if (channel_free(channel)) {
- break;
- }
- }
- if (channel >= EVSYS_SYNCH_NUM) {
- mp_raise_RuntimeError("All sync event channels in use");
- }
- return channel;
-}
-
void disable_event_channel(uint8_t channel_number) {
- #ifdef SAMD51
- EVSYS->Channel[channel_number].CHANNEL.reg = 0;
- #endif
- #ifdef SAMD21
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel_number);
- #endif
}
void disable_event_user(uint8_t user_number) {
- #ifdef SAMD51
- EVSYS->USER[user_number].reg = 0;
- #endif
- #ifdef SAMD21
EVSYS->USER.reg = EVSYS_USER_USER(user_number);
- #endif
}
void connect_event_user_to_channel(uint8_t user, uint8_t channel) {
- #ifdef SAMD51
- EVSYS->USER[user].reg = channel + 1;
- #endif
- #ifdef SAMD21
EVSYS->USER.reg = EVSYS_USER_USER(user) | EVSYS_USER_CHANNEL(channel + 1);
- #endif
}
void init_async_event_channel(uint8_t channel, uint8_t generator) {
- #ifdef SAMD51
- EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
- #endif
- #ifdef SAMD21
- EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) | EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
- #endif
+ EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) |
+ EVSYS_CHANNEL_EVGEN(generator) |
+ EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
}
void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) {
connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel);
- #ifdef SAMD51
- EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) |
- EVSYS_CHANNEL_PATH_SYNCHRONOUS |
- EVSYS_CHANNEL_EDGSEL_RISING_EDGE;
- EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
- EVSYS->Channel[channel].CHINTENSET.reg = EVSYS_CHINTENSET_EVD | EVSYS_CHINTENSET_OVR;
- #endif
- #ifdef SAMD21
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) |
EVSYS_CHANNEL_EVGEN(generator) |
EVSYS_CHANNEL_PATH_RESYNCHRONIZED |
@@ -162,12 +83,10 @@ void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generat
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value);
EVSYS->INTENSET.reg = EVSYS_INTENSET_EVD(value) | EVSYS_INTENSET_OVR(value);
}
- #endif
}
bool event_interrupt_active(uint8_t channel) {
bool active = false;
- #ifdef SAMD21
if (channel > 7) {
uint8_t value = 1 << (channel - 7);
active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVDp8(value)) != 0;
@@ -183,21 +102,11 @@ bool event_interrupt_active(uint8_t channel) {
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value);
}
}
- #endif
- #ifdef SAMD51
- active = EVSYS->Channel[channel].CHINTFLAG.bit.EVD;
- // Only clear if we know its active, otherwise there is the possibility it becomes after we
- // check but before we clear.
- if (active) {
- EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
- }
- #endif
return active;
}
bool event_interrupt_overflow(uint8_t channel) {
bool overflow = false;
- #ifdef SAMD21
if (channel > 7) {
uint8_t value = 1 << (channel - 7);
overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVRp8(value)) != 0;
@@ -205,9 +114,5 @@ bool event_interrupt_overflow(uint8_t channel) {
uint8_t value = 1 << channel;
overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVR(value)) != 0;
}
- #endif
- #ifdef SAMD51
- overflow = EVSYS->Channel[channel].CHINTFLAG.bit.OVR;
- #endif
return overflow;
}
diff --git a/ports/atmel-samd/boards/metro_m4_express_revb/board.c b/ports/atmel-samd/peripherals/samd21/i2s.c
index a98385d29..7df401601 100644
--- a/ports/atmel-samd/boards/metro_m4_express_revb/board.c
+++ b/ports/atmel-samd/peripherals/samd21/i2s.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2018 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
@@ -24,23 +24,23 @@
* THE SOFTWARE.
*/
-#include "boards/board.h"
-#include "mpconfigboard.h"
-#include "hal/include/hal_gpio.h"
+#include "peripherals/i2s.h"
-void board_init(void) {
- gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_TX, true);
+#include "peripherals/clocks.h"
- gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(MICROPY_HW_LED_RX, true);
-}
+#include "hpl/gclk/hpl_gclk_base.h"
+#include "hpl/pm/hpl_pm_base.h"
-bool board_requests_safe_mode(void) {
- return false;
+void turn_on_i2s(void) {
+ _pm_enable_bus_clock(PM_BUS_APBC, I2S);
}
-void reset_board(void) {
+void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
+ while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
+ if (enable) {
+ I2S->CTRLA.vec.SEREN = 1 << serializer;
+ } else {
+ I2S->CTRLA.vec.SEREN &= ~(1 << serializer);
+ }
+ while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
}
diff --git a/ports/atmel-samd/samd21_pins.c b/ports/atmel-samd/peripherals/samd21/pins.c
index 319870b9a..bbb023a54 100644
--- a/ports/atmel-samd/samd21_pins.c
+++ b/ports/atmel-samd/peripherals/samd21/pins.c
@@ -26,8 +26,6 @@
#include "shared-bindings/microcontroller/Pin.h"
-#include "samd21_pins.h"
-
#define SERCOM(sercom_index, p_pad) \
{ \
.index = sercom_index, \
diff --git a/ports/atmel-samd/samd21_pins.h b/ports/atmel-samd/peripherals/samd21/pins.h
index 522563ef1..0b99ce9b3 100644
--- a/ports/atmel-samd/samd21_pins.h
+++ b/ports/atmel-samd/peripherals/samd21/pins.h
@@ -24,12 +24,13 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H
+// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
+// that all necessary includes are already included.
-#include "include/sam.h"
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
-#include "common-hal/microcontroller/Pin.h"
+#include "include/sam.h"
void reset_pin(uint8_t pin);
@@ -201,4 +202,4 @@ extern const mcu_pin_obj_t pin_PB02;
extern const mcu_pin_obj_t pin_PB03;
#endif
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
diff --git a/ports/atmel-samd/samd21_peripherals.c b/ports/atmel-samd/peripherals/samd21/sercom.c
index 5bbac2965..a27e49e0e 100644
--- a/ports/atmel-samd/samd21_peripherals.c
+++ b/ports/atmel-samd/peripherals/samd21/sercom.c
@@ -24,11 +24,9 @@
* THE SOFTWARE.
*/
-#include "hal/include/hal_adc_sync.h"
#include "hpl/gclk/hpl_gclk_base.h"
#include "hpl/pm/hpl_pm_base.h"
-
// The clock initializer values are rather random, so we need to put them in
// tables for lookup. We can't compute them.
@@ -93,21 +91,3 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
return clock_pad == 1 || clock_pad == 3;
}
-
-// Do initialization and calibration setup needed for any use of the ADC.
-// The reference and resolution should be set by the caller.
-void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
- // Turn the clocks on.
- _pm_enable_bus_clock(PM_BUS_APBC, ADC);
- _gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
-
- adc_sync_init(adc, instance, (void *)NULL);
-
- // Load the factory calibration
- hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos);
- // Bits 7:5
- uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
- // Bits 4:0
- linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
- hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity);
-}
diff --git a/ports/atmel-samd/peripherals/samd21/timers.c b/ports/atmel-samd/peripherals/samd21/timers.c
new file mode 100644
index 000000000..c93a71086
--- /dev/null
+++ b/ports/atmel-samd/peripherals/samd21/timers.c
@@ -0,0 +1,75 @@
+/*
+ * 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 <stdbool.h>
+#include <stdint.h>
+
+#include "peripherals/timers.h"
+
+//#include "common-hal/pulseio/PulseOut.h"
+
+#include "hpl/gclk/hpl_gclk_base.h"
+
+const uint8_t tcc_cc_num[3] = {4, 2, 2};
+const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC3_GCLK_ID,
+ TC4_GCLK_ID,
+ TC5_GCLK_ID,
+#ifdef TC6_GCLK_ID
+ TC6_GCLK_ID,
+#endif
+#ifdef TC7_GCLK_ID
+ TC7_GCLK_ID,
+#endif
+ };
+const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID};
+
+void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
+ uint8_t gclk_id;
+ if (is_tc) {
+ gclk_id = tc_gclk_ids[index];
+ } else {
+ gclk_id = tcc_gclk_ids[index];
+ }
+ // Determine the clock slot on the APBC bus. TCC0 is the first and 8 slots in.
+ uint8_t clock_slot = 8 + index;
+ // We index TCs starting at zero but in memory they begin at three so we have to add three.
+ if (is_tc) {
+ clock_slot += 3;
+ }
+ PM->APBCMASK.reg |= 1 << clock_slot;
+ _gclk_enable_channel(gclk_id, gclk_index);
+}
+
+void tc_set_enable(Tc* tc, bool enable) {
+ tc->COUNT16.CTRLA.bit.ENABLE = enable;
+ while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {
+ /* Wait for sync */
+ }
+}
+
+void tc_wait_for_sync(Tc* tc) {
+ while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {}
+}
diff --git a/ports/atmel-samd/peripherals/samd51/adc.c b/ports/atmel-samd/peripherals/samd51/adc.c
new file mode 100644
index 000000000..af6333a94
--- /dev/null
+++ b/ports/atmel-samd/peripherals/samd51/adc.c
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Dan Halbert 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 "hal/include/hal_adc_sync.h"
+#include "hpl/gclk/hpl_gclk_base.h"
+#include "hri/hri_mclk_d51.h"
+
+// Do initialization and calibration setup needed for any use of the ADC.
+// The reference and resolution should be set by the caller.
+void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
+ // Turn the clocks on.
+ if (instance == ADC0) {
+ hri_mclk_set_APBDMASK_ADC0_bit(MCLK);
+ hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
+ } else if (instance == ADC1) {
+ hri_mclk_set_APBDMASK_ADC1_bit(MCLK);
+ hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
+ }
+
+ adc_sync_init(adc, instance, (void *)NULL);
+
+ // SAMD51 has a CALIB register but doesn't have documented fuses for them.
+ uint8_t biasrefbuf;
+ uint8_t biasr2r;
+ uint8_t biascomp;
+ if (instance == ADC0) {
+ biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
+ biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
+ biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
+ } else {
+ biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
+ biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
+ biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
+ }
+ hri_adc_write_CALIB_BIASREFBUF_bf(instance, biasrefbuf);
+ hri_adc_write_CALIB_BIASR2R_bf(instance, biasr2r);
+ hri_adc_write_CALIB_BIASCOMP_bf(instance, biascomp);
+}
diff --git a/ports/atmel-samd/peripherals/samd51/cache.c b/ports/atmel-samd/peripherals/samd51/cache.c
new file mode 100644
index 000000000..f94dd830c
--- /dev/null
+++ b/ports/atmel-samd/peripherals/samd51/cache.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Dan Halbert 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 "sam.h"
+
+// Turn off cache and invalidate all data in it.
+void samd_peripherals_disable_and_clear_cache(void) {
+ CMCC->CTRL.bit.CEN = 0;
+ while (CMCC->SR.bit.CSTS) {}
+ CMCC->MAINT0.bit.INVALL = 1;
+}
+
+// Enable cache
+void samd_peripherals_enable_cache(void) {
+ CMCC->CTRL.bit.CEN = 1;
+}
diff --git a/ports/atmel-samd/samd51_clocks.c b/ports/atmel-samd/peripherals/samd51/clocks.c
index 6f8b1f010..29f9cb99c 100644
--- a/ports/atmel-samd/samd51_clocks.c
+++ b/ports/atmel-samd/peripherals/samd51/clocks.c
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-#include "clocks.h"
+#include "peripherals/clocks.h"
#include "hpl_gclk_config.h"
diff --git a/ports/atmel-samd/peripherals/samd51/dma.c b/ports/atmel-samd/peripherals/samd51/dma.c
new file mode 100644
index 000000000..ccb35aaf6
--- /dev/null
+++ b/ports/atmel-samd/peripherals/samd51/dma.c
@@ -0,0 +1,94 @@
+/*
+ * 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 "peripherals/dma.h"
+
+#include <string.h>
+
+#include "py/gc.h"
+#include "py/mpstate.h"
+
+#include "hal/utils/include/utils.h"
+
+#include "shared-bindings/microcontroller/__init__.h"
+
+uint8_t sercom_index(Sercom* sercom) {
+ const Sercom* sercoms[SERCOM_INST_NUM] = SERCOM_INSTS;
+ for (uint8_t i = 0; i < SERCOM_INST_NUM; i++) {
+ if (sercoms[i] == sercom) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ channel->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
+ channel->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
+ if (output_event) {
+ channel->CHEVCTRL.reg = DMAC_CHEVCTRL_EVOE;
+ }
+ channel->CHCTRLA.reg = DMAC_CHCTRLA_TRIGSRC(trigsrc) |
+ DMAC_CHCTRLA_TRIGACT_BURST |
+ DMAC_CHCTRLA_BURSTLEN_SINGLE;
+}
+
+void dma_enable_channel(uint8_t channel_number) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ channel->CHCTRLA.bit.ENABLE = true;
+ // Clear any previous interrupts.
+ channel->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
+}
+
+void dma_disable_channel(uint8_t channel_number) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ channel->CHCTRLA.bit.ENABLE = false;
+}
+
+void dma_suspend_channel(uint8_t channel_number) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_SUSPEND;
+}
+
+void dma_resume_channel(uint8_t channel_number) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_RESUME;
+}
+
+bool dma_channel_enabled(uint8_t channel_number) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ return channel->CHCTRLA.bit.ENABLE;
+}
+
+uint8_t dma_transfer_status(uint8_t channel_number) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ return channel->CHINTFLAG.reg;
+}
+
+bool dma_channel_free(uint8_t channel_number) {
+ DmacChannel* channel = &DMAC->Channel[channel_number];
+ return channel->CHSTATUS.reg == 0;
+}
diff --git a/ports/atmel-samd/peripherals/samd51/events.c b/ports/atmel-samd/peripherals/samd51/events.c
new file mode 100644
index 000000000..5ea2c87e6
--- /dev/null
+++ b/ports/atmel-samd/peripherals/samd51/events.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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 "peripherals/events.h"
+
+#include "peripherals/clocks.h"
+
+#include "py/runtime.h"
+
+#include "hri/hri_mclk_d51.h"
+
+void turn_on_event_system(void) {
+ hri_mclk_set_APBBMASK_EVSYS_bit(MCLK);
+}
+
+void reset_event_system(void) {
+ EVSYS->CTRLA.bit.SWRST = true;
+ hri_mclk_clear_APBBMASK_EVSYS_bit(MCLK);
+}
+
+bool event_channel_free(uint8_t channel) {
+ uint8_t generator;
+ generator = EVSYS->Channel[channel].CHANNEL.bit.EVGEN;
+ return generator == 0;
+}
+
+void disable_event_channel(uint8_t channel_number) {
+ EVSYS->Channel[channel_number].CHANNEL.reg = 0;
+}
+
+void disable_event_user(uint8_t user_number) {
+ EVSYS->USER[user_number].reg = 0;
+}
+
+void connect_event_user_to_channel(uint8_t user, uint8_t channel) {
+ EVSYS->USER[user].reg = channel + 1;
+}
+
+void init_async_event_channel(uint8_t channel, uint8_t generator) {
+ EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
+}
+
+void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) {
+ connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel);
+ EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) |
+ EVSYS_CHANNEL_PATH_SYNCHRONOUS |
+ EVSYS_CHANNEL_EDGSEL_RISING_EDGE;
+ EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
+ EVSYS->Channel[channel].CHINTENSET.reg = EVSYS_CHINTENSET_EVD | EVSYS_CHINTENSET_OVR;
+}
+
+bool event_interrupt_active(uint8_t channel) {
+ bool active = false;
+ active = EVSYS->Channel[channel].CHINTFLAG.bit.EVD;
+ // Only clear if we know its active, otherwise there is the possibility it becomes after we
+ // check but before we clear.
+ if (active) {
+ EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
+ }
+ return active;
+}
+
+bool event_interrupt_overflow(uint8_t channel) {
+ return EVSYS->Channel[channel].CHINTFLAG.bit.OVR;
+}
diff --git a/ports/atmel-samd/i2s.c b/ports/atmel-samd/peripherals/samd51/i2s.c
index 663ecdd1d..97ce13f7d 100644
--- a/ports/atmel-samd/i2s.c
+++ b/ports/atmel-samd/peripherals/samd51/i2s.c
@@ -24,53 +24,22 @@
* THE SOFTWARE.
*/
-#include "i2s.h"
+#include "peripherals/i2s.h"
-#include "clocks.h"
+#include "peripherals/clocks.h"
#include "hpl/gclk/hpl_gclk_base.h"
-#ifdef SAMD21
-#include "hpl/pm/hpl_pm_base.h"
-#endif
void turn_on_i2s(void) {
// Make sure the I2S peripheral is running so we can see if the resources we need are free.
- #ifdef SAMD51
hri_mclk_set_APBDMASK_I2S_bit(MCLK);
// Connect the clock units to the 2mhz clock by default. They can't reset without it.
connect_gclk_to_peripheral(5, I2S_GCLK_ID_0);
connect_gclk_to_peripheral(5, I2S_GCLK_ID_1);
- #endif
-
- #ifdef SAMD21
- _pm_enable_bus_clock(PM_BUS_APBC, I2S);
- #endif
-}
-
-void i2s_set_enable(bool enable) {
- while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
- I2S->CTRLA.bit.ENABLE = enable;
- while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
-}
-
-void i2s_set_clock_unit_enable(uint8_t clock_unit, bool enable) {
- while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
- I2S->CTRLA.vec.CKEN = 1 << clock_unit;
- while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
}
void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
- #ifdef SAMD21
- while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
- if (enable) {
- I2S->CTRLA.vec.SEREN = 1 << serializer;
- } else {
- I2S->CTRLA.vec.SEREN &= ~(1 << serializer);
- }
- while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
- #endif
- #ifdef SAMD51
if (serializer == 0) {
while (I2S->SYNCBUSY.bit.TXEN == 1) {}
I2S->CTRLA.bit.TXEN = enable;
@@ -80,5 +49,4 @@ void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
I2S->CTRLA.bit.RXEN = enable;
while (I2S->SYNCBUSY.bit.RXEN == 1) {}
}
- #endif
}
diff --git a/ports/atmel-samd/samd51_pins.c b/ports/atmel-samd/peripherals/samd51/pins.c
index 6d597b6e1..1c52d35a2 100644
--- a/ports/atmel-samd/samd51_pins.c
+++ b/ports/atmel-samd/peripherals/samd51/pins.c
@@ -26,8 +26,6 @@
#include "shared-bindings/microcontroller/Pin.h"
-#include "samd51_pins.h"
-
#define SERCOM(sercom_index, p_pad) \
{ \
.index = sercom_index, \
diff --git a/ports/atmel-samd/samd51_pins.h b/ports/atmel-samd/peripherals/samd51/pins.h
index c9ffacc24..b9a05a345 100644
--- a/ports/atmel-samd/samd51_pins.h
+++ b/ports/atmel-samd/peripherals/samd51/pins.h
@@ -24,13 +24,14 @@
* THE SOFTWARE.
*/
+// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
+// that all necessary includes are already included.
+
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H
#include "include/sam.h"
-#include "common-hal/microcontroller/Pin.h"
-
void reset_pin(uint8_t pin);
#define MUX_C 2
diff --git a/ports/atmel-samd/samd51_peripherals.c b/ports/atmel-samd/peripherals/samd51/sercom.c
index 5772b8e0a..fc4421422 100644
--- a/ports/atmel-samd/samd51_peripherals.c
+++ b/ports/atmel-samd/peripherals/samd51/sercom.c
@@ -28,6 +28,8 @@
#include "hpl/gclk/hpl_gclk_base.h"
#include "hri/hri_mclk_d51.h"
+// FIXME(tannewt): Should this be called sercom.c?
+
// The clock initializer values are rather random, so we need to put them in
// tables for lookup. We can't compute them.
@@ -131,47 +133,3 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
return clock_pad == 1;
}
-
-// Do initialization and calibration setup needed for any use of the ADC.
-// The reference and resolution should be set by the caller.
-void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
- // Turn the clocks on.
- if (instance == ADC0) {
- hri_mclk_set_APBDMASK_ADC0_bit(MCLK);
- hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
- } else if (instance == ADC1) {
- hri_mclk_set_APBDMASK_ADC1_bit(MCLK);
- hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
- }
-
- adc_sync_init(adc, instance, (void *)NULL);
-
- // SAMD51 has a CALIB register but doesn't have documented fuses for them.
- uint8_t biasrefbuf;
- uint8_t biasr2r;
- uint8_t biascomp;
- if (instance == ADC0) {
- biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
- biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
- biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
- } else {
- biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
- biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
- biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
- }
- hri_adc_write_CALIB_BIASREFBUF_bf(instance, biasrefbuf);
- hri_adc_write_CALIB_BIASR2R_bf(instance, biasr2r);
- hri_adc_write_CALIB_BIASCOMP_bf(instance, biascomp);
-}
-
-// Turn off cache and invalidate all data in it.
-void samd_peripherals_disable_and_clear_cache(void) {
- CMCC->CTRL.bit.CEN = 0;
- while (CMCC->SR.bit.CSTS) {}
- CMCC->MAINT0.bit.INVALL = 1;
-}
-
-// Enable cache
-void samd_peripherals_enable_cache(void) {
- CMCC->CTRL.bit.CEN = 1;
-}
diff --git a/ports/atmel-samd/timers.c b/ports/atmel-samd/peripherals/samd51/timers.c
index 33518b782..305acce38 100644
--- a/ports/atmel-samd/timers.c
+++ b/ports/atmel-samd/peripherals/samd51/timers.c
@@ -27,36 +27,12 @@
#include <stdbool.h>
#include <stdint.h>
-#include "timers.h"
+#include "peripherals/timers.h"
-#include "common-hal/pulseio/PulseOut.h"
+//#include "common-hal/pulseio/PulseOut.h"
-#ifdef SAMD21
-#include "hpl/gclk/hpl_gclk_base.h"
-#endif
-
-#ifdef SAMD51
#include "hri/hri_gclk_d51.h"
-#endif
-
-const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024};
-// This bitmask keeps track of which channels of a TCC are currently claimed.
-#ifdef SAMD21
-const uint8_t tcc_cc_num[3] = {4, 2, 2};
-const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC3_GCLK_ID,
- TC4_GCLK_ID,
- TC5_GCLK_ID,
-#ifdef TC6_GCLK_ID
- TC6_GCLK_ID,
-#endif
-#ifdef TC7_GCLK_ID
- TC7_GCLK_ID,
-#endif
- };
-const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID};
-#endif
-#ifdef SAMD51
const uint8_t tcc_cc_num[5] = {6, 4, 3, 2, 2};
const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC0_GCLK_ID,
TC1_GCLK_ID,
@@ -85,36 +61,6 @@ const uint8_t tcc_gclk_ids[TCC_INST_NUM] = {TCC0_GCLK_ID,
TCC4_GCLK_ID
#endif
};
-#endif
-Tc* const tc_insts[TC_INST_NUM] = TC_INSTS;
-Tcc* const tcc_insts[TCC_INST_NUM] = TCC_INSTS;
-
-IRQn_Type const tc_irq[TC_INST_NUM] = {
-#ifdef TC0
- TC0_IRQn,
-#endif
-#ifdef TC1
- TC1_IRQn,
-#endif
-#ifdef TC2
- TC2_IRQn,
-#endif
-#ifdef TC3
- TC3_IRQn,
-#endif
-#ifdef TC4
- TC4_IRQn,
-#endif
-#ifdef TC5
- TC5_IRQn,
-#endif
-#ifdef TC6
- TC6_IRQn,
-#endif
-#ifdef TC7
- TC7_IRQn,
-#endif
-};
void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
uint8_t gclk_id;
@@ -124,7 +70,6 @@ void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
gclk_id = tcc_gclk_ids[index];
}
// Turn on the clocks for the peripherals.
- #ifdef SAMD51
if (is_tc) {
switch (index) {
case 0:
@@ -180,122 +125,15 @@ void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
hri_gclk_write_PCHCTRL_reg(GCLK, gclk_id,
gclk_index | (1 << GCLK_PCHCTRL_CHEN_Pos));
- #endif
-
- #ifdef SAMD21
- // Determine the clock slot on the APBC bus. TCC0 is the first and 8 slots in.
- uint8_t clock_slot = 8 + index;
- // We index TCs starting at zero but in memory they begin at three so we have to add three.
- if (is_tc) {
- clock_slot += 3;
- }
- PM->APBCMASK.reg |= 1 << clock_slot;
- _gclk_enable_channel(gclk_id, gclk_index);
- #endif
}
void tc_set_enable(Tc* tc, bool enable) {
tc->COUNT16.CTRLA.bit.ENABLE = enable;
- #ifdef SAMD21
- while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {
- /* Wait for sync */
- }
- #endif
- #ifdef SAMD51
while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) {
/* Wait for sync */
}
- #endif
-}
-
-void tc_enable_interrupts(uint8_t tc_index) {
- NVIC_DisableIRQ(tc_irq[tc_index]);
- NVIC_ClearPendingIRQ(tc_irq[tc_index]);
- NVIC_EnableIRQ(tc_irq[tc_index]);
-}
-
-void tc_disable_interrupts(uint8_t tc_index) {
- NVIC_DisableIRQ(tc_irq[tc_index]);
- NVIC_ClearPendingIRQ(tc_irq[tc_index]);
-}
-
-void tcc_set_enable(Tcc* tcc, bool enable) {
- tcc->CTRLA.bit.ENABLE = enable;
- while (tcc->SYNCBUSY.bit.ENABLE != 0) {
- /* Wait for sync */
- }
}
void tc_wait_for_sync(Tc* tc) {
- #ifdef SAMD21
- while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {}
- #endif
- #ifdef SAMD51
while (tc->COUNT16.SYNCBUSY.reg != 0) {}
- #endif
-}
-
-void tc_reset(Tc* tc) {
- tc->COUNT16.CTRLA.bit.SWRST = 1;
- while (tc->COUNT16.CTRLA.bit.SWRST == 1) {
- }
-}
-
-void shared_timer_handler(bool is_tc, uint8_t index) {
- // Add calls to interrupt handlers for specific functionality here.
- if (is_tc) {
- pulseout_interrupt_handler(index);
- }
-}
-
-#ifdef SAMD51
-#define TC_OFFSET 0
-#endif
-#ifdef SAMD21
-#define TC_OFFSET 3
-#endif
-
-void TCC0_Handler(void) {
- shared_timer_handler(false, 0);
-}
-void TCC1_Handler(void) {
- shared_timer_handler(false, 1);
}
-void TCC2_Handler(void) {
- shared_timer_handler(false, 2);
-}
-// TC0 - TC2 only exist on the SAMD51
-#ifdef TC0
-void TC0_Handler(void) {
- shared_timer_handler(true, 0);
-}
-#endif
-#ifdef TC1
-void TC1_Handler(void) {
- shared_timer_handler(true, 1);
-}
-#endif
-#ifdef TC2
-void TC2_Handler(void) {
- shared_timer_handler(true, 2);
-}
-#endif
-void TC3_Handler(void) {
- shared_timer_handler(true, 3 - TC_OFFSET);
-}
-void TC4_Handler(void) {
- shared_timer_handler(true, 4 - TC_OFFSET);
-}
-void TC5_Handler(void) {
- shared_timer_handler(true, 5 - TC_OFFSET);
-}
-#ifdef TC6
-void TC6_Handler(void) {
- shared_timer_handler(true, 6 - TC_OFFSET);
-}
-#endif
-#ifdef TC7
-void TC7_Handler(void) {
- shared_timer_handler(true, 7 - TC_OFFSET);
-}
-#endif
diff --git a/ports/atmel-samd/peripherals.c b/ports/atmel-samd/peripherals/sercom.c
index c75a1f43b..04c1fd008 100644
--- a/ports/atmel-samd/peripherals.c
+++ b/ports/atmel-samd/peripherals/sercom.c
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-#include "peripherals.h"
+#include "peripherals/sercom.h"
#include "hpl_sercom_config.h"
diff --git a/ports/atmel-samd/peripherals.h b/ports/atmel-samd/peripherals/sercom.h
index 8a07c0045..66ad1a403 100644
--- a/ports/atmel-samd/peripherals.h
+++ b/ports/atmel-samd/peripherals/sercom.h
@@ -24,24 +24,19 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H
-#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
#include <stdint.h>
#include "mpconfigport.h"
-// Routines common across chip families.
+void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
+uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate);
uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value);
+bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
Sercom* sercom_insts[SERCOM_INST_NUM];
-#ifdef SAMD21
-#include "samd21_peripherals.h"
-#endif
-#ifdef SAMD51
-#include "samd51_peripherals.h"
-#endif
-
-#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
diff --git a/ports/atmel-samd/peripherals/timers.c b/ports/atmel-samd/peripherals/timers.c
new file mode 100644
index 000000000..cdcb92ac8
--- /dev/null
+++ b/ports/atmel-samd/peripherals/timers.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <stdbool.h>
+#include <stdint.h>
+
+#include "timers.h"
+
+#include "common-hal/pulseio/PulseOut.h"
+
+const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024};
+
+Tc* const tc_insts[TC_INST_NUM] = TC_INSTS;
+Tcc* const tcc_insts[TCC_INST_NUM] = TCC_INSTS;
+
+IRQn_Type const tc_irq[TC_INST_NUM] = {
+#ifdef TC0
+ TC0_IRQn,
+#endif
+#ifdef TC1
+ TC1_IRQn,
+#endif
+#ifdef TC2
+ TC2_IRQn,
+#endif
+#ifdef TC3
+ TC3_IRQn,
+#endif
+#ifdef TC4
+ TC4_IRQn,
+#endif
+#ifdef TC5
+ TC5_IRQn,
+#endif
+#ifdef TC6
+ TC6_IRQn,
+#endif
+#ifdef TC7
+ TC7_IRQn,
+#endif
+};
+
+void tc_enable_interrupts(uint8_t tc_index) {
+ NVIC_DisableIRQ(tc_irq[tc_index]);
+ NVIC_ClearPendingIRQ(tc_irq[tc_index]);
+ NVIC_EnableIRQ(tc_irq[tc_index]);
+}
+
+void tc_disable_interrupts(uint8_t tc_index) {
+ NVIC_DisableIRQ(tc_irq[tc_index]);
+ NVIC_ClearPendingIRQ(tc_irq[tc_index]);
+}
+
+void tcc_set_enable(Tcc* tcc, bool enable) {
+ tcc->CTRLA.bit.ENABLE = enable;
+ while (tcc->SYNCBUSY.bit.ENABLE != 0) {
+ /* Wait for sync */
+ }
+}
+
+void tc_reset(Tc* tc) {
+ tc->COUNT16.CTRLA.bit.SWRST = 1;
+ while (tc->COUNT16.CTRLA.bit.SWRST == 1) {
+ }
+}
+
+void shared_timer_handler(bool is_tc, uint8_t index) {
+ // Add calls to interrupt handlers for specific functionality here.
+ if (is_tc) {
+ pulseout_interrupt_handler(index);
+ }
+}
+
+#ifdef SAMD51
+#define TC_OFFSET 0
+#endif
+#ifdef SAMD21
+#define TC_OFFSET 3
+#endif
+
+void TCC0_Handler(void) {
+ shared_timer_handler(false, 0);
+}
+void TCC1_Handler(void) {
+ shared_timer_handler(false, 1);
+}
+void TCC2_Handler(void) {
+ shared_timer_handler(false, 2);
+}
+// TC0 - TC2 only exist on the SAMD51
+#ifdef TC0
+void TC0_Handler(void) {
+ shared_timer_handler(true, 0);
+}
+#endif
+#ifdef TC1
+void TC1_Handler(void) {
+ shared_timer_handler(true, 1);
+}
+#endif
+#ifdef TC2
+void TC2_Handler(void) {
+ shared_timer_handler(true, 2);
+}
+#endif
+void TC3_Handler(void) {
+ shared_timer_handler(true, 3 - TC_OFFSET);
+}
+void TC4_Handler(void) {
+ shared_timer_handler(true, 4 - TC_OFFSET);
+}
+void TC5_Handler(void) {
+ shared_timer_handler(true, 5 - TC_OFFSET);
+}
+#ifdef TC6
+void TC6_Handler(void) {
+ shared_timer_handler(true, 6 - TC_OFFSET);
+}
+#endif
+#ifdef TC7
+void TC7_Handler(void) {
+ shared_timer_handler(true, 7 - TC_OFFSET);
+}
+#endif
diff --git a/ports/atmel-samd/timers.h b/ports/atmel-samd/peripherals/timers.h
index fa8965784..fa8965784 100644
--- a/ports/atmel-samd/timers.h
+++ b/ports/atmel-samd/peripherals/timers.h
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index 7c682d120..55e0a7ecf 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -55,11 +55,11 @@
#include "common-hal/rtc/RTC.h"
#include "common-hal/touchio/TouchIn.h"
#include "common-hal/usb_hid/Device.h"
+#include "peripherals/cache.h"
+#include "peripherals/clocks.h"
+#include "peripherals/events.h"
+#include "peripherals/dma.h"
#include "shared-bindings/rtc/__init__.h"
-#include "clocks.h"
-#include "events.h"
-#include "peripherals.h"
-#include "shared_dma.h"
#include "tick.h"
#ifdef CIRCUITPY_GAMEPAD_TICKS
diff --git a/shared-bindings/board/__init__.h b/shared-bindings/board/__init__.h
index 720239f28..2730e5f51 100644
--- a/shared-bindings/board/__init__.h
+++ b/shared-bindings/board/__init__.h
@@ -29,6 +29,8 @@
#include "py/obj.h"
+#include "shared-bindings/microcontroller/Pin.h" // for the pin definitions
+
extern const mp_obj_dict_t board_module_globals;
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BOARD___INIT___H
diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c
new file mode 100644
index 000000000..635826c60
--- /dev/null
+++ b/shared-bindings/rotaryio/IncrementalEncoder.c
@@ -0,0 +1,159 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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 <stdint.h>
+
+#include "lib/utils/context_manager_helpers.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "py/runtime0.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/rotaryio/IncrementalEncoder.h"
+#include "shared-bindings/util.h"
+
+//| .. currentmodule:: rotaryio
+//|
+//| :class:`IncrementalEncoder` -- Read the position of the incremental encoder
+//| ============================================================================
+//|
+//| IncrementalEncoder determines the relative rotational position based on two series of pulses.
+//|
+//| .. class:: IncrementalEncoder(pin_a, pin_b)
+//|
+//| Create an IncrementalEncoder object associated with the given pins. It tracks the positional
+//| state of an incremental rotary encoder (also known as a quadrature encoder.) Position is
+//| relative to the position when the object is contructed.
+//|
+//| :param ~microcontroller.Pin pin: First pin to read pulses from.
+//| :param ~microcontroller.Pin pin: Second pin to read pulses from.
+//|
+//| For example::
+//|
+//| import rotaryio
+//| import time
+//| from board import *
+//|
+//| enc = rotaryio.IncrementalEncoder(D1, D2)
+//| last_position = None
+//| while True;
+//| position = enc.position
+//| if last_position == None or position != last_position:
+//| print(position)
+//| last_position = position
+//|
+STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 2, 2, true);
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+ enum { ARG_pin_a, ARG_pin_b };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_pin_a, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_pin_b, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ assert_pin(args[ARG_pin_a].u_obj, false);
+ const mcu_pin_obj_t* pin_a = MP_OBJ_TO_PTR(args[ARG_pin_a].u_obj);
+ assert_pin_free(pin_a);
+
+ assert_pin(args[ARG_pin_b].u_obj, false);
+ const mcu_pin_obj_t* pin_b = MP_OBJ_TO_PTR(args[ARG_pin_b].u_obj);
+ assert_pin_free(pin_b);
+
+ rotaryio_incrementalencoder_obj_t *self = m_new_obj(rotaryio_incrementalencoder_obj_t);
+ self->base.type = &rotaryio_incrementalencoder_type;
+
+ common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: deinit()
+//|
+//| Deinitialises the IncrementalEncoder and releases any hardware resources for reuse.
+//|
+STATIC mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) {
+ rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_rotaryio_incrementalencoder_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_deinit_obj, rotaryio_incrementalencoder_deinit);
+
+//| .. method:: __enter__()
+//|
+//| No-op used by Context Managers.
+//|
+// Provided by context manager helper.
+
+//| .. method:: __exit__()
+//|
+//| Automatically deinitializes the hardware when exiting a context. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+STATIC mp_obj_t rotaryio_incrementalencoder_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ (void)n_args;
+ common_hal_rotaryio_incrementalencoder_deinit(args[0]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___obj, 4, 4, rotaryio_incrementalencoder_obj___exit__);
+
+
+//| .. attribute:: position
+//|
+//| The current position in terms of pulses. The number of pulses per rotation is defined by the
+//| specific hardware.
+//|
+STATIC mp_obj_t rotaryio_incrementalencoder_obj_get_position(mp_obj_t self_in) {
+ rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self));
+
+ return mp_obj_new_int(common_hal_rotaryio_incrementalencoder_get_position(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_get_position_obj, rotaryio_incrementalencoder_obj_get_position);
+
+const mp_obj_property_t rotaryio_incrementalencoder_position_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&rotaryio_incrementalencoder_get_position_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC const mp_rom_map_elem_t rotaryio_incrementalencoder_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rotaryio_incrementalencoder_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&rotaryio_incrementalencoder___exit___obj) },
+ { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&rotaryio_incrementalencoder_position_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(rotaryio_incrementalencoder_locals_dict, rotaryio_incrementalencoder_locals_dict_table);
+
+const mp_obj_type_t rotaryio_incrementalencoder_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_IncrementalEncoder,
+ .make_new = rotaryio_incrementalencoder_make_new,
+ .locals_dict = (mp_obj_dict_t*)&rotaryio_incrementalencoder_locals_dict,
+};
diff --git a/shared-bindings/rotaryio/IncrementalEncoder.h b/shared-bindings/rotaryio/IncrementalEncoder.h
new file mode 100644
index 000000000..29e89e208
--- /dev/null
+++ b/shared-bindings/rotaryio/IncrementalEncoder.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the Micro Python 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.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H
+
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/rotaryio/IncrementalEncoder.h"
+
+extern const mp_obj_type_t rotaryio_incrementalencoder_type;
+
+extern void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self,
+ const mcu_pin_obj_t* pin_a, const mcu_pin_obj_t* pin_b);
+extern void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t* self);
+extern bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t* self);
+extern mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t* self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H
diff --git a/shared-bindings/rotaryio/__init__.c b/shared-bindings/rotaryio/__init__.c
new file mode 100644
index 000000000..db1ff3d4c
--- /dev/null
+++ b/shared-bindings/rotaryio/__init__.c
@@ -0,0 +1,75 @@
+/*
+ * 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 <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/rotaryio/__init__.h"
+#include "shared-bindings/rotaryio/IncrementalEncoder.h"
+
+//| :mod:`rotaryio` --- Support for pulse based protocols
+//| =====================================================
+//|
+//| .. module:: rotaryio
+//| :synopsis: Support for reading rotation sensors
+//| :platform: SAMD
+//|
+//| The `rotaryio` module contains classes to read different rotation encoding schemes. See
+//| `Wikipedia's Rotary Encoder page <https://en.wikipedia.org/wiki/Rotary_encoder>`_ for more
+//| background.
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| IncrementalEncoder
+//|
+
+//| .. warning:: This module is not available in some SAMD21 (aka M0) builds. See the
+//| :ref:`module-support-matrix` for more info.
+//|
+
+//| All classes change hardware state and should be deinitialized when they
+//| are no longer needed if the program continues after use. To do so, either
+//| call :py:meth:`!deinit` or use a context manager. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+
+STATIC const mp_rom_map_elem_t rotaryio_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rotaryio) },
+ { MP_ROM_QSTR(MP_QSTR_IncrementalEncoder), MP_ROM_PTR(&rotaryio_incrementalencoder_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(rotaryio_module_globals, rotaryio_module_globals_table);
+
+const mp_obj_module_t rotaryio_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&rotaryio_module_globals,
+};
diff --git a/shared-bindings/rotaryio/__init__.h b/shared-bindings/rotaryio/__init__.h
new file mode 100644
index 000000000..5d051d5a1
--- /dev/null
+++ b/shared-bindings/rotaryio/__init__.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft
+ *
+ * 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_SHARED_BINDINGS_ROTARYIO___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H
+
+#include "py/obj.h"
+
+// Nothing now.
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H
diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c
index 8f1b506fe..584d021b0 100644
--- a/supervisor/shared/rgb_led_status.c
+++ b/supervisor/shared/rgb_led_status.c
@@ -27,7 +27,6 @@
#include "mphalport.h"
#include "common-hal/microcontroller/Pin.h"
#include "rgb_led_status.h"
-#include "pins.h"
#ifdef MICROPY_HW_NEOPIXEL
uint8_t rgb_status_brightness = 63;