diff --git a/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/board.json b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/board.json new file mode 100644 index 0000000000000..eef1084ad6d71 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/board.json @@ -0,0 +1,19 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "Micro USB", + "RGB LED", + "SPI Flash" + ], + "mcu": "samd51", + "product": "Grand Central M4 Express", + "images": [ + "grand_central_m4_express.jpg" + ], + "thumbnail": "", + "url": "https://www.adafruit.com/product/4064", + "vendor": "Adafruit" +} diff --git a/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/manifest.py b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/manifest.py new file mode 100644 index 0000000000000..4a722d6ef2149 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/manifest.py @@ -0,0 +1,6 @@ +include("$(PORT_DIR)/boards/manifest.py") +include("$(MPY_DIR)/extmod/uasyncio") +require("onewire") +require("ds18x20") +require("neopixel") +require("sdcard") diff --git a/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/mpconfigboard.h b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/mpconfigboard.h new file mode 100644 index 0000000000000..693639238d177 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/mpconfigboard.h @@ -0,0 +1,13 @@ +#define MICROPY_HW_BOARD_NAME "Grand Central M4 Express" +#define MICROPY_HW_MCU_NAME "ATSAMD51P20A" + +#define MICROPY_HW_XOSC32K (1) + +// 8MB QSPI chip +#define MICROPY_HW_QSPIFLASH GD25Q64C + +// fatfs configuration used in ffconf.h +#define MICROPY_FATFS_ENABLE_LFN (1) +#define MICROPY_FATFS_RPATH (2) +#define MICROPY_FATFS_MAX_SS (4096) +#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ diff --git a/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/mpconfigboard.mk b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/mpconfigboard.mk new file mode 100644 index 0000000000000..b99b2a526a23a --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/mpconfigboard.mk @@ -0,0 +1,13 @@ +MCU_SERIES = SAMD51 +CMSIS_MCU = ATSAMD51P20A +LD_FILES = boards/samd51x20a.ld sections.ld +TEXT0 = 0x4000 + +# The ?='s allow overriding in mpconfigboard.mk. +# MicroPython settings +MICROPY_VFS_LFS1 ?= 1 + +FROZEN_MANIFEST = $(BOARD_DIR)/manifest.py + +# Greater room for code in flash +MICROPY_HW_CODESIZE ?= 1008K \ No newline at end of file diff --git a/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/pins.csv b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/pins.csv new file mode 100644 index 0000000000000..b8ec2629967a6 --- /dev/null +++ b/ports/samd/boards/ADAFRUIT_GRAND_CENTRAL_M4_EXPRESS/pins.csv @@ -0,0 +1,109 @@ +# Pins listed below in order of board pinout picture from Adafruit, with breaks +# corresponding to the same spacing as on the board + +# Analogue input (16 pins) and output (first two of these) + +PIN_PA02,A0 +PIN_PA05,A1 +PIN_PB03,A2 +PIN_PC00,A3 +PIN_PC01,A4 +PIN_PC02,A5 +PIN_PC03,A6 +PIN_PB04,A7 + + +PIN_PB05,A8 +PIN_PB06,A9 +PIN_PB07,A10 +PIN_PB08,A11 +PIN_PB09,A12 +PIN_PA04,A13 +PIN_PA06,A14 +PIN_PA07,A15 + +# Big digital block at bottom of board + +PIN_PD12,D22 +PIN_PA15,D23 +PIN_PC17,D24 +PIN_PC16,D25 +PIN_PA12,D26 +PIN_PA13,D27 +PIN_PA14,D28 +PIN_PB19,D29 +PIN_PA23,D30 +PIN_PA22,D31 +PIN_PA21,D32 +PIN_PA20,D33 +PIN_PA19,D34 +PIN_PA18,D35 +PIN_PA17,D36 +PIN_PA16,D37 +PIN_PB15,D38 +PIN_PB14,D39 +PIN_PC13,D40 +PIN_PC12,D41 +PIN_PC15,D42 +PIN_PC14,D43 +PIN_PC11,D44 +PIN_PC10,D45 +PIN_PC06,D46 +PIN_PC07,D47 +PIN_PC04,D48 +PIN_PC05,D49 +PIN_PD11,D50 +PIN_PD08,D51 +PIN_PD09,D52 +PIN_PD10,D53 + +# Digital row down other side of board - N.B. diplicates + +PIN_PC30,LED_TX +PIN_PC31,LED_RX +PIN_PC24,NEOPIXEL + +PIN_PB21,SCL +PIN_PB20,SDA +PIN_PA03,AREF +PIN_PB01,D13 +PIN_PB00,D12 +PIN_PB23,D11 +PIN_PB22,D10 +PIN_PB02,D9 +PIN_PB18,D8 + +PIN_PD21,D7 +PIN_PD20,D6 +PIN_PC21,D5 +PIN_PC20,D4 +PIN_PC19,D3 +PIN_PC18,D2 +PIN_PB24,D1 +PIN_PB25,D0 + +PIN_PB16,D14 +PIN_PB17,D15 +PIN_PC22,D16 +PIN_PC23,D17 +PIN_PB12,D18 +PIN_PB13,D19 +PIN_PB20,D20 +PIN_PB21,D21 + +PIN_PB26,SD_MOSI +PIN_PB27,SD_SCK +PIN_PB28,SD_CS +PIN_PB29,SD_MISO +PIN_PB31,SD_CARD_DETECT + + +# QSPI flash + +PIN_PB11,QSPI_CS +PIN_PB10,QSPI_SCK +PIN_PA08,QSPI_D0 +PIN_PA09,QSPI_D1 +PIN_PA10,QSPI_D2 +PIN_PA11,QSPI_D3 + diff --git a/ports/samd/machine_dac.c b/ports/samd/machine_dac.c index c611f95e653d0..2b25b18d03d98 100644 --- a/ports/samd/machine_dac.c +++ b/ports/samd/machine_dac.c @@ -72,7 +72,7 @@ static uint8_t dac_vref_table[] = { #define MAX_DAC_VALUE (4095) #define DEFAULT_DAC_VREF (2) #define MAX_DAC_VREF (3) -static bool dac_init = false; +static bool dac_init[2] = {false, false}; #endif @@ -91,10 +91,10 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ uint8_t id = args[ARG_id].u_int; dac_obj_t *self = NULL; - if (0 <= id && id <= MP_ARRAY_SIZE(dac_obj)) { + if (0 <= id && id < MP_ARRAY_SIZE(dac_obj)) { self = &dac_obj[id]; } else { - mp_raise_ValueError(MP_ERROR_TEXT("invalid Pin for DAC")); + mp_raise_ValueError(MP_ERROR_TEXT("invalid id for DAC")); } uint8_t vref = args[ARG_vref].u_int; @@ -102,9 +102,10 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ self->vref = vref; } - Dac *dac = dac_bases[0]; // Just one DAC + Dac *dac = dac_bases[0]; // Just one DAC register block + + // initialize DAC - // Init DAC #if defined(MCU_SAMD21) // Configuration SAMD21 @@ -127,21 +128,39 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ // Configuration SAMD51 // Enable APBD clocks and PCHCTRL clocks; GCLK3 at 8 MHz - dac_init = true; - MCLK->APBDMASK.reg |= MCLK_APBDMASK_DAC; - GCLK->PCHCTRL[DAC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK3 | GCLK_PCHCTRL_CHEN; - // Reset DAC registers - dac->CTRLA.bit.SWRST = 1; - while (dac->CTRLA.bit.SWRST) { + if (!(dac_init[0] | dac_init[1])) { + MCLK->APBDMASK.reg |= MCLK_APBDMASK_DAC; + GCLK->PCHCTRL[DAC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK3 | \ + GCLK_PCHCTRL_CHEN; + + // Reset DAC registers + dac->CTRLA.bit.SWRST = 1; + while (dac->CTRLA.bit.SWRST) { + } + dac->CTRLB.reg = DAC_CTRLB_REFSEL(dac_vref_table[self->vref]); + } - dac->CTRLB.reg = DAC_CTRLB_REFSEL(dac_vref_table[self->vref]); - dac->DACCTRL[self->id].reg = DAC_DACCTRL_ENABLE | DAC_DACCTRL_REFRESH(2) | DAC_DACCTRL_CCTRL_CC12M; - // Enable DAC and wait to be ready - dac->CTRLA.bit.ENABLE = 1; - while (dac->SYNCBUSY.bit.ENABLE) { + // Modify DAC config - requires disabling see ยง47.6.2.3 of data sheet + if (!dac_init[self->id]) { + // Disable DAC and wait + dac->CTRLA.bit.ENABLE = 0; + while (dac->SYNCBUSY.bit.ENABLE) { + } + + // Modify configuration + dac->DACCTRL[self->id].reg = DAC_DACCTRL_ENABLE | \ + DAC_DACCTRL_REFRESH(2) | DAC_DACCTRL_CCTRL_CC12M; + dac->DATA[self->id].reg = 0; + dac_init[self->id] = true; + + // Enable DAC and wait + dac->CTRLA.bit.ENABLE = 1; + while (dac->SYNCBUSY.bit.ENABLE) { + } } + #endif // Set the port as given in self->gpio_id as DAC @@ -170,6 +189,7 @@ static mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) { return mp_const_none; } + MP_DEFINE_CONST_FUN_OBJ_2(dac_write_obj, dac_write); static const mp_rom_map_elem_t dac_locals_dict_table[] = {