From fd71e56891749837a823a4b555b84150b6fbc1e8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 25 May 2018 18:39:16 -0700 Subject: atmel-samd: Re-org helper peripheral files into their own subdirectory. Ideally in the future they won't depend on ASF4 or MicroPython. --- conf.py | 1 + ports/atmel-samd/Makefile | 25 +- ports/atmel-samd/audio_dma.c | 6 +- ports/atmel-samd/bindings/samd/Clock.c | 3 +- ports/atmel-samd/board_busses.c | 6 +- ports/atmel-samd/boards/arduino_zero/pins.c | 2 - .../boards/circuitplayground_express/board.c | 1 - .../boards/circuitplayground_express/pins.c | 3 +- .../circuitplayground_express_crickit/board.c | 1 - .../circuitplayground_express_crickit/pins.c | 3 +- .../atmel-samd/boards/feather_m0_adalogger/pins.c | 3 +- ports/atmel-samd/boards/feather_m0_basic/pins.c | 3 +- ports/atmel-samd/boards/feather_m0_express/pins.c | 3 +- ports/atmel-samd/boards/feather_m0_rfm69/pins.c | 3 +- ports/atmel-samd/boards/feather_m0_rfm9x/pins.c | 3 +- .../atmel-samd/boards/feather_m0_supersized/pins.c | 3 +- ports/atmel-samd/boards/feather_m4_express/pins.c | 3 +- ports/atmel-samd/boards/gemma_m0/pins.c | 3 +- .../atmel-samd/boards/itsybitsy_m0_express/pins.c | 3 +- .../atmel-samd/boards/itsybitsy_m4_express/pins.c | 3 +- ports/atmel-samd/boards/metro_m0_express/pins.c | 3 +- ports/atmel-samd/boards/metro_m4_express/pins.c | 3 +- .../boards/metro_m4_express_revb/board.c | 46 - .../boards/metro_m4_express_revb/mpconfigboard.h | 72 -- .../boards/metro_m4_express_revb/mpconfigboard.mk | 11 - .../atmel-samd/boards/metro_m4_express_revb/pins.c | 48 - ports/atmel-samd/boards/pirkey_m0/pins.c | 3 +- ports/atmel-samd/boards/trinket_m0/pins.c | 3 +- ports/atmel-samd/boards/trinket_m0_haxpress/pins.c | 3 +- ports/atmel-samd/boards/ugame10/pins.c | 3 +- ports/atmel-samd/clocks.c | 96 -- ports/atmel-samd/clocks.h | 73 -- ports/atmel-samd/common-hal/analogio/AnalogIn.c | 2 +- ports/atmel-samd/common-hal/analogio/AnalogOut.c | 6 +- ports/atmel-samd/common-hal/audiobusio/I2SOut.c | 13 +- ports/atmel-samd/common-hal/audiobusio/PDMIn.c | 11 +- ports/atmel-samd/common-hal/audioio/AudioOut.c | 9 +- ports/atmel-samd/common-hal/busio/I2C.c | 3 +- ports/atmel-samd/common-hal/busio/SPI.c | 6 +- ports/atmel-samd/common-hal/busio/UART.c | 3 +- ports/atmel-samd/common-hal/microcontroller/Pin.c | 7 +- ports/atmel-samd/common-hal/microcontroller/Pin.h | 2 + .../common-hal/microcontroller/Processor.c | 2 +- .../common-hal/microcontroller/__init__.c | 2 +- ports/atmel-samd/common-hal/pulseio/PWMOut.c | 4 +- ports/atmel-samd/common-hal/pulseio/PulseIn.c | 4 +- ports/atmel-samd/common-hal/pulseio/PulseOut.c | 4 +- .../common-hal/rotaryio/IncrementalEncoder.c | 158 +++ .../common-hal/rotaryio/IncrementalEncoder.h | 40 + ports/atmel-samd/common-hal/rotaryio/__init__.c | 1 + ports/atmel-samd/common-hal/touchio/TouchIn.c | 6 +- ports/atmel-samd/events.c | 213 ---- ports/atmel-samd/events.h | 47 - ports/atmel-samd/external_flash/external_flash.c | 4 +- ports/atmel-samd/external_flash/qspi_flash.c | 4 +- ports/atmel-samd/external_flash/spi_flash.c | 4 +- ports/atmel-samd/i2s.c | 84 -- ports/atmel-samd/i2s.h | 41 - ports/atmel-samd/mpconfigport.h | 4 +- ports/atmel-samd/peripherals.c | 44 - ports/atmel-samd/peripherals.h | 47 - ports/atmel-samd/peripherals/adc.h | 35 + ports/atmel-samd/peripherals/cache.h | 33 + ports/atmel-samd/peripherals/clocks.c | 96 ++ ports/atmel-samd/peripherals/clocks.h | 73 ++ ports/atmel-samd/peripherals/dma.c | 244 ++++ ports/atmel-samd/peripherals/dma.h | 68 ++ ports/atmel-samd/peripherals/events.c | 62 + ports/atmel-samd/peripherals/events.h | 49 + ports/atmel-samd/peripherals/i2s.c | 46 + ports/atmel-samd/peripherals/i2s.h | 41 + ports/atmel-samd/peripherals/pins.h | 42 + ports/atmel-samd/peripherals/samd21/adc.c | 47 + ports/atmel-samd/peripherals/samd21/cache.c | 32 + ports/atmel-samd/peripherals/samd21/clocks.c | 425 +++++++ ports/atmel-samd/peripherals/samd21/dma.c | 118 ++ ports/atmel-samd/peripherals/samd21/events.c | 118 ++ ports/atmel-samd/peripherals/samd21/i2s.c | 46 + ports/atmel-samd/peripherals/samd21/pins.c | 529 +++++++++ ports/atmel-samd/peripherals/samd21/pins.h | 205 ++++ ports/atmel-samd/peripherals/samd21/sercom.c | 93 ++ ports/atmel-samd/peripherals/samd21/timers.c | 75 ++ ports/atmel-samd/peripherals/samd51/adc.c | 61 + ports/atmel-samd/peripherals/samd51/cache.c | 39 + ports/atmel-samd/peripherals/samd51/clocks.c | 472 ++++++++ ports/atmel-samd/peripherals/samd51/dma.c | 94 ++ ports/atmel-samd/peripherals/samd51/events.c | 88 ++ ports/atmel-samd/peripherals/samd51/i2s.c | 52 + ports/atmel-samd/peripherals/samd51/pins.c | 1232 +++++++++++++++++++ ports/atmel-samd/peripherals/samd51/pins.h | 349 ++++++ ports/atmel-samd/peripherals/samd51/sercom.c | 135 +++ ports/atmel-samd/peripherals/samd51/timers.c | 139 +++ ports/atmel-samd/peripherals/sercom.c | 44 + ports/atmel-samd/peripherals/sercom.h | 42 + ports/atmel-samd/peripherals/timers.c | 147 +++ ports/atmel-samd/peripherals/timers.h | 69 ++ ports/atmel-samd/pins.h | 39 - ports/atmel-samd/samd21_clocks.c | 425 ------- ports/atmel-samd/samd21_peripherals.c | 113 -- ports/atmel-samd/samd21_peripherals.h | 38 - ports/atmel-samd/samd21_pins.c | 531 --------- ports/atmel-samd/samd21_pins.h | 204 ---- ports/atmel-samd/samd51_clocks.c | 472 -------- ports/atmel-samd/samd51_peripherals.c | 177 --- ports/atmel-samd/samd51_peripherals.h | 41 - ports/atmel-samd/samd51_pins.c | 1234 -------------------- ports/atmel-samd/samd51_pins.h | 348 ------ ports/atmel-samd/shared_dma.c | 402 ------- ports/atmel-samd/shared_dma.h | 65 -- ports/atmel-samd/supervisor/port.c | 8 +- ports/atmel-samd/timers.c | 301 ----- ports/atmel-samd/timers.h | 69 -- shared-bindings/board/__init__.h | 2 + shared-bindings/rotaryio/IncrementalEncoder.c | 159 +++ shared-bindings/rotaryio/IncrementalEncoder.h | 41 + shared-bindings/rotaryio/__init__.c | 75 ++ shared-bindings/rotaryio/__init__.h | 34 + supervisor/shared/rgb_led_status.c | 1 - 118 files changed, 6060 insertions(+), 5379 deletions(-) delete mode 100644 ports/atmel-samd/boards/metro_m4_express_revb/board.c delete mode 100644 ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.h delete mode 100644 ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.mk delete mode 100644 ports/atmel-samd/boards/metro_m4_express_revb/pins.c delete mode 100644 ports/atmel-samd/clocks.c delete mode 100644 ports/atmel-samd/clocks.h create mode 100644 ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c create mode 100644 ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h create mode 100644 ports/atmel-samd/common-hal/rotaryio/__init__.c delete mode 100644 ports/atmel-samd/events.c delete mode 100644 ports/atmel-samd/events.h delete mode 100644 ports/atmel-samd/i2s.c delete mode 100644 ports/atmel-samd/i2s.h delete mode 100644 ports/atmel-samd/peripherals.c delete mode 100644 ports/atmel-samd/peripherals.h create mode 100644 ports/atmel-samd/peripherals/adc.h create mode 100644 ports/atmel-samd/peripherals/cache.h create mode 100644 ports/atmel-samd/peripherals/clocks.c create mode 100644 ports/atmel-samd/peripherals/clocks.h create mode 100644 ports/atmel-samd/peripherals/dma.c create mode 100644 ports/atmel-samd/peripherals/dma.h create mode 100644 ports/atmel-samd/peripherals/events.c create mode 100644 ports/atmel-samd/peripherals/events.h create mode 100644 ports/atmel-samd/peripherals/i2s.c create mode 100644 ports/atmel-samd/peripherals/i2s.h create mode 100644 ports/atmel-samd/peripherals/pins.h create mode 100644 ports/atmel-samd/peripherals/samd21/adc.c create mode 100644 ports/atmel-samd/peripherals/samd21/cache.c create mode 100644 ports/atmel-samd/peripherals/samd21/clocks.c create mode 100644 ports/atmel-samd/peripherals/samd21/dma.c create mode 100644 ports/atmel-samd/peripherals/samd21/events.c create mode 100644 ports/atmel-samd/peripherals/samd21/i2s.c create mode 100644 ports/atmel-samd/peripherals/samd21/pins.c create mode 100644 ports/atmel-samd/peripherals/samd21/pins.h create mode 100644 ports/atmel-samd/peripherals/samd21/sercom.c create mode 100644 ports/atmel-samd/peripherals/samd21/timers.c create mode 100644 ports/atmel-samd/peripherals/samd51/adc.c create mode 100644 ports/atmel-samd/peripherals/samd51/cache.c create mode 100644 ports/atmel-samd/peripherals/samd51/clocks.c create mode 100644 ports/atmel-samd/peripherals/samd51/dma.c create mode 100644 ports/atmel-samd/peripherals/samd51/events.c create mode 100644 ports/atmel-samd/peripherals/samd51/i2s.c create mode 100644 ports/atmel-samd/peripherals/samd51/pins.c create mode 100644 ports/atmel-samd/peripherals/samd51/pins.h create mode 100644 ports/atmel-samd/peripherals/samd51/sercom.c create mode 100644 ports/atmel-samd/peripherals/samd51/timers.c create mode 100644 ports/atmel-samd/peripherals/sercom.c create mode 100644 ports/atmel-samd/peripherals/sercom.h create mode 100644 ports/atmel-samd/peripherals/timers.c create mode 100644 ports/atmel-samd/peripherals/timers.h delete mode 100644 ports/atmel-samd/pins.h delete mode 100644 ports/atmel-samd/samd21_clocks.c delete mode 100644 ports/atmel-samd/samd21_peripherals.c delete mode 100644 ports/atmel-samd/samd21_peripherals.h delete mode 100644 ports/atmel-samd/samd21_pins.c delete mode 100644 ports/atmel-samd/samd21_pins.h delete mode 100644 ports/atmel-samd/samd51_clocks.c delete mode 100644 ports/atmel-samd/samd51_peripherals.c delete mode 100644 ports/atmel-samd/samd51_peripherals.h delete mode 100644 ports/atmel-samd/samd51_pins.c delete mode 100644 ports/atmel-samd/samd51_pins.h delete mode 100644 ports/atmel-samd/shared_dma.c delete mode 100644 ports/atmel-samd/shared_dma.h delete mode 100644 ports/atmel-samd/timers.c delete mode 100644 ports/atmel-samd/timers.h create mode 100644 shared-bindings/rotaryio/IncrementalEncoder.c create mode 100644 shared-bindings/rotaryio/IncrementalEncoder.h create mode 100644 shared-bindings/rotaryio/__init__.c create mode 100644 shared-bindings/rotaryio/__init__.h 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/board.c b/ports/atmel-samd/boards/metro_m4_express_revb/board.c deleted file mode 100644 index a98385d29..000000000 --- a/ports/atmel-samd/boards/metro_m4_express_revb/board.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "boards/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.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); - - 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); -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} 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 -// 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/clocks.c b/ports/atmel-samd/clocks.c deleted file mode 100644 index a890210bf..000000000 --- a/ports/atmel-samd/clocks.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 "clocks.h" - -#include "hpl_gclk_config.h" - -#include "shared-bindings/microcontroller/__init__.h" - -#include "py/runtime.h" - -// TODO(tannewt): Should we have a way of sharing GCLKs based on their speed? Divisor doesn't -// gaurantee speed because it depends on the source. -uint8_t find_free_gclk(uint16_t divisor) { - if (divisor > 0xff) { - if (gclk_enabled(1)) { - return 0xff; - } - return 1; - } - uint8_t first_8_bit = 2; - #ifdef SAMD21 - first_8_bit = 3; - if (divisor <= (1 << 5) && !gclk_enabled(2)) { - return 2; - } - #endif - for (uint8_t i = first_8_bit; i < GCLK_GEN_NUM; i++) { - if (!gclk_enabled(i)) { - return i; - } - } - return 0xff; -} - -void reset_gclks(void) { - // Never reset GCLK0 because its used for the core - #if CONF_GCLK_GEN_1_GENEN == 0 - disable_gclk(1); - #endif - #if CONF_GCLK_GEN_2_GENEN == 0 - disable_gclk(2); - #endif - #if CONF_GCLK_GEN_3_GENEN == 0 - disable_gclk(3); - #endif - #if CONF_GCLK_GEN_4_GENEN == 0 - disable_gclk(4); - #endif - #if CONF_GCLK_GEN_5_GENEN == 0 - disable_gclk(5); - #endif - #if CONF_GCLK_GEN_6_GENEN == 0 - disable_gclk(6); - #endif - #if CONF_GCLK_GEN_7_GENEN == 0 - disable_gclk(7); - #endif - #ifdef SAMD51 - #if CONF_GCLK_GEN_8_GENEN == 0 - disable_gclk(8); - #endif - #if CONF_GCLK_GEN_9_GENEN == 0 - disable_gclk(9); - #endif - #if CONF_GCLK_GEN_10_GENEN == 0 - disable_gclk(10); - #endif - #if CONF_GCLK_GEN_11_GENEN == 0 - disable_gclk(11); - #endif - #endif -} diff --git a/ports/atmel-samd/clocks.h b/ports/atmel-samd/clocks.h deleted file mode 100644 index 6b7cfedce..000000000 --- a/ports/atmel-samd/clocks.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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_CLOCKS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_CLOCKS_H - -#include -#include - -#include "include/sam.h" -#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL - -#ifdef SAMD51 -#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL_Val -#endif -#ifdef SAMD21 -#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL48M_Val -#endif - -#define CORE_GCLK 0 - -uint8_t find_free_gclk(uint16_t divisor); - -bool gclk_enabled(uint8_t gclk); -void disable_gclk(uint8_t gclk); -void reset_gclks(void); - -void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral); -void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral); - -void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor); -void disable_clock_generator(uint8_t gclk); - -static inline bool board_has_crystal(void) { -#ifdef BOARD_HAS_CRYSTAL - return BOARD_HAS_CRYSTAL == 1; -#else - return false; -#endif -} - -void clock_init(void); - -bool clock_get_enabled(uint8_t type, uint8_t index); -bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index); -uint32_t clock_get_frequency(uint8_t type, uint8_t index); -uint32_t clock_get_calibration(uint8_t type, uint8_t index); -int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_CLOCKS_H 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 + +#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/events.c b/ports/atmel-samd/events.c deleted file mode 100644 index 05a2ae8a7..000000000 --- a/ports/atmel-samd/events.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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 "events.h" - -#include "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) { - 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 -} - -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 | - EVSYS_CHANNEL_EDGSEL_RISING_EDGE; - if (channel > 7) { - uint8_t value = 1 << (channel - 7); - EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVDp8(value) | EVSYS_INTFLAG_OVRp8(value); - EVSYS->INTENSET.reg = EVSYS_INTENSET_EVDp8(value) | EVSYS_INTENSET_OVRp8(value); - } else { - uint8_t value = 1 << channel; - 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; - // Only clear if we know its active, otherwise there is the possibility it becomes active - // after we check but before we clear. - if (active) { - EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVDp8(value) | EVSYS_INTFLAG_OVRp8(value); - } - } else { - uint8_t value = 1 << channel; - active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVD(value)) != 0; - if (active) { - 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; - } else { - 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/events.h b/ports/atmel-samd/events.h deleted file mode 100644 index 64093c0ab..000000000 --- a/ports/atmel-samd/events.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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_EVENTS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H - -#include -#include - -#include "include/sam.h" - -void turn_on_event_system(void); -void reset_event_system(void); -uint8_t find_async_event_channel(void); -uint8_t find_sync_event_channel(void); -void disable_event_channel(uint8_t channel_number); -void disable_event_user(uint8_t user_number); -void connect_event_user_to_channel(uint8_t user, uint8_t channel); -void init_async_event_channel(uint8_t channel, uint8_t generator); -void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator); -bool event_interrupt_active(uint8_t channel); -bool event_interrupt_overflow(uint8_t channel); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H 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 #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/i2s.c b/ports/atmel-samd/i2s.c deleted file mode 100644 index 663ecdd1d..000000000 --- a/ports/atmel-samd/i2s.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 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; - while (I2S->SYNCBUSY.bit.TXEN == 1) {} - } else { - while (I2S->SYNCBUSY.bit.RXEN == 1) {} - I2S->CTRLA.bit.RXEN = enable; - while (I2S->SYNCBUSY.bit.RXEN == 1) {} - } - #endif -} diff --git a/ports/atmel-samd/i2s.h b/ports/atmel-samd/i2s.h deleted file mode 100644 index 7df667b2a..000000000 --- a/ports/atmel-samd/i2s.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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_I2S_H -#define MICROPY_INCLUDED_ATMEL_SAMD_I2S_H - -#include -#include - -#include "include/sam.h" - -void turn_on_i2s(void); - -void i2s_set_enable(bool enable); -void i2s_set_clock_unit_enable(uint8_t clock, bool enable); -void i2s_set_serializer_enable(uint8_t serializer, bool enable); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_I2S_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/peripherals.c b/ports/atmel-samd/peripherals.c deleted file mode 100644 index c75a1f43b..000000000 --- a/ports/atmel-samd/peripherals.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 "peripherals.h" - -#include "hpl_sercom_config.h" - -// Routines that are the same across all samd variants. - - -// Convert frequency to clock-speed-dependent value. Return 255 if > 255. -uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate) { - uint32_t baud_reg_value = (uint32_t) (((float) PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY / - (2 * baudrate)) - 0.5f); - return (uint8_t) (baud_reg_value > 255 ? 255 : baud_reg_value); -} - -// Convert BAUD reg value back to a frequency. -uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value) { - return PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY / (2 * (baud_reg_value + 1)); -} diff --git a/ports/atmel-samd/peripherals.h b/ports/atmel-samd/peripherals.h deleted file mode 100644 index 8a07c0045..000000000 --- a/ports/atmel-samd/peripherals.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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_ATMEL_SAMD_PERIPHERALS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H - -#include - -#include "mpconfigport.h" - -// Routines common across chip families. -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); - -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 diff --git a/ports/atmel-samd/peripherals/adc.h b/ports/atmel-samd/peripherals/adc.h new file mode 100644 index 000000000..6530b1dcd --- /dev/null +++ b/ports/atmel-samd/peripherals/adc.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 by 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. + */ + +#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_adc_setup(struct adc_sync_descriptor *adc, Adc *instance); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H diff --git a/ports/atmel-samd/peripherals/cache.h b/ports/atmel-samd/peripherals/cache.h new file mode 100644 index 000000000..b260568a3 --- /dev/null +++ b/ports/atmel-samd/peripherals/cache.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 by 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H + +void samd_peripherals_disable_and_clear_cache(void); +void samd_peripherals_enable_cache(void); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H diff --git a/ports/atmel-samd/peripherals/clocks.c b/ports/atmel-samd/peripherals/clocks.c new file mode 100644 index 000000000..a890210bf --- /dev/null +++ b/ports/atmel-samd/peripherals/clocks.c @@ -0,0 +1,96 @@ +/* + * 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 "clocks.h" + +#include "hpl_gclk_config.h" + +#include "shared-bindings/microcontroller/__init__.h" + +#include "py/runtime.h" + +// TODO(tannewt): Should we have a way of sharing GCLKs based on their speed? Divisor doesn't +// gaurantee speed because it depends on the source. +uint8_t find_free_gclk(uint16_t divisor) { + if (divisor > 0xff) { + if (gclk_enabled(1)) { + return 0xff; + } + return 1; + } + uint8_t first_8_bit = 2; + #ifdef SAMD21 + first_8_bit = 3; + if (divisor <= (1 << 5) && !gclk_enabled(2)) { + return 2; + } + #endif + for (uint8_t i = first_8_bit; i < GCLK_GEN_NUM; i++) { + if (!gclk_enabled(i)) { + return i; + } + } + return 0xff; +} + +void reset_gclks(void) { + // Never reset GCLK0 because its used for the core + #if CONF_GCLK_GEN_1_GENEN == 0 + disable_gclk(1); + #endif + #if CONF_GCLK_GEN_2_GENEN == 0 + disable_gclk(2); + #endif + #if CONF_GCLK_GEN_3_GENEN == 0 + disable_gclk(3); + #endif + #if CONF_GCLK_GEN_4_GENEN == 0 + disable_gclk(4); + #endif + #if CONF_GCLK_GEN_5_GENEN == 0 + disable_gclk(5); + #endif + #if CONF_GCLK_GEN_6_GENEN == 0 + disable_gclk(6); + #endif + #if CONF_GCLK_GEN_7_GENEN == 0 + disable_gclk(7); + #endif + #ifdef SAMD51 + #if CONF_GCLK_GEN_8_GENEN == 0 + disable_gclk(8); + #endif + #if CONF_GCLK_GEN_9_GENEN == 0 + disable_gclk(9); + #endif + #if CONF_GCLK_GEN_10_GENEN == 0 + disable_gclk(10); + #endif + #if CONF_GCLK_GEN_11_GENEN == 0 + disable_gclk(11); + #endif + #endif +} diff --git a/ports/atmel-samd/peripherals/clocks.h b/ports/atmel-samd/peripherals/clocks.h new file mode 100644 index 000000000..6b7cfedce --- /dev/null +++ b/ports/atmel-samd/peripherals/clocks.h @@ -0,0 +1,73 @@ +/* + * 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_CLOCKS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_CLOCKS_H + +#include +#include + +#include "include/sam.h" +#include "mpconfigboard.h" // for BOARD_HAS_CRYSTAL + +#ifdef SAMD51 +#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL_Val +#endif +#ifdef SAMD21 +#define CLOCK_48MHZ GCLK_GENCTRL_SRC_DFLL48M_Val +#endif + +#define CORE_GCLK 0 + +uint8_t find_free_gclk(uint16_t divisor); + +bool gclk_enabled(uint8_t gclk); +void disable_gclk(uint8_t gclk); +void reset_gclks(void); + +void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral); +void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral); + +void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor); +void disable_clock_generator(uint8_t gclk); + +static inline bool board_has_crystal(void) { +#ifdef BOARD_HAS_CRYSTAL + return BOARD_HAS_CRYSTAL == 1; +#else + return false; +#endif +} + +void clock_init(void); + +bool clock_get_enabled(uint8_t type, uint8_t index); +bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index); +uint32_t clock_get_frequency(uint8_t type, uint8_t index); +uint32_t clock_get_calibration(uint8_t type, uint8_t index); +int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_CLOCKS_H diff --git a/ports/atmel-samd/peripherals/dma.c b/ports/atmel-samd/peripherals/dma.c new file mode 100644 index 000000000..664c6aea8 --- /dev/null +++ b/ports/atmel-samd/peripherals/dma.c @@ -0,0 +1,244 @@ +/* + * 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 + +#include "py/gc.h" +#include "py/mpstate.h" + +#include "hal/utils/include/utils.h" + +#include "shared-bindings/microcontroller/__init__.h" + +COMPILER_ALIGNED(16) static DmacDescriptor dma_descriptors[DMA_CHANNEL_COUNT]; + +// Don't use these directly. They are used by the DMA engine itself. +COMPILER_ALIGNED(16) static DmacDescriptor write_back_descriptors[DMA_CHANNEL_COUNT]; + +#ifdef SAMD21 +#define FIRST_SERCOM_RX_TRIGSRC 0x01 +#define FIRST_SERCOM_TX_TRIGSRC 0x02 +#endif +#ifdef SAMD51 +#define FIRST_SERCOM_RX_TRIGSRC 0x04 +#define FIRST_SERCOM_TX_TRIGSRC 0x05 +#endif + +void init_shared_dma(void) { + // Turn on the clocks + #ifdef SAMD51 + MCLK->AHBMASK.reg |= MCLK_AHBMASK_DMAC; + #endif + + #ifdef SAMD21 + PM->AHBMASK.reg |= PM_AHBMASK_DMAC; + PM->APBBMASK.reg |= PM_APBBMASK_DMAC; + #endif + + DMAC->CTRL.reg = DMAC_CTRL_SWRST; + + DMAC->BASEADDR.reg = (uint32_t) dma_descriptors; + DMAC->WRBADDR.reg = (uint32_t) write_back_descriptors; + + DMAC->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN0; + + for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { + dma_configure(i, 0, true); + } +} + +// Do write and read simultaneously. If buffer_out is NULL, write the tx byte over and over. +// If buffer_out is a real buffer, ignore tx. +// DMAs buffer_out -> dest +// DMAs src -> buffer_in +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 (!dma_channel_free(SHARED_TX_CHANNEL) || + (buffer_in != NULL && !dma_channel_free(SHARED_RX_CHANNEL))) { + return -1; + } + + uint32_t beat_size = DMAC_BTCTRL_BEATSIZE_BYTE; + bool sercom = true; + bool tx_active = false; + bool rx_active = false; + uint16_t beat_length = length; + #ifdef SAMD51 + if (peripheral == QSPI) { + // Check input alignment on word boundaries. + if ((((uint32_t) buffer_in) & 0x3) != 0 || + (((uint32_t) buffer_out) & 0x3) != 0) { + return -3; + } + beat_size = DMAC_BTCTRL_BEATSIZE_WORD | DMAC_BTCTRL_SRCINC | DMAC_BTCTRL_DSTINC; + beat_length /= 4; + sercom = false; + if (buffer_out != NULL) { + dma_configure(SHARED_TX_CHANNEL, QSPI_DMAC_ID_TX, false); + tx_active = true; + } else { + dma_configure(SHARED_RX_CHANNEL, QSPI_DMAC_ID_RX, false); + rx_active = true; + } + + } else { + #endif + + // sercom index is incorrect for SAMD51 + dma_configure(SHARED_TX_CHANNEL, sercom_index(peripheral) * 2 + FIRST_SERCOM_TX_TRIGSRC, false); + tx_active = true; + if (buffer_in != NULL) { + dma_configure(SHARED_RX_CHANNEL, sercom_index(peripheral) * 2 + FIRST_SERCOM_RX_TRIGSRC, false); + rx_active = true; + } + + #ifdef SAMD51 + } + #endif + + // Set up RX first. + if (rx_active) { + DmacDescriptor* rx_descriptor = &dma_descriptors[SHARED_RX_CHANNEL]; + rx_descriptor->BTCTRL.reg = beat_size | DMAC_BTCTRL_DSTINC; + rx_descriptor->BTCNT.reg = beat_length; + rx_descriptor->SRCADDR.reg = ((uint32_t) src); + #ifdef SAMD51 + if (peripheral == QSPI) { + rx_descriptor->SRCADDR.reg = ((uint32_t) src + length); + } + #endif + rx_descriptor->DSTADDR.reg = ((uint32_t)buffer_in + length); + rx_descriptor->BTCTRL.bit.VALID = true; + } + + // Set up TX second. + if (tx_active) { + DmacDescriptor* tx_descriptor = &dma_descriptors[SHARED_TX_CHANNEL]; + tx_descriptor->BTCTRL.reg = beat_size; + tx_descriptor->BTCNT.reg = beat_length; + + if (buffer_out != NULL) { + tx_descriptor->SRCADDR.reg = ((uint32_t)buffer_out + length); + tx_descriptor->BTCTRL.reg |= DMAC_BTCTRL_SRCINC; + } else { + tx_descriptor->SRCADDR.reg = ((uint32_t) &tx); + } + tx_descriptor->DSTADDR.reg = ((uint32_t) dest); + tx_descriptor->BTCTRL.bit.VALID = true; + } + if (sercom) { + SercomSpi *s = &((Sercom*) peripheral)->SPI; + s->INTFLAG.reg = SERCOM_SPI_INTFLAG_RXC | SERCOM_SPI_INTFLAG_DRE; + } else { + //QSPI->INTFLAG.reg = QSPI_INTFLAG_RXC | QSPI_INTFLAG_DRE; + } + // Start the RX job first so we don't miss the first byte. The TX job clocks + // the output. + if (rx_active) { + dma_enable_channel(SHARED_RX_CHANNEL); + } + if (tx_active) { + dma_enable_channel(SHARED_TX_CHANNEL); + } + + + if (sercom) { + //DMAC->SWTRIGCTRL.reg |= (1 << SHARED_TX_CHANNEL); + } else { + // Do a manual copy to trigger then DMA. We do 32-bit accesses to match the DMA. + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + if (rx_active) { + //buffer_in[0] = *src; + DMAC->SWTRIGCTRL.reg |= (1 << SHARED_RX_CHANNEL); + } else { + //*(uint32_t*)dest = ((uint32_t*) buffer_out)[0]; + } + #pragma GCC diagnostic pop + } + + // Channels cycle between Suspend -> Pending -> Busy and back while transfering. So, we check + // the channels transfer status for an error or completion. + if (rx_active) { + while ((dma_transfer_status(SHARED_RX_CHANNEL) & 0x3) == 0) {} + } + if (tx_active) { + while ((dma_transfer_status(SHARED_TX_CHANNEL) & 0x3) == 0) {} + } + + if (sercom) { + Sercom* s = (Sercom*) peripheral; + // Wait for the SPI transfer to complete. + while (s->SPI.INTFLAG.bit.TXC == 0) {} + + // This transmit will cause the RX buffer overflow but we're OK with that. + // So, read the garbage and clear the overflow flag. + if (!rx_active) { + while (s->SPI.INTFLAG.bit.RXC == 1) { + s->SPI.DATA.reg; + } + s->SPI.STATUS.bit.BUFOVF = 1; + s->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_ERROR; + } + } + + if ((!rx_active || dma_transfer_status(SHARED_RX_CHANNEL) == DMAC_CHINTFLAG_TCMPL) && + (!tx_active || dma_transfer_status(SHARED_TX_CHANNEL) == DMAC_CHINTFLAG_TCMPL)) { + return length; + } + return -2; +} + + +int32_t sercom_dma_transfer(Sercom* sercom, const uint8_t* buffer_out, uint8_t* buffer_in, + uint32_t length) { + return shared_dma_transfer(sercom, buffer_out, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, buffer_in, length, 0); +} + +int32_t sercom_dma_write(Sercom* sercom, const uint8_t* buffer, uint32_t length) { + return shared_dma_transfer(sercom, buffer, &sercom->SPI.DATA.reg, NULL, NULL, length, 0); +} + +int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_t tx) { + return shared_dma_transfer(sercom, NULL, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, buffer, length, tx); +} + +#ifdef SAMD51 +int32_t qspi_dma_write(uint32_t address, const uint8_t* buffer, uint32_t length) { + return shared_dma_transfer(QSPI, buffer, (uint32_t*) (QSPI_AHB + address), NULL, NULL, length, 0); +} + +int32_t qspi_dma_read(uint32_t address, uint8_t* buffer, uint32_t length) { + return shared_dma_transfer(QSPI, NULL, NULL, (uint32_t*) (QSPI_AHB + address), buffer, length, 0); +} +#endif + +DmacDescriptor* dma_descriptor(uint8_t channel_number) { + return &dma_descriptors[channel_number]; +} diff --git a/ports/atmel-samd/peripherals/dma.h b/ports/atmel-samd/peripherals/dma.h new file mode 100644 index 000000000..cf256b962 --- /dev/null +++ b/ports/atmel-samd/peripherals/dma.h @@ -0,0 +1,68 @@ +/* + * 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H +#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H + +#include +#include + +#include "include/sam.h" + +// We allocate DMA resources for the entire lifecycle of the board (not the +// vm) because the general_dma resource will be shared between the REPL and SPI +// flash. Both uses must block each other in order to prevent conflict. +#define AUDIO_DMA_CHANNEL_COUNT 3 +#define DMA_CHANNEL_COUNT (AUDIO_DMA_CHANNEL_COUNT + 2) +#define SHARED_TX_CHANNEL (DMA_CHANNEL_COUNT - 2) +#define SHARED_RX_CHANNEL (DMA_CHANNEL_COUNT - 1) + +volatile bool audio_dma_in_use; + +void init_shared_dma(void); + +#ifdef SAMD51 +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); + +void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event); +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_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 + +#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/peripherals/events.h b/ports/atmel-samd/peripherals/events.h new file mode 100644 index 000000000..0073142f1 --- /dev/null +++ b/ports/atmel-samd/peripherals/events.h @@ -0,0 +1,49 @@ +/* + * 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_EVENTS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H + +#include +#include + +#include "include/sam.h" + +void turn_on_event_system(void); +void reset_event_system(void); +uint8_t find_async_event_channel(void); +uint8_t find_sync_event_channel(void); +void disable_event_channel(uint8_t channel_number); +void disable_event_user(uint8_t user_number); +void connect_event_user_to_channel(uint8_t user, uint8_t channel); +void init_async_event_channel(uint8_t channel, uint8_t generator); +void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator); +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/peripherals/i2s.h b/ports/atmel-samd/peripherals/i2s.h new file mode 100644 index 000000000..7df667b2a --- /dev/null +++ b/ports/atmel-samd/peripherals/i2s.h @@ -0,0 +1,41 @@ +/* + * 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_I2S_H +#define MICROPY_INCLUDED_ATMEL_SAMD_I2S_H + +#include +#include + +#include "include/sam.h" + +void turn_on_i2s(void); + +void i2s_set_enable(bool enable); +void i2s_set_clock_unit_enable(uint8_t clock, bool enable); +void i2s_set_serializer_enable(uint8_t serializer, bool enable); + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_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/peripherals/samd21/cache.c b/ports/atmel-samd/peripherals/samd21/cache.c new file mode 100644 index 000000000..641b5e115 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/cache.c @@ -0,0 +1,32 @@ +/* + * 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. + */ + +// The SAMD21 doesn't have a cache so we have nothing to do. +void samd_peripherals_disable_and_clear_cache(void) { +} + +void samd_peripherals_enable_cache(void) { +} diff --git a/ports/atmel-samd/peripherals/samd21/clocks.c b/ports/atmel-samd/peripherals/samd21/clocks.c new file mode 100644 index 000000000..94b515814 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/clocks.c @@ -0,0 +1,425 @@ +/* + * 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/clocks.h" + +#include "hpl_gclk_config.h" + +#include "bindings/samd/Clock.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "py/runtime.h" + +bool gclk_enabled(uint8_t gclk) { + common_hal_mcu_disable_interrupts(); + // Explicitly do a byte write so the peripheral knows we're just wanting to read the channel + // rather than write to it. + *((uint8_t*) &GCLK->GENCTRL.reg) = gclk; + while (GCLK->STATUS.bit.SYNCBUSY == 1) {} + bool enabled = GCLK->GENCTRL.bit.GENEN; + common_hal_mcu_enable_interrupts(); + return enabled; +} + +void disable_gclk(uint8_t gclk) { + while (GCLK->STATUS.bit.SYNCBUSY == 1) {} + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk); + while (GCLK->STATUS.bit.SYNCBUSY == 1) {} +} + +void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral) { + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(peripheral) | GCLK_CLKCTRL_GEN(gclk) | GCLK_CLKCTRL_CLKEN; +} + +void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral) { + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(peripheral) | GCLK_CLKCTRL_GEN(gclk); +} + +void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor) { + uint32_t divsel = 0; + if (gclk == 2 && divisor > 31) { + divsel = GCLK_GENCTRL_DIVSEL; + for (int i = 15; i > 4; i++) { + if (divisor & (1 << i)) { + divisor = i - 1; + break; + } + } + } + GCLK->GENDIV.reg = GCLK_GENDIV_ID(gclk) | GCLK_GENDIV_DIV(divisor); + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk) | GCLK_GENCTRL_SRC(source) | divsel | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN; + while (GCLK->STATUS.bit.SYNCBUSY != 0) {} +} + +void disable_clock_generator(uint8_t gclk) { + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk); + while (GCLK->STATUS.bit.SYNCBUSY != 0) {} +} + +static void init_clock_source_osc8m(void) { + // Preserve CALIB and FRANGE + SYSCTRL->OSC8M.bit.ONDEMAND = 0; + SYSCTRL->OSC8M.bit.PRESC = 3; + SYSCTRL->OSC8M.bit.ENABLE = 1; + while (!SYSCTRL->PCLKSR.bit.OSC8MRDY) {} +} + +static void init_clock_source_osc32k(void) { + uint32_t calib = (*((uint32_t *)FUSES_OSC32K_CAL_ADDR) & FUSES_OSC32K_CAL_Msk) >> FUSES_OSC32K_CAL_Pos; + SYSCTRL->OSC32K.reg = SYSCTRL_OSC32K_CALIB(calib) | + SYSCTRL_OSC32K_EN32K | + SYSCTRL_OSC32K_ENABLE; + while (!SYSCTRL->PCLKSR.bit.OSC32KRDY) {} +} + +static void init_clock_source_xosc32k(void) { + SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_EN32K | + SYSCTRL_XOSC32K_XTALEN | + SYSCTRL_XOSC32K_ENABLE; + while (!SYSCTRL->PCLKSR.bit.XOSC32KRDY) {} +} + +static void init_clock_source_dfll48m(void) { + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; + while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {} + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | + SYSCTRL_DFLLMUL_FSTEP(1) | + SYSCTRL_DFLLMUL_MUL(48000); + uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos; + if (coarse == 0x3f) + coarse = 0x1f; + SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | + SYSCTRL_DFLLVAL_FINE(512); + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | + SYSCTRL_DFLLCTRL_USBCRM | + SYSCTRL_DFLLCTRL_MODE | + SYSCTRL_DFLLCTRL_ENABLE; + while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {} + while (GCLK->STATUS.bit.SYNCBUSY) {} +} + +void clock_init(void) +{ + init_clock_source_osc8m(); + if (board_has_crystal()) + init_clock_source_xosc32k(); + else + init_clock_source_osc32k(); + enable_clock_generator(0, GCLK_GENCTRL_SRC_DFLL48M_Val, 1); + enable_clock_generator(1, GCLK_GENCTRL_SRC_DFLL48M_Val, 150); + init_clock_source_dfll48m(); + if (board_has_crystal()) + enable_clock_generator(2, GCLK_GENCTRL_SRC_XOSC32K_Val, 32); + else + enable_clock_generator(2, GCLK_GENCTRL_SRC_OSC32K_Val, 32); +} + +static bool clk_enabled(uint8_t clk) { + common_hal_mcu_disable_interrupts(); + *((uint8_t*) &GCLK->CLKCTRL.reg) = clk; + while (GCLK->STATUS.bit.SYNCBUSY == 1) {} + bool enabled = GCLK->CLKCTRL.bit.CLKEN; + common_hal_mcu_enable_interrupts(); + return enabled; +} + +static uint8_t clk_get_generator(uint8_t clk) { + common_hal_mcu_disable_interrupts(); + *((uint8_t*) &GCLK->CLKCTRL.reg) = clk; + while (GCLK->STATUS.bit.SYNCBUSY == 1) {} + uint8_t gen = GCLK->CLKCTRL.bit.GEN; + common_hal_mcu_enable_interrupts(); + return gen; +} + +static uint8_t generator_get_source(uint8_t gen) { + common_hal_mcu_disable_interrupts(); + *((uint8_t*) &GCLK->GENCTRL.reg) = gen; + while (GCLK->STATUS.bit.SYNCBUSY == 1) {} + uint8_t src = GCLK->GENCTRL.bit.SRC; + common_hal_mcu_enable_interrupts(); + return src; +} + +static bool osc_enabled(uint8_t index) { + switch (index) { + case GCLK_SOURCE_XOSC: + return SYSCTRL->XOSC.bit.ENABLE; + // TODO: GCLK_SOURCE_GCLKIN + // TODO: GCLK_SOURCE_GCLKGEN1 + case GCLK_SOURCE_OSCULP32K: + return true; + case GCLK_SOURCE_OSC32K: + return SYSCTRL->OSC32K.bit.ENABLE; + case GCLK_SOURCE_XOSC32K: + return SYSCTRL->XOSC32K.bit.ENABLE; + case GCLK_SOURCE_OSC8M: + return SYSCTRL->OSC8M.bit.ENABLE; + case GCLK_SOURCE_DFLL48M: + return SYSCTRL->DFLLCTRL.bit.ENABLE; + case GCLK_SOURCE_DPLL96M: + return SYSCTRL->DPLLCTRLA.bit.ENABLE; + }; + return false; +} + +static uint32_t osc_get_frequency(uint8_t index) { + switch (index) { + case GCLK_SOURCE_XOSC: + return 0; // unknown 0.4-32MHz + // TODO: GCLK_SOURCE_GCLKIN + // TODO: GCLK_SOURCE_GCLKGEN1 + case GCLK_SOURCE_OSCULP32K: + case GCLK_SOURCE_OSC32K: + case GCLK_SOURCE_XOSC32K: + return 32768; + case GCLK_SOURCE_OSC8M: + return 8000000; + case GCLK_SOURCE_DFLL48M: + return 48000000; + case GCLK_SOURCE_DPLL96M: + return 96000000; + } + return 0; +} + +bool clock_get_enabled(uint8_t type, uint8_t index) { + if (type == 0) + return osc_enabled(index); + if (type == 1) + return clk_enabled(index); + if (type == 2) + return SysTick->CTRL & SysTick_CTRL_ENABLE_Msk; + return false; +} + +bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index) { + if (type == 1 && index <= 0x24 && clk_enabled(index)) { + *p_type = 0; + *p_index = generator_get_source(clk_get_generator(index)); + return true; + } + if (type == 2 && index == 0) { + *p_type = 0; + *p_index = generator_get_source(0); + return true; + } + return false; +} + +uint32_t clock_get_frequency(uint8_t type, uint8_t index) { + if (type == 0) { + return osc_get_frequency(index); + } + if (type == 1) { + if (!clk_enabled(index)) + return 0; + + uint8_t gen = clk_get_generator(index); + + common_hal_mcu_disable_interrupts(); + *((uint8_t*) &GCLK->GENCTRL.reg) = gen; + *((uint8_t*) &GCLK->GENDIV.reg) = gen; + while (GCLK->STATUS.bit.SYNCBUSY == 1) {} + + uint8_t src = GCLK->GENCTRL.bit.SRC; + uint32_t div; + if (GCLK->GENCTRL.bit.DIVSEL) { + div = 1 << (GCLK->GENDIV.bit.DIV + 1); + } else { + div = GCLK->GENDIV.bit.DIV; + if (!div) + div = 1; + } + common_hal_mcu_enable_interrupts(); + + return osc_get_frequency(src) / div; + } + if (type == 2 && index == 0) { + return clock_get_frequency(0, generator_get_source(0)) / SysTick->LOAD; + } + return 0; +} + +uint32_t clock_get_calibration(uint8_t type, uint8_t index) { + if (type == 0) { + switch (index) { + case GCLK_SOURCE_OSCULP32K: + return SYSCTRL->OSCULP32K.bit.CALIB; + case GCLK_SOURCE_OSC32K: + return SYSCTRL->OSC32K.bit.CALIB; + case GCLK_SOURCE_OSC8M: + return SYSCTRL->OSC8M.bit.CALIB; + }; + } + if (type == 2 && index == 0) { + return SysTick->LOAD + 1; + } + return 0; +} + +int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) { + if (type == 0) { + switch (index) { + case GCLK_SOURCE_OSCULP32K: + if (val > 0x1f) + return -1; + SYSCTRL->OSCULP32K.bit.CALIB = val; + return 0; + case GCLK_SOURCE_OSC32K: + if (val > 0x7f) + return -1; + SYSCTRL->OSC32K.bit.CALIB = val; + return 0; + case GCLK_SOURCE_OSC8M: + if (val > 0xfff) + return -1; + SYSCTRL->OSC8M.bit.CALIB = val; + return 0; + }; + } + if (type == 2 && index == 0) { + if (val < 0x1000 || val > 0x1000000) + return -1; + SysTick->LOAD = val - 1; + return 0; + } + return -2; // calibration is read only +} + +#ifdef SAMD21_EXPOSE_ALL_CLOCKS +CLOCK_SOURCE(XOSC); +CLOCK_SOURCE(GCLKIN); +CLOCK_SOURCE(GCLKGEN1); +CLOCK_SOURCE(OSCULP32K); +#endif +CLOCK_SOURCE(OSC32K); +CLOCK_SOURCE(XOSC32K); +#ifdef SAMD21_EXPOSE_ALL_CLOCKS +CLOCK_SOURCE(OSC8M); +CLOCK_SOURCE(DFLL48M); +CLOCK_SOURCE(DPLL96M); + +CLOCK_GCLK_(SYSCTRL, DFLL48); +CLOCK_GCLK_(SYSCTRL, FDPLL); +CLOCK_GCLK_(SYSCTRL, FDPLL32K); +CLOCK_GCLK(WDT); +#endif +CLOCK_GCLK(RTC); +#ifdef SAMD21_EXPOSE_ALL_CLOCKS +CLOCK_GCLK(EIC); +CLOCK_GCLK(USB); +CLOCK_GCLK_(EVSYS, 0); +CLOCK_GCLK_(EVSYS, 1); +CLOCK_GCLK_(EVSYS, 2); +CLOCK_GCLK_(EVSYS, 3); +CLOCK_GCLK_(EVSYS, 4); +CLOCK_GCLK_(EVSYS, 5); +CLOCK_GCLK_(EVSYS, 6); +CLOCK_GCLK_(EVSYS, 7); +CLOCK_GCLK_(EVSYS, 8); +CLOCK_GCLK_(EVSYS, 9); +CLOCK_GCLK_(EVSYS, 10); +CLOCK_GCLK_(EVSYS, 11); +CLOCK(SERCOMx_SLOW, 1, 19); +CLOCK_GCLK_(SERCOM0, CORE); +CLOCK_GCLK_(SERCOM1, CORE); +CLOCK_GCLK_(SERCOM2, CORE); +CLOCK_GCLK_(SERCOM3, CORE); +CLOCK_GCLK_(SERCOM4, CORE); +CLOCK_GCLK_(SERCOM5, CORE); +CLOCK(TCC0_TCC1, 1, 26); +CLOCK(TCC2_TCC3, 1, 27); +CLOCK(TC4_TC5, 1, 28); +CLOCK(TC6_TC7, 1, 29); +CLOCK_GCLK(ADC); +CLOCK_GCLK_(AC, DIG); +CLOCK_GCLK_(AC, ANA); +CLOCK_GCLK(DAC); +CLOCK_GCLK(PTC); +CLOCK_GCLK_(I2S, 0); +CLOCK_GCLK_(I2S, 1); + +CLOCK(SYSTICK, 2, 0); +#endif + +STATIC const mp_rom_map_elem_t samd_clock_global_dict_table[] = { +#ifdef SAMD21_EXPOSE_ALL_CLOCKS + CLOCK_ENTRY(XOSC), + CLOCK_ENTRY(GCLKIN), + CLOCK_ENTRY(GCLKGEN1), + CLOCK_ENTRY(OSCULP32K), +#endif + CLOCK_ENTRY(OSC32K), + CLOCK_ENTRY(XOSC32K), +#ifdef SAMD21_EXPOSE_ALL_CLOCKS + CLOCK_ENTRY(OSC8M), + CLOCK_ENTRY(DFLL48M), + CLOCK_ENTRY(DPLL96M), + CLOCK_ENTRY_(SYSCTRL, DFLL48), + CLOCK_ENTRY_(SYSCTRL, FDPLL), + CLOCK_ENTRY_(SYSCTRL, FDPLL32K), + CLOCK_ENTRY(WDT), +#endif + CLOCK_ENTRY(RTC), +#ifdef SAMD21_EXPOSE_ALL_CLOCKS + CLOCK_ENTRY(EIC), + CLOCK_ENTRY(USB), + CLOCK_ENTRY_(EVSYS, 0), + CLOCK_ENTRY_(EVSYS, 1), + CLOCK_ENTRY_(EVSYS, 2), + CLOCK_ENTRY_(EVSYS, 3), + CLOCK_ENTRY_(EVSYS, 4), + CLOCK_ENTRY_(EVSYS, 5), + CLOCK_ENTRY_(EVSYS, 6), + CLOCK_ENTRY_(EVSYS, 7), + CLOCK_ENTRY_(EVSYS, 8), + CLOCK_ENTRY_(EVSYS, 9), + CLOCK_ENTRY_(EVSYS, 10), + CLOCK_ENTRY_(EVSYS, 11), + CLOCK_ENTRY(SERCOMx_SLOW), + CLOCK_ENTRY_(SERCOM0, CORE), + CLOCK_ENTRY_(SERCOM1, CORE), + CLOCK_ENTRY_(SERCOM2, CORE), + CLOCK_ENTRY_(SERCOM3, CORE), + CLOCK_ENTRY_(SERCOM4, CORE), + CLOCK_ENTRY_(SERCOM5, CORE), + CLOCK_ENTRY(TCC0_TCC1), + CLOCK_ENTRY(TCC2_TCC3), + CLOCK_ENTRY(TC4_TC5), + CLOCK_ENTRY(TC6_TC7), + CLOCK_ENTRY(ADC), + CLOCK_ENTRY_(AC, DIG), + CLOCK_ENTRY_(AC, ANA), + CLOCK_ENTRY(DAC), + CLOCK_ENTRY(PTC), + CLOCK_ENTRY_(I2S, 0), + CLOCK_ENTRY_(I2S, 1), + + CLOCK_ENTRY(SYSTICK), +#endif +}; +MP_DEFINE_CONST_DICT(samd_clock_globals, samd_clock_global_dict_table); 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 + +#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/peripherals/samd21/events.c b/ports/atmel-samd/peripherals/samd21/events.c new file mode 100644 index 000000000..70dfa249d --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/events.c @@ -0,0 +1,118 @@ +/* + * 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 "hpl/pm/hpl_pm_base.h" + +void turn_on_event_system(void) { + _pm_enable_bus_clock(PM_BUS_APBC, EVSYS); +} + +void reset_event_system(void) { + EVSYS->CTRL.bit.SWRST = true; + _pm_disable_bus_clock(PM_BUS_APBC, EVSYS); +} + +bool event_channel_free(uint8_t channel) { + uint8_t generator; + // 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; + return generator == 0; +} + +void disable_event_channel(uint8_t channel_number) { + EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel_number); +} + +void disable_event_user(uint8_t user_number) { + EVSYS->USER.reg = EVSYS_USER_USER(user_number); +} + +void connect_event_user_to_channel(uint8_t user, uint8_t channel) { + EVSYS->USER.reg = EVSYS_USER_USER(user) | EVSYS_USER_CHANNEL(channel + 1); +} + +void init_async_event_channel(uint8_t channel, uint8_t generator) { + 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); + EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) | + EVSYS_CHANNEL_EVGEN(generator) | + EVSYS_CHANNEL_PATH_RESYNCHRONIZED | + EVSYS_CHANNEL_EDGSEL_RISING_EDGE; + if (channel > 7) { + uint8_t value = 1 << (channel - 7); + EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVDp8(value) | EVSYS_INTFLAG_OVRp8(value); + EVSYS->INTENSET.reg = EVSYS_INTENSET_EVDp8(value) | EVSYS_INTENSET_OVRp8(value); + } else { + uint8_t value = 1 << channel; + EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value); + EVSYS->INTENSET.reg = EVSYS_INTENSET_EVD(value) | EVSYS_INTENSET_OVR(value); + } +} + +bool event_interrupt_active(uint8_t channel) { + bool active = false; + if (channel > 7) { + uint8_t value = 1 << (channel - 7); + active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVDp8(value)) != 0; + // Only clear if we know its active, otherwise there is the possibility it becomes active + // after we check but before we clear. + if (active) { + EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVDp8(value) | EVSYS_INTFLAG_OVRp8(value); + } + } else { + uint8_t value = 1 << channel; + active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVD(value)) != 0; + if (active) { + EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value); + } + } + return active; +} + +bool event_interrupt_overflow(uint8_t channel) { + bool overflow = false; + if (channel > 7) { + uint8_t value = 1 << (channel - 7); + overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVRp8(value)) != 0; + } else { + uint8_t value = 1 << channel; + overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVR(value)) != 0; + } + return overflow; +} diff --git a/ports/atmel-samd/peripherals/samd21/i2s.c b/ports/atmel-samd/peripherals/samd21/i2s.c new file mode 100644 index 000000000..7df401601 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/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 "peripherals/i2s.h" + +#include "peripherals/clocks.h" + +#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl/pm/hpl_pm_base.h" + +void turn_on_i2s(void) { + _pm_enable_bus_clock(PM_BUS_APBC, I2S); +} + +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/peripherals/samd21/pins.c b/ports/atmel-samd/peripherals/samd21/pins.c new file mode 100644 index 000000000..bbb023a54 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/pins.c @@ -0,0 +1,529 @@ +/* + * 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. + */ + +#include "shared-bindings/microcontroller/Pin.h" + +#define SERCOM(sercom_index, p_pad) \ +{ \ + .index = sercom_index, \ + .pad = p_pad \ +} + +#define NO_SERCOM \ +{ \ + .index = 0x3f, \ + .pad = 0 \ +} + + +#define TCC(p_index, p_wave_output) \ +{ \ + .index = p_index, \ + .is_tc = false, \ + .wave_output = p_wave_output \ +} + +#define TC(p_index, p_wave_output) \ +{ \ + .index = p_index - 3, \ + .is_tc = true, \ + .wave_output = p_wave_output \ +} + +#define NO_TIMER TCC(0xff, 0) + +#define TOUCH(y_line) \ + .has_touch = true, \ + .touch_y_line = y_line, + +#define NO_TOUCH \ + .has_touch = false, + +#define EXTINT_CHANNEL(channel) \ + .has_extint = true, \ + .extint_channel = channel, + +#define NO_EXTINT \ + .has_extint = false, + +#define ADC_INPUT(input) input + +#define NO_ADC 0xff + +// This macro is used to simplify pin definition in boards//pins.c +#define PIN(p_name, p_extint, p_adc, p_touch, \ + p_primary_sercom, p_secondary_sercom, \ + p_primary_timer, p_secondary_timer) \ +const mcu_pin_obj_t pin_## p_name = { \ + { &mcu_pin_type }, \ + .name = MP_QSTR_## p_name, \ + .pin = (PIN_## p_name), \ + p_extint \ + p_touch \ + .adc_input = {p_adc}, \ + .timer = { p_primary_timer, p_secondary_timer}, \ + .sercom = {p_primary_sercom, p_secondary_sercom}, \ +} + +// Pins in datasheet order. +// NOTE(tannewt): TC wave out 0 is commented out because the first channel is +// used to vary the 16 bit timer's frequency. +#if defined(PIN_PA00) && !defined(IGNORE_PIN_PA00) +PIN(PA00, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(1, 0), + TCC(2, 0), + NO_TIMER); +#endif +#if defined(PIN_PA01) && !defined(IGNORE_PIN_PA01) +PIN(PA01, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(1, 1), + TCC(2, 1), + NO_TIMER); +#endif +#if defined(PIN_PA02) && !defined(IGNORE_PIN_PA02) +// Touch is not allowed on A0 (PA02) on Circuit Playground Express. +PIN(PA02, EXTINT_CHANNEL(2), ADC_INPUT(0), + #ifdef PA02_NO_TOUCH + NO_TOUCH, + #else + TOUCH(0), + #endif + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PA03) && !defined(IGNORE_PIN_PA03) +PIN(PA03, EXTINT_CHANNEL(3), ADC_INPUT(1), TOUCH(1), + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04) +PIN(PB04, EXTINT_CHANNEL(4), ADC_INPUT(12), TOUCH(10), + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05) +PIN(PB05, EXTINT_CHANNEL(5), ADC_INPUT(13), TOUCH(11), + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06) +PIN(PB06, EXTINT_CHANNEL(6), ADC_INPUT(14), TOUCH(12), + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07) +PIN(PB07, EXTINT_CHANNEL(7), ADC_INPUT(15), TOUCH(13), + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08) +PIN(PB08, EXTINT_CHANNEL(8), ADC_INPUT(2), TOUCH(14), + NO_SERCOM, + SERCOM(4, 0), + TC(4, 0), + NO_TIMER); +#endif +#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09) +PIN(PB09, EXTINT_CHANNEL(9), ADC_INPUT(3), TOUCH(15), + NO_SERCOM, + SERCOM(4, 1), + TC(4, 1), + NO_TIMER); +#endif +#if defined(PIN_PA04) && !defined(IGNORE_PIN_PA04) +PIN(PA04, EXTINT_CHANNEL(4), ADC_INPUT(4), TOUCH(2), + NO_SERCOM, + SERCOM(0, 0), + TCC(0, 0), + NO_TIMER); +#endif +#if defined(PIN_PA05) && !defined(IGNORE_PIN_PA05) +PIN(PA05, EXTINT_CHANNEL(5), ADC_INPUT(5), TOUCH(3), + NO_SERCOM, + SERCOM(0, 1), + TCC(0, 1), + NO_TIMER); +#endif +#if defined(PIN_PA06) && !defined(IGNORE_PIN_PA06) +PIN(PA06, EXTINT_CHANNEL(6), ADC_INPUT(6), TOUCH(4), + NO_SERCOM, + SERCOM(0, 2), + TCC(1, 0), + NO_TIMER); +#endif +#if defined(PIN_PA07) && !defined(IGNORE_PIN_PA07) +PIN(PA07, EXTINT_CHANNEL(7), ADC_INPUT(7), TOUCH(5), + NO_SERCOM, + SERCOM(0, 3), + TCC(1, 1), + NO_TIMER); +#endif +#if defined(PIN_PA08) && !defined(IGNORE_PIN_PA08) +PIN(PA08, NO_EXTINT, ADC_INPUT(16), NO_TOUCH, + SERCOM(0, 0), + SERCOM(2, 0), + TCC(0, 0), + TCC(1, 2)); +#endif +#if defined(PIN_PA09) && !defined(IGNORE_PIN_PA09) +PIN(PA09, EXTINT_CHANNEL(9), ADC_INPUT(17), NO_TOUCH, + SERCOM(0, 1), + SERCOM(2, 1), + TCC(0, 1), + TCC(1, 3)); +#endif +#if defined(PIN_PA10) && !defined(IGNORE_PIN_PA10) +PIN(PA10, EXTINT_CHANNEL(10), ADC_INPUT(18), NO_TOUCH, + SERCOM(0, 2), + SERCOM(2, 2), + TCC(1, 0), + TCC(0, 2)); +#endif +#if defined(PIN_PA11) && !defined(IGNORE_PIN_PA11) +PIN(PA11, EXTINT_CHANNEL(11), ADC_INPUT(19), NO_TOUCH, + SERCOM(0, 3), + SERCOM(2, 3), + TCC(1, 1), + TCC(0, 3)); +#endif +#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10) +PIN(PB10, EXTINT_CHANNEL(10), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(4, 2), + TC(5, 0), + TCC(0, 4)); +#endif +#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11) +PIN(PB11, EXTINT_CHANNEL(11), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(4, 3), + TC(5, 1), + TCC(0, 5)); +#endif +#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12) +PIN(PB12, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH, + SERCOM(4, 0), + NO_SERCOM, + TC(4, 0), + TCC(0, 6)); +#endif +#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13) +PIN(PB13, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH, + SERCOM(4, 1), + NO_SERCOM, + TC(4, 1), + TCC(0, 7)); +#endif +#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14) +PIN(PB14, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH, + SERCOM(4, 2), + NO_SERCOM, + TC(5, 0), + NO_TIMER); +#endif + +// Second page. +#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15) +PIN(PB15, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, + SERCOM(4, 3), + NO_SERCOM, + TC(5, 1), + NO_TIMER); +#endif +#if defined(PIN_PA12) && !defined(IGNORE_PIN_PA12) +PIN(PA12, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH, + SERCOM(2, 0), + SERCOM(4, 0), + TCC(2, 0), + TCC(0, 6)); +#endif +#if defined(PIN_PA13) && !defined(IGNORE_PIN_PA13) +PIN(PA13, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH, + SERCOM(2, 1), + SERCOM(4, 1), + TCC(2, 1), + TCC(0, 7)); +#endif +#if defined(PIN_PA14) && !defined(IGNORE_PIN_PA14) +PIN(PA14, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH, + SERCOM(2, 2), + #ifdef SERCOM4 + SERCOM(4, 2), + #else + NO_SERCOM, + #endif + TC(3, 0), + TCC(0, 4)); +#endif +#if defined(PIN_PA15) && !defined(IGNORE_PIN_PA15) +PIN(PA15, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, + SERCOM(2, 3), + #ifdef SERCOM4 + SERCOM(4, 3), + #else + NO_SERCOM, + #endif + TC(3, 1), + TCC(0, 5)); +#endif +#if defined(PIN_PA16) && !defined(IGNORE_PIN_PA16) +PIN(PA16, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH, + SERCOM(1, 0), + SERCOM(3, 0), + TCC(2, 0), + TCC(0, 6)); +#endif +#if defined(PIN_PA17) && !defined(IGNORE_PIN_PA17) +PIN(PA17, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH, + SERCOM(1, 1), + SERCOM(3, 1), + TCC(2, 1), + TCC(0, 7)); +#endif +#if defined(PIN_PA18) && !defined(IGNORE_PIN_PA18) +PIN(PA18, EXTINT_CHANNEL(2), NO_ADC, NO_TOUCH, + SERCOM(1, 2), + SERCOM(3, 2), + TC(3, 0), + TCC(0, 2)); +#endif +#if defined(PIN_PA19) && !defined(IGNORE_PIN_PA19) +PIN(PA19, EXTINT_CHANNEL(3), NO_ADC, NO_TOUCH, + SERCOM(1, 3), + SERCOM(3, 3), + TC(3, 1), + TCC(0, 3)); +#endif +#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16) +PIN(PB16, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH, + SERCOM(5, 0), + NO_SERCOM, + #ifdef TC6 + TC(6, 0), + #else + NO_TIMER, + #endif + TCC(0, 4)); +#endif +#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17) +PIN(PB17, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH, + SERCOM(5, 1), + NO_SERCOM, + #ifdef TC6 + TC(6, 1), + #else + NO_TIMER, + #endif + TCC(0, 5)); +#endif +#if defined(PIN_PA20) && !defined(IGNORE_PIN_PA20) +PIN(PA20, EXTINT_CHANNEL(4), NO_ADC, NO_TOUCH, + SERCOM(5, 2), + SERCOM(3, 2), + #ifdef TC7 + TC(7, 0), + #else + NO_TIMER, + #endif + TCC(0, 6)); +#endif +#if defined(PIN_PA21) && !defined(IGNORE_PIN_PA21) +PIN(PA21, EXTINT_CHANNEL(5), NO_ADC, NO_TOUCH, + SERCOM(5, 3), + SERCOM(3, 3), + #ifdef TC7 + TC(7, 1), + #else + NO_TIMER, + #endif + TCC(0, 7)); +#endif +#if defined(PIN_PA22) && !defined(IGNORE_PIN_PA22) +PIN(PA22, EXTINT_CHANNEL(6), NO_ADC, NO_TOUCH, + SERCOM(3, 0), + #ifdef SERCOM5 + SERCOM(5, 0), + #else + NO_SERCOM, + #endif + TC(4, 0), + TCC(0, 4)); +#endif +#if defined(PIN_PA23) && !defined(IGNORE_PIN_PA23) +PIN(PA23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH, + SERCOM(3, 1), + #ifdef SERCOM5 + SERCOM(5, 1), + #else + NO_SERCOM, + #endif + TC(4, 1), + TCC(0, 5)); +#endif +#if defined(PIN_PA24) && !defined(IGNORE_PIN_PA24) +PIN(PA24, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH, + SERCOM(3, 2), + #ifdef SERCOM5 + SERCOM(5, 2), + #else + NO_SERCOM, + #endif + TC(5, 0), + TCC(0, 2)); +#endif +#if defined(PIN_PA25) && !defined(IGNORE_PIN_PA25) +PIN(PA25, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH, + SERCOM(3, 3), + #ifdef SERCOM5 + SERCOM(5, 3), + #else + NO_SERCOM, + #endif + TC(5, 1), + TCC(1, 3)); +#endif +#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22) +PIN(PB22, EXTINT_CHANNEL(6), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(5, 2), + #ifdef TC7 + TC(7, 0, 0), + #else + NO_TIMER, + #endif + NO_TIMER); +#endif +#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23) +PIN(PB23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(5, 3), + #ifdef TC7 + TC(7, 1, 1), + #else + NO_TIMER, + #endif + NO_TIMER); +#endif +#if defined(PIN_PA27) && !defined(IGNORE_PIN_PA27) +PIN(PA27, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PA28) && !defined(IGNORE_PIN_PA28) +PIN(PA28, EXTINT_CHANNEL(8), NO_ADC, NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER); +#endif +#if defined(PIN_PA30) && !defined(IGNORE_PIN_PA30) +PIN(PA30, EXTINT_CHANNEL(10), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(1, 2), + TCC(1, 0), + NO_TIMER); +#endif +#if defined(PIN_PA31) && !defined(IGNORE_PIN_PA31) +PIN(PA31, EXTINT_CHANNEL(11), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(1, 3), + TCC(1, 1), + NO_TIMER); +#endif +#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30) +PIN(PB30, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(5, 0), + TCC(0, 0), + TCC(1, 2)); +#endif +#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31) +PIN(PB31, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(5, 1), + TCC(0, 1), + TCC(1, 3)); +#endif +#if defined(PIN_PB00) && !defined(IGNORE_PIN_PB00) +PIN(PB00, EXTINT_CHANNEL(0), ADC_INPUT(8), TOUCH(6), + NO_SERCOM, + SERCOM(5, 2), + #ifdef TC7 + TC(7, 0, 0), + #else + NO_TIMER, + #endif + NO_TIMER); +#endif +#if defined(PIN_PB01) && !defined(IGNORE_PIN_PB01) +PIN(PB01, EXTINT_CHANNEL(1), ADC_INPUT(9), TOUCH(7), + NO_SERCOM, + SERCOM(5, 3)), + #ifdef TC7 + TC(7, 1), + #else + NO_TIMER, + #endif + NO_TIMER; +#endif +#if defined(PIN_PB02) && !defined(IGNORE_PIN_PB02) +PIN(PB02, EXTINT_CHANNEL(2), ADC_INPUT(10), TOUCH(8), + NO_SERCOM, + SERCOM(5, 0), + #ifdef TC6 + TC(6, 0), + #else + NO_TIMER, + #endif + NO_TIMER); +#endif +#if defined(PIN_PB03) && !defined(IGNORE_PIN_PB03) +PIN(PB03, EXTINT_CHANNEL(3), ADC_INPUT(11), TOUCH(9), + NO_SERCOM, + SERCOM(5, 1), + #ifdef TC6 + TC(6, 1), + #else + NO_TIMER, + #endif + NO_TIMER); +#endif diff --git a/ports/atmel-samd/peripherals/samd21/pins.h b/ports/atmel-samd/peripherals/samd21/pins.h new file mode 100644 index 000000000..0b99ce9b3 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/pins.h @@ -0,0 +1,205 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 by 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_SAMD21_PINS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H + +#include "include/sam.h" + +void reset_pin(uint8_t pin); + +#define MUX_C 2 +#define MUX_D 3 +#define MUX_E 4 +#define MUX_F 5 +#define PINMUX(pin, mux) ((((uint32_t) pin) << 16) | (mux)) + +#define NO_PIN PORT_BITS + +// Pins in datasheet order. +#ifdef PIN_PA00 +extern const mcu_pin_obj_t pin_PA00; +#endif +#ifdef PIN_PA01 +extern const mcu_pin_obj_t pin_PA01; +#endif +#ifdef PIN_PA02 +extern const mcu_pin_obj_t pin_PA02; +#endif +#ifdef PIN_PA03 +extern const mcu_pin_obj_t pin_PA03; +#endif +#ifdef PIN_PB04 +extern const mcu_pin_obj_t pin_PB04; +#endif +#ifdef PIN_PB05 +extern const mcu_pin_obj_t pin_PB05; +#endif +#ifdef PIN_PB06 +extern const mcu_pin_obj_t pin_PB06; +#endif +#ifdef PIN_PB07 +extern const mcu_pin_obj_t pin_PB07; +#endif +#ifdef PIN_PB08 +extern const mcu_pin_obj_t pin_PB08; +#endif +#ifdef PIN_PB09 +extern const mcu_pin_obj_t pin_PB09; +#endif +#ifdef PIN_PA04 +extern const mcu_pin_obj_t pin_PA04; +#endif +#ifdef PIN_PA05 +extern const mcu_pin_obj_t pin_PA05; +#endif +#ifdef PIN_PA06 +extern const mcu_pin_obj_t pin_PA06; +#endif +#ifdef PIN_PA07 +extern const mcu_pin_obj_t pin_PA07; +#endif +#ifdef PIN_PA08 +extern const mcu_pin_obj_t pin_PA08; +#endif +#ifdef PIN_PA09 +extern const mcu_pin_obj_t pin_PA09; +#endif +#ifdef PIN_PA10 +extern const mcu_pin_obj_t pin_PA10; +#endif +#ifdef PIN_PA11 +extern const mcu_pin_obj_t pin_PA11; +#endif +#ifdef PIN_PB10 +extern const mcu_pin_obj_t pin_PB10; +#endif +#ifdef PIN_PB11 +extern const mcu_pin_obj_t pin_PB11; +#endif +#ifdef PIN_PB12 +extern const mcu_pin_obj_t pin_PB12; +#endif +#ifdef PIN_PB13 +extern const mcu_pin_obj_t pin_PB13; +#endif +#ifdef PIN_PB14 +extern const mcu_pin_obj_t pin_PB14; +#endif + +// Second page. +#ifdef PIN_PB15 +extern const mcu_pin_obj_t pin_PB15; +#endif +#ifdef PIN_PA12 +extern const mcu_pin_obj_t pin_PA12; +#endif +#ifdef PIN_PA13 +extern const mcu_pin_obj_t pin_PA13; +#endif +#ifdef PIN_PA14 +extern const mcu_pin_obj_t pin_PA14; +#endif +#ifdef PIN_PA15 +extern const mcu_pin_obj_t pin_PA15; +#endif +#ifdef PIN_PA16 +extern const mcu_pin_obj_t pin_PA16; +#endif +#ifdef PIN_PA17 +extern const mcu_pin_obj_t pin_PA17; +#endif +#ifdef PIN_PA18 +extern const mcu_pin_obj_t pin_PA18; +#endif +#ifdef PIN_PA19 +extern const mcu_pin_obj_t pin_PA19; +#endif +#ifdef PIN_PB16 +extern const mcu_pin_obj_t pin_PB16; +#endif +#ifdef PIN_PB17 +extern const mcu_pin_obj_t pin_PB17; +#endif +#ifdef PIN_PA20 +extern const mcu_pin_obj_t pin_PA20; +#endif +#ifdef PIN_PA21 +extern const mcu_pin_obj_t pin_PA21; +#endif +#ifdef PIN_PA22 +extern const mcu_pin_obj_t pin_PA22; +#endif +#ifdef PIN_PA23 +extern const mcu_pin_obj_t pin_PA23; +#endif +#ifdef PIN_PA24 +extern const mcu_pin_obj_t pin_PA24; +#endif +#ifdef PIN_PA25 +extern const mcu_pin_obj_t pin_PA25; +#endif +#ifdef PIN_PB22 +extern const mcu_pin_obj_t pin_PB22; +#endif +#ifdef PIN_PB23 +extern const mcu_pin_obj_t pin_PB23; +#endif +#ifdef PIN_PA27 +extern const mcu_pin_obj_t pin_PA27; +#endif +#ifdef PIN_PA28 +extern const mcu_pin_obj_t pin_PA28; +#endif +#ifdef PIN_PA30 +extern const mcu_pin_obj_t pin_PA30; +#endif +#ifdef PIN_PA31 +extern const mcu_pin_obj_t pin_PA31; +#endif +#ifdef PIN_PB30 +extern const mcu_pin_obj_t pin_PB30; +#endif +#ifdef PIN_PB31 +extern const mcu_pin_obj_t pin_PB31; +#endif +#ifdef PIN_PB00 +extern const mcu_pin_obj_t pin_PB00; +#endif +#ifdef PIN_PB01 +extern const mcu_pin_obj_t pin_PB01; +#endif +#ifdef PIN_PB02 +extern const mcu_pin_obj_t pin_PB02; +#endif +#ifdef PIN_PB03 +extern const mcu_pin_obj_t pin_PB03; +#endif + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H diff --git a/ports/atmel-samd/peripherals/samd21/sercom.c b/ports/atmel-samd/peripherals/samd21/sercom.c new file mode 100644 index 000000000..a27e49e0e --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/sercom.c @@ -0,0 +1,93 @@ +/* + * 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 "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. + +static const uint8_t SERCOMx_GCLK_ID_CORE[] = { + SERCOM0_GCLK_ID_CORE, + SERCOM1_GCLK_ID_CORE, + SERCOM2_GCLK_ID_CORE, + SERCOM3_GCLK_ID_CORE, +#ifdef SERCOM4 + SERCOM4_GCLK_ID_CORE, +#endif +#ifdef SERCOM5 + SERCOM5_GCLK_ID_CORE, +#endif +}; + +static const uint8_t SERCOMx_GCLK_ID_SLOW[] = { + SERCOM0_GCLK_ID_SLOW, + SERCOM1_GCLK_ID_SLOW, + SERCOM2_GCLK_ID_SLOW, + SERCOM3_GCLK_ID_SLOW, +#ifdef SERCOM4 + SERCOM4_GCLK_ID_SLOW, +#endif +#ifdef SERCOM5 + SERCOM5_GCLK_ID_SLOW, +#endif +}; + +Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS; + +// Clock initialization as done in Atmel START. +void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) { + _pm_enable_bus_clock(PM_BUS_APBC, sercom); + _gclk_enable_channel(SERCOMx_GCLK_ID_CORE[sercom_index], GCLK_CLKCTRL_GEN_GCLK0_Val); + _gclk_enable_channel(SERCOMx_GCLK_ID_SLOW[sercom_index], GCLK_CLKCTRL_GEN_GCLK3_Val); +} + +// Figure out the DOPO value given the chosen clock pad and mosi pad. +// Return an out-of-range value (255) if the combination is not permitted. +// <0x0=>PAD[0,1]_DO_SCK +// <0x1=>PAD[2,3]_DO_SCK +// <0x2=>PAD[3,1]_DO_SCK +// <0x3=>PAD[0,3]_DO_SCK +uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) { + if (clock_pad == 1) { + if (mosi_pad == 0) { + return 0; + } else if (mosi_pad == 3) { + return 2; + } + } else if (clock_pad == 3) { + if (mosi_pad == 0) { + return 3; + } else if (mosi_pad == 2) { + return 1; + } + } + return 255; +} + +bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) { + return clock_pad == 1 || clock_pad == 3; +} 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 +#include + +#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/peripherals/samd51/clocks.c b/ports/atmel-samd/peripherals/samd51/clocks.c new file mode 100644 index 000000000..29f9cb99c --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/clocks.c @@ -0,0 +1,472 @@ +/* + * 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/clocks.h" + +#include "hpl_gclk_config.h" + +#include "bindings/samd/Clock.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "py/runtime.h" + +bool gclk_enabled(uint8_t gclk) { + return GCLK->GENCTRL[gclk].bit.GENEN; +} + +void disable_gclk(uint8_t gclk) { + while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} + GCLK->GENCTRL[gclk].bit.GENEN = false; + while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} +} + +void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral) { + GCLK->PCHCTRL[peripheral].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk); + while(GCLK->SYNCBUSY.reg != 0) {} +} + +void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral) { + GCLK->PCHCTRL[peripheral].reg = 0; +} + +static void enable_clock_generator_sync(uint8_t gclk, uint32_t source, uint16_t divisor, bool sync) { + uint32_t divsel = 0; + // The datasheet says 8 bits and max value of 512, how is that possible? + if (divisor > 255) { // Generator 1 has 16 bits + divsel = GCLK_GENCTRL_DIVSEL; + for (int i = 15; i > 0; i--) { + if (divisor & (1 << i)) { + divisor = i - 1; + break; + } + } + } + + GCLK->GENCTRL[gclk].reg = GCLK_GENCTRL_SRC(source) | GCLK_GENCTRL_DIV(divisor) | divsel | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN; + if (sync) + while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} +} + +void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor) { + enable_clock_generator_sync(gclk, source, divisor, true); +} + +void disable_clock_generator(uint8_t gclk) { + GCLK->GENCTRL[gclk].reg = 0; + while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} +} + +static void init_clock_source_osculp32k(void) { + // Calibration value is loaded at startup + OSC32KCTRL->OSCULP32K.bit.EN1K = 1; + OSC32KCTRL->OSCULP32K.bit.EN32K = 0; +} + +static void init_clock_source_xosc32k(void) { + OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ONDEMAND | + OSC32KCTRL_XOSC32K_EN1K | + OSC32KCTRL_XOSC32K_XTALEN | + OSC32KCTRL_XOSC32K_ENABLE | + OSC32KCTRL_XOSC32K_CGM(1); +} + +static void init_clock_source_dpll0(void) +{ + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(5); + OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0) | OSCCTRL_DPLLRATIO_LDR(59); + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK(0); + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; + + while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY)) {} +} + +void clock_init(void) { + // DFLL48M is enabled by default + + init_clock_source_osculp32k(); + + if (board_has_crystal()) { + init_clock_source_xosc32k(); + OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K_Val; + } else { + OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K_Val; + } + + MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV(1); + + enable_clock_generator_sync(0, GCLK_GENCTRL_SRC_DPLL0_Val, 1, false); + enable_clock_generator_sync(1, GCLK_GENCTRL_SRC_DFLL_Val, 1, false); + enable_clock_generator_sync(4, GCLK_GENCTRL_SRC_DPLL0_Val, 1, false); + enable_clock_generator_sync(5, GCLK_GENCTRL_SRC_DFLL_Val, 24, false); + + init_clock_source_dpll0(); +} + +static bool clk_enabled(uint8_t clk) { + return GCLK->PCHCTRL[clk].bit.CHEN; +} + +static uint8_t clk_get_generator(uint8_t clk) { + return GCLK->PCHCTRL[clk].bit.GEN; +} + +static uint8_t generator_get_source(uint8_t gen) { + return GCLK->GENCTRL[gen].bit.SRC; +} + +static bool osc_enabled(uint8_t index) { + switch (index) { + case GCLK_SOURCE_XOSC0: + return OSCCTRL->XOSCCTRL[0].bit.ENABLE; + case GCLK_SOURCE_XOSC1: + return OSCCTRL->XOSCCTRL[1].bit.ENABLE; + case GCLK_SOURCE_OSCULP32K: + return true; + case GCLK_SOURCE_XOSC32K: + return OSC32KCTRL->XOSC32K.bit.ENABLE; + case GCLK_SOURCE_DFLL: + return OSCCTRL->DFLLCTRLA.bit.ENABLE; + case GCLK_SOURCE_DPLL0: + return OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE; + case GCLK_SOURCE_DPLL1: + return OSCCTRL->Dpll[1].DPLLCTRLA.bit.ENABLE; + }; + return false; +} + +static uint32_t osc_get_source(uint8_t index) { + uint8_t dpll_index = index - GCLK_SOURCE_DPLL0; + uint32_t refclk = OSCCTRL->Dpll[dpll_index].DPLLCTRLB.bit.REFCLK; + switch (refclk) { + case 0x0: + return generator_get_source(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + dpll_index].bit.GEN); + case 0x1: + return GCLK_SOURCE_XOSC32K; + case 0x2: + return GCLK_SOURCE_XOSC0; + case 0x3: + return GCLK_SOURCE_XOSC1; + } + return 0; +} + +static uint32_t osc_get_frequency(uint8_t index); + +static uint32_t generator_get_frequency(uint8_t gen) { + uint8_t src = GCLK->GENCTRL[gen].bit.SRC; + uint32_t div; + if (GCLK->GENCTRL[gen].bit.DIVSEL) { + div = 1 << (GCLK->GENCTRL[gen].bit.DIV + 1); + } else { + div = GCLK->GENCTRL[gen].bit.DIV; + if (!div) + div = 1; + } + + return osc_get_frequency(src) / div; +} + +static uint32_t dpll_get_frequency(uint8_t index) { + uint8_t dpll_index = index - GCLK_SOURCE_DPLL0; + uint32_t refclk = OSCCTRL->Dpll[dpll_index].DPLLCTRLB.bit.REFCLK; + uint32_t freq; + + switch (refclk) { + case 0x0: // GCLK + freq = generator_get_frequency(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + dpll_index].bit.GEN); + break; + case 0x1: // XOSC32 + freq = 32768; + break; + case 0x2: // XOSC0 + case 0x3: // XOSC1 + return 0; // unknown + } + + return (freq * (OSCCTRL->Dpll[dpll_index].DPLLRATIO.bit.LDR + 1)) + + (freq * OSCCTRL->Dpll[dpll_index].DPLLRATIO.bit.LDRFRAC / 32); +} + +static uint32_t osc_get_frequency(uint8_t index) { + switch (index) { + case GCLK_SOURCE_XOSC0: + case GCLK_SOURCE_XOSC1: + return 0; // unknown + case GCLK_SOURCE_OSCULP32K: + case GCLK_SOURCE_XOSC32K: + return 32768; + case GCLK_SOURCE_DFLL: + return 48000000; + case GCLK_SOURCE_DPLL0: + case GCLK_SOURCE_DPLL1: + return dpll_get_frequency(index); + } + return 0; +} + +bool clock_get_enabled(uint8_t type, uint8_t index) { + if (type == 0) + return osc_enabled(index); + if (type == 1) + return clk_enabled(index); + if (type == 2) + return SysTick->CTRL & SysTick_CTRL_ENABLE_Msk; + return false; +} + +bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index) { + if (type == 0 && osc_enabled(index)) { + if (index == GCLK_SOURCE_DPLL0 || index == GCLK_SOURCE_DPLL1) { + *p_type = 0; + *p_index = osc_get_source(index); + return true; + } + return false; + } + if (type == 1 && index <= 47 && clk_enabled(index)) { + *p_type = 0; + *p_index = generator_get_source(clk_get_generator(index)); + return true; + } + if (type == 2) { + switch (index) { + case 0: + case 1: + *p_type = 0; + *p_index = generator_get_source(0); + return true; + case 2: + *p_type = 0; + switch (OSC32KCTRL->RTCCTRL.bit.RTCSEL) { + case 0: + case 1: + *p_index = GCLK_SOURCE_OSCULP32K; + return true; + case 4: + case 5: + *p_index = GCLK_SOURCE_XOSC32K; + return true; + } + return false; + } + } + return false; +} + +uint32_t clock_get_frequency(uint8_t type, uint8_t index) { + if (type == 0) { + return osc_get_frequency(index); + } + if (type == 1 && index <= 47 && clk_enabled(index)) { + return generator_get_frequency(clk_get_generator(index)); + } + if (type == 2) { + switch (index) { + case 0: + return clock_get_frequency(0, generator_get_source(0)) / SysTick->LOAD; + case 1: + return clock_get_frequency(0, generator_get_source(0)) / MCLK->CPUDIV.bit.DIV; + case 2: + switch (OSC32KCTRL->RTCCTRL.bit.RTCSEL) { + case 0: + case 4: + return 1024; + case 1: + case 5: + return 32768; + } + } + } + return 0; +} + +uint32_t clock_get_calibration(uint8_t type, uint8_t index) { + if (type == 0) { + switch (index) { + case GCLK_SOURCE_OSCULP32K: + return OSC32KCTRL->OSCULP32K.bit.CALIB; + }; + } + if (type == 2 && index == 0) { + return SysTick->LOAD + 1; + } + return 0; +} + +int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) { + if (type == 0) { + switch (index) { + case GCLK_SOURCE_OSCULP32K: + if (val > 0x3f) + return -1; + OSC32KCTRL->OSCULP32K.bit.CALIB = val; + return 0; + }; + } + if (type == 2 && index == 0) { + if (val < 0x1000 || val > 0x1000000) + return -1; + SysTick->LOAD = val - 1; + return 0; + } + return -2; +} + +#include +#include +#include +#include +#include +#include +#include + +CLOCK_SOURCE(XOSC0); +CLOCK_SOURCE(XOSC1); +CLOCK_SOURCE(GCLKIN); +CLOCK_SOURCE(GCLKGEN1); +CLOCK_SOURCE(OSCULP32K); +CLOCK_SOURCE(XOSC32K); +CLOCK_SOURCE(DFLL); +CLOCK_SOURCE(DPLL0); +CLOCK_SOURCE(DPLL1); + +CLOCK_GCLK_(OSCCTRL, DFLL48); +CLOCK_GCLK_(OSCCTRL, FDPLL0); +CLOCK_GCLK_(OSCCTRL, FDPLL1); +CLOCK_GCLK_(OSCCTRL, FDPLL032K); // GCLK_OSCCTRL_FDPLL1_32K, GCLK_SDHC0_SLOW, GCLK_SDHC1_SLOW, GCLK_SERCOM[0..7]_SLOW +CLOCK_GCLK(EIC); +CLOCK_GCLK_(FREQM, MSR); +// 6: GCLK_FREQM_REF +CLOCK_GCLK_(SERCOM0, CORE); +CLOCK_GCLK_(SERCOM1, CORE); +CLOCK(TC0_TC1, 1, 9); +CLOCK_GCLK(USB); +CLOCK_GCLK_(EVSYS, 0); +CLOCK_GCLK_(EVSYS, 1); +CLOCK_GCLK_(EVSYS, 2); +CLOCK_GCLK_(EVSYS, 3); +CLOCK_GCLK_(EVSYS, 4); +CLOCK_GCLK_(EVSYS, 5); +CLOCK_GCLK_(EVSYS, 6); +CLOCK_GCLK_(EVSYS, 7); +CLOCK_GCLK_(EVSYS, 8); +CLOCK_GCLK_(EVSYS, 9); +CLOCK_GCLK_(EVSYS, 10); +CLOCK_GCLK_(EVSYS, 11); +CLOCK_GCLK_(SERCOM2, CORE); +CLOCK_GCLK_(SERCOM3, CORE); +CLOCK(TCC0_TCC1, 1, 25); +CLOCK(TC2_TC3, 1, 26); +CLOCK_GCLK(CAN0); +CLOCK_GCLK(CAN1); +CLOCK(TCC2_TCC3, 1, 29); +CLOCK(TC4_TC5, 1, 30); +CLOCK_GCLK(PDEC); +CLOCK_GCLK(AC); +CLOCK_GCLK(CCL); +CLOCK_GCLK_(SERCOM4, CORE); +CLOCK_GCLK_(SERCOM5, CORE); +CLOCK_GCLK_(SERCOM6, CORE); +CLOCK_GCLK_(SERCOM7, CORE); +CLOCK_GCLK(TCC4); +CLOCK(TC6_TC7, 1, 39); +CLOCK_GCLK(ADC0); +CLOCK_GCLK(ADC1); +CLOCK_GCLK(DAC); +CLOCK_GCLK_(I2S, 0); +CLOCK_GCLK_(I2S, 1); +CLOCK_GCLK(SDHC0); +CLOCK_GCLK(SDHC1); +// 47: GCLK_CM4_TRACE + +CLOCK(SYSTICK, 2, 0); +CLOCK(CPU, 2, 1); +CLOCK(RTC, 2, 2); + + +STATIC const mp_rom_map_elem_t samd_clock_global_dict_table[] = { + CLOCK_ENTRY(XOSC0), + CLOCK_ENTRY(XOSC1), + CLOCK_ENTRY(GCLKIN), + CLOCK_ENTRY(GCLKGEN1), + CLOCK_ENTRY(OSCULP32K), + CLOCK_ENTRY(XOSC32K), + CLOCK_ENTRY(DFLL), + CLOCK_ENTRY(DPLL0), + CLOCK_ENTRY(DPLL1), + + CLOCK_ENTRY_(OSCCTRL, DFLL48), + CLOCK_ENTRY_(OSCCTRL, FDPLL0), + CLOCK_ENTRY_(OSCCTRL, FDPLL1), + CLOCK_ENTRY_(OSCCTRL, FDPLL032K), + CLOCK_ENTRY(EIC), + CLOCK_ENTRY_(FREQM, MSR), + CLOCK_ENTRY_(SERCOM0, CORE), + CLOCK_ENTRY_(SERCOM1, CORE), + CLOCK_ENTRY(TC0_TC1), + CLOCK_ENTRY(USB), + CLOCK_ENTRY_(EVSYS, 0), + CLOCK_ENTRY_(EVSYS, 1), + CLOCK_ENTRY_(EVSYS, 2), + CLOCK_ENTRY_(EVSYS, 3), + CLOCK_ENTRY_(EVSYS, 4), + CLOCK_ENTRY_(EVSYS, 5), + CLOCK_ENTRY_(EVSYS, 6), + CLOCK_ENTRY_(EVSYS, 7), + CLOCK_ENTRY_(EVSYS, 8), + CLOCK_ENTRY_(EVSYS, 9), + CLOCK_ENTRY_(EVSYS, 10), + CLOCK_ENTRY_(EVSYS, 11), + CLOCK_ENTRY_(SERCOM2, CORE), + CLOCK_ENTRY_(SERCOM3, CORE), + CLOCK_ENTRY(TCC0_TCC1), + CLOCK_ENTRY(TC2_TC3), + CLOCK_ENTRY(CAN0), + CLOCK_ENTRY(CAN1), + CLOCK_ENTRY(TCC2_TCC3), + CLOCK_ENTRY(TC4_TC5), + CLOCK_ENTRY(PDEC), + CLOCK_ENTRY(AC), + CLOCK_ENTRY(CCL), + CLOCK_ENTRY_(SERCOM4, CORE), + CLOCK_ENTRY_(SERCOM5, CORE), + CLOCK_ENTRY_(SERCOM6, CORE), + CLOCK_ENTRY_(SERCOM7, CORE), + CLOCK_ENTRY(TCC4), + CLOCK_ENTRY(TC6_TC7), + CLOCK_ENTRY(ADC0), + CLOCK_ENTRY(ADC1), + CLOCK_ENTRY(DAC), + CLOCK_ENTRY_(I2S, 0), + CLOCK_ENTRY_(I2S, 1), + CLOCK_ENTRY(SDHC0), + CLOCK_ENTRY(SDHC1), + + CLOCK_ENTRY(SYSTICK), + CLOCK_ENTRY(CPU), + CLOCK_ENTRY(RTC), +}; +MP_DEFINE_CONST_DICT(samd_clock_globals, samd_clock_global_dict_table); 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 + +#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/peripherals/samd51/i2s.c b/ports/atmel-samd/peripherals/samd51/i2s.c new file mode 100644 index 000000000..97ce13f7d --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/i2s.c @@ -0,0 +1,52 @@ +/* + * 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/i2s.h" + +#include "peripherals/clocks.h" + +#include "hpl/gclk/hpl_gclk_base.h" + +void turn_on_i2s(void) { + // Make sure the I2S peripheral is running so we can see if the resources we need are free. + 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); +} + +void i2s_set_serializer_enable(uint8_t serializer, bool enable) { + if (serializer == 0) { + while (I2S->SYNCBUSY.bit.TXEN == 1) {} + I2S->CTRLA.bit.TXEN = enable; + while (I2S->SYNCBUSY.bit.TXEN == 1) {} + } else { + while (I2S->SYNCBUSY.bit.RXEN == 1) {} + I2S->CTRLA.bit.RXEN = enable; + while (I2S->SYNCBUSY.bit.RXEN == 1) {} + } +} diff --git a/ports/atmel-samd/peripherals/samd51/pins.c b/ports/atmel-samd/peripherals/samd51/pins.c new file mode 100644 index 000000000..1c52d35a2 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/pins.c @@ -0,0 +1,1232 @@ +/* + * 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. + */ + +#include "shared-bindings/microcontroller/Pin.h" + +#define SERCOM(sercom_index, p_pad) \ +{ \ + .index = sercom_index, \ + .pad = p_pad \ +} + +#define NO_SERCOM \ +{ \ + .index = 0x3f, \ + .pad = 0 \ +} + +#define TCC(p_index, p_wave_output) \ +{ \ + .index = p_index, \ + .is_tc = false, \ + .wave_output = p_wave_output \ +} + +#define TC(p_index, p_wave_output) \ +{ \ + .index = p_index, \ + .is_tc = true, \ + .wave_output = p_wave_output \ +} + +#define NO_TIMER TCC(0xff, 0) + +#define TOUCH(y_line) \ + .has_touch = true, \ + .touch_y_line = y_line, + +#define NO_TOUCH \ + .has_touch = false, + +#define EXTINT_CHANNEL(channel) \ + .has_extint = true, \ + .extint_channel = channel, + +#define NO_EXTINT \ + .has_extint = false, + +#define ADC_INPUT(input) (input) + +#define NO_ADC 0xff + +// This macro is used to simplify pin definition in boards//pins.c +#define PIN(p_name, p_extint, p_adc0, p_adc1, p_touch, \ + p_primary_sercom, p_secondary_sercom, \ + p_primary_timer, p_secondary_timer, p_tertiary_timer) \ +const mcu_pin_obj_t pin_## p_name = { \ + { &mcu_pin_type }, \ + .name = MP_QSTR_## p_name, \ + .pin = (PIN_## p_name), \ + p_extint \ + p_touch \ + .adc_input = {p_adc0, p_adc1}, \ + .timer = {p_primary_timer, p_secondary_timer, p_tertiary_timer}, \ + .sercom = {p_primary_sercom, p_secondary_sercom}, \ +} + +// Pins in datasheet order. +// NOTE(tannewt): TC wave out 0 is commented out because the first channel is +// used to vary the 16 bit timer's frequency. +#ifdef PIN_PB03 +PIN(PB03, EXTINT_CHANNEL(3), ADC_INPUT(15), NO_ADC, + TOUCH(21), + NO_SERCOM, + SERCOM(5, 1), + #ifdef TC6 + TC(6, 1), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA00 +PIN(PA00, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, + NO_TOUCH, + NO_SERCOM, + SERCOM(1, 0), + TC(2, 0), + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA01 +PIN(PA01, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, + NO_TOUCH, + NO_SERCOM, + SERCOM(1, 1), + TC(2, 0), + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC00 +PIN(PC00, EXTINT_CHANNEL(0), NO_ADC, ADC_INPUT(10), + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC01 +PIN(PC01, EXTINT_CHANNEL(1), NO_ADC, ADC_INPUT(11), + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC02 +PIN(PC02, EXTINT_CHANNEL(2), NO_ADC, ADC_INPUT(4), + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC03 +PIN(PC03, EXTINT_CHANNEL(3), NO_ADC, ADC_INPUT(5), + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA02 +PIN(PA02, EXTINT_CHANNEL(2), ADC_INPUT(0), NO_ADC, + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA03 +PIN(PA03, EXTINT_CHANNEL(3), ADC_INPUT(1), NO_ADC, + TOUCH(0), + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB04 +PIN(PB04, EXTINT_CHANNEL(4), NO_ADC, ADC_INPUT(6), + #ifdef PINMUX_PB04B_ADC0_PTCXY22 + TOUCH(22), + #else + NO_TOUCH, + #endif + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB05 +PIN(PB05, EXTINT_CHANNEL(5), NO_ADC, ADC_INPUT(7), + #ifdef PINMUX_PB05B_ADC0_PTCXY23 + TOUCH(23), + #else + NO_TOUCH, + #endif + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PD00 +PIN(PD00, EXTINT_CHANNEL(0), NO_ADC, ADC_INPUT(14), NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PD01 +PIN(PD01, EXTINT_CHANNEL(1), NO_ADC, ADC_INPUT(15), NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB06 +PIN(PB06, EXTINT_CHANNEL(6), NO_ADC, ADC_INPUT(8), + #ifdef PINMUX_PB06B_ADC0_PTCXY24 + TOUCH(24), + #else + NO_TOUCH, + #endif + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB07 +PIN(PB07, EXTINT_CHANNEL(7), NO_ADC, ADC_INPUT(9), + #ifdef PINMUX_PB07B_ADC0_PTCXY25 + TOUCH(25), + #else + NO_TOUCH, + #endif + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB08 +PIN(PB08, EXTINT_CHANNEL(8), ADC_INPUT(2), ADC_INPUT(0), TOUCH(1), + NO_SERCOM, + SERCOM(4, 0), + #ifdef TC4 + TC(4, 0), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB09 +PIN(PB09, EXTINT_CHANNEL(9), ADC_INPUT(3), ADC_INPUT(1), TOUCH(2), + NO_SERCOM, + SERCOM(4, 1), + #ifdef TC4 + TC(4, 1), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA04 +PIN(PA04, EXTINT_CHANNEL(4), ADC_INPUT(4), NO_ADC, TOUCH(3), + NO_SERCOM, + SERCOM(0, 0), + TC(0, 0), + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA05 +PIN(PA05, EXTINT_CHANNEL(5), ADC_INPUT(5), NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(0, 1), + TC(0, 1), + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA06 +PIN(PA06, EXTINT_CHANNEL(6), ADC_INPUT(6), NO_ADC, TOUCH(4), + NO_SERCOM, + SERCOM(0, 2), + TC(1, 0), + NO_TIMER, + NO_TIMER); +#endif + +// Second page +#ifdef PIN_PA07 +PIN(PA07, EXTINT_CHANNEL(7), ADC_INPUT(7), NO_ADC, TOUCH(5), + NO_SERCOM, + SERCOM(0, 3), + TC(1, 1), + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC04 +PIN(PC04, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 0), + #else + NO_SERCOM, + #endif + NO_SERCOM, + NO_TIMER, + TCC(0, 0), + NO_TIMER); +#endif +#ifdef PIN_PC05 +PIN(PC05, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 1), + #else + NO_SERCOM, + #endif + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC06 +PIN(PC06, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 2), + #else + NO_SERCOM, + #endif + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC07 +PIN(PC07, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 3), + #else + NO_SERCOM, + #endif + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA08 +PIN(PA08, NO_EXTINT, ADC_INPUT(8), ADC_INPUT(2), TOUCH(6), + SERCOM(0, 0), + SERCOM(2, 1), + TC(0, 0), + TCC(0, 0), + TCC(1, 4)); +#endif +#ifdef PIN_PA09 +PIN(PA09, EXTINT_CHANNEL(9), ADC_INPUT(9), ADC_INPUT(3), TOUCH(7), + SERCOM(0, 1), + SERCOM(2, 0), + TC(0, 1), + TCC(0, 1), + TCC(1, 5)); +#endif +#ifdef PIN_PA10 +PIN(PA10, EXTINT_CHANNEL(10), ADC_INPUT(10), NO_ADC, TOUCH(8), + SERCOM(0, 2), + SERCOM(2, 2), + TC(1, 0), + TCC(0, 2), + TCC(1, 6)); +#endif +#ifdef PIN_PA11 +PIN(PA11, EXTINT_CHANNEL(11), ADC_INPUT(11), NO_ADC, TOUCH(9), + SERCOM(0, 3), + SERCOM(2, 3), + TC(1, 0), + TCC(0, 3), + TCC(1, 7)); +#endif +#ifdef PIN_PB10 +PIN(PB10, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(4, 2), + #ifdef TC5 + TC(5, 0), + #else + NO_TIMER, + #endif + TCC(0, 4), + TCC(1, 0)); +#endif +#ifdef PIN_PB11 +PIN(PB11, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, NO_TOUCH, + NO_SERCOM, + SERCOM(4, 3), + #ifdef TC5 + TC(5, 1), + #else + NO_TIMER, + #endif + TCC(0, 5), + TCC(1, 1)); +#endif +#ifdef PIN_PB12 +PIN(PB12, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, + #ifdef PINMUX_PB12B_ADC0_PTCXY26 + TOUCH(26), + #else + NO_TOUCH, + #endif + SERCOM(4, 0), + NO_SERCOM, + #ifdef TC4 + TC(4, 0), + #else + NO_TIMER, + #endif + #ifdef TCC3 + TCC(3, 0), + #else + NO_TIMER, + #endif + TCC(0, 0)); +#endif +#ifdef PIN_PB13 +PIN(PB13, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, + #ifdef PINMUX_PB13B_ADC0_PTCXY27 + TOUCH(27), + #else + NO_TOUCH, + #endif + SERCOM(4, 1), + NO_SERCOM, + #ifdef TC4 + TC(4, 1), + #else + NO_TIMER, + #endif + #ifdef TCC3 + TCC(3, 1), + #else + NO_TIMER, + #endif + TCC(0, 1)); +#endif +#ifdef PIN_PB14 +PIN(PB14, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, + #ifdef PINMUX_PB14B_ADC0_PTCXY28 + TOUCH(28), + #else + NO_TOUCH, + #endif + SERCOM(4, 2), + NO_SERCOM, + #ifdef TC5 + TC(5, 0), + #else + NO_TIMER, + #endif + #ifdef TCC4 + TCC(4, 0), + #else + NO_TIMER, + #endif + TCC(0, 2)); +#endif +#ifdef PIN_PB15 +PIN(PB15, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, + #ifdef PINMUX_PB15B_ADC0_PTCXY29 + TOUCH(28), + #else + NO_TOUCH, + #endif + SERCOM(4, 3), + NO_SERCOM, + #ifdef TC5 + TC(5, 1), + #else + NO_TIMER, + #endif + #ifdef TCC4 + TCC(4, 1), + #else + NO_TIMER, + #endif + TCC(0, 3)); +#endif +#ifdef PIN_PD08 +PIN(PD08, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 0), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 1), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 1), + NO_TIMER); +#endif +#ifdef PIN_PD09 +PIN(PD09, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 1), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 0), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 2), + NO_TIMER); +#endif +#ifdef PIN_PD10 +PIN(PD10, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 2), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 2), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 3), + NO_TIMER); +#endif +#ifdef PIN_PD11 +PIN(PD11, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 3), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 3), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 4), + NO_TIMER); +#endif +#ifdef PIN_PD12 +PIN(PD12, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + TCC(0, 5), + NO_TIMER); +#endif +#ifdef PIN_PC10 +PIN(PC10, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 2), + #else + NO_SERCOM, + #endif + #ifdef SERCOM7 + SERCOM(7, 2), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 0), + TCC(1, 4)); +#endif +#ifdef PIN_PC11 +PIN(PC11, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 3), + #else + NO_SERCOM, + #endif + #ifdef SERCOM7 + SERCOM(7, 3), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 1), + TCC(1, 5)); +#endif +#ifdef PIN_PC12 +PIN(PC12, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 0), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 1), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 2), + TCC(1, 6)); +#endif +#ifdef PIN_PC13 +PIN(PC13, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 1), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 0), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 3), + TCC(1, 7)); +#endif +#ifdef PIN_PC14 +PIN(PC14, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 2), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 2), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 4), + TCC(1, 0)); +#endif +#ifdef PIN_PC15 +PIN(PC15, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 3), + #else + NO_SERCOM, + #endif + #ifdef SERCOM6 + SERCOM(6, 3), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(0, 5), + TCC(1, 1)); +#endif +#ifdef PIN_PA12 +PIN(PA12, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 0), + SERCOM(4, 1), + TC(2, 0), + TCC(0, 6), + TCC(1, 2)); +#endif +#ifdef PIN_PA13 +PIN(PA13, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 1), + SERCOM(4, 0), + TC(2, 1), + TCC(0, 7), + TCC(1, 3)); +#endif + +// Third page +#ifdef PIN_PA14 +PIN(PA14, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 2), + SERCOM(4, 2), + TC(3, 0), + TCC(2, 0), + TCC(1, 2)); +#endif +#ifdef PIN_PA15 +PIN(PA15, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 3), + SERCOM(4, 3), + TC(3, 1), + TCC(2, 1), + TCC(1, 3)); +#endif +#ifdef PIN_PA16 +PIN(PA16, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, TOUCH(10), + SERCOM(1, 0), + SERCOM(3, 1), + TC(2, 0), + TCC(1, 0), + TCC(0, 4)); +#endif +#ifdef PIN_PA17 +PIN(PA17, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, TOUCH(11), + SERCOM(1, 1), + SERCOM(3, 0), + TC(2, 1), + TCC(1, 1), + TCC(0, 5)); +#endif +#ifdef PIN_PA18 +PIN(PA18, EXTINT_CHANNEL(2), NO_ADC, NO_ADC, TOUCH(12), + SERCOM(1, 2), + SERCOM(3, 2), + TC(3, 0), + TCC(1, 2), + TCC(0, 6)); +#endif +#ifdef PIN_PA19 +PIN(PA19, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, TOUCH(13), + SERCOM(1, 3), + SERCOM(3, 3), + TC(3, 1), + TCC(1, 3), + TCC(0, 7)); +#endif +#ifdef PIN_PC16 +PIN(PC16, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 0), + #else + NO_SERCOM, + #endif + SERCOM(0, 1), + NO_TIMER, + TCC(TCC0, 0), + NO_TIMER); +#endif +#ifdef PIN_PC17 +PIN(PC17, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 1), + #else + NO_SERCOM, + #endif + SERCOM(0, 0), + NO_TIMER, + TCC(0, 1), + NO_TIMER); +#endif +#ifdef PIN_PC18 +PIN(PC18, EXTINT_CHANNEL(2), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 2), + #else + NO_SERCOM, + #endif + SERCOM(0, 2), + NO_TIMER, + TCC(0, 2), + NO_TIMER); +#endif +#ifdef PIN_PC19 +PIN(PC19, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, + NO_TOUCH, + #ifdef SERCOM6 + SERCOM(6, 3), + #else + NO_SERCOM, + #endif + SERCOM(0, 3), + NO_TIMER, + TCC(0, 3), + NO_TIMER); +#endif +#ifdef PIN_PC20 +PIN(PC20, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + TCC(0, 4), + NO_TIMER); +#endif +#ifdef PIN_PC21 +PIN(PC21, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, + NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + TCC(0, 5), + NO_TIMER); +#endif +#ifdef PIN_PC22 +PIN(PC22, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, + NO_TOUCH, + SERCOM(1, 0), + SERCOM(3, 1), + NO_TIMER, + TCC(0, 6), + NO_TIMER); +#endif +#ifdef PIN_PC23 +PIN(PC23, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, + NO_TOUCH, + SERCOM(1, 1), + SERCOM(3, 0), + NO_TIMER, + TCC(0, 7), + NO_TIMER); +#endif +#ifdef PIN_PD20 +PIN(PD20, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, + NO_TOUCH, + SERCOM(1, 2), + SERCOM(3, 2), + NO_TIMER, + TCC(1, 0), + NO_TIMER); +#endif +#ifdef PIN_PD21 +PIN(PD21, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, + NO_TOUCH, + SERCOM(1, 3), + SERCOM(3, 3), + NO_TIMER, + TCC(1, 1), + NO_TIMER); +#endif + + + + +#ifdef PIN_PB16 +PIN(PB16, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(5, 0), + NO_SERCOM, + #ifdef TC6 + TC(6, 0), + #else + NO_TIMER, + #endif + TCC(3, 0), + TCC(0, 4)); +#endif +#ifdef PIN_PB17 +PIN(PB17, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(5, 1), + NO_SERCOM, + #ifdef TC6 + TC(6, 1), + #else + NO_TIMER, + #endif + TCC(3, 1), + TCC(0, 5)); +#endif +#ifdef PIN_PB18 +PIN(PB18, EXTINT_CHANNEL(2), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(5, 2), + #ifdef SERCOM7 + SERCOM(7, 2), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(1, 0), + NO_TIMER); +#endif +#ifdef PIN_PB19 +PIN(PB19, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(5, 3), + #ifdef SERCOM7 + SERCOM(7, 3), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(1, 1), + NO_TIMER); +#endif +#ifdef PIN_PB20 +PIN(PB20, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(5, 0), + #ifdef SERCOM7 + SERCOM(7, 1), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(1, 2), + NO_TIMER); +#endif +#ifdef PIN_PB21 +PIN(PB21, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(5, 1), + #ifdef SERCOM7 + SERCOM(7, 0), + #else + NO_SERCOM, + #endif + NO_TIMER, + TCC(1, 3), + NO_TIMER); +#endif +#ifdef PIN_PA20 +PIN(PA20, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, TOUCH(14), + SERCOM(5, 2), + SERCOM(3, 2), + #ifdef TC7 + TC(7, 0), + #else + NO_TIMER, + #endif + TCC(1, 4), + TCC(0, 0)); +#endif +#ifdef PIN_PA21 +PIN(PA21, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, TOUCH(15), + SERCOM(5, 3), + SERCOM(3, 3), + #ifdef TC7 + TC(7, 1), + #else + NO_TIMER, + #endif + TCC(1, 5), + TCC(0, 1)); +#endif +#ifdef PIN_PA22 +PIN(PA22, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, TOUCH(16), + SERCOM(3, 0), + SERCOM(5, 1), + #ifdef TC4 + TC(4, 0), + #else + NO_TIMER, + #endif + TCC(1, 6), + TCC(0, 2)); +#endif +#ifdef PIN_PA23 +PIN(PA23, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, TOUCH(17), + SERCOM(3, 1), + SERCOM(5, 0), + #ifdef TC4 + TC(4, 1), + #else + NO_TIMER, + #endif + TCC(1, 7), + TCC(0, 3)); +#endif +#ifdef PIN_PA24 +PIN(PA24, EXTINT_CHANNEL(8), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(3, 2), + SERCOM(5, 2), + #ifdef TC5 + TC(5, 0), + #else + NO_TIMER, + #endif + TCC(2, 2), + NO_TIMER); +#endif +#ifdef PIN_PA25 +PIN(PA25, EXTINT_CHANNEL(9), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(3, 3), + SERCOM(5, 3), + #ifdef TC5 + TC(5, 1), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif + +// Fourth page +#ifdef PIN_PB22 +PIN(PB22, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(1, 2), + SERCOM(5, 2), + #ifdef TC7 + TC(7, 0), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB23 +PIN(PB23, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(1, 3), + SERCOM(5, 3), + #ifdef TC7 + TC(7, 1), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB24 +PIN(PB24, EXTINT_CHANNEL(8), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(0, 0), + SERCOM(2, 1), + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB25 +PIN(PB25, EXTINT_CHANNEL(9), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(0, 1), + SERCOM(2, 0), + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB26 +PIN(PB26, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 0), + SERCOM(4, 1), + NO_TIMER, + TCC(TCC1, 2), + NO_TIMER); +#endif +#ifdef PIN_PB27 +PIN(PB27, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 1), + SERCOM(4, 0), + NO_TIMER, + TCC(1, 3), + NO_TIMER); +#endif +#ifdef PIN_PB28 +PIN(PB28, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 2), + SERCOM(4, 2), + NO_TIMER, + TCC(1, 4), + NO_TIMER); +#endif +#ifdef PIN_PB29 +PIN(PB29, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(2, 3), + SERCOM(4, 3), + NO_TIMER, + TCC(1, 5), + NO_TIMER); +#endif +#ifdef PIN_PC24 +PIN(PC24, EXTINT_CHANNEL(8), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(0, 2), + SERCOM(2, 2), + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC25 +PIN(PC25, EXTINT_CHANNEL(9), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(0, 3), + SERCOM(2, 3), + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC26 +PIN(PC26, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC27 +PIN(PC27, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(1, 0), + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC28 +PIN(PC28, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, NO_TOUCH, + SERCOM(1, 1), + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA27 +PIN(PA27, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, TOUCH(18), + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PA30 +PIN(PA30, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, TOUCH(19), + #ifdef SERCOM7 + SERCOM(7, 2), + #else + NO_SERCOM, + #endif + SERCOM(1, 2), + #ifdef TC6 + TC(6, 0), + #else + NO_TIMER, + #endif + TCC(2, 0), + NO_TIMER); +#endif +#ifdef PIN_PA31 +PIN(PA31, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 3), + #else + NO_SERCOM, + #endif + SERCOM(1, 3), + #ifdef TC6 + TC(6, 1), + #else + NO_TIMER, + #endif + TCC(2, 1), + NO_TIMER); +#endif +#ifdef PIN_PB30 +PIN(PB30, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 0), + #else + NO_SERCOM, + #endif + SERCOM(5, 1), + TC(0, 0), + TCC(4, 0), + TCC(0, 6)); +#endif +#ifdef PIN_PB31 +PIN(PB31, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, + #ifdef SERCOM7 + SERCOM(7, 1), + #else + NO_SERCOM, + #endif + SERCOM(5, 0), + TC(0, 1), + TCC(4, 1), + TCC(0, 7)); +#endif +#ifdef PIN_PC30 +PIN(PC30, EXTINT_CHANNEL(14), NO_ADC, ADC_INPUT(12), NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PC31 +PIN(PC31, EXTINT_CHANNEL(15), NO_ADC, ADC_INPUT(13), NO_TOUCH, + NO_SERCOM, + NO_SERCOM, + NO_TIMER, + NO_TIMER, + NO_TIMER); +#endif + + +#ifdef PIN_PB00 +PIN(PB00, EXTINT_CHANNEL(0), ADC_INPUT(12), NO_ADC, + #ifdef PINMUX_PB00B_ADC0_PTCXY30 + TOUCH(30), + #else + NO_TOUCH, + #endif + NO_SERCOM, + SERCOM(5, 2), + #ifdef TC7 + TC(7, 0), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB01 +PIN(PB01, EXTINT_CHANNEL(1), ADC_INPUT(13), NO_ADC, + #ifdef PINMUX_PB01B_ADC0_PTCXY31 + TOUCH(31), + #else + NO_TOUCH, + #endif + NO_SERCOM, + SERCOM(5, 3), + #ifdef TC7 + TC(7, 1), + #else + NO_TIMER, + #endif + NO_TIMER, + NO_TIMER); +#endif +#ifdef PIN_PB02 +PIN(PB02, EXTINT_CHANNEL(2), ADC_INPUT(14), NO_ADC, TOUCH(20), + NO_SERCOM, + SERCOM(5, 0), + #ifdef TC6 + TC(6, 0), + #else + NO_TIMER, + #endif + TCC(2, 2), + NO_TIMER); +#endif diff --git a/ports/atmel-samd/peripherals/samd51/pins.h b/ports/atmel-samd/peripherals/samd51/pins.h new file mode 100644 index 000000000..b9a05a345 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/pins.h @@ -0,0 +1,349 @@ +/* + * 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_SAMD51_PINS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H + +#include "include/sam.h" + +void reset_pin(uint8_t pin); + +#define MUX_C 2 +#define MUX_D 3 +#define MUX_E 4 +#define MUX_F 5 +#define PINMUX(pin, mux) ((((uint32_t) pin) << 16) | (mux)) + +#define NO_PIN PORT_BITS + +// Pins in datasheet order. +#ifdef PIN_PB03 +extern const mcu_pin_obj_t pin_PB03; +#endif +#ifdef PIN_PA00 +extern const mcu_pin_obj_t pin_PA00; +#endif +#ifdef PIN_PA01 +extern const mcu_pin_obj_t pin_PA01; +#endif +#ifdef PIN_PC00 +extern const mcu_pin_obj_t pin_PC00; +#endif +#ifdef PIN_PC01 +extern const mcu_pin_obj_t pin_PC01; +#endif +#ifdef PIN_PC02 +extern const mcu_pin_obj_t pin_PC02; +#endif +#ifdef PIN_PC03 +extern const mcu_pin_obj_t pin_PC03; +#endif +#ifdef PIN_PA02 +extern const mcu_pin_obj_t pin_PA02; +#endif +#ifdef PIN_PA03 +extern const mcu_pin_obj_t pin_PA03; +#endif +#ifdef PIN_PB04 +extern const mcu_pin_obj_t pin_PB04; +#endif +#ifdef PIN_PB05 +extern const mcu_pin_obj_t pin_PB05; +#endif +#ifdef PIN_PD00 +extern const mcu_pin_obj_t pin_PD00; +#endif +#ifdef PIN_PD01 +extern const mcu_pin_obj_t pin_PD01; +#endif +#ifdef PIN_PB06 +extern const mcu_pin_obj_t pin_PB06; +#endif +#ifdef PIN_PB07 +extern const mcu_pin_obj_t pin_PB07; +#endif +#ifdef PIN_PB08 +extern const mcu_pin_obj_t pin_PB08; +#endif +#ifdef PIN_PB09 +extern const mcu_pin_obj_t pin_PB09; +#endif +#ifdef PIN_PA04 +extern const mcu_pin_obj_t pin_PA04; +#endif +#ifdef PIN_PA05 +extern const mcu_pin_obj_t pin_PA05; +#endif +#ifdef PIN_PA06 +extern const mcu_pin_obj_t pin_PA06; +#endif + +// Second page +#ifdef PIN_PA07 +extern const mcu_pin_obj_t pin_PA07; +#endif +#ifdef PIN_PC04 +extern const mcu_pin_obj_t pin_PC04; +#endif +#ifdef PIN_PC05 +extern const mcu_pin_obj_t pin_PC05; +#endif +#ifdef PIN_PC06 +extern const mcu_pin_obj_t pin_PC06; +#endif +#ifdef PIN_PC07 +extern const mcu_pin_obj_t pin_PC07; +#endif +#ifdef PIN_PA08 +extern const mcu_pin_obj_t pin_PA08; +#endif +#ifdef PIN_PA09 +extern const mcu_pin_obj_t pin_PA09; +#endif +#ifdef PIN_PA10 +extern const mcu_pin_obj_t pin_PA10; +#endif +#ifdef PIN_PA11 +extern const mcu_pin_obj_t pin_PA11; +#endif +#ifdef PIN_PB10 +extern const mcu_pin_obj_t pin_PB10; +#endif +#ifdef PIN_PB11 +extern const mcu_pin_obj_t pin_PB11; +#endif +#ifdef PIN_PB12 +extern const mcu_pin_obj_t pin_PB12; +#endif +#ifdef PIN_PB13 +extern const mcu_pin_obj_t pin_PB13; +#endif +#ifdef PIN_PB14 +extern const mcu_pin_obj_t pin_PB14; +#endif +#ifdef PIN_PB15 +extern const mcu_pin_obj_t pin_PB15; +#endif +#ifdef PIN_PD08 +extern const mcu_pin_obj_t pin_PD08; +#endif +#ifdef PIN_PD09 +extern const mcu_pin_obj_t pin_PD09; +#endif +#ifdef PIN_PD10 +extern const mcu_pin_obj_t pin_PD10; +#endif +#ifdef PIN_PD11 +extern const mcu_pin_obj_t pin_PD11; +#endif +#ifdef PIN_PD12 +extern const mcu_pin_obj_t pin_PD12; +#endif +#ifdef PIN_PC10 +extern const mcu_pin_obj_t pin_PC10; +#endif +#ifdef PIN_PC11 +extern const mcu_pin_obj_t pin_PC11; +#endif +#ifdef PIN_PC12 +extern const mcu_pin_obj_t pin_PC12; +#endif +#ifdef PIN_PC13 +extern const mcu_pin_obj_t pin_PC13; +#endif +#ifdef PIN_PC14 +extern const mcu_pin_obj_t pin_PC14; +#endif +#ifdef PIN_PC15 +extern const mcu_pin_obj_t pin_PC15; +#endif +#ifdef PIN_PA12 +extern const mcu_pin_obj_t pin_PA12; +#endif +#ifdef PIN_PA13 +extern const mcu_pin_obj_t pin_PA13; +#endif + +// Third page +#ifdef PIN_PA14 +extern const mcu_pin_obj_t pin_PA14; +#endif +#ifdef PIN_PA15 +extern const mcu_pin_obj_t pin_PA15; +#endif +#ifdef PIN_PA16 +extern const mcu_pin_obj_t pin_PA16; +#endif +#ifdef PIN_PA17 +extern const mcu_pin_obj_t pin_PA17; +#endif +#ifdef PIN_PA18 +extern const mcu_pin_obj_t pin_PA18; +#endif +#ifdef PIN_PA19 +extern const mcu_pin_obj_t pin_PA19; +#endif +#ifdef PIN_PC16 +extern const mcu_pin_obj_t pin_PC16; +#endif +#ifdef PIN_PC17 +extern const mcu_pin_obj_t pin_PC17; +#endif +#ifdef PIN_PC18 +extern const mcu_pin_obj_t pin_PC18; +#endif +#ifdef PIN_PC19 +extern const mcu_pin_obj_t pin_PC19; +#endif +#ifdef PIN_PC20 +extern const mcu_pin_obj_t pin_PC20; +#endif +#ifdef PIN_PC21 +extern const mcu_pin_obj_t pin_PC21; +#endif +#ifdef PIN_PC22 +extern const mcu_pin_obj_t pin_PC22; +#endif +#ifdef PIN_PC23 +extern const mcu_pin_obj_t pin_PC23; +#endif +#ifdef PIN_PD20 +extern const mcu_pin_obj_t pin_PD20; +#endif +#ifdef PIN_PD21 +extern const mcu_pin_obj_t pin_PD21; +#endif +#ifdef PIN_PB16 +extern const mcu_pin_obj_t pin_PB16; +#endif +#ifdef PIN_PB17 +extern const mcu_pin_obj_t pin_PB17; +#endif +#ifdef PIN_PB18 +extern const mcu_pin_obj_t pin_PB18; +#endif +#ifdef PIN_PB19 +extern const mcu_pin_obj_t pin_PB19; +#endif +#ifdef PIN_PB20 +extern const mcu_pin_obj_t pin_PB20; +#endif +#ifdef PIN_PB21 +extern const mcu_pin_obj_t pin_PB21; +#endif +#ifdef PIN_PA20 +extern const mcu_pin_obj_t pin_PA20; +#endif +#ifdef PIN_PA21 +extern const mcu_pin_obj_t pin_PA21; +#endif +#ifdef PIN_PA22 +extern const mcu_pin_obj_t pin_PA22; +#endif +#ifdef PIN_PA23 +extern const mcu_pin_obj_t pin_PA23; +#endif +#ifdef PIN_PA24 +extern const mcu_pin_obj_t pin_PA24; +#endif +#ifdef PIN_PA25 +extern const mcu_pin_obj_t pin_PA25; +#endif + +// Fourth page +#ifdef PIN_PB22 +extern const mcu_pin_obj_t pin_PB22; +#endif +#ifdef PIN_PB23 +extern const mcu_pin_obj_t pin_PB23; +#endif +#ifdef PIN_PB24 +extern const mcu_pin_obj_t pin_PB24; +#endif +#ifdef PIN_PB25 +extern const mcu_pin_obj_t pin_PB25; +#endif +#ifdef PIN_PB26 +extern const mcu_pin_obj_t pin_PB26; +#endif +#ifdef PIN_PB27 +extern const mcu_pin_obj_t pin_PB27; +#endif +#ifdef PIN_PB28 +extern const mcu_pin_obj_t pin_PB28; +#endif +#ifdef PIN_PB29 +extern const mcu_pin_obj_t pin_PB29; +#endif +#ifdef PIN_PC24 +extern const mcu_pin_obj_t pin_PC24; +#endif +#ifdef PIN_PC25 +extern const mcu_pin_obj_t pin_PC25; +#endif +#ifdef PIN_PC26 +extern const mcu_pin_obj_t pin_PC26; +#endif +#ifdef PIN_PC27 +extern const mcu_pin_obj_t pin_PC27; +#endif +#ifdef PIN_PC28 +extern const mcu_pin_obj_t pin_PC28; +#endif +#ifdef PIN_PA27 +extern const mcu_pin_obj_t pin_PA27; +#endif +#ifdef PIN_PA30 +extern const mcu_pin_obj_t pin_PA30; +#endif +#ifdef PIN_PA31 +extern const mcu_pin_obj_t pin_PA31; +#endif +#ifdef PIN_PB30 +extern const mcu_pin_obj_t pin_PB30; +#endif +#ifdef PIN_PB31 +extern const mcu_pin_obj_t pin_PB31; +#endif +#ifdef PIN_PC30 +extern const mcu_pin_obj_t pin_PC30; +#endif +#ifdef PIN_PC31 +extern const mcu_pin_obj_t pin_PC31; +#endif +#ifdef PIN_PB00 +extern const mcu_pin_obj_t pin_PB00; +#endif +#ifdef PIN_PB01 +extern const mcu_pin_obj_t pin_PB01; +#endif +#ifdef PIN_PB02 +extern const mcu_pin_obj_t pin_PB02; +#endif +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H diff --git a/ports/atmel-samd/peripherals/samd51/sercom.c b/ports/atmel-samd/peripherals/samd51/sercom.c new file mode 100644 index 000000000..fc4421422 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/sercom.c @@ -0,0 +1,135 @@ +/* + * 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" + +// 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. + +static const uint8_t SERCOMx_GCLK_ID_CORE[] = { + SERCOM0_GCLK_ID_CORE, + SERCOM1_GCLK_ID_CORE, + SERCOM2_GCLK_ID_CORE, + SERCOM3_GCLK_ID_CORE, + SERCOM4_GCLK_ID_CORE, + SERCOM5_GCLK_ID_CORE, +#ifdef SERCOM6 + SERCOM6_GCLK_ID_CORE, +#endif +#ifdef SERCOM7 + SERCOM7_GCLK_ID_CORE, +#endif +}; + +static const uint8_t SERCOMx_GCLK_ID_SLOW[] = { + SERCOM0_GCLK_ID_SLOW, + SERCOM1_GCLK_ID_SLOW, + SERCOM2_GCLK_ID_SLOW, + SERCOM3_GCLK_ID_SLOW, + SERCOM4_GCLK_ID_SLOW, + SERCOM5_GCLK_ID_SLOW, +#ifdef SERCOM6 + SERCOM6_GCLK_ID_SLOW, +#endif +#ifdef SERCOM7 + SERCOM7_GCLK_ID_SLOW, +#endif +}; + +Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS; + +// Clock initialization as done in Atmel START. +void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) { + hri_gclk_write_PCHCTRL_reg(GCLK, + SERCOMx_GCLK_ID_CORE[sercom_index], + GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); + hri_gclk_write_PCHCTRL_reg(GCLK, + SERCOMx_GCLK_ID_SLOW[sercom_index], + GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); + + // hri_mclk_set_APBAMASK_SERCOMx_bit is an inline, so let's use a switch, not a table. + switch (sercom_index) { + case 0: + hri_mclk_set_APBAMASK_SERCOM0_bit(MCLK); + break; + case 1: + hri_mclk_set_APBAMASK_SERCOM1_bit(MCLK); + break; + case 2: + hri_mclk_set_APBBMASK_SERCOM2_bit(MCLK); + break; + case 3: + hri_mclk_set_APBBMASK_SERCOM3_bit(MCLK); + break; + case 4: + hri_mclk_set_APBDMASK_SERCOM4_bit(MCLK); + break; + case 5: + hri_mclk_set_APBDMASK_SERCOM5_bit(MCLK); + break; +#ifdef SERCOM6 + case 6: + hri_mclk_set_APBDMASK_SERCOM6_bit(MCLK); + break; +#endif +#ifdef SERCOM7 + case 7: + hri_mclk_set_APBDMASK_SERCOM7_bit(MCLK); + break; +#endif + } +} + + +// Figure out the DOPO value given the chosen clock pad and mosi pad. +// Return an out-of-range value (255) if the combination is not permitted +// The ASF4 config files list this, but the SAMD51 datasheet +// says 0x1 and 0x3 are reserved, so don't allow pad 3 SCK. +// Transmit Data Pinout +// <0x0=>PAD[0,1]_DO_SCK +// <0x1=>PAD[2,3]_DO_SCK [RESERVED] +// <0x2=>PAD[3,1]_DO_SCK +// <0x3=>PAD[0,3]_DO_SCK [RESERVED] +uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) { + if (clock_pad != 1) { + return 255; + } + if (mosi_pad == 0) { + return 0x1; + } + if (mosi_pad == 3) { + return 0x2; + } + return 255; +} + +bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) { + return clock_pad == 1; +} diff --git a/ports/atmel-samd/peripherals/samd51/timers.c b/ports/atmel-samd/peripherals/samd51/timers.c new file mode 100644 index 000000000..305acce38 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/timers.c @@ -0,0 +1,139 @@ +/* + * 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 +#include + +#include "peripherals/timers.h" + +//#include "common-hal/pulseio/PulseOut.h" + +#include "hri/hri_gclk_d51.h" + +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, + TC2_GCLK_ID, + TC3_GCLK_ID, +#ifdef TC4_GCLK_ID + TC4_GCLK_ID, +#endif +#ifdef TC5_GCLK_ID + TC5_GCLK_ID, +#endif +#ifdef TC6_GCLK_ID + TC6_GCLK_ID, +#endif +#ifdef TC7_GCLK_ID + TC7_GCLK_ID, +#endif + }; +const uint8_t tcc_gclk_ids[TCC_INST_NUM] = {TCC0_GCLK_ID, + TCC1_GCLK_ID, + TCC2_GCLK_ID, +#ifdef TCC3_GCLK_ID + TCC3_GCLK_ID, +#endif +#ifdef TCC4_GCLK_ID + TCC4_GCLK_ID +#endif + }; + +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]; + } + // Turn on the clocks for the peripherals. + if (is_tc) { + switch (index) { + case 0: + MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC0; + break; + case 1: + MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC1; + break; + case 2: + MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC2; + break; + case 3: + MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC3; + break; + case 4: + MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC4; + break; + case 5: + MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC5; + break; + case 6: + MCLK->APBDMASK.reg |= MCLK_APBDMASK_TC6; + break; + case 7: + MCLK->APBDMASK.reg |= MCLK_APBDMASK_TC7; + break; + default: + break; + } + } else { + switch (index) { + case 0: + MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC0; + break; + case 1: + MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC1; + break; + case 2: + MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC2; + break; + case 3: + MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC3; + break; + case 4: + MCLK->APBDMASK.reg |= MCLK_APBDMASK_TCC4; + break; + default: + break; + } + } + + // FIXME(tannewt): TC4-TC7 can only have 100mhz inputs. + + hri_gclk_write_PCHCTRL_reg(GCLK, gclk_id, + gclk_index | (1 << GCLK_PCHCTRL_CHEN_Pos)); +} + +void tc_set_enable(Tc* tc, bool enable) { + tc->COUNT16.CTRLA.bit.ENABLE = enable; + while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) { + /* Wait for sync */ + } +} + +void tc_wait_for_sync(Tc* tc) { + while (tc->COUNT16.SYNCBUSY.reg != 0) {} +} diff --git a/ports/atmel-samd/peripherals/sercom.c b/ports/atmel-samd/peripherals/sercom.c new file mode 100644 index 000000000..04c1fd008 --- /dev/null +++ b/ports/atmel-samd/peripherals/sercom.c @@ -0,0 +1,44 @@ +/* + * 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 "peripherals/sercom.h" + +#include "hpl_sercom_config.h" + +// Routines that are the same across all samd variants. + + +// Convert frequency to clock-speed-dependent value. Return 255 if > 255. +uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate) { + uint32_t baud_reg_value = (uint32_t) (((float) PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY / + (2 * baudrate)) - 0.5f); + return (uint8_t) (baud_reg_value > 255 ? 255 : baud_reg_value); +} + +// Convert BAUD reg value back to a frequency. +uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value) { + return PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY / (2 * (baud_reg_value + 1)); +} diff --git a/ports/atmel-samd/peripherals/sercom.h b/ports/atmel-samd/peripherals/sercom.h new file mode 100644 index 000000000..66ad1a403 --- /dev/null +++ b/ports/atmel-samd/peripherals/sercom.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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H +#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H + +#include + +#include "mpconfigport.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); +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]; + +#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 +#include + +#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/peripherals/timers.h b/ports/atmel-samd/peripherals/timers.h new file mode 100644 index 000000000..fa8965784 --- /dev/null +++ b/ports/atmel-samd/peripherals/timers.h @@ -0,0 +1,69 @@ +/* + * 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_TIMERS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H + +#include "include/sam.h" + +const uint16_t prescaler[8]; + +#ifdef SAMD21 +const uint8_t tcc_cc_num[3]; +const uint8_t tc_gclk_ids[TC_INST_NUM]; +const uint8_t tcc_gclk_ids[3]; +#endif +#ifdef SAMD51 +const uint8_t tcc_cc_num[5]; +const uint8_t tc_gclk_ids[TC_INST_NUM]; +const uint8_t tcc_gclk_ids[TCC_INST_NUM]; +#endif +Tc* const tc_insts[TC_INST_NUM]; +Tcc* const tcc_insts[TCC_INST_NUM]; + +void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index); +void tc_set_enable(Tc* tc, bool enable); +void tcc_set_enable(Tcc* tcc, bool enable); +void tc_wait_for_sync(Tc* tc); +void tc_reset(Tc* tc); + +void tc_enable_interrupts(uint8_t tc_index); +void tc_disable_interrupts(uint8_t tc_index); + +// Handlers +void TCC0_Handler(void); +void TCC1_Handler(void); +void TCC2_Handler(void); +void TC3_Handler(void); +void TC4_Handler(void); +void TC5_Handler(void); +#ifdef TC6 +void TC6_Handler(void); +#endif +#ifdef TC7 +void TC7_Handler(void); +#endif + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H diff --git a/ports/atmel-samd/pins.h b/ports/atmel-samd/pins.h deleted file mode 100644 index 1842efbc0..000000000 --- a/ports/atmel-samd/pins.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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_ATMEL_SAMD_PINS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_PINS_H - -#include "mpconfigport.h" - -#ifdef SAMD21 -#include "samd21_pins.h" -#endif -#ifdef SAMD51 -#include "samd51_pins.h" -#endif - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_PINS_H diff --git a/ports/atmel-samd/samd21_clocks.c b/ports/atmel-samd/samd21_clocks.c deleted file mode 100644 index 0fc4d63e5..000000000 --- a/ports/atmel-samd/samd21_clocks.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * 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 "clocks.h" - -#include "hpl_gclk_config.h" - -#include "bindings/samd/Clock.h" -#include "shared-bindings/microcontroller/__init__.h" - -#include "py/runtime.h" - -bool gclk_enabled(uint8_t gclk) { - common_hal_mcu_disable_interrupts(); - // Explicitly do a byte write so the peripheral knows we're just wanting to read the channel - // rather than write to it. - *((uint8_t*) &GCLK->GENCTRL.reg) = gclk; - while (GCLK->STATUS.bit.SYNCBUSY == 1) {} - bool enabled = GCLK->GENCTRL.bit.GENEN; - common_hal_mcu_enable_interrupts(); - return enabled; -} - -void disable_gclk(uint8_t gclk) { - while (GCLK->STATUS.bit.SYNCBUSY == 1) {} - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk); - while (GCLK->STATUS.bit.SYNCBUSY == 1) {} -} - -void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral) { - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(peripheral) | GCLK_CLKCTRL_GEN(gclk) | GCLK_CLKCTRL_CLKEN; -} - -void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral) { - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(peripheral) | GCLK_CLKCTRL_GEN(gclk); -} - -void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor) { - uint32_t divsel = 0; - if (gclk == 2 && divisor > 31) { - divsel = GCLK_GENCTRL_DIVSEL; - for (int i = 15; i > 4; i++) { - if (divisor & (1 << i)) { - divisor = i - 1; - break; - } - } - } - GCLK->GENDIV.reg = GCLK_GENDIV_ID(gclk) | GCLK_GENDIV_DIV(divisor); - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk) | GCLK_GENCTRL_SRC(source) | divsel | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN; - while (GCLK->STATUS.bit.SYNCBUSY != 0) {} -} - -void disable_clock_generator(uint8_t gclk) { - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk); - while (GCLK->STATUS.bit.SYNCBUSY != 0) {} -} - -static void init_clock_source_osc8m(void) { - // Preserve CALIB and FRANGE - SYSCTRL->OSC8M.bit.ONDEMAND = 0; - SYSCTRL->OSC8M.bit.PRESC = 3; - SYSCTRL->OSC8M.bit.ENABLE = 1; - while (!SYSCTRL->PCLKSR.bit.OSC8MRDY) {} -} - -static void init_clock_source_osc32k(void) { - uint32_t calib = (*((uint32_t *)FUSES_OSC32K_CAL_ADDR) & FUSES_OSC32K_CAL_Msk) >> FUSES_OSC32K_CAL_Pos; - SYSCTRL->OSC32K.reg = SYSCTRL_OSC32K_CALIB(calib) | - SYSCTRL_OSC32K_EN32K | - SYSCTRL_OSC32K_ENABLE; - while (!SYSCTRL->PCLKSR.bit.OSC32KRDY) {} -} - -static void init_clock_source_xosc32k(void) { - SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_EN32K | - SYSCTRL_XOSC32K_XTALEN | - SYSCTRL_XOSC32K_ENABLE; - while (!SYSCTRL->PCLKSR.bit.XOSC32KRDY) {} -} - -static void init_clock_source_dfll48m(void) { - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; - while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {} - SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP(1) | - SYSCTRL_DFLLMUL_FSTEP(1) | - SYSCTRL_DFLLMUL_MUL(48000); - uint32_t coarse = (*((uint32_t *)FUSES_DFLL48M_COARSE_CAL_ADDR) & FUSES_DFLL48M_COARSE_CAL_Msk) >> FUSES_DFLL48M_COARSE_CAL_Pos; - if (coarse == 0x3f) - coarse = 0x1f; - SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | - SYSCTRL_DFLLVAL_FINE(512); - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_CCDIS | - SYSCTRL_DFLLCTRL_USBCRM | - SYSCTRL_DFLLCTRL_MODE | - SYSCTRL_DFLLCTRL_ENABLE; - while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {} - while (GCLK->STATUS.bit.SYNCBUSY) {} -} - -void clock_init(void) -{ - init_clock_source_osc8m(); - if (board_has_crystal()) - init_clock_source_xosc32k(); - else - init_clock_source_osc32k(); - enable_clock_generator(0, GCLK_GENCTRL_SRC_DFLL48M_Val, 1); - enable_clock_generator(1, GCLK_GENCTRL_SRC_DFLL48M_Val, 150); - init_clock_source_dfll48m(); - if (board_has_crystal()) - enable_clock_generator(2, GCLK_GENCTRL_SRC_XOSC32K_Val, 32); - else - enable_clock_generator(2, GCLK_GENCTRL_SRC_OSC32K_Val, 32); -} - -static bool clk_enabled(uint8_t clk) { - common_hal_mcu_disable_interrupts(); - *((uint8_t*) &GCLK->CLKCTRL.reg) = clk; - while (GCLK->STATUS.bit.SYNCBUSY == 1) {} - bool enabled = GCLK->CLKCTRL.bit.CLKEN; - common_hal_mcu_enable_interrupts(); - return enabled; -} - -static uint8_t clk_get_generator(uint8_t clk) { - common_hal_mcu_disable_interrupts(); - *((uint8_t*) &GCLK->CLKCTRL.reg) = clk; - while (GCLK->STATUS.bit.SYNCBUSY == 1) {} - uint8_t gen = GCLK->CLKCTRL.bit.GEN; - common_hal_mcu_enable_interrupts(); - return gen; -} - -static uint8_t generator_get_source(uint8_t gen) { - common_hal_mcu_disable_interrupts(); - *((uint8_t*) &GCLK->GENCTRL.reg) = gen; - while (GCLK->STATUS.bit.SYNCBUSY == 1) {} - uint8_t src = GCLK->GENCTRL.bit.SRC; - common_hal_mcu_enable_interrupts(); - return src; -} - -static bool osc_enabled(uint8_t index) { - switch (index) { - case GCLK_SOURCE_XOSC: - return SYSCTRL->XOSC.bit.ENABLE; - // TODO: GCLK_SOURCE_GCLKIN - // TODO: GCLK_SOURCE_GCLKGEN1 - case GCLK_SOURCE_OSCULP32K: - return true; - case GCLK_SOURCE_OSC32K: - return SYSCTRL->OSC32K.bit.ENABLE; - case GCLK_SOURCE_XOSC32K: - return SYSCTRL->XOSC32K.bit.ENABLE; - case GCLK_SOURCE_OSC8M: - return SYSCTRL->OSC8M.bit.ENABLE; - case GCLK_SOURCE_DFLL48M: - return SYSCTRL->DFLLCTRL.bit.ENABLE; - case GCLK_SOURCE_DPLL96M: - return SYSCTRL->DPLLCTRLA.bit.ENABLE; - }; - return false; -} - -static uint32_t osc_get_frequency(uint8_t index) { - switch (index) { - case GCLK_SOURCE_XOSC: - return 0; // unknown 0.4-32MHz - // TODO: GCLK_SOURCE_GCLKIN - // TODO: GCLK_SOURCE_GCLKGEN1 - case GCLK_SOURCE_OSCULP32K: - case GCLK_SOURCE_OSC32K: - case GCLK_SOURCE_XOSC32K: - return 32768; - case GCLK_SOURCE_OSC8M: - return 8000000; - case GCLK_SOURCE_DFLL48M: - return 48000000; - case GCLK_SOURCE_DPLL96M: - return 96000000; - } - return 0; -} - -bool clock_get_enabled(uint8_t type, uint8_t index) { - if (type == 0) - return osc_enabled(index); - if (type == 1) - return clk_enabled(index); - if (type == 2) - return SysTick->CTRL & SysTick_CTRL_ENABLE_Msk; - return false; -} - -bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index) { - if (type == 1 && index <= 0x24 && clk_enabled(index)) { - *p_type = 0; - *p_index = generator_get_source(clk_get_generator(index)); - return true; - } - if (type == 2 && index == 0) { - *p_type = 0; - *p_index = generator_get_source(0); - return true; - } - return false; -} - -uint32_t clock_get_frequency(uint8_t type, uint8_t index) { - if (type == 0) { - return osc_get_frequency(index); - } - if (type == 1) { - if (!clk_enabled(index)) - return 0; - - uint8_t gen = clk_get_generator(index); - - common_hal_mcu_disable_interrupts(); - *((uint8_t*) &GCLK->GENCTRL.reg) = gen; - *((uint8_t*) &GCLK->GENDIV.reg) = gen; - while (GCLK->STATUS.bit.SYNCBUSY == 1) {} - - uint8_t src = GCLK->GENCTRL.bit.SRC; - uint32_t div; - if (GCLK->GENCTRL.bit.DIVSEL) { - div = 1 << (GCLK->GENDIV.bit.DIV + 1); - } else { - div = GCLK->GENDIV.bit.DIV; - if (!div) - div = 1; - } - common_hal_mcu_enable_interrupts(); - - return osc_get_frequency(src) / div; - } - if (type == 2 && index == 0) { - return clock_get_frequency(0, generator_get_source(0)) / SysTick->LOAD; - } - return 0; -} - -uint32_t clock_get_calibration(uint8_t type, uint8_t index) { - if (type == 0) { - switch (index) { - case GCLK_SOURCE_OSCULP32K: - return SYSCTRL->OSCULP32K.bit.CALIB; - case GCLK_SOURCE_OSC32K: - return SYSCTRL->OSC32K.bit.CALIB; - case GCLK_SOURCE_OSC8M: - return SYSCTRL->OSC8M.bit.CALIB; - }; - } - if (type == 2 && index == 0) { - return SysTick->LOAD + 1; - } - return 0; -} - -int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) { - if (type == 0) { - switch (index) { - case GCLK_SOURCE_OSCULP32K: - if (val > 0x1f) - return -1; - SYSCTRL->OSCULP32K.bit.CALIB = val; - return 0; - case GCLK_SOURCE_OSC32K: - if (val > 0x7f) - return -1; - SYSCTRL->OSC32K.bit.CALIB = val; - return 0; - case GCLK_SOURCE_OSC8M: - if (val > 0xfff) - return -1; - SYSCTRL->OSC8M.bit.CALIB = val; - return 0; - }; - } - if (type == 2 && index == 0) { - if (val < 0x1000 || val > 0x1000000) - return -1; - SysTick->LOAD = val - 1; - return 0; - } - return -2; // calibration is read only -} - -#ifdef SAMD21_EXPOSE_ALL_CLOCKS -CLOCK_SOURCE(XOSC); -CLOCK_SOURCE(GCLKIN); -CLOCK_SOURCE(GCLKGEN1); -CLOCK_SOURCE(OSCULP32K); -#endif -CLOCK_SOURCE(OSC32K); -CLOCK_SOURCE(XOSC32K); -#ifdef SAMD21_EXPOSE_ALL_CLOCKS -CLOCK_SOURCE(OSC8M); -CLOCK_SOURCE(DFLL48M); -CLOCK_SOURCE(DPLL96M); - -CLOCK_GCLK_(SYSCTRL, DFLL48); -CLOCK_GCLK_(SYSCTRL, FDPLL); -CLOCK_GCLK_(SYSCTRL, FDPLL32K); -CLOCK_GCLK(WDT); -#endif -CLOCK_GCLK(RTC); -#ifdef SAMD21_EXPOSE_ALL_CLOCKS -CLOCK_GCLK(EIC); -CLOCK_GCLK(USB); -CLOCK_GCLK_(EVSYS, 0); -CLOCK_GCLK_(EVSYS, 1); -CLOCK_GCLK_(EVSYS, 2); -CLOCK_GCLK_(EVSYS, 3); -CLOCK_GCLK_(EVSYS, 4); -CLOCK_GCLK_(EVSYS, 5); -CLOCK_GCLK_(EVSYS, 6); -CLOCK_GCLK_(EVSYS, 7); -CLOCK_GCLK_(EVSYS, 8); -CLOCK_GCLK_(EVSYS, 9); -CLOCK_GCLK_(EVSYS, 10); -CLOCK_GCLK_(EVSYS, 11); -CLOCK(SERCOMx_SLOW, 1, 19); -CLOCK_GCLK_(SERCOM0, CORE); -CLOCK_GCLK_(SERCOM1, CORE); -CLOCK_GCLK_(SERCOM2, CORE); -CLOCK_GCLK_(SERCOM3, CORE); -CLOCK_GCLK_(SERCOM4, CORE); -CLOCK_GCLK_(SERCOM5, CORE); -CLOCK(TCC0_TCC1, 1, 26); -CLOCK(TCC2_TCC3, 1, 27); -CLOCK(TC4_TC5, 1, 28); -CLOCK(TC6_TC7, 1, 29); -CLOCK_GCLK(ADC); -CLOCK_GCLK_(AC, DIG); -CLOCK_GCLK_(AC, ANA); -CLOCK_GCLK(DAC); -CLOCK_GCLK(PTC); -CLOCK_GCLK_(I2S, 0); -CLOCK_GCLK_(I2S, 1); - -CLOCK(SYSTICK, 2, 0); -#endif - -STATIC const mp_rom_map_elem_t samd_clock_global_dict_table[] = { -#ifdef SAMD21_EXPOSE_ALL_CLOCKS - CLOCK_ENTRY(XOSC), - CLOCK_ENTRY(GCLKIN), - CLOCK_ENTRY(GCLKGEN1), - CLOCK_ENTRY(OSCULP32K), -#endif - CLOCK_ENTRY(OSC32K), - CLOCK_ENTRY(XOSC32K), -#ifdef SAMD21_EXPOSE_ALL_CLOCKS - CLOCK_ENTRY(OSC8M), - CLOCK_ENTRY(DFLL48M), - CLOCK_ENTRY(DPLL96M), - CLOCK_ENTRY_(SYSCTRL, DFLL48), - CLOCK_ENTRY_(SYSCTRL, FDPLL), - CLOCK_ENTRY_(SYSCTRL, FDPLL32K), - CLOCK_ENTRY(WDT), -#endif - CLOCK_ENTRY(RTC), -#ifdef SAMD21_EXPOSE_ALL_CLOCKS - CLOCK_ENTRY(EIC), - CLOCK_ENTRY(USB), - CLOCK_ENTRY_(EVSYS, 0), - CLOCK_ENTRY_(EVSYS, 1), - CLOCK_ENTRY_(EVSYS, 2), - CLOCK_ENTRY_(EVSYS, 3), - CLOCK_ENTRY_(EVSYS, 4), - CLOCK_ENTRY_(EVSYS, 5), - CLOCK_ENTRY_(EVSYS, 6), - CLOCK_ENTRY_(EVSYS, 7), - CLOCK_ENTRY_(EVSYS, 8), - CLOCK_ENTRY_(EVSYS, 9), - CLOCK_ENTRY_(EVSYS, 10), - CLOCK_ENTRY_(EVSYS, 11), - CLOCK_ENTRY(SERCOMx_SLOW), - CLOCK_ENTRY_(SERCOM0, CORE), - CLOCK_ENTRY_(SERCOM1, CORE), - CLOCK_ENTRY_(SERCOM2, CORE), - CLOCK_ENTRY_(SERCOM3, CORE), - CLOCK_ENTRY_(SERCOM4, CORE), - CLOCK_ENTRY_(SERCOM5, CORE), - CLOCK_ENTRY(TCC0_TCC1), - CLOCK_ENTRY(TCC2_TCC3), - CLOCK_ENTRY(TC4_TC5), - CLOCK_ENTRY(TC6_TC7), - CLOCK_ENTRY(ADC), - CLOCK_ENTRY_(AC, DIG), - CLOCK_ENTRY_(AC, ANA), - CLOCK_ENTRY(DAC), - CLOCK_ENTRY(PTC), - CLOCK_ENTRY_(I2S, 0), - CLOCK_ENTRY_(I2S, 1), - - CLOCK_ENTRY(SYSTICK), -#endif -}; -MP_DEFINE_CONST_DICT(samd_clock_globals, samd_clock_global_dict_table); diff --git a/ports/atmel-samd/samd21_peripherals.c b/ports/atmel-samd/samd21_peripherals.c deleted file mode 100644 index 5bbac2965..000000000 --- a/ports/atmel-samd/samd21_peripherals.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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" - - -// The clock initializer values are rather random, so we need to put them in -// tables for lookup. We can't compute them. - -static const uint8_t SERCOMx_GCLK_ID_CORE[] = { - SERCOM0_GCLK_ID_CORE, - SERCOM1_GCLK_ID_CORE, - SERCOM2_GCLK_ID_CORE, - SERCOM3_GCLK_ID_CORE, -#ifdef SERCOM4 - SERCOM4_GCLK_ID_CORE, -#endif -#ifdef SERCOM5 - SERCOM5_GCLK_ID_CORE, -#endif -}; - -static const uint8_t SERCOMx_GCLK_ID_SLOW[] = { - SERCOM0_GCLK_ID_SLOW, - SERCOM1_GCLK_ID_SLOW, - SERCOM2_GCLK_ID_SLOW, - SERCOM3_GCLK_ID_SLOW, -#ifdef SERCOM4 - SERCOM4_GCLK_ID_SLOW, -#endif -#ifdef SERCOM5 - SERCOM5_GCLK_ID_SLOW, -#endif -}; - -Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS; - -// Clock initialization as done in Atmel START. -void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) { - _pm_enable_bus_clock(PM_BUS_APBC, sercom); - _gclk_enable_channel(SERCOMx_GCLK_ID_CORE[sercom_index], GCLK_CLKCTRL_GEN_GCLK0_Val); - _gclk_enable_channel(SERCOMx_GCLK_ID_SLOW[sercom_index], GCLK_CLKCTRL_GEN_GCLK3_Val); -} - -// Figure out the DOPO value given the chosen clock pad and mosi pad. -// Return an out-of-range value (255) if the combination is not permitted. -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK -uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) { - if (clock_pad == 1) { - if (mosi_pad == 0) { - return 0; - } else if (mosi_pad == 3) { - return 2; - } - } else if (clock_pad == 3) { - if (mosi_pad == 0) { - return 3; - } else if (mosi_pad == 2) { - return 1; - } - } - return 255; -} - -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/samd21_peripherals.h b/ports/atmel-samd/samd21_peripherals.h deleted file mode 100644 index 805717695..000000000 --- a/ports/atmel-samd/samd21_peripherals.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 by 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. - */ - -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_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 diff --git a/ports/atmel-samd/samd21_pins.c b/ports/atmel-samd/samd21_pins.c deleted file mode 100644 index 319870b9a..000000000 --- a/ports/atmel-samd/samd21_pins.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * 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. - */ - -#include "shared-bindings/microcontroller/Pin.h" - -#include "samd21_pins.h" - -#define SERCOM(sercom_index, p_pad) \ -{ \ - .index = sercom_index, \ - .pad = p_pad \ -} - -#define NO_SERCOM \ -{ \ - .index = 0x3f, \ - .pad = 0 \ -} - - -#define TCC(p_index, p_wave_output) \ -{ \ - .index = p_index, \ - .is_tc = false, \ - .wave_output = p_wave_output \ -} - -#define TC(p_index, p_wave_output) \ -{ \ - .index = p_index - 3, \ - .is_tc = true, \ - .wave_output = p_wave_output \ -} - -#define NO_TIMER TCC(0xff, 0) - -#define TOUCH(y_line) \ - .has_touch = true, \ - .touch_y_line = y_line, - -#define NO_TOUCH \ - .has_touch = false, - -#define EXTINT_CHANNEL(channel) \ - .has_extint = true, \ - .extint_channel = channel, - -#define NO_EXTINT \ - .has_extint = false, - -#define ADC_INPUT(input) input - -#define NO_ADC 0xff - -// This macro is used to simplify pin definition in boards//pins.c -#define PIN(p_name, p_extint, p_adc, p_touch, \ - p_primary_sercom, p_secondary_sercom, \ - p_primary_timer, p_secondary_timer) \ -const mcu_pin_obj_t pin_## p_name = { \ - { &mcu_pin_type }, \ - .name = MP_QSTR_## p_name, \ - .pin = (PIN_## p_name), \ - p_extint \ - p_touch \ - .adc_input = {p_adc}, \ - .timer = { p_primary_timer, p_secondary_timer}, \ - .sercom = {p_primary_sercom, p_secondary_sercom}, \ -} - -// Pins in datasheet order. -// NOTE(tannewt): TC wave out 0 is commented out because the first channel is -// used to vary the 16 bit timer's frequency. -#if defined(PIN_PA00) && !defined(IGNORE_PIN_PA00) -PIN(PA00, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(1, 0), - TCC(2, 0), - NO_TIMER); -#endif -#if defined(PIN_PA01) && !defined(IGNORE_PIN_PA01) -PIN(PA01, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(1, 1), - TCC(2, 1), - NO_TIMER); -#endif -#if defined(PIN_PA02) && !defined(IGNORE_PIN_PA02) -// Touch is not allowed on A0 (PA02) on Circuit Playground Express. -PIN(PA02, EXTINT_CHANNEL(2), ADC_INPUT(0), - #ifdef PA02_NO_TOUCH - NO_TOUCH, - #else - TOUCH(0), - #endif - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PA03) && !defined(IGNORE_PIN_PA03) -PIN(PA03, EXTINT_CHANNEL(3), ADC_INPUT(1), TOUCH(1), - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PB04) && !defined(IGNORE_PIN_PB04) -PIN(PB04, EXTINT_CHANNEL(4), ADC_INPUT(12), TOUCH(10), - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PB05) && !defined(IGNORE_PIN_PB05) -PIN(PB05, EXTINT_CHANNEL(5), ADC_INPUT(13), TOUCH(11), - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PB06) && !defined(IGNORE_PIN_PB06) -PIN(PB06, EXTINT_CHANNEL(6), ADC_INPUT(14), TOUCH(12), - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PB07) && !defined(IGNORE_PIN_PB07) -PIN(PB07, EXTINT_CHANNEL(7), ADC_INPUT(15), TOUCH(13), - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PB08) && !defined(IGNORE_PIN_PB08) -PIN(PB08, EXTINT_CHANNEL(8), ADC_INPUT(2), TOUCH(14), - NO_SERCOM, - SERCOM(4, 0), - TC(4, 0), - NO_TIMER); -#endif -#if defined(PIN_PB09) && !defined(IGNORE_PIN_PB09) -PIN(PB09, EXTINT_CHANNEL(9), ADC_INPUT(3), TOUCH(15), - NO_SERCOM, - SERCOM(4, 1), - TC(4, 1), - NO_TIMER); -#endif -#if defined(PIN_PA04) && !defined(IGNORE_PIN_PA04) -PIN(PA04, EXTINT_CHANNEL(4), ADC_INPUT(4), TOUCH(2), - NO_SERCOM, - SERCOM(0, 0), - TCC(0, 0), - NO_TIMER); -#endif -#if defined(PIN_PA05) && !defined(IGNORE_PIN_PA05) -PIN(PA05, EXTINT_CHANNEL(5), ADC_INPUT(5), TOUCH(3), - NO_SERCOM, - SERCOM(0, 1), - TCC(0, 1), - NO_TIMER); -#endif -#if defined(PIN_PA06) && !defined(IGNORE_PIN_PA06) -PIN(PA06, EXTINT_CHANNEL(6), ADC_INPUT(6), TOUCH(4), - NO_SERCOM, - SERCOM(0, 2), - TCC(1, 0), - NO_TIMER); -#endif -#if defined(PIN_PA07) && !defined(IGNORE_PIN_PA07) -PIN(PA07, EXTINT_CHANNEL(7), ADC_INPUT(7), TOUCH(5), - NO_SERCOM, - SERCOM(0, 3), - TCC(1, 1), - NO_TIMER); -#endif -#if defined(PIN_PA08) && !defined(IGNORE_PIN_PA08) -PIN(PA08, NO_EXTINT, ADC_INPUT(16), NO_TOUCH, - SERCOM(0, 0), - SERCOM(2, 0), - TCC(0, 0), - TCC(1, 2)); -#endif -#if defined(PIN_PA09) && !defined(IGNORE_PIN_PA09) -PIN(PA09, EXTINT_CHANNEL(9), ADC_INPUT(17), NO_TOUCH, - SERCOM(0, 1), - SERCOM(2, 1), - TCC(0, 1), - TCC(1, 3)); -#endif -#if defined(PIN_PA10) && !defined(IGNORE_PIN_PA10) -PIN(PA10, EXTINT_CHANNEL(10), ADC_INPUT(18), NO_TOUCH, - SERCOM(0, 2), - SERCOM(2, 2), - TCC(1, 0), - TCC(0, 2)); -#endif -#if defined(PIN_PA11) && !defined(IGNORE_PIN_PA11) -PIN(PA11, EXTINT_CHANNEL(11), ADC_INPUT(19), NO_TOUCH, - SERCOM(0, 3), - SERCOM(2, 3), - TCC(1, 1), - TCC(0, 3)); -#endif -#if defined(PIN_PB10) && !defined(IGNORE_PIN_PB10) -PIN(PB10, EXTINT_CHANNEL(10), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(4, 2), - TC(5, 0), - TCC(0, 4)); -#endif -#if defined(PIN_PB11) && !defined(IGNORE_PIN_PB11) -PIN(PB11, EXTINT_CHANNEL(11), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(4, 3), - TC(5, 1), - TCC(0, 5)); -#endif -#if defined(PIN_PB12) && !defined(IGNORE_PIN_PB12) -PIN(PB12, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH, - SERCOM(4, 0), - NO_SERCOM, - TC(4, 0), - TCC(0, 6)); -#endif -#if defined(PIN_PB13) && !defined(IGNORE_PIN_PB13) -PIN(PB13, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH, - SERCOM(4, 1), - NO_SERCOM, - TC(4, 1), - TCC(0, 7)); -#endif -#if defined(PIN_PB14) && !defined(IGNORE_PIN_PB14) -PIN(PB14, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH, - SERCOM(4, 2), - NO_SERCOM, - TC(5, 0), - NO_TIMER); -#endif - -// Second page. -#if defined(PIN_PB15) && !defined(IGNORE_PIN_PB15) -PIN(PB15, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, - SERCOM(4, 3), - NO_SERCOM, - TC(5, 1), - NO_TIMER); -#endif -#if defined(PIN_PA12) && !defined(IGNORE_PIN_PA12) -PIN(PA12, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH, - SERCOM(2, 0), - SERCOM(4, 0), - TCC(2, 0), - TCC(0, 6)); -#endif -#if defined(PIN_PA13) && !defined(IGNORE_PIN_PA13) -PIN(PA13, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH, - SERCOM(2, 1), - SERCOM(4, 1), - TCC(2, 1), - TCC(0, 7)); -#endif -#if defined(PIN_PA14) && !defined(IGNORE_PIN_PA14) -PIN(PA14, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH, - SERCOM(2, 2), - #ifdef SERCOM4 - SERCOM(4, 2), - #else - NO_SERCOM, - #endif - TC(3, 0), - TCC(0, 4)); -#endif -#if defined(PIN_PA15) && !defined(IGNORE_PIN_PA15) -PIN(PA15, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, - SERCOM(2, 3), - #ifdef SERCOM4 - SERCOM(4, 3), - #else - NO_SERCOM, - #endif - TC(3, 1), - TCC(0, 5)); -#endif -#if defined(PIN_PA16) && !defined(IGNORE_PIN_PA16) -PIN(PA16, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH, - SERCOM(1, 0), - SERCOM(3, 0), - TCC(2, 0), - TCC(0, 6)); -#endif -#if defined(PIN_PA17) && !defined(IGNORE_PIN_PA17) -PIN(PA17, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH, - SERCOM(1, 1), - SERCOM(3, 1), - TCC(2, 1), - TCC(0, 7)); -#endif -#if defined(PIN_PA18) && !defined(IGNORE_PIN_PA18) -PIN(PA18, EXTINT_CHANNEL(2), NO_ADC, NO_TOUCH, - SERCOM(1, 2), - SERCOM(3, 2), - TC(3, 0), - TCC(0, 2)); -#endif -#if defined(PIN_PA19) && !defined(IGNORE_PIN_PA19) -PIN(PA19, EXTINT_CHANNEL(3), NO_ADC, NO_TOUCH, - SERCOM(1, 3), - SERCOM(3, 3), - TC(3, 1), - TCC(0, 3)); -#endif -#if defined(PIN_PB16) && !defined(IGNORE_PIN_PB16) -PIN(PB16, EXTINT_CHANNEL(0), NO_ADC, NO_TOUCH, - SERCOM(5, 0), - NO_SERCOM, - #ifdef TC6 - TC(6, 0), - #else - NO_TIMER, - #endif - TCC(0, 4)); -#endif -#if defined(PIN_PB17) && !defined(IGNORE_PIN_PB17) -PIN(PB17, EXTINT_CHANNEL(1), NO_ADC, NO_TOUCH, - SERCOM(5, 1), - NO_SERCOM, - #ifdef TC6 - TC(6, 1), - #else - NO_TIMER, - #endif - TCC(0, 5)); -#endif -#if defined(PIN_PA20) && !defined(IGNORE_PIN_PA20) -PIN(PA20, EXTINT_CHANNEL(4), NO_ADC, NO_TOUCH, - SERCOM(5, 2), - SERCOM(3, 2), - #ifdef TC7 - TC(7, 0), - #else - NO_TIMER, - #endif - TCC(0, 6)); -#endif -#if defined(PIN_PA21) && !defined(IGNORE_PIN_PA21) -PIN(PA21, EXTINT_CHANNEL(5), NO_ADC, NO_TOUCH, - SERCOM(5, 3), - SERCOM(3, 3), - #ifdef TC7 - TC(7, 1), - #else - NO_TIMER, - #endif - TCC(0, 7)); -#endif -#if defined(PIN_PA22) && !defined(IGNORE_PIN_PA22) -PIN(PA22, EXTINT_CHANNEL(6), NO_ADC, NO_TOUCH, - SERCOM(3, 0), - #ifdef SERCOM5 - SERCOM(5, 0), - #else - NO_SERCOM, - #endif - TC(4, 0), - TCC(0, 4)); -#endif -#if defined(PIN_PA23) && !defined(IGNORE_PIN_PA23) -PIN(PA23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH, - SERCOM(3, 1), - #ifdef SERCOM5 - SERCOM(5, 1), - #else - NO_SERCOM, - #endif - TC(4, 1), - TCC(0, 5)); -#endif -#if defined(PIN_PA24) && !defined(IGNORE_PIN_PA24) -PIN(PA24, EXTINT_CHANNEL(12), NO_ADC, NO_TOUCH, - SERCOM(3, 2), - #ifdef SERCOM5 - SERCOM(5, 2), - #else - NO_SERCOM, - #endif - TC(5, 0), - TCC(0, 2)); -#endif -#if defined(PIN_PA25) && !defined(IGNORE_PIN_PA25) -PIN(PA25, EXTINT_CHANNEL(13), NO_ADC, NO_TOUCH, - SERCOM(3, 3), - #ifdef SERCOM5 - SERCOM(5, 3), - #else - NO_SERCOM, - #endif - TC(5, 1), - TCC(1, 3)); -#endif -#if defined(PIN_PB22) && !defined(IGNORE_PIN_PB22) -PIN(PB22, EXTINT_CHANNEL(6), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(5, 2), - #ifdef TC7 - TC(7, 0, 0), - #else - NO_TIMER, - #endif - NO_TIMER); -#endif -#if defined(PIN_PB23) && !defined(IGNORE_PIN_PB23) -PIN(PB23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(5, 3), - #ifdef TC7 - TC(7, 1, 1), - #else - NO_TIMER, - #endif - NO_TIMER); -#endif -#if defined(PIN_PA27) && !defined(IGNORE_PIN_PA27) -PIN(PA27, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PA28) && !defined(IGNORE_PIN_PA28) -PIN(PA28, EXTINT_CHANNEL(8), NO_ADC, NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER); -#endif -#if defined(PIN_PA30) && !defined(IGNORE_PIN_PA30) -PIN(PA30, EXTINT_CHANNEL(10), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(1, 2), - TCC(1, 0), - NO_TIMER); -#endif -#if defined(PIN_PA31) && !defined(IGNORE_PIN_PA31) -PIN(PA31, EXTINT_CHANNEL(11), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(1, 3), - TCC(1, 1), - NO_TIMER); -#endif -#if defined(PIN_PB30) && !defined(IGNORE_PIN_PB30) -PIN(PB30, EXTINT_CHANNEL(14), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(5, 0), - TCC(0, 0), - TCC(1, 2)); -#endif -#if defined(PIN_PB31) && !defined(IGNORE_PIN_PB31) -PIN(PB31, EXTINT_CHANNEL(15), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(5, 1), - TCC(0, 1), - TCC(1, 3)); -#endif -#if defined(PIN_PB00) && !defined(IGNORE_PIN_PB00) -PIN(PB00, EXTINT_CHANNEL(0), ADC_INPUT(8), TOUCH(6), - NO_SERCOM, - SERCOM(5, 2), - #ifdef TC7 - TC(7, 0, 0), - #else - NO_TIMER, - #endif - NO_TIMER); -#endif -#if defined(PIN_PB01) && !defined(IGNORE_PIN_PB01) -PIN(PB01, EXTINT_CHANNEL(1), ADC_INPUT(9), TOUCH(7), - NO_SERCOM, - SERCOM(5, 3)), - #ifdef TC7 - TC(7, 1), - #else - NO_TIMER, - #endif - NO_TIMER; -#endif -#if defined(PIN_PB02) && !defined(IGNORE_PIN_PB02) -PIN(PB02, EXTINT_CHANNEL(2), ADC_INPUT(10), TOUCH(8), - NO_SERCOM, - SERCOM(5, 0), - #ifdef TC6 - TC(6, 0), - #else - NO_TIMER, - #endif - NO_TIMER); -#endif -#if defined(PIN_PB03) && !defined(IGNORE_PIN_PB03) -PIN(PB03, EXTINT_CHANNEL(3), ADC_INPUT(11), TOUCH(9), - NO_SERCOM, - SERCOM(5, 1), - #ifdef TC6 - TC(6, 1), - #else - NO_TIMER, - #endif - NO_TIMER); -#endif diff --git a/ports/atmel-samd/samd21_pins.h b/ports/atmel-samd/samd21_pins.h deleted file mode 100644 index 522563ef1..000000000 --- a/ports/atmel-samd/samd21_pins.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 by 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_BOARDS_SAMD21_PINS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H - -#include "include/sam.h" - -#include "common-hal/microcontroller/Pin.h" - -void reset_pin(uint8_t pin); - -#define MUX_C 2 -#define MUX_D 3 -#define MUX_E 4 -#define MUX_F 5 -#define PINMUX(pin, mux) ((((uint32_t) pin) << 16) | (mux)) - -#define NO_PIN PORT_BITS - -// Pins in datasheet order. -#ifdef PIN_PA00 -extern const mcu_pin_obj_t pin_PA00; -#endif -#ifdef PIN_PA01 -extern const mcu_pin_obj_t pin_PA01; -#endif -#ifdef PIN_PA02 -extern const mcu_pin_obj_t pin_PA02; -#endif -#ifdef PIN_PA03 -extern const mcu_pin_obj_t pin_PA03; -#endif -#ifdef PIN_PB04 -extern const mcu_pin_obj_t pin_PB04; -#endif -#ifdef PIN_PB05 -extern const mcu_pin_obj_t pin_PB05; -#endif -#ifdef PIN_PB06 -extern const mcu_pin_obj_t pin_PB06; -#endif -#ifdef PIN_PB07 -extern const mcu_pin_obj_t pin_PB07; -#endif -#ifdef PIN_PB08 -extern const mcu_pin_obj_t pin_PB08; -#endif -#ifdef PIN_PB09 -extern const mcu_pin_obj_t pin_PB09; -#endif -#ifdef PIN_PA04 -extern const mcu_pin_obj_t pin_PA04; -#endif -#ifdef PIN_PA05 -extern const mcu_pin_obj_t pin_PA05; -#endif -#ifdef PIN_PA06 -extern const mcu_pin_obj_t pin_PA06; -#endif -#ifdef PIN_PA07 -extern const mcu_pin_obj_t pin_PA07; -#endif -#ifdef PIN_PA08 -extern const mcu_pin_obj_t pin_PA08; -#endif -#ifdef PIN_PA09 -extern const mcu_pin_obj_t pin_PA09; -#endif -#ifdef PIN_PA10 -extern const mcu_pin_obj_t pin_PA10; -#endif -#ifdef PIN_PA11 -extern const mcu_pin_obj_t pin_PA11; -#endif -#ifdef PIN_PB10 -extern const mcu_pin_obj_t pin_PB10; -#endif -#ifdef PIN_PB11 -extern const mcu_pin_obj_t pin_PB11; -#endif -#ifdef PIN_PB12 -extern const mcu_pin_obj_t pin_PB12; -#endif -#ifdef PIN_PB13 -extern const mcu_pin_obj_t pin_PB13; -#endif -#ifdef PIN_PB14 -extern const mcu_pin_obj_t pin_PB14; -#endif - -// Second page. -#ifdef PIN_PB15 -extern const mcu_pin_obj_t pin_PB15; -#endif -#ifdef PIN_PA12 -extern const mcu_pin_obj_t pin_PA12; -#endif -#ifdef PIN_PA13 -extern const mcu_pin_obj_t pin_PA13; -#endif -#ifdef PIN_PA14 -extern const mcu_pin_obj_t pin_PA14; -#endif -#ifdef PIN_PA15 -extern const mcu_pin_obj_t pin_PA15; -#endif -#ifdef PIN_PA16 -extern const mcu_pin_obj_t pin_PA16; -#endif -#ifdef PIN_PA17 -extern const mcu_pin_obj_t pin_PA17; -#endif -#ifdef PIN_PA18 -extern const mcu_pin_obj_t pin_PA18; -#endif -#ifdef PIN_PA19 -extern const mcu_pin_obj_t pin_PA19; -#endif -#ifdef PIN_PB16 -extern const mcu_pin_obj_t pin_PB16; -#endif -#ifdef PIN_PB17 -extern const mcu_pin_obj_t pin_PB17; -#endif -#ifdef PIN_PA20 -extern const mcu_pin_obj_t pin_PA20; -#endif -#ifdef PIN_PA21 -extern const mcu_pin_obj_t pin_PA21; -#endif -#ifdef PIN_PA22 -extern const mcu_pin_obj_t pin_PA22; -#endif -#ifdef PIN_PA23 -extern const mcu_pin_obj_t pin_PA23; -#endif -#ifdef PIN_PA24 -extern const mcu_pin_obj_t pin_PA24; -#endif -#ifdef PIN_PA25 -extern const mcu_pin_obj_t pin_PA25; -#endif -#ifdef PIN_PB22 -extern const mcu_pin_obj_t pin_PB22; -#endif -#ifdef PIN_PB23 -extern const mcu_pin_obj_t pin_PB23; -#endif -#ifdef PIN_PA27 -extern const mcu_pin_obj_t pin_PA27; -#endif -#ifdef PIN_PA28 -extern const mcu_pin_obj_t pin_PA28; -#endif -#ifdef PIN_PA30 -extern const mcu_pin_obj_t pin_PA30; -#endif -#ifdef PIN_PA31 -extern const mcu_pin_obj_t pin_PA31; -#endif -#ifdef PIN_PB30 -extern const mcu_pin_obj_t pin_PB30; -#endif -#ifdef PIN_PB31 -extern const mcu_pin_obj_t pin_PB31; -#endif -#ifdef PIN_PB00 -extern const mcu_pin_obj_t pin_PB00; -#endif -#ifdef PIN_PB01 -extern const mcu_pin_obj_t pin_PB01; -#endif -#ifdef PIN_PB02 -extern const mcu_pin_obj_t pin_PB02; -#endif -#ifdef PIN_PB03 -extern const mcu_pin_obj_t pin_PB03; -#endif - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H diff --git a/ports/atmel-samd/samd51_clocks.c b/ports/atmel-samd/samd51_clocks.c deleted file mode 100644 index 6f8b1f010..000000000 --- a/ports/atmel-samd/samd51_clocks.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * 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 "clocks.h" - -#include "hpl_gclk_config.h" - -#include "bindings/samd/Clock.h" -#include "shared-bindings/microcontroller/__init__.h" - -#include "py/runtime.h" - -bool gclk_enabled(uint8_t gclk) { - return GCLK->GENCTRL[gclk].bit.GENEN; -} - -void disable_gclk(uint8_t gclk) { - while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} - GCLK->GENCTRL[gclk].bit.GENEN = false; - while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} -} - -void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral) { - GCLK->PCHCTRL[peripheral].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(gclk); - while(GCLK->SYNCBUSY.reg != 0) {} -} - -void disconnect_gclk_from_peripheral(uint8_t gclk, uint8_t peripheral) { - GCLK->PCHCTRL[peripheral].reg = 0; -} - -static void enable_clock_generator_sync(uint8_t gclk, uint32_t source, uint16_t divisor, bool sync) { - uint32_t divsel = 0; - // The datasheet says 8 bits and max value of 512, how is that possible? - if (divisor > 255) { // Generator 1 has 16 bits - divsel = GCLK_GENCTRL_DIVSEL; - for (int i = 15; i > 0; i--) { - if (divisor & (1 << i)) { - divisor = i - 1; - break; - } - } - } - - GCLK->GENCTRL[gclk].reg = GCLK_GENCTRL_SRC(source) | GCLK_GENCTRL_DIV(divisor) | divsel | GCLK_GENCTRL_OE | GCLK_GENCTRL_GENEN; - if (sync) - while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} -} - -void enable_clock_generator(uint8_t gclk, uint32_t source, uint16_t divisor) { - enable_clock_generator_sync(gclk, source, divisor, true); -} - -void disable_clock_generator(uint8_t gclk) { - GCLK->GENCTRL[gclk].reg = 0; - while ((GCLK->SYNCBUSY.vec.GENCTRL & (1 << gclk)) != 0) {} -} - -static void init_clock_source_osculp32k(void) { - // Calibration value is loaded at startup - OSC32KCTRL->OSCULP32K.bit.EN1K = 1; - OSC32KCTRL->OSCULP32K.bit.EN32K = 0; -} - -static void init_clock_source_xosc32k(void) { - OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ONDEMAND | - OSC32KCTRL_XOSC32K_EN1K | - OSC32KCTRL_XOSC32K_XTALEN | - OSC32KCTRL_XOSC32K_ENABLE | - OSC32KCTRL_XOSC32K_CGM(1); -} - -static void init_clock_source_dpll0(void) -{ - GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(5); - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0) | OSCCTRL_DPLLRATIO_LDR(59); - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK(0); - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; - - while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK || OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY)) {} -} - -void clock_init(void) { - // DFLL48M is enabled by default - - init_clock_source_osculp32k(); - - if (board_has_crystal()) { - init_clock_source_xosc32k(); - OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K_Val; - } else { - OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K_Val; - } - - MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV(1); - - enable_clock_generator_sync(0, GCLK_GENCTRL_SRC_DPLL0_Val, 1, false); - enable_clock_generator_sync(1, GCLK_GENCTRL_SRC_DFLL_Val, 1, false); - enable_clock_generator_sync(4, GCLK_GENCTRL_SRC_DPLL0_Val, 1, false); - enable_clock_generator_sync(5, GCLK_GENCTRL_SRC_DFLL_Val, 24, false); - - init_clock_source_dpll0(); -} - -static bool clk_enabled(uint8_t clk) { - return GCLK->PCHCTRL[clk].bit.CHEN; -} - -static uint8_t clk_get_generator(uint8_t clk) { - return GCLK->PCHCTRL[clk].bit.GEN; -} - -static uint8_t generator_get_source(uint8_t gen) { - return GCLK->GENCTRL[gen].bit.SRC; -} - -static bool osc_enabled(uint8_t index) { - switch (index) { - case GCLK_SOURCE_XOSC0: - return OSCCTRL->XOSCCTRL[0].bit.ENABLE; - case GCLK_SOURCE_XOSC1: - return OSCCTRL->XOSCCTRL[1].bit.ENABLE; - case GCLK_SOURCE_OSCULP32K: - return true; - case GCLK_SOURCE_XOSC32K: - return OSC32KCTRL->XOSC32K.bit.ENABLE; - case GCLK_SOURCE_DFLL: - return OSCCTRL->DFLLCTRLA.bit.ENABLE; - case GCLK_SOURCE_DPLL0: - return OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE; - case GCLK_SOURCE_DPLL1: - return OSCCTRL->Dpll[1].DPLLCTRLA.bit.ENABLE; - }; - return false; -} - -static uint32_t osc_get_source(uint8_t index) { - uint8_t dpll_index = index - GCLK_SOURCE_DPLL0; - uint32_t refclk = OSCCTRL->Dpll[dpll_index].DPLLCTRLB.bit.REFCLK; - switch (refclk) { - case 0x0: - return generator_get_source(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + dpll_index].bit.GEN); - case 0x1: - return GCLK_SOURCE_XOSC32K; - case 0x2: - return GCLK_SOURCE_XOSC0; - case 0x3: - return GCLK_SOURCE_XOSC1; - } - return 0; -} - -static uint32_t osc_get_frequency(uint8_t index); - -static uint32_t generator_get_frequency(uint8_t gen) { - uint8_t src = GCLK->GENCTRL[gen].bit.SRC; - uint32_t div; - if (GCLK->GENCTRL[gen].bit.DIVSEL) { - div = 1 << (GCLK->GENCTRL[gen].bit.DIV + 1); - } else { - div = GCLK->GENCTRL[gen].bit.DIV; - if (!div) - div = 1; - } - - return osc_get_frequency(src) / div; -} - -static uint32_t dpll_get_frequency(uint8_t index) { - uint8_t dpll_index = index - GCLK_SOURCE_DPLL0; - uint32_t refclk = OSCCTRL->Dpll[dpll_index].DPLLCTRLB.bit.REFCLK; - uint32_t freq; - - switch (refclk) { - case 0x0: // GCLK - freq = generator_get_frequency(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + dpll_index].bit.GEN); - break; - case 0x1: // XOSC32 - freq = 32768; - break; - case 0x2: // XOSC0 - case 0x3: // XOSC1 - return 0; // unknown - } - - return (freq * (OSCCTRL->Dpll[dpll_index].DPLLRATIO.bit.LDR + 1)) + - (freq * OSCCTRL->Dpll[dpll_index].DPLLRATIO.bit.LDRFRAC / 32); -} - -static uint32_t osc_get_frequency(uint8_t index) { - switch (index) { - case GCLK_SOURCE_XOSC0: - case GCLK_SOURCE_XOSC1: - return 0; // unknown - case GCLK_SOURCE_OSCULP32K: - case GCLK_SOURCE_XOSC32K: - return 32768; - case GCLK_SOURCE_DFLL: - return 48000000; - case GCLK_SOURCE_DPLL0: - case GCLK_SOURCE_DPLL1: - return dpll_get_frequency(index); - } - return 0; -} - -bool clock_get_enabled(uint8_t type, uint8_t index) { - if (type == 0) - return osc_enabled(index); - if (type == 1) - return clk_enabled(index); - if (type == 2) - return SysTick->CTRL & SysTick_CTRL_ENABLE_Msk; - return false; -} - -bool clock_get_parent(uint8_t type, uint8_t index, uint8_t *p_type, uint8_t *p_index) { - if (type == 0 && osc_enabled(index)) { - if (index == GCLK_SOURCE_DPLL0 || index == GCLK_SOURCE_DPLL1) { - *p_type = 0; - *p_index = osc_get_source(index); - return true; - } - return false; - } - if (type == 1 && index <= 47 && clk_enabled(index)) { - *p_type = 0; - *p_index = generator_get_source(clk_get_generator(index)); - return true; - } - if (type == 2) { - switch (index) { - case 0: - case 1: - *p_type = 0; - *p_index = generator_get_source(0); - return true; - case 2: - *p_type = 0; - switch (OSC32KCTRL->RTCCTRL.bit.RTCSEL) { - case 0: - case 1: - *p_index = GCLK_SOURCE_OSCULP32K; - return true; - case 4: - case 5: - *p_index = GCLK_SOURCE_XOSC32K; - return true; - } - return false; - } - } - return false; -} - -uint32_t clock_get_frequency(uint8_t type, uint8_t index) { - if (type == 0) { - return osc_get_frequency(index); - } - if (type == 1 && index <= 47 && clk_enabled(index)) { - return generator_get_frequency(clk_get_generator(index)); - } - if (type == 2) { - switch (index) { - case 0: - return clock_get_frequency(0, generator_get_source(0)) / SysTick->LOAD; - case 1: - return clock_get_frequency(0, generator_get_source(0)) / MCLK->CPUDIV.bit.DIV; - case 2: - switch (OSC32KCTRL->RTCCTRL.bit.RTCSEL) { - case 0: - case 4: - return 1024; - case 1: - case 5: - return 32768; - } - } - } - return 0; -} - -uint32_t clock_get_calibration(uint8_t type, uint8_t index) { - if (type == 0) { - switch (index) { - case GCLK_SOURCE_OSCULP32K: - return OSC32KCTRL->OSCULP32K.bit.CALIB; - }; - } - if (type == 2 && index == 0) { - return SysTick->LOAD + 1; - } - return 0; -} - -int clock_set_calibration(uint8_t type, uint8_t index, uint32_t val) { - if (type == 0) { - switch (index) { - case GCLK_SOURCE_OSCULP32K: - if (val > 0x3f) - return -1; - OSC32KCTRL->OSCULP32K.bit.CALIB = val; - return 0; - }; - } - if (type == 2 && index == 0) { - if (val < 0x1000 || val > 0x1000000) - return -1; - SysTick->LOAD = val - 1; - return 0; - } - return -2; -} - -#include -#include -#include -#include -#include -#include -#include - -CLOCK_SOURCE(XOSC0); -CLOCK_SOURCE(XOSC1); -CLOCK_SOURCE(GCLKIN); -CLOCK_SOURCE(GCLKGEN1); -CLOCK_SOURCE(OSCULP32K); -CLOCK_SOURCE(XOSC32K); -CLOCK_SOURCE(DFLL); -CLOCK_SOURCE(DPLL0); -CLOCK_SOURCE(DPLL1); - -CLOCK_GCLK_(OSCCTRL, DFLL48); -CLOCK_GCLK_(OSCCTRL, FDPLL0); -CLOCK_GCLK_(OSCCTRL, FDPLL1); -CLOCK_GCLK_(OSCCTRL, FDPLL032K); // GCLK_OSCCTRL_FDPLL1_32K, GCLK_SDHC0_SLOW, GCLK_SDHC1_SLOW, GCLK_SERCOM[0..7]_SLOW -CLOCK_GCLK(EIC); -CLOCK_GCLK_(FREQM, MSR); -// 6: GCLK_FREQM_REF -CLOCK_GCLK_(SERCOM0, CORE); -CLOCK_GCLK_(SERCOM1, CORE); -CLOCK(TC0_TC1, 1, 9); -CLOCK_GCLK(USB); -CLOCK_GCLK_(EVSYS, 0); -CLOCK_GCLK_(EVSYS, 1); -CLOCK_GCLK_(EVSYS, 2); -CLOCK_GCLK_(EVSYS, 3); -CLOCK_GCLK_(EVSYS, 4); -CLOCK_GCLK_(EVSYS, 5); -CLOCK_GCLK_(EVSYS, 6); -CLOCK_GCLK_(EVSYS, 7); -CLOCK_GCLK_(EVSYS, 8); -CLOCK_GCLK_(EVSYS, 9); -CLOCK_GCLK_(EVSYS, 10); -CLOCK_GCLK_(EVSYS, 11); -CLOCK_GCLK_(SERCOM2, CORE); -CLOCK_GCLK_(SERCOM3, CORE); -CLOCK(TCC0_TCC1, 1, 25); -CLOCK(TC2_TC3, 1, 26); -CLOCK_GCLK(CAN0); -CLOCK_GCLK(CAN1); -CLOCK(TCC2_TCC3, 1, 29); -CLOCK(TC4_TC5, 1, 30); -CLOCK_GCLK(PDEC); -CLOCK_GCLK(AC); -CLOCK_GCLK(CCL); -CLOCK_GCLK_(SERCOM4, CORE); -CLOCK_GCLK_(SERCOM5, CORE); -CLOCK_GCLK_(SERCOM6, CORE); -CLOCK_GCLK_(SERCOM7, CORE); -CLOCK_GCLK(TCC4); -CLOCK(TC6_TC7, 1, 39); -CLOCK_GCLK(ADC0); -CLOCK_GCLK(ADC1); -CLOCK_GCLK(DAC); -CLOCK_GCLK_(I2S, 0); -CLOCK_GCLK_(I2S, 1); -CLOCK_GCLK(SDHC0); -CLOCK_GCLK(SDHC1); -// 47: GCLK_CM4_TRACE - -CLOCK(SYSTICK, 2, 0); -CLOCK(CPU, 2, 1); -CLOCK(RTC, 2, 2); - - -STATIC const mp_rom_map_elem_t samd_clock_global_dict_table[] = { - CLOCK_ENTRY(XOSC0), - CLOCK_ENTRY(XOSC1), - CLOCK_ENTRY(GCLKIN), - CLOCK_ENTRY(GCLKGEN1), - CLOCK_ENTRY(OSCULP32K), - CLOCK_ENTRY(XOSC32K), - CLOCK_ENTRY(DFLL), - CLOCK_ENTRY(DPLL0), - CLOCK_ENTRY(DPLL1), - - CLOCK_ENTRY_(OSCCTRL, DFLL48), - CLOCK_ENTRY_(OSCCTRL, FDPLL0), - CLOCK_ENTRY_(OSCCTRL, FDPLL1), - CLOCK_ENTRY_(OSCCTRL, FDPLL032K), - CLOCK_ENTRY(EIC), - CLOCK_ENTRY_(FREQM, MSR), - CLOCK_ENTRY_(SERCOM0, CORE), - CLOCK_ENTRY_(SERCOM1, CORE), - CLOCK_ENTRY(TC0_TC1), - CLOCK_ENTRY(USB), - CLOCK_ENTRY_(EVSYS, 0), - CLOCK_ENTRY_(EVSYS, 1), - CLOCK_ENTRY_(EVSYS, 2), - CLOCK_ENTRY_(EVSYS, 3), - CLOCK_ENTRY_(EVSYS, 4), - CLOCK_ENTRY_(EVSYS, 5), - CLOCK_ENTRY_(EVSYS, 6), - CLOCK_ENTRY_(EVSYS, 7), - CLOCK_ENTRY_(EVSYS, 8), - CLOCK_ENTRY_(EVSYS, 9), - CLOCK_ENTRY_(EVSYS, 10), - CLOCK_ENTRY_(EVSYS, 11), - CLOCK_ENTRY_(SERCOM2, CORE), - CLOCK_ENTRY_(SERCOM3, CORE), - CLOCK_ENTRY(TCC0_TCC1), - CLOCK_ENTRY(TC2_TC3), - CLOCK_ENTRY(CAN0), - CLOCK_ENTRY(CAN1), - CLOCK_ENTRY(TCC2_TCC3), - CLOCK_ENTRY(TC4_TC5), - CLOCK_ENTRY(PDEC), - CLOCK_ENTRY(AC), - CLOCK_ENTRY(CCL), - CLOCK_ENTRY_(SERCOM4, CORE), - CLOCK_ENTRY_(SERCOM5, CORE), - CLOCK_ENTRY_(SERCOM6, CORE), - CLOCK_ENTRY_(SERCOM7, CORE), - CLOCK_ENTRY(TCC4), - CLOCK_ENTRY(TC6_TC7), - CLOCK_ENTRY(ADC0), - CLOCK_ENTRY(ADC1), - CLOCK_ENTRY(DAC), - CLOCK_ENTRY_(I2S, 0), - CLOCK_ENTRY_(I2S, 1), - CLOCK_ENTRY(SDHC0), - CLOCK_ENTRY(SDHC1), - - CLOCK_ENTRY(SYSTICK), - CLOCK_ENTRY(CPU), - CLOCK_ENTRY(RTC), -}; -MP_DEFINE_CONST_DICT(samd_clock_globals, samd_clock_global_dict_table); diff --git a/ports/atmel-samd/samd51_peripherals.c b/ports/atmel-samd/samd51_peripherals.c deleted file mode 100644 index 5772b8e0a..000000000 --- a/ports/atmel-samd/samd51_peripherals.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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" - -// The clock initializer values are rather random, so we need to put them in -// tables for lookup. We can't compute them. - -static const uint8_t SERCOMx_GCLK_ID_CORE[] = { - SERCOM0_GCLK_ID_CORE, - SERCOM1_GCLK_ID_CORE, - SERCOM2_GCLK_ID_CORE, - SERCOM3_GCLK_ID_CORE, - SERCOM4_GCLK_ID_CORE, - SERCOM5_GCLK_ID_CORE, -#ifdef SERCOM6 - SERCOM6_GCLK_ID_CORE, -#endif -#ifdef SERCOM7 - SERCOM7_GCLK_ID_CORE, -#endif -}; - -static const uint8_t SERCOMx_GCLK_ID_SLOW[] = { - SERCOM0_GCLK_ID_SLOW, - SERCOM1_GCLK_ID_SLOW, - SERCOM2_GCLK_ID_SLOW, - SERCOM3_GCLK_ID_SLOW, - SERCOM4_GCLK_ID_SLOW, - SERCOM5_GCLK_ID_SLOW, -#ifdef SERCOM6 - SERCOM6_GCLK_ID_SLOW, -#endif -#ifdef SERCOM7 - SERCOM7_GCLK_ID_SLOW, -#endif -}; - -Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS; - -// Clock initialization as done in Atmel START. -void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) { - hri_gclk_write_PCHCTRL_reg(GCLK, - SERCOMx_GCLK_ID_CORE[sercom_index], - GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); - hri_gclk_write_PCHCTRL_reg(GCLK, - SERCOMx_GCLK_ID_SLOW[sercom_index], - GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); - - // hri_mclk_set_APBAMASK_SERCOMx_bit is an inline, so let's use a switch, not a table. - switch (sercom_index) { - case 0: - hri_mclk_set_APBAMASK_SERCOM0_bit(MCLK); - break; - case 1: - hri_mclk_set_APBAMASK_SERCOM1_bit(MCLK); - break; - case 2: - hri_mclk_set_APBBMASK_SERCOM2_bit(MCLK); - break; - case 3: - hri_mclk_set_APBBMASK_SERCOM3_bit(MCLK); - break; - case 4: - hri_mclk_set_APBDMASK_SERCOM4_bit(MCLK); - break; - case 5: - hri_mclk_set_APBDMASK_SERCOM5_bit(MCLK); - break; -#ifdef SERCOM6 - case 6: - hri_mclk_set_APBDMASK_SERCOM6_bit(MCLK); - break; -#endif -#ifdef SERCOM7 - case 7: - hri_mclk_set_APBDMASK_SERCOM7_bit(MCLK); - break; -#endif - } -} - - -// Figure out the DOPO value given the chosen clock pad and mosi pad. -// Return an out-of-range value (255) if the combination is not permitted -// The ASF4 config files list this, but the SAMD51 datasheet -// says 0x1 and 0x3 are reserved, so don't allow pad 3 SCK. -// Transmit Data Pinout -// <0x0=>PAD[0,1]_DO_SCK -// <0x1=>PAD[2,3]_DO_SCK [RESERVED] -// <0x2=>PAD[3,1]_DO_SCK -// <0x3=>PAD[0,3]_DO_SCK [RESERVED] -uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) { - if (clock_pad != 1) { - return 255; - } - if (mosi_pad == 0) { - return 0x1; - } - if (mosi_pad == 3) { - return 0x2; - } - return 255; -} - -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/samd51_peripherals.h b/ports/atmel-samd/samd51_peripherals.h deleted file mode 100644 index 6643379a5..000000000 --- a/ports/atmel-samd/samd51_peripherals.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 by 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. - */ - -#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); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H diff --git a/ports/atmel-samd/samd51_pins.c b/ports/atmel-samd/samd51_pins.c deleted file mode 100644 index 6d597b6e1..000000000 --- a/ports/atmel-samd/samd51_pins.c +++ /dev/null @@ -1,1234 +0,0 @@ -/* - * 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. - */ - -#include "shared-bindings/microcontroller/Pin.h" - -#include "samd51_pins.h" - -#define SERCOM(sercom_index, p_pad) \ -{ \ - .index = sercom_index, \ - .pad = p_pad \ -} - -#define NO_SERCOM \ -{ \ - .index = 0x3f, \ - .pad = 0 \ -} - -#define TCC(p_index, p_wave_output) \ -{ \ - .index = p_index, \ - .is_tc = false, \ - .wave_output = p_wave_output \ -} - -#define TC(p_index, p_wave_output) \ -{ \ - .index = p_index, \ - .is_tc = true, \ - .wave_output = p_wave_output \ -} - -#define NO_TIMER TCC(0xff, 0) - -#define TOUCH(y_line) \ - .has_touch = true, \ - .touch_y_line = y_line, - -#define NO_TOUCH \ - .has_touch = false, - -#define EXTINT_CHANNEL(channel) \ - .has_extint = true, \ - .extint_channel = channel, - -#define NO_EXTINT \ - .has_extint = false, - -#define ADC_INPUT(input) (input) - -#define NO_ADC 0xff - -// This macro is used to simplify pin definition in boards//pins.c -#define PIN(p_name, p_extint, p_adc0, p_adc1, p_touch, \ - p_primary_sercom, p_secondary_sercom, \ - p_primary_timer, p_secondary_timer, p_tertiary_timer) \ -const mcu_pin_obj_t pin_## p_name = { \ - { &mcu_pin_type }, \ - .name = MP_QSTR_## p_name, \ - .pin = (PIN_## p_name), \ - p_extint \ - p_touch \ - .adc_input = {p_adc0, p_adc1}, \ - .timer = {p_primary_timer, p_secondary_timer, p_tertiary_timer}, \ - .sercom = {p_primary_sercom, p_secondary_sercom}, \ -} - -// Pins in datasheet order. -// NOTE(tannewt): TC wave out 0 is commented out because the first channel is -// used to vary the 16 bit timer's frequency. -#ifdef PIN_PB03 -PIN(PB03, EXTINT_CHANNEL(3), ADC_INPUT(15), NO_ADC, - TOUCH(21), - NO_SERCOM, - SERCOM(5, 1), - #ifdef TC6 - TC(6, 1), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA00 -PIN(PA00, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, - NO_TOUCH, - NO_SERCOM, - SERCOM(1, 0), - TC(2, 0), - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA01 -PIN(PA01, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, - NO_TOUCH, - NO_SERCOM, - SERCOM(1, 1), - TC(2, 0), - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC00 -PIN(PC00, EXTINT_CHANNEL(0), NO_ADC, ADC_INPUT(10), - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC01 -PIN(PC01, EXTINT_CHANNEL(1), NO_ADC, ADC_INPUT(11), - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC02 -PIN(PC02, EXTINT_CHANNEL(2), NO_ADC, ADC_INPUT(4), - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC03 -PIN(PC03, EXTINT_CHANNEL(3), NO_ADC, ADC_INPUT(5), - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA02 -PIN(PA02, EXTINT_CHANNEL(2), ADC_INPUT(0), NO_ADC, - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA03 -PIN(PA03, EXTINT_CHANNEL(3), ADC_INPUT(1), NO_ADC, - TOUCH(0), - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB04 -PIN(PB04, EXTINT_CHANNEL(4), NO_ADC, ADC_INPUT(6), - #ifdef PINMUX_PB04B_ADC0_PTCXY22 - TOUCH(22), - #else - NO_TOUCH, - #endif - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB05 -PIN(PB05, EXTINT_CHANNEL(5), NO_ADC, ADC_INPUT(7), - #ifdef PINMUX_PB05B_ADC0_PTCXY23 - TOUCH(23), - #else - NO_TOUCH, - #endif - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PD00 -PIN(PD00, EXTINT_CHANNEL(0), NO_ADC, ADC_INPUT(14), NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PD01 -PIN(PD01, EXTINT_CHANNEL(1), NO_ADC, ADC_INPUT(15), NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB06 -PIN(PB06, EXTINT_CHANNEL(6), NO_ADC, ADC_INPUT(8), - #ifdef PINMUX_PB06B_ADC0_PTCXY24 - TOUCH(24), - #else - NO_TOUCH, - #endif - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB07 -PIN(PB07, EXTINT_CHANNEL(7), NO_ADC, ADC_INPUT(9), - #ifdef PINMUX_PB07B_ADC0_PTCXY25 - TOUCH(25), - #else - NO_TOUCH, - #endif - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB08 -PIN(PB08, EXTINT_CHANNEL(8), ADC_INPUT(2), ADC_INPUT(0), TOUCH(1), - NO_SERCOM, - SERCOM(4, 0), - #ifdef TC4 - TC(4, 0), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB09 -PIN(PB09, EXTINT_CHANNEL(9), ADC_INPUT(3), ADC_INPUT(1), TOUCH(2), - NO_SERCOM, - SERCOM(4, 1), - #ifdef TC4 - TC(4, 1), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA04 -PIN(PA04, EXTINT_CHANNEL(4), ADC_INPUT(4), NO_ADC, TOUCH(3), - NO_SERCOM, - SERCOM(0, 0), - TC(0, 0), - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA05 -PIN(PA05, EXTINT_CHANNEL(5), ADC_INPUT(5), NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(0, 1), - TC(0, 1), - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA06 -PIN(PA06, EXTINT_CHANNEL(6), ADC_INPUT(6), NO_ADC, TOUCH(4), - NO_SERCOM, - SERCOM(0, 2), - TC(1, 0), - NO_TIMER, - NO_TIMER); -#endif - -// Second page -#ifdef PIN_PA07 -PIN(PA07, EXTINT_CHANNEL(7), ADC_INPUT(7), NO_ADC, TOUCH(5), - NO_SERCOM, - SERCOM(0, 3), - TC(1, 1), - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC04 -PIN(PC04, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 0), - #else - NO_SERCOM, - #endif - NO_SERCOM, - NO_TIMER, - TCC(0, 0), - NO_TIMER); -#endif -#ifdef PIN_PC05 -PIN(PC05, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 1), - #else - NO_SERCOM, - #endif - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC06 -PIN(PC06, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 2), - #else - NO_SERCOM, - #endif - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC07 -PIN(PC07, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 3), - #else - NO_SERCOM, - #endif - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA08 -PIN(PA08, NO_EXTINT, ADC_INPUT(8), ADC_INPUT(2), TOUCH(6), - SERCOM(0, 0), - SERCOM(2, 1), - TC(0, 0), - TCC(0, 0), - TCC(1, 4)); -#endif -#ifdef PIN_PA09 -PIN(PA09, EXTINT_CHANNEL(9), ADC_INPUT(9), ADC_INPUT(3), TOUCH(7), - SERCOM(0, 1), - SERCOM(2, 0), - TC(0, 1), - TCC(0, 1), - TCC(1, 5)); -#endif -#ifdef PIN_PA10 -PIN(PA10, EXTINT_CHANNEL(10), ADC_INPUT(10), NO_ADC, TOUCH(8), - SERCOM(0, 2), - SERCOM(2, 2), - TC(1, 0), - TCC(0, 2), - TCC(1, 6)); -#endif -#ifdef PIN_PA11 -PIN(PA11, EXTINT_CHANNEL(11), ADC_INPUT(11), NO_ADC, TOUCH(9), - SERCOM(0, 3), - SERCOM(2, 3), - TC(1, 0), - TCC(0, 3), - TCC(1, 7)); -#endif -#ifdef PIN_PB10 -PIN(PB10, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(4, 2), - #ifdef TC5 - TC(5, 0), - #else - NO_TIMER, - #endif - TCC(0, 4), - TCC(1, 0)); -#endif -#ifdef PIN_PB11 -PIN(PB11, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, NO_TOUCH, - NO_SERCOM, - SERCOM(4, 3), - #ifdef TC5 - TC(5, 1), - #else - NO_TIMER, - #endif - TCC(0, 5), - TCC(1, 1)); -#endif -#ifdef PIN_PB12 -PIN(PB12, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, - #ifdef PINMUX_PB12B_ADC0_PTCXY26 - TOUCH(26), - #else - NO_TOUCH, - #endif - SERCOM(4, 0), - NO_SERCOM, - #ifdef TC4 - TC(4, 0), - #else - NO_TIMER, - #endif - #ifdef TCC3 - TCC(3, 0), - #else - NO_TIMER, - #endif - TCC(0, 0)); -#endif -#ifdef PIN_PB13 -PIN(PB13, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, - #ifdef PINMUX_PB13B_ADC0_PTCXY27 - TOUCH(27), - #else - NO_TOUCH, - #endif - SERCOM(4, 1), - NO_SERCOM, - #ifdef TC4 - TC(4, 1), - #else - NO_TIMER, - #endif - #ifdef TCC3 - TCC(3, 1), - #else - NO_TIMER, - #endif - TCC(0, 1)); -#endif -#ifdef PIN_PB14 -PIN(PB14, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, - #ifdef PINMUX_PB14B_ADC0_PTCXY28 - TOUCH(28), - #else - NO_TOUCH, - #endif - SERCOM(4, 2), - NO_SERCOM, - #ifdef TC5 - TC(5, 0), - #else - NO_TIMER, - #endif - #ifdef TCC4 - TCC(4, 0), - #else - NO_TIMER, - #endif - TCC(0, 2)); -#endif -#ifdef PIN_PB15 -PIN(PB15, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, - #ifdef PINMUX_PB15B_ADC0_PTCXY29 - TOUCH(28), - #else - NO_TOUCH, - #endif - SERCOM(4, 3), - NO_SERCOM, - #ifdef TC5 - TC(5, 1), - #else - NO_TIMER, - #endif - #ifdef TCC4 - TCC(4, 1), - #else - NO_TIMER, - #endif - TCC(0, 3)); -#endif -#ifdef PIN_PD08 -PIN(PD08, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 0), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 1), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 1), - NO_TIMER); -#endif -#ifdef PIN_PD09 -PIN(PD09, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 1), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 0), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 2), - NO_TIMER); -#endif -#ifdef PIN_PD10 -PIN(PD10, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 2), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 2), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 3), - NO_TIMER); -#endif -#ifdef PIN_PD11 -PIN(PD11, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 3), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 3), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 4), - NO_TIMER); -#endif -#ifdef PIN_PD12 -PIN(PD12, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - TCC(0, 5), - NO_TIMER); -#endif -#ifdef PIN_PC10 -PIN(PC10, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 2), - #else - NO_SERCOM, - #endif - #ifdef SERCOM7 - SERCOM(7, 2), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 0), - TCC(1, 4)); -#endif -#ifdef PIN_PC11 -PIN(PC11, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 3), - #else - NO_SERCOM, - #endif - #ifdef SERCOM7 - SERCOM(7, 3), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 1), - TCC(1, 5)); -#endif -#ifdef PIN_PC12 -PIN(PC12, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 0), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 1), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 2), - TCC(1, 6)); -#endif -#ifdef PIN_PC13 -PIN(PC13, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 1), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 0), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 3), - TCC(1, 7)); -#endif -#ifdef PIN_PC14 -PIN(PC14, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 2), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 2), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 4), - TCC(1, 0)); -#endif -#ifdef PIN_PC15 -PIN(PC15, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 3), - #else - NO_SERCOM, - #endif - #ifdef SERCOM6 - SERCOM(6, 3), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(0, 5), - TCC(1, 1)); -#endif -#ifdef PIN_PA12 -PIN(PA12, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 0), - SERCOM(4, 1), - TC(2, 0), - TCC(0, 6), - TCC(1, 2)); -#endif -#ifdef PIN_PA13 -PIN(PA13, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 1), - SERCOM(4, 0), - TC(2, 1), - TCC(0, 7), - TCC(1, 3)); -#endif - -// Third page -#ifdef PIN_PA14 -PIN(PA14, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 2), - SERCOM(4, 2), - TC(3, 0), - TCC(2, 0), - TCC(1, 2)); -#endif -#ifdef PIN_PA15 -PIN(PA15, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 3), - SERCOM(4, 3), - TC(3, 1), - TCC(2, 1), - TCC(1, 3)); -#endif -#ifdef PIN_PA16 -PIN(PA16, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, TOUCH(10), - SERCOM(1, 0), - SERCOM(3, 1), - TC(2, 0), - TCC(1, 0), - TCC(0, 4)); -#endif -#ifdef PIN_PA17 -PIN(PA17, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, TOUCH(11), - SERCOM(1, 1), - SERCOM(3, 0), - TC(2, 1), - TCC(1, 1), - TCC(0, 5)); -#endif -#ifdef PIN_PA18 -PIN(PA18, EXTINT_CHANNEL(2), NO_ADC, NO_ADC, TOUCH(12), - SERCOM(1, 2), - SERCOM(3, 2), - TC(3, 0), - TCC(1, 2), - TCC(0, 6)); -#endif -#ifdef PIN_PA19 -PIN(PA19, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, TOUCH(13), - SERCOM(1, 3), - SERCOM(3, 3), - TC(3, 1), - TCC(1, 3), - TCC(0, 7)); -#endif -#ifdef PIN_PC16 -PIN(PC16, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 0), - #else - NO_SERCOM, - #endif - SERCOM(0, 1), - NO_TIMER, - TCC(TCC0, 0), - NO_TIMER); -#endif -#ifdef PIN_PC17 -PIN(PC17, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 1), - #else - NO_SERCOM, - #endif - SERCOM(0, 0), - NO_TIMER, - TCC(0, 1), - NO_TIMER); -#endif -#ifdef PIN_PC18 -PIN(PC18, EXTINT_CHANNEL(2), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 2), - #else - NO_SERCOM, - #endif - SERCOM(0, 2), - NO_TIMER, - TCC(0, 2), - NO_TIMER); -#endif -#ifdef PIN_PC19 -PIN(PC19, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, - NO_TOUCH, - #ifdef SERCOM6 - SERCOM(6, 3), - #else - NO_SERCOM, - #endif - SERCOM(0, 3), - NO_TIMER, - TCC(0, 3), - NO_TIMER); -#endif -#ifdef PIN_PC20 -PIN(PC20, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - TCC(0, 4), - NO_TIMER); -#endif -#ifdef PIN_PC21 -PIN(PC21, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, - NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - TCC(0, 5), - NO_TIMER); -#endif -#ifdef PIN_PC22 -PIN(PC22, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, - NO_TOUCH, - SERCOM(1, 0), - SERCOM(3, 1), - NO_TIMER, - TCC(0, 6), - NO_TIMER); -#endif -#ifdef PIN_PC23 -PIN(PC23, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, - NO_TOUCH, - SERCOM(1, 1), - SERCOM(3, 0), - NO_TIMER, - TCC(0, 7), - NO_TIMER); -#endif -#ifdef PIN_PD20 -PIN(PD20, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, - NO_TOUCH, - SERCOM(1, 2), - SERCOM(3, 2), - NO_TIMER, - TCC(1, 0), - NO_TIMER); -#endif -#ifdef PIN_PD21 -PIN(PD21, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, - NO_TOUCH, - SERCOM(1, 3), - SERCOM(3, 3), - NO_TIMER, - TCC(1, 1), - NO_TIMER); -#endif - - - - -#ifdef PIN_PB16 -PIN(PB16, EXTINT_CHANNEL(0), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(5, 0), - NO_SERCOM, - #ifdef TC6 - TC(6, 0), - #else - NO_TIMER, - #endif - TCC(3, 0), - TCC(0, 4)); -#endif -#ifdef PIN_PB17 -PIN(PB17, EXTINT_CHANNEL(1), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(5, 1), - NO_SERCOM, - #ifdef TC6 - TC(6, 1), - #else - NO_TIMER, - #endif - TCC(3, 1), - TCC(0, 5)); -#endif -#ifdef PIN_PB18 -PIN(PB18, EXTINT_CHANNEL(2), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(5, 2), - #ifdef SERCOM7 - SERCOM(7, 2), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(1, 0), - NO_TIMER); -#endif -#ifdef PIN_PB19 -PIN(PB19, EXTINT_CHANNEL(3), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(5, 3), - #ifdef SERCOM7 - SERCOM(7, 3), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(1, 1), - NO_TIMER); -#endif -#ifdef PIN_PB20 -PIN(PB20, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(5, 0), - #ifdef SERCOM7 - SERCOM(7, 1), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(1, 2), - NO_TIMER); -#endif -#ifdef PIN_PB21 -PIN(PB21, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(5, 1), - #ifdef SERCOM7 - SERCOM(7, 0), - #else - NO_SERCOM, - #endif - NO_TIMER, - TCC(1, 3), - NO_TIMER); -#endif -#ifdef PIN_PA20 -PIN(PA20, EXTINT_CHANNEL(4), NO_ADC, NO_ADC, TOUCH(14), - SERCOM(5, 2), - SERCOM(3, 2), - #ifdef TC7 - TC(7, 0), - #else - NO_TIMER, - #endif - TCC(1, 4), - TCC(0, 0)); -#endif -#ifdef PIN_PA21 -PIN(PA21, EXTINT_CHANNEL(5), NO_ADC, NO_ADC, TOUCH(15), - SERCOM(5, 3), - SERCOM(3, 3), - #ifdef TC7 - TC(7, 1), - #else - NO_TIMER, - #endif - TCC(1, 5), - TCC(0, 1)); -#endif -#ifdef PIN_PA22 -PIN(PA22, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, TOUCH(16), - SERCOM(3, 0), - SERCOM(5, 1), - #ifdef TC4 - TC(4, 0), - #else - NO_TIMER, - #endif - TCC(1, 6), - TCC(0, 2)); -#endif -#ifdef PIN_PA23 -PIN(PA23, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, TOUCH(17), - SERCOM(3, 1), - SERCOM(5, 0), - #ifdef TC4 - TC(4, 1), - #else - NO_TIMER, - #endif - TCC(1, 7), - TCC(0, 3)); -#endif -#ifdef PIN_PA24 -PIN(PA24, EXTINT_CHANNEL(8), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(3, 2), - SERCOM(5, 2), - #ifdef TC5 - TC(5, 0), - #else - NO_TIMER, - #endif - TCC(2, 2), - NO_TIMER); -#endif -#ifdef PIN_PA25 -PIN(PA25, EXTINT_CHANNEL(9), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(3, 3), - SERCOM(5, 3), - #ifdef TC5 - TC(5, 1), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif - -// Fourth page -#ifdef PIN_PB22 -PIN(PB22, EXTINT_CHANNEL(6), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(1, 2), - SERCOM(5, 2), - #ifdef TC7 - TC(7, 0), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB23 -PIN(PB23, EXTINT_CHANNEL(7), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(1, 3), - SERCOM(5, 3), - #ifdef TC7 - TC(7, 1), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB24 -PIN(PB24, EXTINT_CHANNEL(8), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(0, 0), - SERCOM(2, 1), - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB25 -PIN(PB25, EXTINT_CHANNEL(9), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(0, 1), - SERCOM(2, 0), - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB26 -PIN(PB26, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 0), - SERCOM(4, 1), - NO_TIMER, - TCC(TCC1, 2), - NO_TIMER); -#endif -#ifdef PIN_PB27 -PIN(PB27, EXTINT_CHANNEL(13), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 1), - SERCOM(4, 0), - NO_TIMER, - TCC(1, 3), - NO_TIMER); -#endif -#ifdef PIN_PB28 -PIN(PB28, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 2), - SERCOM(4, 2), - NO_TIMER, - TCC(1, 4), - NO_TIMER); -#endif -#ifdef PIN_PB29 -PIN(PB29, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(2, 3), - SERCOM(4, 3), - NO_TIMER, - TCC(1, 5), - NO_TIMER); -#endif -#ifdef PIN_PC24 -PIN(PC24, EXTINT_CHANNEL(8), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(0, 2), - SERCOM(2, 2), - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC25 -PIN(PC25, EXTINT_CHANNEL(9), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(0, 3), - SERCOM(2, 3), - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC26 -PIN(PC26, EXTINT_CHANNEL(10), NO_ADC, NO_ADC, NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC27 -PIN(PC27, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(1, 0), - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC28 -PIN(PC28, EXTINT_CHANNEL(12), NO_ADC, NO_ADC, NO_TOUCH, - SERCOM(1, 1), - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA27 -PIN(PA27, EXTINT_CHANNEL(11), NO_ADC, NO_ADC, TOUCH(18), - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PA30 -PIN(PA30, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, TOUCH(19), - #ifdef SERCOM7 - SERCOM(7, 2), - #else - NO_SERCOM, - #endif - SERCOM(1, 2), - #ifdef TC6 - TC(6, 0), - #else - NO_TIMER, - #endif - TCC(2, 0), - NO_TIMER); -#endif -#ifdef PIN_PA31 -PIN(PA31, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 3), - #else - NO_SERCOM, - #endif - SERCOM(1, 3), - #ifdef TC6 - TC(6, 1), - #else - NO_TIMER, - #endif - TCC(2, 1), - NO_TIMER); -#endif -#ifdef PIN_PB30 -PIN(PB30, EXTINT_CHANNEL(14), NO_ADC, NO_ADC, NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 0), - #else - NO_SERCOM, - #endif - SERCOM(5, 1), - TC(0, 0), - TCC(4, 0), - TCC(0, 6)); -#endif -#ifdef PIN_PB31 -PIN(PB31, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, - #ifdef SERCOM7 - SERCOM(7, 1), - #else - NO_SERCOM, - #endif - SERCOM(5, 0), - TC(0, 1), - TCC(4, 1), - TCC(0, 7)); -#endif -#ifdef PIN_PC30 -PIN(PC30, EXTINT_CHANNEL(14), NO_ADC, ADC_INPUT(12), NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PC31 -PIN(PC31, EXTINT_CHANNEL(15), NO_ADC, ADC_INPUT(13), NO_TOUCH, - NO_SERCOM, - NO_SERCOM, - NO_TIMER, - NO_TIMER, - NO_TIMER); -#endif - - -#ifdef PIN_PB00 -PIN(PB00, EXTINT_CHANNEL(0), ADC_INPUT(12), NO_ADC, - #ifdef PINMUX_PB00B_ADC0_PTCXY30 - TOUCH(30), - #else - NO_TOUCH, - #endif - NO_SERCOM, - SERCOM(5, 2), - #ifdef TC7 - TC(7, 0), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB01 -PIN(PB01, EXTINT_CHANNEL(1), ADC_INPUT(13), NO_ADC, - #ifdef PINMUX_PB01B_ADC0_PTCXY31 - TOUCH(31), - #else - NO_TOUCH, - #endif - NO_SERCOM, - SERCOM(5, 3), - #ifdef TC7 - TC(7, 1), - #else - NO_TIMER, - #endif - NO_TIMER, - NO_TIMER); -#endif -#ifdef PIN_PB02 -PIN(PB02, EXTINT_CHANNEL(2), ADC_INPUT(14), NO_ADC, TOUCH(20), - NO_SERCOM, - SERCOM(5, 0), - #ifdef TC6 - TC(6, 0), - #else - NO_TIMER, - #endif - TCC(2, 2), - NO_TIMER); -#endif diff --git a/ports/atmel-samd/samd51_pins.h b/ports/atmel-samd/samd51_pins.h deleted file mode 100644 index c9ffacc24..000000000 --- a/ports/atmel-samd/samd51_pins.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 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_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 -#define MUX_D 3 -#define MUX_E 4 -#define MUX_F 5 -#define PINMUX(pin, mux) ((((uint32_t) pin) << 16) | (mux)) - -#define NO_PIN PORT_BITS - -// Pins in datasheet order. -#ifdef PIN_PB03 -extern const mcu_pin_obj_t pin_PB03; -#endif -#ifdef PIN_PA00 -extern const mcu_pin_obj_t pin_PA00; -#endif -#ifdef PIN_PA01 -extern const mcu_pin_obj_t pin_PA01; -#endif -#ifdef PIN_PC00 -extern const mcu_pin_obj_t pin_PC00; -#endif -#ifdef PIN_PC01 -extern const mcu_pin_obj_t pin_PC01; -#endif -#ifdef PIN_PC02 -extern const mcu_pin_obj_t pin_PC02; -#endif -#ifdef PIN_PC03 -extern const mcu_pin_obj_t pin_PC03; -#endif -#ifdef PIN_PA02 -extern const mcu_pin_obj_t pin_PA02; -#endif -#ifdef PIN_PA03 -extern const mcu_pin_obj_t pin_PA03; -#endif -#ifdef PIN_PB04 -extern const mcu_pin_obj_t pin_PB04; -#endif -#ifdef PIN_PB05 -extern const mcu_pin_obj_t pin_PB05; -#endif -#ifdef PIN_PD00 -extern const mcu_pin_obj_t pin_PD00; -#endif -#ifdef PIN_PD01 -extern const mcu_pin_obj_t pin_PD01; -#endif -#ifdef PIN_PB06 -extern const mcu_pin_obj_t pin_PB06; -#endif -#ifdef PIN_PB07 -extern const mcu_pin_obj_t pin_PB07; -#endif -#ifdef PIN_PB08 -extern const mcu_pin_obj_t pin_PB08; -#endif -#ifdef PIN_PB09 -extern const mcu_pin_obj_t pin_PB09; -#endif -#ifdef PIN_PA04 -extern const mcu_pin_obj_t pin_PA04; -#endif -#ifdef PIN_PA05 -extern const mcu_pin_obj_t pin_PA05; -#endif -#ifdef PIN_PA06 -extern const mcu_pin_obj_t pin_PA06; -#endif - -// Second page -#ifdef PIN_PA07 -extern const mcu_pin_obj_t pin_PA07; -#endif -#ifdef PIN_PC04 -extern const mcu_pin_obj_t pin_PC04; -#endif -#ifdef PIN_PC05 -extern const mcu_pin_obj_t pin_PC05; -#endif -#ifdef PIN_PC06 -extern const mcu_pin_obj_t pin_PC06; -#endif -#ifdef PIN_PC07 -extern const mcu_pin_obj_t pin_PC07; -#endif -#ifdef PIN_PA08 -extern const mcu_pin_obj_t pin_PA08; -#endif -#ifdef PIN_PA09 -extern const mcu_pin_obj_t pin_PA09; -#endif -#ifdef PIN_PA10 -extern const mcu_pin_obj_t pin_PA10; -#endif -#ifdef PIN_PA11 -extern const mcu_pin_obj_t pin_PA11; -#endif -#ifdef PIN_PB10 -extern const mcu_pin_obj_t pin_PB10; -#endif -#ifdef PIN_PB11 -extern const mcu_pin_obj_t pin_PB11; -#endif -#ifdef PIN_PB12 -extern const mcu_pin_obj_t pin_PB12; -#endif -#ifdef PIN_PB13 -extern const mcu_pin_obj_t pin_PB13; -#endif -#ifdef PIN_PB14 -extern const mcu_pin_obj_t pin_PB14; -#endif -#ifdef PIN_PB15 -extern const mcu_pin_obj_t pin_PB15; -#endif -#ifdef PIN_PD08 -extern const mcu_pin_obj_t pin_PD08; -#endif -#ifdef PIN_PD09 -extern const mcu_pin_obj_t pin_PD09; -#endif -#ifdef PIN_PD10 -extern const mcu_pin_obj_t pin_PD10; -#endif -#ifdef PIN_PD11 -extern const mcu_pin_obj_t pin_PD11; -#endif -#ifdef PIN_PD12 -extern const mcu_pin_obj_t pin_PD12; -#endif -#ifdef PIN_PC10 -extern const mcu_pin_obj_t pin_PC10; -#endif -#ifdef PIN_PC11 -extern const mcu_pin_obj_t pin_PC11; -#endif -#ifdef PIN_PC12 -extern const mcu_pin_obj_t pin_PC12; -#endif -#ifdef PIN_PC13 -extern const mcu_pin_obj_t pin_PC13; -#endif -#ifdef PIN_PC14 -extern const mcu_pin_obj_t pin_PC14; -#endif -#ifdef PIN_PC15 -extern const mcu_pin_obj_t pin_PC15; -#endif -#ifdef PIN_PA12 -extern const mcu_pin_obj_t pin_PA12; -#endif -#ifdef PIN_PA13 -extern const mcu_pin_obj_t pin_PA13; -#endif - -// Third page -#ifdef PIN_PA14 -extern const mcu_pin_obj_t pin_PA14; -#endif -#ifdef PIN_PA15 -extern const mcu_pin_obj_t pin_PA15; -#endif -#ifdef PIN_PA16 -extern const mcu_pin_obj_t pin_PA16; -#endif -#ifdef PIN_PA17 -extern const mcu_pin_obj_t pin_PA17; -#endif -#ifdef PIN_PA18 -extern const mcu_pin_obj_t pin_PA18; -#endif -#ifdef PIN_PA19 -extern const mcu_pin_obj_t pin_PA19; -#endif -#ifdef PIN_PC16 -extern const mcu_pin_obj_t pin_PC16; -#endif -#ifdef PIN_PC17 -extern const mcu_pin_obj_t pin_PC17; -#endif -#ifdef PIN_PC18 -extern const mcu_pin_obj_t pin_PC18; -#endif -#ifdef PIN_PC19 -extern const mcu_pin_obj_t pin_PC19; -#endif -#ifdef PIN_PC20 -extern const mcu_pin_obj_t pin_PC20; -#endif -#ifdef PIN_PC21 -extern const mcu_pin_obj_t pin_PC21; -#endif -#ifdef PIN_PC22 -extern const mcu_pin_obj_t pin_PC22; -#endif -#ifdef PIN_PC23 -extern const mcu_pin_obj_t pin_PC23; -#endif -#ifdef PIN_PD20 -extern const mcu_pin_obj_t pin_PD20; -#endif -#ifdef PIN_PD21 -extern const mcu_pin_obj_t pin_PD21; -#endif -#ifdef PIN_PB16 -extern const mcu_pin_obj_t pin_PB16; -#endif -#ifdef PIN_PB17 -extern const mcu_pin_obj_t pin_PB17; -#endif -#ifdef PIN_PB18 -extern const mcu_pin_obj_t pin_PB18; -#endif -#ifdef PIN_PB19 -extern const mcu_pin_obj_t pin_PB19; -#endif -#ifdef PIN_PB20 -extern const mcu_pin_obj_t pin_PB20; -#endif -#ifdef PIN_PB21 -extern const mcu_pin_obj_t pin_PB21; -#endif -#ifdef PIN_PA20 -extern const mcu_pin_obj_t pin_PA20; -#endif -#ifdef PIN_PA21 -extern const mcu_pin_obj_t pin_PA21; -#endif -#ifdef PIN_PA22 -extern const mcu_pin_obj_t pin_PA22; -#endif -#ifdef PIN_PA23 -extern const mcu_pin_obj_t pin_PA23; -#endif -#ifdef PIN_PA24 -extern const mcu_pin_obj_t pin_PA24; -#endif -#ifdef PIN_PA25 -extern const mcu_pin_obj_t pin_PA25; -#endif - -// Fourth page -#ifdef PIN_PB22 -extern const mcu_pin_obj_t pin_PB22; -#endif -#ifdef PIN_PB23 -extern const mcu_pin_obj_t pin_PB23; -#endif -#ifdef PIN_PB24 -extern const mcu_pin_obj_t pin_PB24; -#endif -#ifdef PIN_PB25 -extern const mcu_pin_obj_t pin_PB25; -#endif -#ifdef PIN_PB26 -extern const mcu_pin_obj_t pin_PB26; -#endif -#ifdef PIN_PB27 -extern const mcu_pin_obj_t pin_PB27; -#endif -#ifdef PIN_PB28 -extern const mcu_pin_obj_t pin_PB28; -#endif -#ifdef PIN_PB29 -extern const mcu_pin_obj_t pin_PB29; -#endif -#ifdef PIN_PC24 -extern const mcu_pin_obj_t pin_PC24; -#endif -#ifdef PIN_PC25 -extern const mcu_pin_obj_t pin_PC25; -#endif -#ifdef PIN_PC26 -extern const mcu_pin_obj_t pin_PC26; -#endif -#ifdef PIN_PC27 -extern const mcu_pin_obj_t pin_PC27; -#endif -#ifdef PIN_PC28 -extern const mcu_pin_obj_t pin_PC28; -#endif -#ifdef PIN_PA27 -extern const mcu_pin_obj_t pin_PA27; -#endif -#ifdef PIN_PA30 -extern const mcu_pin_obj_t pin_PA30; -#endif -#ifdef PIN_PA31 -extern const mcu_pin_obj_t pin_PA31; -#endif -#ifdef PIN_PB30 -extern const mcu_pin_obj_t pin_PB30; -#endif -#ifdef PIN_PB31 -extern const mcu_pin_obj_t pin_PB31; -#endif -#ifdef PIN_PC30 -extern const mcu_pin_obj_t pin_PC30; -#endif -#ifdef PIN_PC31 -extern const mcu_pin_obj_t pin_PC31; -#endif -#ifdef PIN_PB00 -extern const mcu_pin_obj_t pin_PB00; -#endif -#ifdef PIN_PB01 -extern const mcu_pin_obj_t pin_PB01; -#endif -#ifdef PIN_PB02 -extern const mcu_pin_obj_t pin_PB02; -#endif -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H diff --git a/ports/atmel-samd/shared_dma.c b/ports/atmel-samd/shared_dma.c deleted file mode 100644 index edc2d0f1a..000000000 --- a/ports/atmel-samd/shared_dma.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * 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 "shared_dma.h" - -#include - -#include "py/gc.h" -#include "py/mpstate.h" - -#include "hal/utils/include/utils.h" - -#include "shared-bindings/microcontroller/__init__.h" - -COMPILER_ALIGNED(16) static DmacDescriptor dma_descriptors[DMA_CHANNEL_COUNT]; - -// Don't use these directly. They are used by the DMA engine itself. -COMPILER_ALIGNED(16) static DmacDescriptor write_back_descriptors[DMA_CHANNEL_COUNT]; - -#ifdef SAMD21 -#define FIRST_SERCOM_RX_TRIGSRC 0x01 -#define FIRST_SERCOM_TX_TRIGSRC 0x02 -#endif -#ifdef SAMD51 -#define FIRST_SERCOM_RX_TRIGSRC 0x04 -#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 - MCLK->AHBMASK.reg |= MCLK_AHBMASK_DMAC; - #endif - - #ifdef SAMD21 - PM->AHBMASK.reg |= PM_AHBMASK_DMAC; - PM->APBBMASK.reg |= PM_APBBMASK_DMAC; - #endif - - DMAC->CTRL.reg = DMAC_CTRL_SWRST; - - DMAC->BASEADDR.reg = (uint32_t) dma_descriptors; - DMAC->WRBADDR.reg = (uint32_t) write_back_descriptors; - - DMAC->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN0; - - for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { - dma_configure(i, 0, true); - } -} - -// Do write and read simultaneously. If buffer_out is NULL, write the tx byte over and over. -// If buffer_out is a real buffer, ignore tx. -// DMAs buffer_out -> dest -// DMAs src -> buffer_in -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))) { - return -1; - } - - uint32_t beat_size = DMAC_BTCTRL_BEATSIZE_BYTE; - bool sercom = true; - bool tx_active = false; - bool rx_active = false; - uint16_t beat_length = length; - #ifdef SAMD51 - if (peripheral == QSPI) { - // Check input alignment on word boundaries. - if ((((uint32_t) buffer_in) & 0x3) != 0 || - (((uint32_t) buffer_out) & 0x3) != 0) { - return -3; - } - beat_size = DMAC_BTCTRL_BEATSIZE_WORD | DMAC_BTCTRL_SRCINC | DMAC_BTCTRL_DSTINC; - beat_length /= 4; - sercom = false; - if (buffer_out != NULL) { - dma_configure(SHARED_TX_CHANNEL, QSPI_DMAC_ID_TX, false); - tx_active = true; - } else { - dma_configure(SHARED_RX_CHANNEL, QSPI_DMAC_ID_RX, false); - rx_active = true; - } - - } else { - #endif - - // sercom index is incorrect for SAMD51 - dma_configure(SHARED_TX_CHANNEL, sercom_index(peripheral) * 2 + FIRST_SERCOM_TX_TRIGSRC, false); - tx_active = true; - if (buffer_in != NULL) { - dma_configure(SHARED_RX_CHANNEL, sercom_index(peripheral) * 2 + FIRST_SERCOM_RX_TRIGSRC, false); - rx_active = true; - } - - #ifdef SAMD51 - } - #endif - - // Set up RX first. - if (rx_active) { - DmacDescriptor* rx_descriptor = &dma_descriptors[SHARED_RX_CHANNEL]; - rx_descriptor->BTCTRL.reg = beat_size | DMAC_BTCTRL_DSTINC; - rx_descriptor->BTCNT.reg = beat_length; - rx_descriptor->SRCADDR.reg = ((uint32_t) src); - #ifdef SAMD51 - if (peripheral == QSPI) { - rx_descriptor->SRCADDR.reg = ((uint32_t) src + length); - } - #endif - rx_descriptor->DSTADDR.reg = ((uint32_t)buffer_in + length); - rx_descriptor->BTCTRL.bit.VALID = true; - } - - // Set up TX second. - if (tx_active) { - DmacDescriptor* tx_descriptor = &dma_descriptors[SHARED_TX_CHANNEL]; - tx_descriptor->BTCTRL.reg = beat_size; - tx_descriptor->BTCNT.reg = beat_length; - - if (buffer_out != NULL) { - tx_descriptor->SRCADDR.reg = ((uint32_t)buffer_out + length); - tx_descriptor->BTCTRL.reg |= DMAC_BTCTRL_SRCINC; - } else { - tx_descriptor->SRCADDR.reg = ((uint32_t) &tx); - } - tx_descriptor->DSTADDR.reg = ((uint32_t) dest); - tx_descriptor->BTCTRL.bit.VALID = true; - } - if (sercom) { - SercomSpi *s = &((Sercom*) peripheral)->SPI; - s->INTFLAG.reg = SERCOM_SPI_INTFLAG_RXC | SERCOM_SPI_INTFLAG_DRE; - } else { - //QSPI->INTFLAG.reg = QSPI_INTFLAG_RXC | QSPI_INTFLAG_DRE; - } - // Start the RX job first so we don't miss the first byte. The TX job clocks - // the output. - if (rx_active) { - dma_enable_channel(SHARED_RX_CHANNEL); - } - if (tx_active) { - dma_enable_channel(SHARED_TX_CHANNEL); - } - - - if (sercom) { - //DMAC->SWTRIGCTRL.reg |= (1 << SHARED_TX_CHANNEL); - } else { - // Do a manual copy to trigger then DMA. We do 32-bit accesses to match the DMA. - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wcast-align" - if (rx_active) { - //buffer_in[0] = *src; - DMAC->SWTRIGCTRL.reg |= (1 << SHARED_RX_CHANNEL); - } else { - //*(uint32_t*)dest = ((uint32_t*) buffer_out)[0]; - } - #pragma GCC diagnostic pop - } - - // Channels cycle between Suspend -> Pending -> Busy and back while transfering. So, we check - // the channels transfer status for an error or completion. - if (rx_active) { - while ((dma_transfer_status(SHARED_RX_CHANNEL) & 0x3) == 0) {} - } - if (tx_active) { - while ((dma_transfer_status(SHARED_TX_CHANNEL) & 0x3) == 0) {} - } - - if (sercom) { - Sercom* s = (Sercom*) peripheral; - // Wait for the SPI transfer to complete. - while (s->SPI.INTFLAG.bit.TXC == 0) {} - - // This transmit will cause the RX buffer overflow but we're OK with that. - // So, read the garbage and clear the overflow flag. - if (!rx_active) { - while (s->SPI.INTFLAG.bit.RXC == 1) { - s->SPI.DATA.reg; - } - s->SPI.STATUS.bit.BUFOVF = 1; - s->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_ERROR; - } - } - - if ((!rx_active || dma_transfer_status(SHARED_RX_CHANNEL) == DMAC_CHINTFLAG_TCMPL) && - (!tx_active || dma_transfer_status(SHARED_TX_CHANNEL) == DMAC_CHINTFLAG_TCMPL)) { - return length; - } - return -2; -} - - -int32_t sercom_dma_transfer(Sercom* sercom, const uint8_t* buffer_out, uint8_t* buffer_in, - uint32_t length) { - return shared_dma_transfer(sercom, buffer_out, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, buffer_in, length, 0); -} - -int32_t sercom_dma_write(Sercom* sercom, const uint8_t* buffer, uint32_t length) { - return shared_dma_transfer(sercom, buffer, &sercom->SPI.DATA.reg, NULL, NULL, length, 0); -} - -int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_t tx) { - return shared_dma_transfer(sercom, NULL, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, buffer, length, tx); -} - -#ifdef SAMD51 -int32_t qspi_dma_write(uint32_t address, const uint8_t* buffer, uint32_t length) { - return shared_dma_transfer(QSPI, buffer, (uint32_t*) (QSPI_AHB + address), NULL, NULL, length, 0); -} - -int32_t qspi_dma_read(uint32_t address, uint8_t* buffer, uint32_t length) { - return shared_dma_transfer(QSPI, NULL, NULL, (uint32_t*) (QSPI_AHB + address), buffer, length, 0); -} -#endif - -DmacDescriptor* dma_descriptor(uint8_t channel_number) { - return &dma_descriptors[channel_number]; -} diff --git a/ports/atmel-samd/shared_dma.h b/ports/atmel-samd/shared_dma.h deleted file mode 100644 index 03e5b276c..000000000 --- a/ports/atmel-samd/shared_dma.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ - -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H - -#include -#include - -#include "include/sam.h" - -// We allocate DMA resources for the entire lifecycle of the board (not the -// vm) because the general_dma resource will be shared between the REPL and SPI -// flash. Both uses must block each other in order to prevent conflict. -#define AUDIO_DMA_CHANNEL_COUNT 3 -#define DMA_CHANNEL_COUNT (AUDIO_DMA_CHANNEL_COUNT + 2) -#define SHARED_TX_CHANNEL (DMA_CHANNEL_COUNT - 2) -#define SHARED_RX_CHANNEL (DMA_CHANNEL_COUNT - 1) - -volatile bool audio_dma_in_use; - -void init_shared_dma(void); - -#ifdef SAMD51 -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 - -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); - -void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event); -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_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 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/ports/atmel-samd/timers.c b/ports/atmel-samd/timers.c deleted file mode 100644 index 33518b782..000000000 --- a/ports/atmel-samd/timers.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * 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 -#include - -#include "timers.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, - TC2_GCLK_ID, - TC3_GCLK_ID, -#ifdef TC4_GCLK_ID - TC4_GCLK_ID, -#endif -#ifdef TC5_GCLK_ID - TC5_GCLK_ID, -#endif -#ifdef TC6_GCLK_ID - TC6_GCLK_ID, -#endif -#ifdef TC7_GCLK_ID - TC7_GCLK_ID, -#endif - }; -const uint8_t tcc_gclk_ids[TCC_INST_NUM] = {TCC0_GCLK_ID, - TCC1_GCLK_ID, - TCC2_GCLK_ID, -#ifdef TCC3_GCLK_ID - TCC3_GCLK_ID, -#endif -#ifdef TCC4_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; - if (is_tc) { - gclk_id = tc_gclk_ids[index]; - } else { - gclk_id = tcc_gclk_ids[index]; - } - // Turn on the clocks for the peripherals. - #ifdef SAMD51 - if (is_tc) { - switch (index) { - case 0: - MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC0; - break; - case 1: - MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC1; - break; - case 2: - MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC2; - break; - case 3: - MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC3; - break; - case 4: - MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC4; - break; - case 5: - MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC5; - break; - case 6: - MCLK->APBDMASK.reg |= MCLK_APBDMASK_TC6; - break; - case 7: - MCLK->APBDMASK.reg |= MCLK_APBDMASK_TC7; - break; - default: - break; - } - } else { - switch (index) { - case 0: - MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC0; - break; - case 1: - MCLK->APBBMASK.reg |= MCLK_APBBMASK_TCC1; - break; - case 2: - MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC2; - break; - case 3: - MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC3; - break; - case 4: - MCLK->APBDMASK.reg |= MCLK_APBDMASK_TCC4; - break; - default: - break; - } - } - - // FIXME(tannewt): TC4-TC7 can only have 100mhz inputs. - - 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/timers.h b/ports/atmel-samd/timers.h deleted file mode 100644 index fa8965784..000000000 --- a/ports/atmel-samd/timers.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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_TIMERS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H - -#include "include/sam.h" - -const uint16_t prescaler[8]; - -#ifdef SAMD21 -const uint8_t tcc_cc_num[3]; -const uint8_t tc_gclk_ids[TC_INST_NUM]; -const uint8_t tcc_gclk_ids[3]; -#endif -#ifdef SAMD51 -const uint8_t tcc_cc_num[5]; -const uint8_t tc_gclk_ids[TC_INST_NUM]; -const uint8_t tcc_gclk_ids[TCC_INST_NUM]; -#endif -Tc* const tc_insts[TC_INST_NUM]; -Tcc* const tcc_insts[TCC_INST_NUM]; - -void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index); -void tc_set_enable(Tc* tc, bool enable); -void tcc_set_enable(Tcc* tcc, bool enable); -void tc_wait_for_sync(Tc* tc); -void tc_reset(Tc* tc); - -void tc_enable_interrupts(uint8_t tc_index); -void tc_disable_interrupts(uint8_t tc_index); - -// Handlers -void TCC0_Handler(void); -void TCC1_Handler(void); -void TCC2_Handler(void); -void TC3_Handler(void); -void TC4_Handler(void); -void TC5_Handler(void); -#ifdef TC6 -void TC6_Handler(void); -#endif -#ifdef TC7 -void TC7_Handler(void); -#endif - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_TIMERS_H 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 + +#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 + +#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 `_ 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; -- cgit v1.2.3