diff --git a/conf.py b/conf.py index eb4b1490f7..03d100f121 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 d627e76410..162e6b3e61 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 e8dbdc61d6..5a572e9d1f 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 81e8fb1cec..3c87177a46 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 02d08133c7..008391bf0a 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 4fa417b373..8a7ff70e6d 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 eb7ffab4a2..5c5e9f7faf 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 f4540573a8..14ae89c55e 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 eb7ffab4a2..5c5e9f7faf 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 f4540573a8..14ae89c55e 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 7eff106e82..0754617ddd 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 b3edabe812..4486d27ab4 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 6bd74f3729..68666c273e 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 e6cede3dd9..6055f8a1b2 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 8f52a5767c..7395c6e2f1 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 6bd74f3729..68666c273e 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 bc3cb1f477..5767f63fad 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 6d031c6854..196e438e0b 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 2b35c91aad..25407bc147 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 fdcf039e64..3997ecda42 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 4cd8752bea..13f0eb0ba2 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 8dc0f25d6b..0e66817f7c 100644 --- a/ports/atmel-samd/boards/metro_m4_express/pins.c +++ b/ports/atmel-samd/boards/metro_m4_express/pins.c @@ -1,4 +1,5 @@ -#include "samd51_pins.h" +#include "shared-bindings/board/__init__.h" + #include "board_busses.h" // This mapping only includes functional names because pins broken diff --git a/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express_revb/mpconfigboard.h deleted file mode 100644 index db51140d66..0000000000 --- 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 9e6965063c..0000000000 --- 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 23e662f1c3..0000000000 --- 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 7efc8eb33f..e08302f140 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 0fdcbc2790..6330170249 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 0fdcbc2790..6330170249 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 acf73c9ffc..87ace5e96f 100644 --- a/ports/atmel-samd/boards/ugame10/pins.c +++ b/ports/atmel-samd/boards/ugame10/pins.c @@ -1,4 +1,5 @@ -#include "samd21_pins.h" +#include "shared-bindings/board/__init__.h" + #include "board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { diff --git a/ports/atmel-samd/common-hal/analogio/AnalogIn.c b/ports/atmel-samd/common-hal/analogio/AnalogIn.c index 02613ae078..e452eb0305 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 97299a8634..9ceca38683 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 f4a8eb52e8..27a7b9ee04 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 44129eed12..5502fcd812 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 331ae9c9b5..fc5c756731 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 347a2e3490..66929beff5 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 a2bf30f054..a2ee93c6db 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 5376775206..a95ccf3acc 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 e1ca5d6223..ad97581e14 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 4e21a14cd8..4230246a5a 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 e7f758cd10..a76ee2e78c 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 a9c83646fd..fa057facac 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 24cd154c2a..18d896686a 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 6e3aa3abb3..266a9251e9 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 95b0bbee07..8e715d4109 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 0000000000..58119fa7e9 --- /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 0000000000..c878239bcf --- /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 0000000000..2bee925bc7 --- /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 eda1b72c43..e39a091d79 100644 --- a/ports/atmel-samd/common-hal/touchio/TouchIn.c +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.c @@ -37,10 +37,10 @@ #include "hpl/pm/hpl_pm_base.h" #endif -#include "clocks.h" -#include "samd21_pins.h" -#include "tick.h" +#include "peripherals/clocks.h" +#include "peripherals/pins.h" +#include "tick.h" #include "adafruit_ptc.h" bool touch_enabled = false; diff --git a/ports/atmel-samd/external_flash/external_flash.c b/ports/atmel-samd/external_flash/external_flash.c index ccc47e5b14..b0e40fc705 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 3fc9d31be4..ec91c21e2d 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 8a8cbaef81..faad8d9e0f 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/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index cd05927b08..ee75a26c5b 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -174,6 +174,7 @@ extern const struct _mp_obj_module_t board_module; extern const struct _mp_obj_module_t math_module; extern const struct _mp_obj_module_t os_module; extern const struct _mp_obj_module_t random_module; +extern const struct _mp_obj_module_t rotaryio_module; extern const struct _mp_obj_module_t rtc_module; extern const struct _mp_obj_module_t samd_module; extern const struct _mp_obj_module_t storage_module; @@ -220,6 +221,7 @@ extern const struct _mp_obj_module_t usb_hid_module; { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \ AUDIOBUSIO_MODULE \ { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module } #endif #define EXPRESS_BOARD @@ -304,7 +306,7 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MP_STATE_PORT MP_STATE_VM -#include "shared_dma.h" +#include "peripherals/dma.h" #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ diff --git a/ports/atmel-samd/samd21_peripherals.h b/ports/atmel-samd/peripherals/adc.h similarity index 78% rename from ports/atmel-samd/samd21_peripherals.h rename to ports/atmel-samd/peripherals/adc.h index 805717695a..6530b1dcdc 100644 --- a/ports/atmel-samd/samd21_peripherals.h +++ b/ports/atmel-samd/peripherals/adc.h @@ -24,15 +24,12 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H +#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H #include "include/sam.h" #include "hal/include/hal_adc_sync.h" -void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index); -uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad); -bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad); void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance); -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H +#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H diff --git a/ports/atmel-samd/samd51_peripherals.h b/ports/atmel-samd/peripherals/cache.h similarity index 81% rename from ports/atmel-samd/samd51_peripherals.h rename to ports/atmel-samd/peripherals/cache.h index 6643379a5c..b260568a3b 100644 --- a/ports/atmel-samd/samd51_peripherals.h +++ b/ports/atmel-samd/peripherals/cache.h @@ -27,14 +27,6 @@ #ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H #define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H -#include "sam.h" -#include "hal/include/hal_adc_sync.h" - -void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index); -uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad); -bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad); -void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance); - void samd_peripherals_disable_and_clear_cache(void); void samd_peripherals_enable_cache(void); diff --git a/ports/atmel-samd/clocks.c b/ports/atmel-samd/peripherals/clocks.c similarity index 100% rename from ports/atmel-samd/clocks.c rename to ports/atmel-samd/peripherals/clocks.c diff --git a/ports/atmel-samd/clocks.h b/ports/atmel-samd/peripherals/clocks.h similarity index 100% rename from ports/atmel-samd/clocks.h rename to ports/atmel-samd/peripherals/clocks.h diff --git a/ports/atmel-samd/shared_dma.c b/ports/atmel-samd/peripherals/dma.c similarity index 62% rename from ports/atmel-samd/shared_dma.c rename to ports/atmel-samd/peripherals/dma.c index edc2d0f1a0..664c6aea8f 100644 --- a/ports/atmel-samd/shared_dma.c +++ b/ports/atmel-samd/peripherals/dma.c @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "shared_dma.h" +#include "peripherals/dma.h" #include @@ -48,164 +48,6 @@ COMPILER_ALIGNED(16) static DmacDescriptor write_back_descriptors[DMA_CHANNEL_CO #define FIRST_SERCOM_TX_TRIGSRC 0x05 #endif -static uint8_t sercom_index(Sercom* sercom) { - #ifdef SAMD21 - return ((uint32_t) sercom - (uint32_t) SERCOM0) / 0x400; - #else - const Sercom* sercoms[SERCOM_INST_NUM] = SERCOM_INSTS; - for (uint8_t i = 0; i < SERCOM_INST_NUM; i++) { - if (sercoms[i] == sercom) { - return i; - } - } - return 0; - #endif -} - -void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - /** Select the DMA channel and clear software trigger */ - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - DMAC->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE; - DMAC->CHCTRLA.reg = DMAC_CHCTRLA_SWRST; - DMAC->SWTRIGCTRL.reg &= (uint32_t)(~(1 << channel_number)); - uint32_t event_output_enable = 0; - if (output_event) { - event_output_enable = DMAC_CHCTRLB_EVOE; - } - DMAC->CHCTRLB.reg = DMAC_CHCTRLB_LVL_LVL0 | - DMAC_CHCTRLB_TRIGSRC(trigsrc) | - DMAC_CHCTRLB_TRIGACT_BEAT | - event_output_enable; - common_hal_mcu_enable_interrupts(); - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - channel->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE; - channel->CHCTRLA.reg = DMAC_CHCTRLA_SWRST; - if (output_event) { - channel->CHEVCTRL.reg = DMAC_CHEVCTRL_EVOE; - } - channel->CHCTRLA.reg = DMAC_CHCTRLA_TRIGSRC(trigsrc) | - DMAC_CHCTRLA_TRIGACT_BURST | - DMAC_CHCTRLA_BURSTLEN_SINGLE; - #endif -} - -void dma_enable_channel(uint8_t channel_number) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - /** Select the DMA channel and clear software trigger */ - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - // Clear any previous interrupts. - DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK; - DMAC->CHCTRLA.bit.ENABLE = true; - common_hal_mcu_enable_interrupts(); - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - channel->CHCTRLA.bit.ENABLE = true; - // Clear any previous interrupts. - channel->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK; - #endif -} - -void dma_disable_channel(uint8_t channel_number) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - /** Select the DMA channel and clear software trigger */ - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - DMAC->CHCTRLA.bit.ENABLE = false; - common_hal_mcu_enable_interrupts(); - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - channel->CHCTRLA.bit.ENABLE = false; - #endif -} - -void dma_suspend_channel(uint8_t channel_number) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - /** Select the DMA channel and clear software trigger */ - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_SUSPEND_Val; - common_hal_mcu_enable_interrupts(); - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_SUSPEND; - #endif -} - -void dma_resume_channel(uint8_t channel_number) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - /** Select the DMA channel and clear software trigger */ - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_RESUME_Val; - DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_SUSP; - common_hal_mcu_enable_interrupts(); - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_RESUME; - #endif -} - -bool dma_channel_enabled(uint8_t channel_number) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - /** Select the DMA channel and clear software trigger */ - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - bool enabled = DMAC->CHCTRLA.bit.ENABLE; - common_hal_mcu_enable_interrupts(); - return enabled; - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - return channel->CHCTRLA.bit.ENABLE; - #endif -} - -uint8_t dma_transfer_status(uint8_t channel_number) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - /** Select the DMA channel and clear software trigger */ - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - uint8_t status = DMAC->CHINTFLAG.reg; - common_hal_mcu_enable_interrupts(); - return status; - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - return channel->CHINTFLAG.reg; - #endif -} - -static bool channel_free(uint8_t channel_number) { - #ifdef SAMD21 - common_hal_mcu_disable_interrupts(); - DMAC->CHID.reg = DMAC_CHID_ID(channel_number); - bool channel_free = DMAC->CHSTATUS.reg == 0; - common_hal_mcu_enable_interrupts(); - return channel_free; - #endif - - #ifdef SAMD51 - DmacChannel* channel = &DMAC->Channel[channel_number]; - return channel->CHSTATUS.reg == 0; - #endif -} - void init_shared_dma(void) { // Turn on the clocks #ifdef SAMD51 @@ -237,8 +79,8 @@ static int32_t shared_dma_transfer(void* peripheral, const uint8_t* buffer_out, volatile uint32_t* dest, volatile uint32_t* src, uint8_t* buffer_in, uint32_t length, uint8_t tx) { - if (!channel_free(SHARED_TX_CHANNEL) || - (buffer_in != NULL && !channel_free(SHARED_RX_CHANNEL))) { + if (!dma_channel_free(SHARED_TX_CHANNEL) || + (buffer_in != NULL && !dma_channel_free(SHARED_RX_CHANNEL))) { return -1; } diff --git a/ports/atmel-samd/shared_dma.h b/ports/atmel-samd/peripherals/dma.h similarity index 91% rename from ports/atmel-samd/shared_dma.h rename to ports/atmel-samd/peripherals/dma.h index 03e5b276c8..cf256b962c 100644 --- a/ports/atmel-samd/shared_dma.h +++ b/ports/atmel-samd/peripherals/dma.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H +#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H #include #include @@ -49,6 +49,8 @@ int32_t qspi_dma_write(uint32_t address, const uint8_t* buffer, uint32_t length) int32_t qspi_dma_read(uint32_t address, uint8_t* buffer, uint32_t length); #endif +uint8_t sercom_index(Sercom* sercom); + int32_t sercom_dma_write(Sercom* sercom, const uint8_t* buffer, uint32_t length); int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_t tx); int32_t sercom_dma_transfer(Sercom* sercom, const uint8_t* buffer_out, uint8_t* buffer_in, uint32_t length); @@ -58,8 +60,9 @@ void dma_enable_channel(uint8_t channel_number); void dma_disable_channel(uint8_t channel_number); void dma_suspend_channel(uint8_t channel_number); void dma_resume_channel(uint8_t channel_number); +bool dma_channel_free(uint8_t channel_number); bool dma_channel_enabled(uint8_t channel_number); uint8_t dma_transfer_status(uint8_t channel_number); DmacDescriptor* dma_descriptor(uint8_t channel_number); -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H +#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H diff --git a/ports/atmel-samd/peripherals/events.c b/ports/atmel-samd/peripherals/events.c new file mode 100644 index 0000000000..9a4ab3b0ca --- /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/events.h b/ports/atmel-samd/peripherals/events.h similarity index 97% rename from ports/atmel-samd/events.h rename to ports/atmel-samd/peripherals/events.h index 64093c0ab3..0073142f11 100644 --- a/ports/atmel-samd/events.h +++ b/ports/atmel-samd/peripherals/events.h @@ -44,4 +44,6 @@ void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generat bool event_interrupt_active(uint8_t channel); bool event_interrupt_overflow(uint8_t channel); +bool event_channel_free(uint8_t channel); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H diff --git a/ports/atmel-samd/peripherals/i2s.c b/ports/atmel-samd/peripherals/i2s.c new file mode 100644 index 0000000000..4d99e7b5b9 --- /dev/null +++ b/ports/atmel-samd/peripherals/i2s.c @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "i2s.h" + +#include "clocks.h" + +#include "hpl/gclk/hpl_gclk_base.h" +#ifdef SAMD21 +#include "hpl/pm/hpl_pm_base.h" +#endif + +void i2s_set_enable(bool enable) { + while (I2S->SYNCBUSY.bit.ENABLE == 1) {} + I2S->CTRLA.bit.ENABLE = enable; + while (I2S->SYNCBUSY.bit.ENABLE == 1) {} +} + +void i2s_set_clock_unit_enable(uint8_t clock_unit, bool enable) { + while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {} + I2S->CTRLA.vec.CKEN = 1 << clock_unit; + while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {} +} diff --git a/ports/atmel-samd/i2s.h b/ports/atmel-samd/peripherals/i2s.h similarity index 100% rename from ports/atmel-samd/i2s.h rename to ports/atmel-samd/peripherals/i2s.h diff --git a/ports/atmel-samd/peripherals/pins.h b/ports/atmel-samd/peripherals/pins.h new file mode 100644 index 0000000000..1ddbf3329e --- /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 0000000000..3a7f1e8116 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd21/adc.c @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "hal/include/hal_adc_sync.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl/pm/hpl_pm_base.h" + +// Do initialization and calibration setup needed for any use of the ADC. +// The reference and resolution should be set by the caller. +void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) { + // Turn the clocks on. + _pm_enable_bus_clock(PM_BUS_APBC, ADC); + _gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + + adc_sync_init(adc, instance, (void *)NULL); + + // Load the factory calibration + hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos); + // Bits 7:5 + uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5; + // Bits 4:0 + linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos; + hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity); +} diff --git a/ports/atmel-samd/pins.h b/ports/atmel-samd/peripherals/samd21/cache.c similarity index 79% rename from ports/atmel-samd/pins.h rename to ports/atmel-samd/peripherals/samd21/cache.c index 1842efbc06..641b5e1155 100644 --- a/ports/atmel-samd/pins.h +++ b/ports/atmel-samd/peripherals/samd21/cache.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2017 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,16 +24,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PINS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_PINS_H +// The SAMD21 doesn't have a cache so we have nothing to do. +void samd_peripherals_disable_and_clear_cache(void) { +} -#include "mpconfigport.h" - -#ifdef SAMD21 -#include "samd21_pins.h" -#endif -#ifdef SAMD51 -#include "samd51_pins.h" -#endif - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_PINS_H +void samd_peripherals_enable_cache(void) { +} diff --git a/ports/atmel-samd/samd21_clocks.c b/ports/atmel-samd/peripherals/samd21/clocks.c similarity index 99% rename from ports/atmel-samd/samd21_clocks.c rename to ports/atmel-samd/peripherals/samd21/clocks.c index 0fc4d63e50..94b5158146 100644 --- a/ports/atmel-samd/samd21_clocks.c +++ b/ports/atmel-samd/peripherals/samd21/clocks.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "clocks.h" +#include "peripherals/clocks.h" #include "hpl_gclk_config.h" diff --git a/ports/atmel-samd/peripherals/samd21/dma.c b/ports/atmel-samd/peripherals/samd21/dma.c new file mode 100644 index 0000000000..3a399745ac --- /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/events.c b/ports/atmel-samd/peripherals/samd21/events.c similarity index 60% rename from ports/atmel-samd/events.c rename to ports/atmel-samd/peripherals/samd21/events.c index 05a2ae8a73..70dfa249dd 100644 --- a/ports/atmel-samd/events.c +++ b/ports/atmel-samd/peripherals/samd21/events.c @@ -24,131 +24,52 @@ * THE SOFTWARE. */ -#include "events.h" +#include "peripherals/events.h" -#include "clocks.h" +#include "peripherals/clocks.h" #include "py/runtime.h" -#ifdef SAMD21 #include "hpl/pm/hpl_pm_base.h" -#endif - -#ifdef SAMD51 -#include "hri/hri_mclk_d51.h" -#endif void turn_on_event_system(void) { - #ifdef SAMD51 - hri_mclk_set_APBBMASK_EVSYS_bit(MCLK); - #endif - - #ifdef SAMD21 _pm_enable_bus_clock(PM_BUS_APBC, EVSYS); - #endif } void reset_event_system(void) { - #ifdef SAMD51 - EVSYS->CTRLA.bit.SWRST = true; - hri_mclk_clear_APBBMASK_EVSYS_bit(MCLK); - #endif - - #ifdef SAMD21 EVSYS->CTRL.bit.SWRST = true; _pm_disable_bus_clock(PM_BUS_APBC, EVSYS); - #endif } -static bool channel_free(int8_t channel) { +bool event_channel_free(uint8_t channel) { uint8_t generator; - #ifdef SAMD51 - generator = EVSYS->Channel[channel].CHANNEL.bit.EVGEN; - #endif - #ifdef SAMD21 // Explicitly do a byte write so the peripheral knows we're just wanting to read the channel // rather than write to it. *((uint8_t*) &EVSYS->CHANNEL.reg) = channel; generator = (EVSYS->CHANNEL.reg & EVSYS_CHANNEL_EVGEN_Msk) >> EVSYS_CHANNEL_EVGEN_Pos; - #endif return generator == 0; } -uint8_t find_async_event_channel(void) { - int8_t channel; - for (channel = EVSYS_CHANNELS - 1; channel > 0; channel--) { - if (channel_free(channel)) { - break; - } - } - if (channel < 0) { - mp_raise_RuntimeError("All event channels in use"); - } - return channel; -} - -#ifdef SAMD21 -#define EVSYS_SYNCH_NUM EVSYS_CHANNELS -#endif -uint8_t find_sync_event_channel(void) { - uint8_t channel; - for (channel = 0; channel < EVSYS_SYNCH_NUM; channel++) { - if (channel_free(channel)) { - break; - } - } - if (channel >= EVSYS_SYNCH_NUM) { - mp_raise_RuntimeError("All sync event channels in use"); - } - return channel; -} - void disable_event_channel(uint8_t channel_number) { - #ifdef SAMD51 - EVSYS->Channel[channel_number].CHANNEL.reg = 0; - #endif - #ifdef SAMD21 EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel_number); - #endif } void disable_event_user(uint8_t user_number) { - #ifdef SAMD51 - EVSYS->USER[user_number].reg = 0; - #endif - #ifdef SAMD21 EVSYS->USER.reg = EVSYS_USER_USER(user_number); - #endif } void connect_event_user_to_channel(uint8_t user, uint8_t channel) { - #ifdef SAMD51 - EVSYS->USER[user].reg = channel + 1; - #endif - #ifdef SAMD21 EVSYS->USER.reg = EVSYS_USER_USER(user) | EVSYS_USER_CHANNEL(channel + 1); - #endif } void init_async_event_channel(uint8_t channel, uint8_t generator) { - #ifdef SAMD51 - EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS; - #endif - #ifdef SAMD21 - EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) | EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS; - #endif + EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) | + EVSYS_CHANNEL_EVGEN(generator) | + EVSYS_CHANNEL_PATH_ASYNCHRONOUS; } void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) { connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel); - #ifdef SAMD51 - EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | - EVSYS_CHANNEL_PATH_SYNCHRONOUS | - EVSYS_CHANNEL_EDGSEL_RISING_EDGE; - EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR; - EVSYS->Channel[channel].CHINTENSET.reg = EVSYS_CHINTENSET_EVD | EVSYS_CHINTENSET_OVR; - #endif - #ifdef SAMD21 EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) | EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_RESYNCHRONIZED | @@ -162,12 +83,10 @@ void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generat EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value); EVSYS->INTENSET.reg = EVSYS_INTENSET_EVD(value) | EVSYS_INTENSET_OVR(value); } - #endif } bool event_interrupt_active(uint8_t channel) { bool active = false; - #ifdef SAMD21 if (channel > 7) { uint8_t value = 1 << (channel - 7); active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVDp8(value)) != 0; @@ -183,21 +102,11 @@ bool event_interrupt_active(uint8_t channel) { EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value); } } - #endif - #ifdef SAMD51 - active = EVSYS->Channel[channel].CHINTFLAG.bit.EVD; - // Only clear if we know its active, otherwise there is the possibility it becomes after we - // check but before we clear. - if (active) { - EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR; - } - #endif return active; } bool event_interrupt_overflow(uint8_t channel) { bool overflow = false; - #ifdef SAMD21 if (channel > 7) { uint8_t value = 1 << (channel - 7); overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVRp8(value)) != 0; @@ -205,9 +114,5 @@ bool event_interrupt_overflow(uint8_t channel) { uint8_t value = 1 << channel; overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVR(value)) != 0; } - #endif - #ifdef SAMD51 - overflow = EVSYS->Channel[channel].CHINTFLAG.bit.OVR; - #endif return overflow; } diff --git a/ports/atmel-samd/boards/metro_m4_express_revb/board.c b/ports/atmel-samd/peripherals/samd21/i2s.c similarity index 65% rename from ports/atmel-samd/boards/metro_m4_express_revb/board.c rename to ports/atmel-samd/peripherals/samd21/i2s.c index a98385d295..7df401601d 100644 --- a/ports/atmel-samd/boards/metro_m4_express_revb/board.c +++ b/ports/atmel-samd/peripherals/samd21/i2s.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,23 +24,23 @@ * THE SOFTWARE. */ -#include "boards/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" +#include "peripherals/i2s.h" -void board_init(void) { - gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_TX, true); +#include "peripherals/clocks.h" - gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT); - gpio_set_pin_level(MICROPY_HW_LED_RX, true); +#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl/pm/hpl_pm_base.h" + +void turn_on_i2s(void) { + _pm_enable_bus_clock(PM_BUS_APBC, I2S); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { +void i2s_set_serializer_enable(uint8_t serializer, bool enable) { + while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {} + if (enable) { + I2S->CTRLA.vec.SEREN = 1 << serializer; + } else { + I2S->CTRLA.vec.SEREN &= ~(1 << serializer); + } + while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {} } diff --git a/ports/atmel-samd/samd21_pins.c b/ports/atmel-samd/peripherals/samd21/pins.c similarity index 99% rename from ports/atmel-samd/samd21_pins.c rename to ports/atmel-samd/peripherals/samd21/pins.c index 319870b9a3..bbb023a54f 100644 --- a/ports/atmel-samd/samd21_pins.c +++ b/ports/atmel-samd/peripherals/samd21/pins.c @@ -26,8 +26,6 @@ #include "shared-bindings/microcontroller/Pin.h" -#include "samd21_pins.h" - #define SERCOM(sercom_index, p_pad) \ { \ .index = sercom_index, \ diff --git a/ports/atmel-samd/samd21_pins.h b/ports/atmel-samd/peripherals/samd21/pins.h similarity index 93% rename from ports/atmel-samd/samd21_pins.h rename to ports/atmel-samd/peripherals/samd21/pins.h index 522563ef11..0b99ce9b36 100644 --- a/ports/atmel-samd/samd21_pins.h +++ b/ports/atmel-samd/peripherals/samd21/pins.h @@ -24,13 +24,14 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H +// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure +// that all necessary includes are already included. + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H #include "include/sam.h" -#include "common-hal/microcontroller/Pin.h" - void reset_pin(uint8_t pin); #define MUX_C 2 @@ -201,4 +202,4 @@ extern const mcu_pin_obj_t pin_PB02; extern const mcu_pin_obj_t pin_PB03; #endif -#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H +#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H diff --git a/ports/atmel-samd/samd21_peripherals.c b/ports/atmel-samd/peripherals/samd21/sercom.c similarity index 76% rename from ports/atmel-samd/samd21_peripherals.c rename to ports/atmel-samd/peripherals/samd21/sercom.c index 5bbac29655..a27e49e0e5 100644 --- a/ports/atmel-samd/samd21_peripherals.c +++ b/ports/atmel-samd/peripherals/samd21/sercom.c @@ -24,11 +24,9 @@ * THE SOFTWARE. */ -#include "hal/include/hal_adc_sync.h" #include "hpl/gclk/hpl_gclk_base.h" #include "hpl/pm/hpl_pm_base.h" - // The clock initializer values are rather random, so we need to put them in // tables for lookup. We can't compute them. @@ -93,21 +91,3 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) { bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) { return clock_pad == 1 || clock_pad == 3; } - -// Do initialization and calibration setup needed for any use of the ADC. -// The reference and resolution should be set by the caller. -void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) { - // Turn the clocks on. - _pm_enable_bus_clock(PM_BUS_APBC, ADC); - _gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); - - adc_sync_init(adc, instance, (void *)NULL); - - // Load the factory calibration - hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos); - // Bits 7:5 - uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5; - // Bits 4:0 - linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos; - hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity); -} diff --git a/ports/atmel-samd/peripherals/samd21/timers.c b/ports/atmel-samd/peripherals/samd21/timers.c new file mode 100644 index 0000000000..c93a710867 --- /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 0000000000..af6333a949 --- /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 0000000000..f94dd830c0 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/cache.c @@ -0,0 +1,39 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "sam.h" + +// Turn off cache and invalidate all data in it. +void samd_peripherals_disable_and_clear_cache(void) { + CMCC->CTRL.bit.CEN = 0; + while (CMCC->SR.bit.CSTS) {} + CMCC->MAINT0.bit.INVALL = 1; +} + +// Enable cache +void samd_peripherals_enable_cache(void) { + CMCC->CTRL.bit.CEN = 1; +} diff --git a/ports/atmel-samd/samd51_clocks.c b/ports/atmel-samd/peripherals/samd51/clocks.c similarity index 99% rename from ports/atmel-samd/samd51_clocks.c rename to ports/atmel-samd/peripherals/samd51/clocks.c index 6f8b1f0102..29f9cb99cb 100644 --- a/ports/atmel-samd/samd51_clocks.c +++ b/ports/atmel-samd/peripherals/samd51/clocks.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "clocks.h" +#include "peripherals/clocks.h" #include "hpl_gclk_config.h" diff --git a/ports/atmel-samd/peripherals/samd51/dma.c b/ports/atmel-samd/peripherals/samd51/dma.c new file mode 100644 index 0000000000..ccb35aaf65 --- /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 0000000000..5ea2c87e69 --- /dev/null +++ b/ports/atmel-samd/peripherals/samd51/events.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "peripherals/events.h" + +#include "peripherals/clocks.h" + +#include "py/runtime.h" + +#include "hri/hri_mclk_d51.h" + +void turn_on_event_system(void) { + hri_mclk_set_APBBMASK_EVSYS_bit(MCLK); +} + +void reset_event_system(void) { + EVSYS->CTRLA.bit.SWRST = true; + hri_mclk_clear_APBBMASK_EVSYS_bit(MCLK); +} + +bool event_channel_free(uint8_t channel) { + uint8_t generator; + generator = EVSYS->Channel[channel].CHANNEL.bit.EVGEN; + return generator == 0; +} + +void disable_event_channel(uint8_t channel_number) { + EVSYS->Channel[channel_number].CHANNEL.reg = 0; +} + +void disable_event_user(uint8_t user_number) { + EVSYS->USER[user_number].reg = 0; +} + +void connect_event_user_to_channel(uint8_t user, uint8_t channel) { + EVSYS->USER[user].reg = channel + 1; +} + +void init_async_event_channel(uint8_t channel, uint8_t generator) { + EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS; +} + +void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) { + connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel); + EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | + EVSYS_CHANNEL_PATH_SYNCHRONOUS | + EVSYS_CHANNEL_EDGSEL_RISING_EDGE; + EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR; + EVSYS->Channel[channel].CHINTENSET.reg = EVSYS_CHINTENSET_EVD | EVSYS_CHINTENSET_OVR; +} + +bool event_interrupt_active(uint8_t channel) { + bool active = false; + active = EVSYS->Channel[channel].CHINTFLAG.bit.EVD; + // Only clear if we know its active, otherwise there is the possibility it becomes after we + // check but before we clear. + if (active) { + EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR; + } + return active; +} + +bool event_interrupt_overflow(uint8_t channel) { + return EVSYS->Channel[channel].CHINTFLAG.bit.OVR; +} diff --git a/ports/atmel-samd/i2s.c b/ports/atmel-samd/peripherals/samd51/i2s.c similarity index 68% rename from ports/atmel-samd/i2s.c rename to ports/atmel-samd/peripherals/samd51/i2s.c index 663ecdd1dc..97ce13f7d9 100644 --- a/ports/atmel-samd/i2s.c +++ b/ports/atmel-samd/peripherals/samd51/i2s.c @@ -24,53 +24,22 @@ * THE SOFTWARE. */ -#include "i2s.h" +#include "peripherals/i2s.h" -#include "clocks.h" +#include "peripherals/clocks.h" #include "hpl/gclk/hpl_gclk_base.h" -#ifdef SAMD21 -#include "hpl/pm/hpl_pm_base.h" -#endif void turn_on_i2s(void) { // Make sure the I2S peripheral is running so we can see if the resources we need are free. - #ifdef SAMD51 hri_mclk_set_APBDMASK_I2S_bit(MCLK); // Connect the clock units to the 2mhz clock by default. They can't reset without it. connect_gclk_to_peripheral(5, I2S_GCLK_ID_0); connect_gclk_to_peripheral(5, I2S_GCLK_ID_1); - #endif - - #ifdef SAMD21 - _pm_enable_bus_clock(PM_BUS_APBC, I2S); - #endif -} - -void i2s_set_enable(bool enable) { - while (I2S->SYNCBUSY.bit.ENABLE == 1) {} - I2S->CTRLA.bit.ENABLE = enable; - while (I2S->SYNCBUSY.bit.ENABLE == 1) {} -} - -void i2s_set_clock_unit_enable(uint8_t clock_unit, bool enable) { - while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {} - I2S->CTRLA.vec.CKEN = 1 << clock_unit; - while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {} } void i2s_set_serializer_enable(uint8_t serializer, bool enable) { - #ifdef SAMD21 - while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {} - if (enable) { - I2S->CTRLA.vec.SEREN = 1 << serializer; - } else { - I2S->CTRLA.vec.SEREN &= ~(1 << serializer); - } - while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {} - #endif - #ifdef SAMD51 if (serializer == 0) { while (I2S->SYNCBUSY.bit.TXEN == 1) {} I2S->CTRLA.bit.TXEN = enable; @@ -80,5 +49,4 @@ void i2s_set_serializer_enable(uint8_t serializer, bool enable) { I2S->CTRLA.bit.RXEN = enable; while (I2S->SYNCBUSY.bit.RXEN == 1) {} } - #endif } diff --git a/ports/atmel-samd/samd51_pins.c b/ports/atmel-samd/peripherals/samd51/pins.c similarity index 99% rename from ports/atmel-samd/samd51_pins.c rename to ports/atmel-samd/peripherals/samd51/pins.c index 6d597b6e1a..1c52d35a24 100644 --- a/ports/atmel-samd/samd51_pins.c +++ b/ports/atmel-samd/peripherals/samd51/pins.c @@ -26,8 +26,6 @@ #include "shared-bindings/microcontroller/Pin.h" -#include "samd51_pins.h" - #define SERCOM(sercom_index, p_pad) \ { \ .index = sercom_index, \ diff --git a/ports/atmel-samd/samd51_pins.h b/ports/atmel-samd/peripherals/samd51/pins.h similarity index 98% rename from ports/atmel-samd/samd51_pins.h rename to ports/atmel-samd/peripherals/samd51/pins.h index c9ffacc24b..b9a05a3459 100644 --- a/ports/atmel-samd/samd51_pins.h +++ b/ports/atmel-samd/peripherals/samd51/pins.h @@ -24,13 +24,14 @@ * THE SOFTWARE. */ +// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure +// that all necessary includes are already included. + #ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H #define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H #include "include/sam.h" -#include "common-hal/microcontroller/Pin.h" - void reset_pin(uint8_t pin); #define MUX_C 2 diff --git a/ports/atmel-samd/samd51_peripherals.c b/ports/atmel-samd/peripherals/samd51/sercom.c similarity index 67% rename from ports/atmel-samd/samd51_peripherals.c rename to ports/atmel-samd/peripherals/samd51/sercom.c index 5772b8e0ab..fc44214220 100644 --- a/ports/atmel-samd/samd51_peripherals.c +++ b/ports/atmel-samd/peripherals/samd51/sercom.c @@ -28,6 +28,8 @@ #include "hpl/gclk/hpl_gclk_base.h" #include "hri/hri_mclk_d51.h" +// FIXME(tannewt): Should this be called sercom.c? + // The clock initializer values are rather random, so we need to put them in // tables for lookup. We can't compute them. @@ -131,47 +133,3 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) { bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) { return clock_pad == 1; } - -// Do initialization and calibration setup needed for any use of the ADC. -// The reference and resolution should be set by the caller. -void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) { - // Turn the clocks on. - if (instance == ADC0) { - hri_mclk_set_APBDMASK_ADC0_bit(MCLK); - hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); - } else if (instance == ADC1) { - hri_mclk_set_APBDMASK_ADC1_bit(MCLK); - hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos)); - } - - adc_sync_init(adc, instance, (void *)NULL); - - // SAMD51 has a CALIB register but doesn't have documented fuses for them. - uint8_t biasrefbuf; - uint8_t biasr2r; - uint8_t biascomp; - if (instance == ADC0) { - biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos; - biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos; - biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos; - } else { - biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos; - biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos; - biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos; - } - hri_adc_write_CALIB_BIASREFBUF_bf(instance, biasrefbuf); - hri_adc_write_CALIB_BIASR2R_bf(instance, biasr2r); - hri_adc_write_CALIB_BIASCOMP_bf(instance, biascomp); -} - -// Turn off cache and invalidate all data in it. -void samd_peripherals_disable_and_clear_cache(void) { - CMCC->CTRL.bit.CEN = 0; - while (CMCC->SR.bit.CSTS) {} - CMCC->MAINT0.bit.INVALL = 1; -} - -// Enable cache -void samd_peripherals_enable_cache(void) { - CMCC->CTRL.bit.CEN = 1; -} diff --git a/ports/atmel-samd/timers.c b/ports/atmel-samd/peripherals/samd51/timers.c similarity index 56% rename from ports/atmel-samd/timers.c rename to ports/atmel-samd/peripherals/samd51/timers.c index 33518b782f..305acce381 100644 --- a/ports/atmel-samd/timers.c +++ b/ports/atmel-samd/peripherals/samd51/timers.c @@ -27,36 +27,12 @@ #include #include -#include "timers.h" +#include "peripherals/timers.h" -#include "common-hal/pulseio/PulseOut.h" +//#include "common-hal/pulseio/PulseOut.h" -#ifdef SAMD21 -#include "hpl/gclk/hpl_gclk_base.h" -#endif - -#ifdef SAMD51 #include "hri/hri_gclk_d51.h" -#endif -const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024}; - -// This bitmask keeps track of which channels of a TCC are currently claimed. -#ifdef SAMD21 -const uint8_t tcc_cc_num[3] = {4, 2, 2}; -const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC3_GCLK_ID, - TC4_GCLK_ID, - TC5_GCLK_ID, -#ifdef TC6_GCLK_ID - TC6_GCLK_ID, -#endif -#ifdef TC7_GCLK_ID - TC7_GCLK_ID, -#endif - }; -const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID}; -#endif -#ifdef SAMD51 const uint8_t tcc_cc_num[5] = {6, 4, 3, 2, 2}; const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC0_GCLK_ID, TC1_GCLK_ID, @@ -85,36 +61,6 @@ const uint8_t tcc_gclk_ids[TCC_INST_NUM] = {TCC0_GCLK_ID, TCC4_GCLK_ID #endif }; -#endif -Tc* const tc_insts[TC_INST_NUM] = TC_INSTS; -Tcc* const tcc_insts[TCC_INST_NUM] = TCC_INSTS; - -IRQn_Type const tc_irq[TC_INST_NUM] = { -#ifdef TC0 - TC0_IRQn, -#endif -#ifdef TC1 - TC1_IRQn, -#endif -#ifdef TC2 - TC2_IRQn, -#endif -#ifdef TC3 - TC3_IRQn, -#endif -#ifdef TC4 - TC4_IRQn, -#endif -#ifdef TC5 - TC5_IRQn, -#endif -#ifdef TC6 - TC6_IRQn, -#endif -#ifdef TC7 - TC7_IRQn, -#endif -}; void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) { uint8_t gclk_id; @@ -124,7 +70,6 @@ void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) { gclk_id = tcc_gclk_ids[index]; } // Turn on the clocks for the peripherals. - #ifdef SAMD51 if (is_tc) { switch (index) { case 0: @@ -180,122 +125,15 @@ void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) { hri_gclk_write_PCHCTRL_reg(GCLK, gclk_id, gclk_index | (1 << GCLK_PCHCTRL_CHEN_Pos)); - #endif - - #ifdef SAMD21 - // Determine the clock slot on the APBC bus. TCC0 is the first and 8 slots in. - uint8_t clock_slot = 8 + index; - // We index TCs starting at zero but in memory they begin at three so we have to add three. - if (is_tc) { - clock_slot += 3; - } - PM->APBCMASK.reg |= 1 << clock_slot; - _gclk_enable_channel(gclk_id, gclk_index); - #endif } void tc_set_enable(Tc* tc, bool enable) { tc->COUNT16.CTRLA.bit.ENABLE = enable; - #ifdef SAMD21 - while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) { - /* Wait for sync */ - } - #endif - #ifdef SAMD51 while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) { /* Wait for sync */ } - #endif -} - -void tc_enable_interrupts(uint8_t tc_index) { - NVIC_DisableIRQ(tc_irq[tc_index]); - NVIC_ClearPendingIRQ(tc_irq[tc_index]); - NVIC_EnableIRQ(tc_irq[tc_index]); -} - -void tc_disable_interrupts(uint8_t tc_index) { - NVIC_DisableIRQ(tc_irq[tc_index]); - NVIC_ClearPendingIRQ(tc_irq[tc_index]); -} - -void tcc_set_enable(Tcc* tcc, bool enable) { - tcc->CTRLA.bit.ENABLE = enable; - while (tcc->SYNCBUSY.bit.ENABLE != 0) { - /* Wait for sync */ - } } void tc_wait_for_sync(Tc* tc) { - #ifdef SAMD21 - while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {} - #endif - #ifdef SAMD51 while (tc->COUNT16.SYNCBUSY.reg != 0) {} - #endif } - -void tc_reset(Tc* tc) { - tc->COUNT16.CTRLA.bit.SWRST = 1; - while (tc->COUNT16.CTRLA.bit.SWRST == 1) { - } -} - -void shared_timer_handler(bool is_tc, uint8_t index) { - // Add calls to interrupt handlers for specific functionality here. - if (is_tc) { - pulseout_interrupt_handler(index); - } -} - -#ifdef SAMD51 -#define TC_OFFSET 0 -#endif -#ifdef SAMD21 -#define TC_OFFSET 3 -#endif - -void TCC0_Handler(void) { - shared_timer_handler(false, 0); -} -void TCC1_Handler(void) { - shared_timer_handler(false, 1); -} -void TCC2_Handler(void) { - shared_timer_handler(false, 2); -} -// TC0 - TC2 only exist on the SAMD51 -#ifdef TC0 -void TC0_Handler(void) { - shared_timer_handler(true, 0); -} -#endif -#ifdef TC1 -void TC1_Handler(void) { - shared_timer_handler(true, 1); -} -#endif -#ifdef TC2 -void TC2_Handler(void) { - shared_timer_handler(true, 2); -} -#endif -void TC3_Handler(void) { - shared_timer_handler(true, 3 - TC_OFFSET); -} -void TC4_Handler(void) { - shared_timer_handler(true, 4 - TC_OFFSET); -} -void TC5_Handler(void) { - shared_timer_handler(true, 5 - TC_OFFSET); -} -#ifdef TC6 -void TC6_Handler(void) { - shared_timer_handler(true, 6 - TC_OFFSET); -} -#endif -#ifdef TC7 -void TC7_Handler(void) { - shared_timer_handler(true, 7 - TC_OFFSET); -} -#endif diff --git a/ports/atmel-samd/peripherals.c b/ports/atmel-samd/peripherals/sercom.c similarity index 98% rename from ports/atmel-samd/peripherals.c rename to ports/atmel-samd/peripherals/sercom.c index c75a1f43b5..04c1fd008d 100644 --- a/ports/atmel-samd/peripherals.c +++ b/ports/atmel-samd/peripherals/sercom.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "peripherals.h" +#include "peripherals/sercom.h" #include "hpl_sercom_config.h" diff --git a/ports/atmel-samd/peripherals.h b/ports/atmel-samd/peripherals/sercom.h similarity index 79% rename from ports/atmel-samd/peripherals.h rename to ports/atmel-samd/peripherals/sercom.h index 8a07c00457..66ad1a403f 100644 --- a/ports/atmel-samd/peripherals.h +++ b/ports/atmel-samd/peripherals/sercom.h @@ -24,24 +24,19 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H -#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H +#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H #include #include "mpconfigport.h" -// Routines common across chip families. +void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index); +uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad); uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate); uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value); +bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad); Sercom* sercom_insts[SERCOM_INST_NUM]; -#ifdef SAMD21 -#include "samd21_peripherals.h" -#endif -#ifdef SAMD51 -#include "samd51_peripherals.h" -#endif - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H +#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H diff --git a/ports/atmel-samd/peripherals/timers.c b/ports/atmel-samd/peripherals/timers.c new file mode 100644 index 0000000000..cdcb92ac82 --- /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/timers.h b/ports/atmel-samd/peripherals/timers.h similarity index 100% rename from ports/atmel-samd/timers.h rename to ports/atmel-samd/peripherals/timers.h diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 7c682d1206..55e0a7ecfc 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -55,11 +55,11 @@ #include "common-hal/rtc/RTC.h" #include "common-hal/touchio/TouchIn.h" #include "common-hal/usb_hid/Device.h" +#include "peripherals/cache.h" +#include "peripherals/clocks.h" +#include "peripherals/events.h" +#include "peripherals/dma.h" #include "shared-bindings/rtc/__init__.h" -#include "clocks.h" -#include "events.h" -#include "peripherals.h" -#include "shared_dma.h" #include "tick.h" #ifdef CIRCUITPY_GAMEPAD_TICKS diff --git a/shared-bindings/board/__init__.h b/shared-bindings/board/__init__.h index 720239f280..2730e5f51b 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 0000000000..635826c60e --- /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 0000000000..29e89e2089 --- /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 0000000000..db1ff3d4c6 --- /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 0000000000..5d051d5a1a --- /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 8f1b506fea..584d021b0e 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;