From 243e22dc72e6a89a0e931c89d66c77c70402d887 Mon Sep 17 00:00:00 2001 From: dean Date: Thu, 19 Jul 2018 17:01:58 -0400 Subject: [PATCH] DM: add feather radio --- boards.txt | 53 ++-- cores/arduino/USB/SAMR21_USBDevice.h | 171 +----------- libraries/SPI/SPI.h | 2 +- .../debug_scripts/variant.gdb | 31 +++ .../gcc/flash_with_bootloader.ld | 213 +++++++++++++++ .../gcc/flash_without_bootloader.ld | 214 +++++++++++++++ .../openocd_scripts/arduino_zero.cfg | 30 +++ variants/feather_m0_radiofruit/pins_arduino.h | 21 ++ variants/feather_m0_radiofruit/variant.cpp | 121 +++++++++ variants/feather_m0_radiofruit/variant.h | 245 ++++++++++++++++++ 10 files changed, 905 insertions(+), 196 deletions(-) create mode 100644 variants/feather_m0_radiofruit/debug_scripts/variant.gdb create mode 100644 variants/feather_m0_radiofruit/linker_scripts/gcc/flash_with_bootloader.ld create mode 100644 variants/feather_m0_radiofruit/linker_scripts/gcc/flash_without_bootloader.ld create mode 100644 variants/feather_m0_radiofruit/openocd_scripts/arduino_zero.cfg create mode 100644 variants/feather_m0_radiofruit/pins_arduino.h create mode 100644 variants/feather_m0_radiofruit/variant.cpp create mode 100644 variants/feather_m0_radiofruit/variant.h diff --git a/boards.txt b/boards.txt index 3cdb9f2d..73791ca5 100644 --- a/boards.txt +++ b/boards.txt @@ -72,32 +72,33 @@ adafruit_feather_m0_express.build.pid=0x801B adafruit_feather_m0_express.bootloader.tool=openocd adafruit_feather_m0_express.bootloader.file=featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin -#adafruit_radio_m0.name=Adafruit M0 Radio (Native USB Port) -#adafruit_radio_m0.vid.0=0x239A -#adafruit_radio_m0.pid.0=0x8014 -#adafruit_radio_m0.vid.1=0x239A -#adafruit_radio_m0.pid.1=0x0014 -#adafruit_radio_m0.upload.tool=bossac -#adafruit_radio_m0.upload.protocol=sam-ba -#adafruit_radio_m0.upload.maximum_size=262144 -#adafruit_radio_m0.upload.use_1200bps_touch=true -#adafruit_radio_m0.upload.wait_for_upload_port=true -#adafruit_radio_m0.upload.native_usb=true -#adafruit_radio_m0.build.mcu=cortex-m0plus -#adafruit_radio_m0.build.f_cpu=48000000L -#adafruit_radio_m0.build.usb_product="Radio M0" -#adafruit_radio_m0.build.usb_manufacturer="Adafruit" -#adafruit_radio_m0.build.board=SAMD_ZERO -#adafruit_radio_m0.build.core=arduino -#adafruit_radio_m0.build.extra_flags=-D__SAMR21G18A__ -DARM_MATH_CM0PLUS {build.usb_flags} -#adafruit_radio_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -#adafruit_radio_m0.build.openocdscript=openocd_scripts/arduino_zero.cfg -#adafruit_radio_m0.build.variant=zero_radio -#adafruit_radio_m0.build.variant_system_lib= -#adafruit_radio_m0.build.vid=0x239A -#adafruit_radio_m0.build.pid=0x8014 -#adafruit_radio_m0.bootloader.tool=openocd -#adafruit_radio_m0.bootloader.file=feather/samr21_sam_ba.bin +adafruit_radio_m0.name=Adafruit Feather RadioFruit +adafruit_radio_m0.vid.0=0x239A +adafruit_radio_m0.pid.0=0x8024 +adafruit_radio_m0.vid.1=0x239A +adafruit_radio_m0.pid.1=0x0024 +adafruit_radio_m0.upload.tool=bossac18 +adafruit_radio_m0.upload.protocol=sam-ba +adafruit_radio_m0.upload.maximum_size=262144 +adafruit_radio_m0.upload.offset=0x2000 +adafruit_radio_m0.upload.use_1200bps_touch=true +adafruit_radio_m0.upload.wait_for_upload_port=true +adafruit_radio_m0.upload.native_usb=true +adafruit_radio_m0.build.mcu=cortex-m0plus +adafruit_radio_m0.build.f_cpu=48000000L +adafruit_radio_m0.build.usb_product="Feather RadioFruit" +adafruit_radio_m0.build.usb_manufacturer="Adafruit" +adafruit_radio_m0.build.board=SAMD_ZERO +adafruit_radio_m0.build.core=arduino +adafruit_radio_m0.build.extra_flags=-DARDUINO_SAMD_ZERO -DARDUINO_SAMD_FEATHER_M0 -DARM_MATH_CM0PLUS -DADAFRUIT_FEATHER_M0_RADIOFRUIT -D__SAMR21G18A__ {build.usb_flags} +adafruit_radio_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_radio_m0.build.openocdscript=openocd_scripts/arduino_zero.cfg +adafruit_radio_m0.build.variant=feather_m0_radiofruit +adafruit_radio_m0.build.variant_system_lib= +adafruit_radio_m0.build.vid=0x239A +adafruit_radio_m0.build.pid=0x8024 +adafruit_radio_m0.bootloader.tool=openocd +adafruit_radio_m0.bootloader.file=feather/samr21_sam_ba.bin adafruit_metro_m0.name=Adafruit Metro M0 Express adafruit_metro_m0.vid.0=0x239A diff --git a/cores/arduino/USB/SAMR21_USBDevice.h b/cores/arduino/USB/SAMR21_USBDevice.h index 1da5579a..b3c92a21 100644 --- a/cores/arduino/USB/SAMR21_USBDevice.h +++ b/cores/arduino/USB/SAMR21_USBDevice.h @@ -24,174 +24,7 @@ #include #include -typedef uint8_t ep_t; -class USBDevice_SAMR21G18x { -public: - USBDevice_SAMR21G18x() : usb(USB->DEVICE) { - // Empty - } - - // USB Device function mapping - // --------------------------- - - // Reset USB Device - void reset(); - - // Enable - inline void enable() { usb.CTRLA.bit.ENABLE = 1; } - inline void disable() { usb.CTRLA.bit.ENABLE = 0; } - - // USB mode (device/host) - inline void setUSBDeviceMode() { usb.CTRLA.bit.MODE = USB_CTRLA_MODE_DEVICE_Val; } - inline void setUSBHostMode() { usb.CTRLA.bit.MODE = USB_CTRLA_MODE_HOST_Val; } - - inline void runInStandby() { usb.CTRLA.bit.RUNSTDBY = 1; } - inline void noRunInStandby() { usb.CTRLA.bit.RUNSTDBY = 0; } - - // USB speed - inline void setFullSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; } - inline void setLowSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_LS_Val; } - inline void setHiSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_HS_Val; } - inline void setHiSpeedTestMode() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_HSTM_Val; } - - // Authorize attach if Vbus is present - inline void attach() { usb.CTRLB.bit.DETACH = 0; } - inline void detach() { usb.CTRLB.bit.DETACH = 1; } - - // USB Interrupts - inline bool isEndOfResetInterrupt() { return usb.INTFLAG.bit.EORST; } - inline void ackEndOfResetInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; } - inline void enableEndOfResetInterrupt() { usb.INTENSET.bit.EORST = 1; } - inline void disableEndOfResetInterrupt() { usb.INTENCLR.bit.EORST = 1; } - - inline bool isStartOfFrameInterrupt() { return usb.INTFLAG.bit.SOF; } - inline void ackStartOfFrameInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; } - inline void enableStartOfFrameInterrupt() { usb.INTENSET.bit.SOF = 1; } - inline void disableStartOfFrameInterrupt() { usb.INTENCLR.bit.SOF = 1; } - - // USB Address - inline void setAddress(uint32_t addr) { usb.DADD.bit.DADD = addr; usb.DADD.bit.ADDEN = 1; } - inline void unsetAddress() { usb.DADD.bit.DADD = 0; usb.DADD.bit.ADDEN = 0; } - - // Frame number - inline uint16_t frameNumber() { return usb.FNUM.bit.FNUM; } - - // Load calibration values - void calibrate(); - - // USB Device Endpoints function mapping - // ------------------------------------- - - // Config - inline void epBank0SetType(ep_t ep, uint8_t type) { usb.DeviceEndpoint[ep].EPCFG.bit.EPTYPE0 = type; } - inline void epBank1SetType(ep_t ep, uint8_t type) { usb.DeviceEndpoint[ep].EPCFG.bit.EPTYPE1 = type; } - - // Interrupts - inline uint16_t epInterruptSummary() { return usb.EPINTSMRY.reg; } - - inline bool epBank0IsSetupReceived(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.RXSTP; } - inline bool epBank0IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL0; } - inline bool epBank1IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL1; } - inline bool epBank0IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT0; } - inline bool epBank1IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT1; } - - inline void epBank0AckSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; } - inline void epBank0AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(1); } - inline void epBank1AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(2); } - inline void epBank0AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(1); } - inline void epBank1AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(2); } - - inline void epBank0EnableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.RXSTP = 1; } - inline void epBank0EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL0 = 1; } - inline void epBank1EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL1 = 1; } - inline void epBank0EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT0 = 1; } - inline void epBank1EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT1 = 1; } - - inline void epBank0DisableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.RXSTP = 1; } - inline void epBank0DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL0 = 1; } - inline void epBank1DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL1 = 1; } - inline void epBank0DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT0 = 1; } - inline void epBank1DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT1 = 1; } - - // Status - inline bool epBank0IsReady(ep_t ep) { return usb.DeviceEndpoint[ep].EPSTATUS.bit.BK0RDY; } - inline bool epBank1IsReady(ep_t ep) { return usb.DeviceEndpoint[ep].EPSTATUS.bit.BK1RDY; } - inline void epBank0SetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.BK0RDY = 1; } - inline void epBank1SetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.BK1RDY = 1; } - inline void epBank0ResetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.BK0RDY = 1; } - inline void epBank1ResetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.BK1RDY = 1; } - - inline void epBank0SetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.STALLRQ0 = 1; } - inline void epBank1SetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.STALLRQ1 = 1; } - inline void epBank0ResetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.STALLRQ0 = 1; } - inline void epBank1ResetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.STALLRQ1 = 1; } - - // Packet - inline uint16_t epBank0ByteCount(ep_t ep) { return EP[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT; } - inline uint16_t epBank1ByteCount(ep_t ep) { return EP[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT; } - inline void epBank0SetByteCount(ep_t ep, uint16_t bc) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = bc; } - inline void epBank1SetByteCount(ep_t ep, uint16_t bc) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = bc; } - inline void epBank0SetMultiPacketSize(ep_t ep, uint16_t s) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = s; } - inline void epBank1SetMultiPacketSize(ep_t ep, uint16_t s) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = s; } - - inline void epBank0SetAddress(ep_t ep, void *addr) { EP[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)addr; } - inline void epBank1SetAddress(ep_t ep, void *addr) { EP[ep].DeviceDescBank[1].ADDR.reg = (uint32_t)addr; } - inline void epBank0SetSize(ep_t ep, uint16_t size) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.SIZE = EP_PCKSIZE_SIZE(size); } - inline void epBank1SetSize(ep_t ep, uint16_t size) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.SIZE = EP_PCKSIZE_SIZE(size); } - inline uint8_t EP_PCKSIZE_SIZE(uint16_t size) { - switch (size) { - case 8: return 0; - case 16: return 1; - case 32: return 2; - case 64: return 3; - case 128: return 4; - case 256: return 5; - case 512: return 6; - case 1023: return 7; - default: return 0; - } - } - - inline void epBank0DisableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.AUTO_ZLP = 0; } - inline void epBank1DisableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = 0; } - inline void epBank0EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.AUTO_ZLP = 1; } - inline void epBank1EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = 1; } - -private: - // USB Device registers - UsbDevice &usb; - - // Endpoints descriptors table - __attribute__((__aligned__(4))) UsbDeviceDescriptor EP[USB_EPT_NUM]; -}; - -void USBDevice_SAMR21G18x::reset() { - usb.CTRLA.bit.SWRST = 1; - memset(EP, 0, sizeof(EP)); - while (usb.SYNCBUSY.bit.SWRST) {} - usb.DESCADD.reg = (uint32_t)(&EP); -} - -void USBDevice_SAMR21G18x::calibrate() { - // Load Pad Calibration data from non-volatile memory - uint32_t *pad_transn_p = (uint32_t *) USB_FUSES_TRANSN_ADDR; - uint32_t *pad_transp_p = (uint32_t *) USB_FUSES_TRANSP_ADDR; - uint32_t *pad_trim_p = (uint32_t *) USB_FUSES_TRIM_ADDR; - - uint32_t pad_transn = (*pad_transn_p & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; - uint32_t pad_transp = (*pad_transp_p & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; - uint32_t pad_trim = (*pad_trim_p & USB_FUSES_TRIM_Msk ) >> USB_FUSES_TRIM_Pos; - - if (pad_transn == 0x1F) // maximum value (31) - pad_transn = 5; - if (pad_transp == 0x1F) // maximum value (31) - pad_transp = 29; - if (pad_trim == 0x7) // maximum value (7) - pad_trim = 3; - - usb.PADCAL.bit.TRANSN = pad_transn; - usb.PADCAL.bit.TRANSP = pad_transp; - usb.PADCAL.bit.TRIM = pad_trim; -} +#include "SAMD21_USBDevice.h" +#define USBDevice_SAMR21G18x USBDevice_SAMD21G18x \ No newline at end of file diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index d119bf4a..55eb4aab 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -34,7 +34,7 @@ #define SPI_MODE2 0x03 #define SPI_MODE3 0x01 -#if defined(__SAMD21G18A__) +#if defined(__SAMD21G18A__) || defined(__SAMR21G18A__) // Even if not specified on the datasheet, the SAMD21G18A MCU // doesn't operate correctly with clock dividers lower than 4. // This allows a theoretical maximum SPI clock speed of 12Mhz diff --git a/variants/feather_m0_radiofruit/debug_scripts/variant.gdb b/variants/feather_m0_radiofruit/debug_scripts/variant.gdb new file mode 100644 index 00000000..3c37ffde --- /dev/null +++ b/variants/feather_m0_radiofruit/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/feather_m0_radiofruit/linker_scripts/gcc/flash_with_bootloader.ld b/variants/feather_m0_radiofruit/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 00000000..7d75f819 --- /dev/null +++ b/variants/feather_m0_radiofruit/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,213 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/feather_m0_radiofruit/linker_scripts/gcc/flash_without_bootloader.ld b/variants/feather_m0_radiofruit/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 00000000..ebeeee37 --- /dev/null +++ b/variants/feather_m0_radiofruit/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/feather_m0_radiofruit/openocd_scripts/arduino_zero.cfg b/variants/feather_m0_radiofruit/openocd_scripts/arduino_zero.cfg new file mode 100644 index 00000000..36c65c32 --- /dev/null +++ b/variants/feather_m0_radiofruit/openocd_scripts/arduino_zero.cfg @@ -0,0 +1,30 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +source [find interface/cmsis-dap.cfg] + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/feather_m0_radiofruit/pins_arduino.h b/variants/feather_m0_radiofruit/pins_arduino.h new file mode 100644 index 00000000..db0e40c3 --- /dev/null +++ b/variants/feather_m0_radiofruit/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/feather_m0_radiofruit/variant.cpp b/variants/feather_m0_radiofruit/variant.cpp new file mode 100644 index 00000000..be4fb9d1 --- /dev/null +++ b/variants/feather_m0_radiofruit/variant.cpp @@ -0,0 +1,121 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + + // 0 & 1 - Serial1 TX & RX as PWMs! + { PORTA, 8, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 9, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + + // 2, 3, 4 - Internal SPI for Flash + { PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // SPI CLK + { PORTA, 30, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_10 }, // SPI MISO + { PORTA, 31, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_11 }, // SPI MOSI + + // 5, 6 - normal GPIO pins w/PWM output + { PORTA, 14, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_14 }, // SPI MISO SERCOM 2.2 + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // TC3/WO[1] + + // 7 - SPI Flash CS + { PORTA, 28, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash CS + + // 8 - fake pin (crystal) used for USB host enable + { PORTA, 00, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB host enable + + // 9, 10, 11 + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3] + + // 12 (NeoPixel LED) + { PORTA, 22, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // Internal NeoPixel + + // 13 (LED) + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 14..19 - Analog pins + // -------------------- + { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10] + { PORTB, 3, PIO_ANALOG, 0, ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // ADC/AIN[11] + { PORTA, 4, PIO_ANALOG, 0, ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, 0, ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // ADC/AIN[5] + { PORTA, 6, PIO_ANALOG, 0, ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_ANALOG, 0, ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + + // Extra Analog pins! 20..21 + { PORTA, 8, PIO_ANALOG, 0, ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 9, PIO_ANALOG, 0, ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + + // 22,23 - SDA & SCL + { PORTA, 12, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_12 }, // SDA: SERCOM2.0 + { PORTA, 13, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_13 }, // SCL: SERCOM2.1 + + // 24..26 - SPI + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCK: SERCOM5.3 + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MOSI: SERCOM5.2 + { PORTA, 23, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MISO: SERCOM5.1 + + // ----- Special SAMR pins! ------ + { PORTB, 15, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #27 PB15 == AT86_RESETN + { PORTC, 16, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #28 PC16 == AT86_CLKM + { PORTC, 18, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #29 PC18 == AT86_SCLK sercom4.3 + { PORTC, 19, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #30 PC19 == AT86_MISO sercom4.0 + { PORTB, 30, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #31 PB30 == AT86_MOSI sercom4.2 + { PORTB, 31, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #32 PB31 == AT86_SEL sercom4.1 + { PORTB, 00, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // #33 PB00 = AT86_IRQ + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #34 = AT86_SLPTR + // 34..37 - AT86RF233 internal pins + { PORTB, 16, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // AT86RF233 DIG1 + { PORTB, 17, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // AT86RF233 DIG2 + { PORTA, 10, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // AT86RF233 DIG3 + { PORTA, 11, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // AT86RF233 DIG4 + + + // 38..39 - USB + // -------------------- + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +// We'll use sercom5 for Serial1 hardware serial since pins 0 and 1 are not external +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} \ No newline at end of file diff --git a/variants/feather_m0_radiofruit/variant.h b/variants/feather_m0_radiofruit/variant.h new file mode 100644 index 00000000..e87ebe53 --- /dev/null +++ b/variants/feather_m0_radiofruit/variant.h @@ -0,0 +1,245 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_FEATHER_RADIOFRUIT_ +#define _VARIANT_FEATHER_RADIOFRUIT_ + +// The definitions here needs a SAMD core >=1.6.6 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10606 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (48000000ul) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (37u) +#define NUM_DIGITAL_PINS (37u) + +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (0u) +#define analogInputToDigitalPin(p) ((p < 8u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) + //#define PIN_LED_RXL (25u) + //#define PIN_LED_TXL (26u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0+1) +#define PIN_A2 (PIN_A0+2) +#define PIN_A3 (PIN_A0+3) +#define PIN_A4 (PIN_A0+4) +#define PIN_A5 (PIN_A0+5) +#define PIN_A6 (PIN_A0+6) +#define PIN_A7 (PIN_A0+7) + + +static const uint8_t A0 = PIN_A0 ; +static const uint8_t A1 = PIN_A1 ; +static const uint8_t A2 = PIN_A2 ; +static const uint8_t A3 = PIN_A3 ; +static const uint8_t A4 = PIN_A4 ; +static const uint8_t A5 = PIN_A5 ; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; + + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATRF_RESETN (27u) +#define PIN_ATRF_CLKM (28u) +#define PIN_ATRF_SCLK (29u) +#define PIN_ATRF_MISO (30u) +#define PIN_ATRF_MOSI (31u) +#define PIN_ATRF_SEL (32u) +#define PIN_ATRF_IRQ (33u) +#define PIN_ATRF_SLPTR (34u) + +/* + * Serial interfaces + */ + +// Serial1 on SERCOM0 +#define PIN_SERIAL1_RX (1ul) +#define PIN_SERIAL1_TX (0ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 3 + +// "external" SPI, used for sensors, displays, available to user +#define PIN_SPI_SCK (24u) +#define PIN_SPI_MOSI (25u) +#define PIN_SPI_MISO (26u) +#define PERIPH_SPI sercom5 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_1 + +static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +// "internal" SPI #1, used for SPI FLASH only! +#define PIN_SPI1_SCK (2u) +#define PIN_SPI1_MOSI (4u) +#define PIN_SPI1_MISO (3u) +#define PERIPH_SPI1 sercom1 +#define PAD_SPI1_TX SPI_PAD_3_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_2 + +static const uint8_t SS1 = 7; // CS for flash +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +// "internal" SPI #2, used for AT86RF233 only! +#define PIN_SPI2_MISO PIN_ATRF_MISO +#define PIN_SPI2_MOSI PIN_ATRF_MOSI +#define PIN_SPI2_SCK PIN_ATRF_SCLK +#define PIN_SPI2_SEL PIN_ATRF_SEL +#define PERIPH_SPI2 sercom4 +#define PAD_SPI2_TX SPI_PAD_2_SCK_3 +#define PAD_SPI2_RX SERCOM_RX_PAD_0 + +static const uint8_t SS2 = PIN_SPI2_SEL ; +static const uint8_t MOSI2 = PIN_SPI2_MOSI ; +static const uint8_t MISO2 = PIN_SPI2_MISO ; +static const uint8_t SCK2 = PIN_SPI2_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (22u) +#define PIN_WIRE_SCL (23u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_DM (38ul) +#define PIN_USB_DP (39ul) +#define PIN_USB_HOST_ENABLE (8ul) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_FEATHER_RADIOFRUIT_ */