Compare commits

...

7 commits

Author SHA1 Message Date
dean
9f2846bf7f DM: bunch of updates for mega 2018-08-30 18:23:57 -04:00
dean
affe732e4f DM: adding stuff for metro mega 2018-08-29 13:05:39 -04:00
dean
8c40629173 Merge branch 'dm-mega' of github.com:adafruit/ArduinoCore-samd into dm-mega 2018-08-29 11:31:31 -04:00
dean
4df7370f12 DM: in progress metro m4 mega 2018-08-28 17:08:22 -04:00
dean
a278034831 DM: add spi DMA to other boards and reserved channels macro 2018-07-25 17:44:53 -04:00
dean
703c6dd497 DM: fix for samd21 2018-07-25 17:38:04 -04:00
dean
16567c4af4 DM: add SPI DMA stuff 2018-07-25 16:44:53 -04:00
26 changed files with 1739 additions and 59 deletions

View file

@ -307,7 +307,40 @@ adafruit_metro_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE
adafruit_metro_m4.menu.cache.off=Disabled adafruit_metro_m4.menu.cache.off=Disabled
adafruit_metro_m4.menu.cache.off.build.cache_flags= adafruit_metro_m4.menu.cache.off.build.cache_flags=
# Adafruit Metro M4 Mega (SAMD51)
# ------------------------------
adafruit_metro_m4_mega.name=Adafruit Metro M4 Mega (SAMD51)
adafruit_metro_m4_mega.vid.0=0x239A
adafruit_metro_m4_mega.pid.0=0x8020
adafruit_metro_m4_mega.vid.1=0x239A
adafruit_metro_m4_mega.pid.1=0x0020
adafruit_metro_m4_mega.upload.tool=bossac18
adafruit_metro_m4_mega.upload.protocol=sam-ba
adafruit_metro_m4_mega.upload.maximum_size=1032192
adafruit_metro_m4_mega.upload.offset=0x4000
adafruit_metro_m4_mega.upload.use_1200bps_touch=true
adafruit_metro_m4_mega.upload.wait_for_upload_port=true
adafruit_metro_m4_mega.upload.native_usb=true
adafruit_metro_m4_mega.build.mcu=cortex-m4
adafruit_metro_m4_mega.build.f_cpu=120000000L
adafruit_metro_m4_mega.build.usb_product="Adafruit Metro M4 Mega"
adafruit_metro_m4_mega.build.usb_manufacturer="Adafruit LLC"
adafruit_metro_m4_mega.build.board=METRO_M4_MEGA
adafruit_metro_m4_mega.build.core=arduino
adafruit_metro_m4_mega.build.extra_flags=-D__SAMD51P20A__ -DADAFRUIT_METRO_M4_MEGA -D__SAMD51__ {build.usb_flags} -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
adafruit_metro_m4_mega.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld
adafruit_metro_m4_mega.build.openocdscript=openocd_scripts/arduino_zero.cfg
adafruit_metro_m4_mega.build.variant=metro_m4_mega
adafruit_metro_m4_mega.build.variant_system_lib=
adafruit_metro_m4_mega.build.vid=0x239A
adafruit_metro_m4_mega.build.pid=0x8020
adafruit_metro_m4_mega.bootloader.tool=openocd
adafruit_metro_m4_mega.bootloader.file=metroM4/bootloader-metro_m4_mega-v2.0.0-adafruit.5.bin
adafruit_metro_m4_mega.compiler.arm.cmsis.ldflags="-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16
adafruit_metro_m4_mega.menu.cache.on=Enabled
adafruit_metro_m4_mega.menu.cache.on.build.cache_flags=-DENABLE_CACHE
adafruit_metro_m4_mega.menu.cache.off=Disabled
adafruit_metro_m4_mega.menu.cache.off.build.cache_flags=
# Adafruit ItsyBitsy M4 (SAMD51) # Adafruit ItsyBitsy M4 (SAMD51)
# ------------------------------ # ------------------------------

View file

@ -337,23 +337,115 @@ bool SERCOM::isDataRegisterEmptySPI()
return sercom->SPI.INTFLAG.bit.DRE; return sercom->SPI.INTFLAG.bit.DRE;
} }
//bool SERCOM::isTransmitCompleteSPI() bool SERCOM::isTransmitCompleteSPI()
//{ {
// //TXC : Transmit complete //TXC : Transmit complete
// return sercom->SPI.INTFLAG.bit.TXC; return sercom->SPI.INTFLAG.bit.TXC;
//} }
//
//bool SERCOM::isReceiveCompleteSPI() bool SERCOM::isReceiveCompleteSPI()
//{ {
// //RXC : Receive complete //RXC : Receive complete
// return sercom->SPI.INTFLAG.bit.RXC; return sercom->SPI.INTFLAG.bit.RXC;
//} }
uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate) uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate)
{ {
return SERCOM_FREQ_REF / (2 * baudrate) - 1; return SERCOM_FREQ_REF / (2 * baudrate) - 1;
} }
void SERCOM::initSPIDMA( uint8_t channelRx, uint8_t channelTx, DmacDescriptor *descrx, DmacDescriptor *desctx )
{
descrx->SRCADDR.reg = (uint32_t)(&sercom->SPI.DATA.reg);
desctx->DSTADDR.reg = (uint32_t)(&sercom->SPI.DATA.reg);
#ifdef __SAMD51__
if(sercom == SERCOM0)
{
DMAC->Channel[channelRx].CHCTRLA.bit.TRIGSRC = SERCOM0_DMAC_ID_RX;
DMAC->Channel[channelTx].CHCTRLA.bit.TRIGSRC = SERCOM0_DMAC_ID_TX;
}
else if(sercom == SERCOM1)
{
DMAC->Channel[channelRx].CHCTRLA.bit.TRIGSRC = SERCOM1_DMAC_ID_RX;
DMAC->Channel[channelTx].CHCTRLA.bit.TRIGSRC = SERCOM1_DMAC_ID_TX;
}
else if(sercom == SERCOM2)
{
DMAC->Channel[channelRx].CHCTRLA.bit.TRIGSRC = SERCOM2_DMAC_ID_RX;
DMAC->Channel[channelTx].CHCTRLA.bit.TRIGSRC = SERCOM2_DMAC_ID_TX;
}
else if(sercom == SERCOM3)
{
DMAC->Channel[channelRx].CHCTRLA.bit.TRIGSRC = SERCOM3_DMAC_ID_RX;
DMAC->Channel[channelTx].CHCTRLA.bit.TRIGSRC = SERCOM3_DMAC_ID_TX;
}
else if(sercom == SERCOM4)
{
DMAC->Channel[channelRx].CHCTRLA.bit.TRIGSRC = SERCOM4_DMAC_ID_RX;
DMAC->Channel[channelTx].CHCTRLA.bit.TRIGSRC = SERCOM4_DMAC_ID_TX;
}
else if(sercom == SERCOM5)
{
DMAC->Channel[channelRx].CHCTRLA.bit.TRIGSRC = SERCOM5_DMAC_ID_RX;
DMAC->Channel[channelTx].CHCTRLA.bit.TRIGSRC = SERCOM5_DMAC_ID_TX;
}
#else
if(sercom == SERCOM0)
{
DMAC->CHID.bit.ID = channelRx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM0_DMAC_ID_RX;
DMAC->CHID.bit.ID = channelTx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM0_DMAC_ID_TX;
}
else if(sercom == SERCOM1)
{
DMAC->CHID.bit.ID = channelRx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM1_DMAC_ID_RX;
DMAC->CHID.bit.ID = channelTx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM1_DMAC_ID_TX;
}
else if(sercom == SERCOM2)
{
DMAC->CHID.bit.ID = channelRx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM2_DMAC_ID_RX;
DMAC->CHID.bit.ID = channelTx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM2_DMAC_ID_TX;
}
else if(sercom == SERCOM3)
{
DMAC->CHID.bit.ID = channelRx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM3_DMAC_ID_RX;
DMAC->CHID.bit.ID = channelTx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM3_DMAC_ID_TX;
}
#if defined(SERCOM4)
else if(sercom == SERCOM4)
{
DMAC->CHID.bit.ID = channelRx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM4_DMAC_ID_RX;
DMAC->CHID.bit.ID = channelTx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM4_DMAC_ID_TX;
}
#endif
#if defined(SERCOM5)
else if(sercom == SERCOM5)
{
DMAC->CHID.bit.ID = channelRx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM5_DMAC_ID_RX;
DMAC->CHID.bit.ID = channelTx;
DMAC->CHCTRLB.bit.TRIGSRC = SERCOM5_DMAC_ID_TX;
}
#endif
#endif
}
/* ========================= /* =========================
* ===== Sercom WIRE * ===== Sercom WIRE
@ -374,7 +466,7 @@ void SERCOM::enableWIRE()
{ {
// I2C Master and Slave modes share the ENABLE bit function. // I2C Master and Slave modes share the ENABLE bit function.
// Enable the I²C master mode // Enable the I<EFBFBD>C master mode
sercom->I2CM.CTRLA.bit.ENABLE = 1 ; sercom->I2CM.CTRLA.bit.ENABLE = 1 ;
while ( sercom->I2CM.SYNCBUSY.bit.ENABLE != 0 ) while ( sercom->I2CM.SYNCBUSY.bit.ENABLE != 0 )
@ -395,7 +487,7 @@ void SERCOM::disableWIRE()
{ {
// I2C Master and Slave modes share the ENABLE bit function. // I2C Master and Slave modes share the ENABLE bit function.
// Enable the I²C master mode // Enable the I<EFBFBD>C master mode
sercom->I2CM.CTRLA.bit.ENABLE = 0 ; sercom->I2CM.CTRLA.bit.ENABLE = 0 ;
while ( sercom->I2CM.SYNCBUSY.bit.ENABLE != 0 ) while ( sercom->I2CM.SYNCBUSY.bit.ENABLE != 0 )

View file

@ -20,6 +20,7 @@
#define _SERCOM_CLASS_ #define _SERCOM_CLASS_
#include "sam.h" #include "sam.h"
#include "dma.h"
#define SERCOM_FREQ_REF 48000000ul #define SERCOM_FREQ_REF 48000000ul
@ -180,6 +181,7 @@ class SERCOM
bool isDataRegisterEmptySPI( void ) ; bool isDataRegisterEmptySPI( void ) ;
bool isTransmitCompleteSPI( void ) ; bool isTransmitCompleteSPI( void ) ;
bool isReceiveCompleteSPI( void ) ; bool isReceiveCompleteSPI( void ) ;
void initSPIDMA( uint8_t channelRx, uint8_t channelTx, DmacDescriptor *descrx, DmacDescriptor *desctx ) ;
/* ========== WIRE ========== */ /* ========== WIRE ========== */
void initSlaveWIRE(uint8_t address) ; void initSlaveWIRE(uint8_t address) ;

View file

@ -55,6 +55,20 @@ typedef enum _EAnalogChannel
ADC_Channel17=17, ADC_Channel17=17,
ADC_Channel18=18, ADC_Channel18=18,
ADC_Channel19=19, ADC_Channel19=19,
#if defined(__SAMD51__)
ADC_Channel20=20,
ADC_Channel21=21,
ADC_Channel22=22,
ADC_Channel23=23,
ADC_Channel24=24,
ADC_Channel25=25,
ADC_Channel26=26,
ADC_Channel27=27,
ADC_Channel28=28,
ADC_Channel29=29,
ADC_Channel30=30,
ADC_Channel31=31,
#endif
DAC_Channel0, DAC_Channel0,
DAC_Channel1, DAC_Channel1,
} EAnalogChannel ; } EAnalogChannel ;
@ -80,6 +94,47 @@ typedef enum _ETCChannel
TCC1_CH5 = (1<<8)|(1), TCC1_CH5 = (1<<8)|(1),
TCC1_CH6 = (1<<8)|(2), TCC1_CH6 = (1<<8)|(2),
TCC1_CH7 = (1<<8)|(3), TCC1_CH7 = (1<<8)|(3),
TCC2_CH0 = (2<<8)|(0),
TCC2_CH1 = (2<<8)|(1),
TCC2_CH2 = (2<<8)|(2),
TCC2_CH3 = (2<<8)|(3),
TCC2_CH4 = (2<<8)|(0),
TCC2_CH5 = (2<<8)|(1),
TCC2_CH6 = (2<<8)|(2),
TCC2_CH7 = (2<<8)|(3),
TCC3_CH0 = (3<<8)|(0),
TCC3_CH1 = (3<<8)|(1),
TCC3_CH2 = (3<<8)|(2),
TCC3_CH3 = (3<<8)|(3),
TCC3_CH4 = (3<<8)|(0),
TCC3_CH5 = (3<<8)|(1),
TCC3_CH6 = (3<<8)|(2),
TCC3_CH7 = (3<<8)|(3),
TCC4_CH0 = (4<<8)|(0),
TCC4_CH1 = (4<<8)|(1),
TCC4_CH2 = (4<<8)|(2),
TCC4_CH3 = (4<<8)|(3),
TCC4_CH4 = (4<<8)|(0),
TCC4_CH5 = (4<<8)|(1),
TCC4_CH6 = (4<<8)|(2),
TCC4_CH7 = (4<<8)|(3),
TC0_CH0 = (5<<8)|(0),
TC0_CH1 = (5<<8)|(1),
TC1_CH0 = (6<<8)|(0),
TC1_CH1 = (6<<8)|(1),
TC2_CH0 = (7<<8)|(0),
TC2_CH1 = (7<<8)|(1),
TC3_CH0 = (8<<8)|(0),
TC3_CH1 = (8<<8)|(1),
TC4_CH0 = (9<<8)|(0),
TC4_CH1 = (9<<8)|(1),
TC5_CH0 = (10<<8)|(0),
TC5_CH1 = (10<<8)|(1),
TC6_CH0 = (11<<8)|(0),
TC6_CH1 = (11<<8)|(1),
TC7_CH0 = (12<<8)|(0),
TC7_CH1 = (12<<8)|(1),
} ETCChannel ; } ETCChannel ;
#else #else
@ -140,6 +195,47 @@ extern const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM] ;
PWM1_CH5=TCC1_CH5, PWM1_CH5=TCC1_CH5,
PWM1_CH6=TCC1_CH6, PWM1_CH6=TCC1_CH6,
PWM1_CH7=TCC1_CH7, PWM1_CH7=TCC1_CH7,
PWM2_CH0=TCC2_CH0,
PWM2_CH1=TCC2_CH1,
PWM2_CH2=TCC2_CH2,
PWM2_CH3=TCC2_CH3,
PWM2_CH4=TCC2_CH4,
PWM2_CH5=TCC2_CH5,
PWM2_CH6=TCC2_CH6,
PWM2_CH7=TCC2_CH7,
PWM3_CH0=TCC3_CH0,
PWM3_CH1=TCC3_CH1,
PWM3_CH2=TCC3_CH2,
PWM3_CH3=TCC3_CH3,
PWM3_CH4=TCC3_CH4,
PWM3_CH5=TCC3_CH5,
PWM3_CH6=TCC3_CH6,
PWM3_CH7=TCC3_CH7,
PWM4_CH0=TCC4_CH0,
PWM4_CH1=TCC4_CH1,
PWM4_CH2=TCC4_CH2,
PWM4_CH3=TCC4_CH3,
PWM4_CH4=TCC4_CH4,
PWM4_CH5=TCC4_CH5,
PWM4_CH6=TCC4_CH6,
PWM4_CH7=TCC4_CH7,
PWM5_CH0=TC0_CH0,
PWM5_CH1=TC0_CH1,
PWM6_CH0=TC1_CH0,
PWM6_CH1=TC1_CH1,
PWM7_CH0=TC2_CH0,
PWM7_CH1=TC2_CH1,
PWM8_CH0=TC3_CH0,
PWM8_CH1=TC3_CH1,
PWM9_CH0=TC4_CH0,
PWM9_CH1=TC4_CH1,
PWM10_CH0=TC5_CH0,
PWM10_CH1=TC5_CH1,
PWM11_CH0=TC6_CH0,
PWM11_CH1=TC6_CH1,
PWM12_CH0=TC7_CH0,
PWM12_CH1=TC7_CH1,
} EPWMChannel ; } EPWMChannel ;
#else //end __SAMD51J19A__ #else //end __SAMD51J19A__
@ -186,6 +282,7 @@ typedef enum _EPortType
PORTA=0, PORTA=0,
PORTB=1, PORTB=1,
PORTC=2, PORTC=2,
PORTD=3,
} EPortType ; } EPortType ;
#define PIN_NOT_A_PIN (UINT_MAX) #define PIN_NOT_A_PIN (UINT_MAX)
@ -214,6 +311,34 @@ typedef enum
EXTERNAL_INT_NONE = NOT_AN_INTERRUPT, EXTERNAL_INT_NONE = NOT_AN_INTERRUPT,
} EExt_Interrupts ; } EExt_Interrupts ;
#if defined(__SAMD51__)
typedef enum _EPioType
{
PIO_NOT_A_PIN=-1, /* Not under control of a peripheral. */
PIO_EXTINT=0, /* The pin is controlled by the associated signal of peripheral A. */
PIO_ANALOG, /* The pin is controlled by the associated signal of peripheral B. */
PIO_SERCOM, /* The pin is controlled by the associated signal of peripheral C. */
PIO_SERCOM_ALT, /* The pin is controlled by the associated signal of peripheral D. */
PIO_TC, /* The pin is controlled by the associated signal of peripheral E. */
PIO_TCC, /* The pin is controlled by the associated signal of peripheral F. */
PIO_TCC_PDEC, /* The pin is controlled by the associated signal of peripheral G. */
PIO_COM, /* The pin is controlled by the associated signal of peripheral H. */
PIO_SDHC, /* The pin is controlled by the associated signal of peripheral I. */
PIO_I2S, /* The pin is controlled by the associated signal of peripheral J. */
PIO_PCC, /* The pin is controlled by the associated signal of peripheral K. */
PIO_GMAC, /* The pin is controlled by the associated signal of peripheral L. */
PIO_AC_CLK, /* The pin is controlled by the associated signal of peripheral M. */
PIO_CCL, /* The pin is controlled by the associated signal of peripheral N. */
PIO_DIGITAL, /* The pin is controlled by PORT. */
PIO_INPUT, /* The pin is controlled by PORT and is an input. */
PIO_INPUT_PULLUP, /* The pin is controlled by PORT and is an input with internal pull-up resistor enabled. */
PIO_OUTPUT, /* The pin is controlled by PORT and is an output. */
} EPioType ;
#else
//A B C D E F G H //A B C D E F G H
//EIC REF ADC AC PTC DAC SERCOM SERCOM_ALT TC/TCC TCC COM AC/GCLK //EIC REF ADC AC PTC DAC SERCOM SERCOM_ALT TC/TCC TCC COM AC/GCLK
@ -226,19 +351,9 @@ typedef enum _EPioType
PIO_SERCOM_ALT, /* The pin is controlled by the associated signal of peripheral D. */ PIO_SERCOM_ALT, /* The pin is controlled by the associated signal of peripheral D. */
PIO_TIMER, /* The pin is controlled by the associated signal of peripheral E. */ PIO_TIMER, /* The pin is controlled by the associated signal of peripheral E. */
PIO_TIMER_ALT, /* The pin is controlled by the associated signal of peripheral F. */ PIO_TIMER_ALT, /* The pin is controlled by the associated signal of peripheral F. */
#if defined(__SAMD51__)
PIO_TCC_PDEC, /* The pin is controlled by the associated signal of peripheral G. */
PIO_COM, /* The pin is controlled by the associated signal of peripheral H. */
PIO_SDHC, /* The pin is controlled by the associated signal of peripheral I. */
PIO_I2S, /* The pin is controlled by the associated signal of peripheral J. */
PIO_PCC, /* The pin is controlled by the associated signal of peripheral K. */
PIO_GMAC, /* The pin is controlled by the associated signal of peripheral L. */
PIO_AC_CLK, /* The pin is controlled by the associated signal of peripheral M. */
PIO_CCL, /* The pin is controlled by the associated signal of peripheral N. */
#else
PIO_COM, /* The pin is controlled by the associated signal of peripheral G. */ PIO_COM, /* The pin is controlled by the associated signal of peripheral G. */
PIO_AC_CLK, /* The pin is controlled by the associated signal of peripheral H. */ PIO_AC_CLK, /* The pin is controlled by the associated signal of peripheral H. */
#endif
PIO_DIGITAL, /* The pin is controlled by PORT. */ PIO_DIGITAL, /* The pin is controlled by PORT. */
PIO_INPUT, /* The pin is controlled by PORT and is an input. */ PIO_INPUT, /* The pin is controlled by PORT and is an input. */
PIO_INPUT_PULLUP, /* The pin is controlled by PORT and is an input with internal pull-up resistor enabled. */ PIO_INPUT_PULLUP, /* The pin is controlled by PORT and is an input with internal pull-up resistor enabled. */
@ -247,6 +362,7 @@ typedef enum _EPioType
PIO_PWM=PIO_TIMER, PIO_PWM=PIO_TIMER,
PIO_PWM_ALT=PIO_TIMER_ALT, PIO_PWM_ALT=PIO_TIMER_ALT,
} EPioType ; } EPioType ;
#endif
/** /**
* Pin Attributes to be OR-ed * Pin Attributes to be OR-ed
@ -260,6 +376,12 @@ typedef enum _EPioType
#define PIN_ATTR_TIMER_ALT (1UL<<5) #define PIN_ATTR_TIMER_ALT (1UL<<5)
#define PIN_ATTR_EXTINT (1UL<<6) #define PIN_ATTR_EXTINT (1UL<<6)
#if defined(__SAMD51__)
#define PIN_ATTR_PWM_TC (1UL<<7)
#define PIN_ATTR_PWM_TCC (1UL<<8)
#define PIN_ATTR_PWM_TCC_PDEC (1UL<<9)
#endif
/* Types used for the table below */ /* Types used for the table below */
typedef struct _PinDescription typedef struct _PinDescription
{ {

141
cores/arduino/dma.h Normal file
View file

@ -0,0 +1,141 @@
/**
* \file
*
* \brief SAM Direct Memory Access Controller Driver
*
* Copyright (C) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef DMA_H_INCLUDED
#define DMA_H_INCLUDED
// THIS IS A PARED-DOWN VERSION OF DMA.H FROM ATMEL ASFCORE 3.
// Please keep original copyright and license intact!
#ifdef __cplusplus
extern "C" {
#endif
extern DmacDescriptor // 128 bit alignment
_descriptor[DMAC_CH_NUM],
_writeback[DMAC_CH_NUM];
#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || defined(__DOXYGEN__) || defined(__SAMD51__)
#define FEATURE_DMA_CHANNEL_STANDBY
#endif
enum dma_transfer_trigger_action{
#ifdef __SAMD51__
// SAMD51 has a 'burst' transfer which can be set to one
// beat to accomplish same idea as SAMD21's 'beat' transfer.
// Trigger name is ACTON_BEAT for backward compatibility.
DMA_TRIGGER_ACTON_BLOCK = DMAC_CHCTRLA_TRIGACT_BLOCK_Val,
DMA_TRIGGER_ACTON_BEAT = DMAC_CHCTRLA_TRIGACT_BURST_Val,
DMA_TRIGGER_ACTON_TRANSACTION = DMAC_CHCTRLA_TRIGACT_TRANSACTION_Val,
#else
DMA_TRIGGER_ACTON_BLOCK = DMAC_CHCTRLB_TRIGACT_BLOCK_Val,
DMA_TRIGGER_ACTON_BEAT = DMAC_CHCTRLB_TRIGACT_BEAT_Val,
DMA_TRIGGER_ACTON_TRANSACTION = DMAC_CHCTRLB_TRIGACT_TRANSACTION_Val,
#endif
};
enum dma_callback_type {
// First item here is for any transfer errors. A transfer error is
// flagged if a bus error is detected during an AHB access or when
// the DMAC fetches an invalid descriptor
DMA_CALLBACK_TRANSFER_ERROR,
DMA_CALLBACK_TRANSFER_DONE,
DMA_CALLBACK_CHANNEL_SUSPEND,
DMA_CALLBACK_N, // Number of available callbacks
};
enum dma_beat_size {
DMA_BEAT_SIZE_BYTE = 0, // 8-bit
DMA_BEAT_SIZE_HWORD, // 16-bit
DMA_BEAT_SIZE_WORD, // 32-bit
};
enum dma_event_output_selection {
DMA_EVENT_OUTPUT_DISABLE = 0, // Disable event generation
DMA_EVENT_OUTPUT_BLOCK, // Event strobe when block xfer complete
DMA_EVENT_OUTPUT_RESERVED,
DMA_EVENT_OUTPUT_BEAT, // Event strobe when beat xfer complete
};
enum dma_block_action {
DMA_BLOCK_ACTION_NOACT = 0,
// Channel in normal operation and sets transfer complete interrupt
// flag after block transfer
DMA_BLOCK_ACTION_INT,
// Trigger channel suspend after block transfer and sets channel
// suspend interrupt flag once the channel is suspended
DMA_BLOCK_ACTION_SUSPEND,
// Sets transfer complete interrupt flag after a block transfer and
// trigger channel suspend. The channel suspend interrupt flag will
// be set once the channel is suspended.
DMA_BLOCK_ACTION_BOTH,
};
// DMA step selection. This bit determines whether the step size setting
// is applied to source or destination address.
enum dma_step_selection {
DMA_STEPSEL_DST = 0,
DMA_STEPSEL_SRC,
};
// Address increment step size. These bits select the address increment step
// size. The setting apply to source or destination address, depending on
// STEPSEL setting.
enum dma_address_increment_stepsize {
DMA_ADDRESS_INCREMENT_STEP_SIZE_1 = 0, // beat size * 1
DMA_ADDRESS_INCREMENT_STEP_SIZE_2, // beat size * 2
DMA_ADDRESS_INCREMENT_STEP_SIZE_4, // beat size * 4
DMA_ADDRESS_INCREMENT_STEP_SIZE_8, // etc...
DMA_ADDRESS_INCREMENT_STEP_SIZE_16,
DMA_ADDRESS_INCREMENT_STEP_SIZE_32,
DMA_ADDRESS_INCREMENT_STEP_SIZE_64,
DMA_ADDRESS_INCREMENT_STEP_SIZE_128,
};
#ifdef __cplusplus
}
#endif
#endif // DMA_H_INCLUDED

View file

@ -62,6 +62,12 @@ void calibrateADC()
* - Watchdog is disabled by default, unless someone plays with NVM User page * - Watchdog is disabled by default, unless someone plays with NVM User page
* - During reset, all PORT lines are configured as inputs with input buffers, output buffers and pull disabled. * - During reset, all PORT lines are configured as inputs with input buffers, output buffers and pull disabled.
*/ */
// DMA descriptor list entry point (and writeback buffer) per channel
__attribute__((__aligned__(16))) DmacDescriptor // 128 bit alignment
_descriptor[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR,
_writeback[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR;
void init( void ) void init( void )
{ {
// Set Systick to 1ms interval, common to all Cortex-M variants // Set Systick to 1ms interval, common to all Cortex-M variants
@ -185,6 +191,26 @@ void init( void )
#endif //SAMD51 #endif //SAMD51
//init DMAC
#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21)
PM->AHBMASK.bit.DMAC_ = 1;
#elif defined(__SAMD51__)
MCLK->AHBMASK.bit.DMAC_ = 1; // Initialize DMA clocks
#else
PM->AHBMASK.bit.DMAC_ = 1; // Initialize DMA clocks
PM->APBBMASK.bit.DMAC_ = 1;
#endif
DMAC->CTRL.bit.DMAENABLE = 0; // Disable DMA controller
DMAC->CTRL.bit.SWRST = 1; // Perform software reset
// Initialize descriptor list addresses
DMAC->BASEADDR.bit.BASEADDR = (uint32_t)_descriptor;
DMAC->WRBADDR.bit.WRBADDR = (uint32_t)_writeback;
memset(_descriptor, 0, sizeof(_descriptor));
memset(_writeback , 0, sizeof(_writeback));
DMAC->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN(0xF);
} }
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -253,6 +253,8 @@ uint32_t analogRead(uint32_t pin)
#endif #endif
#if defined(__SAMD51__) #if defined(__SAMD51__)
//TODO: This should use ADC1 depending on the channel
while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync while( ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync
ADC0->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input ADC0->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input
@ -337,6 +339,8 @@ uint32_t analogRead(uint32_t pin)
// hardware support. These are defined in the appropriate // hardware support. These are defined in the appropriate
// pins_*.c file. For the rest of the pins, we default // pins_*.c file. For the rest of the pins, we default
// to digital output. // to digital output.
//TODO: this needs to be updated to work with the metro m4 mega
void analogWrite(uint32_t pin, uint32_t value) void analogWrite(uint32_t pin, uint32_t value)
{ {
PinDescription pinDesc = g_APinDescription[pin]; PinDescription pinDesc = g_APinDescription[pin];
@ -422,32 +426,24 @@ void analogWrite(uint32_t pin, uint32_t value)
} }
#endif #endif
if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) #if defined(__SAMD51__)
if ((attr & PIN_ATTR_PWM_TC) == PIN_ATTR_PWM_TC ||
(attr & PIN_ATTR_PWM_TC) == PIN_ATTR_PWM_TCC ||
(attr & PIN_ATTR_PWM_TC) == PIN_ATTR_PWM_TCC_PDEC )
{ {
uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel); uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel);
uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel); uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel);
static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM]; static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM];
if (attr & PIN_ATTR_TIMER) { if ((attr & PIN_ATTR_PWM_TC) == PIN_ATTR_PWM_TC) {
#if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603) pinPeripheral(pin, PIO_TC);
// Compatibility for cores based on SAMD core <=1.6.2 } else if ((attr & PIN_ATTR_PWM_TCC) == PIN_ATTR_PWM_TCC){
if (pinDesc.ulPinType == PIO_TIMER_ALT) { //this is on a TCC
pinPeripheral(pin, PIO_TIMER_ALT); pinPeripheral(pin, PIO_TCC);
} else } else if ((attr & PIN_ATTR_PWM_TCC_PDEC) == PIN_ATTR_PWM_TCC_PDEC){
#endif //this is on a TCC_PDEC
{
#if defined(__SAMD51__)
//on SAMD51 we are only using TCC for timers
pinPeripheral(pin, PIO_TCC_PDEC); pinPeripheral(pin, PIO_TCC_PDEC);
#else
pinPeripheral(pin, PIO_TIMER);
#endif
}
} else if ((attr & PIN_ATTR_TIMER_ALT) == PIN_ATTR_TIMER_ALT){
//this is on an alt timer
pinPeripheral(pin, PIO_TIMER_ALT);
} }
else{ else{
return; return;
@ -456,7 +452,6 @@ void analogWrite(uint32_t pin, uint32_t value)
if (!tcEnabled[tcNum]) { if (!tcEnabled[tcNum]) {
tcEnabled[tcNum] = true; tcEnabled[tcNum] = true;
#if defined(__SAMD51__)
uint32_t GCLK_CLKCTRL_IDs[] = { uint32_t GCLK_CLKCTRL_IDs[] = {
TCC0_GCLK_ID, TCC0_GCLK_ID,
TCC1_GCLK_ID, TCC1_GCLK_ID,
@ -464,8 +459,31 @@ void analogWrite(uint32_t pin, uint32_t value)
#if defined(TCC3) #if defined(TCC3)
TCC3_GCLK_ID, TCC3_GCLK_ID,
TCC4_GCLK_ID, TCC4_GCLK_ID,
#endif
#if defined(TC0)
TC0_GCLK_ID,
#endif
#if defined(TC1)
TC1_GCLK_ID,
#endif
#if defined(TC2)
TC2_GCLK_ID,
#endif
#if defined(TC3)
TC3_GCLK_ID,
#endif
#if defined(TC4)
TC4_GCLK_ID,
#endif
#if defined(TC5)
TC5_GCLK_ID, TC5_GCLK_ID,
#endif #endif
#if defined(TC6)
TC6_GCLK_ID,
#endif
#if defined(TC7)
TC7_GCLK_ID,
#endif
}; };
GCLK->PCHCTRL[GCLK_CLKCTRL_IDs[tcNum]].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 0 GCLK->PCHCTRL[GCLK_CLKCTRL_IDs[tcNum]].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 0
@ -541,6 +559,35 @@ void analogWrite(uint32_t pin, uint32_t value)
} }
#else #else
if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM)
{
uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel);
uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel);
static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM];
if (attr & PIN_ATTR_TIMER) {
#if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603)
// Compatibility for cores based on SAMD core <=1.6.2
if (pinDesc.ulPinType == PIO_TIMER_ALT) {
pinPeripheral(pin, PIO_TIMER_ALT);
} else
#endif
{
pinPeripheral(pin, PIO_TIMER);
}
} else if ((attr & PIN_ATTR_TIMER_ALT) == PIN_ATTR_TIMER_ALT){
//this is on an alt timer
pinPeripheral(pin, PIO_TIMER_ALT);
}
else{
return;
}
if (!tcEnabled[tcNum]) {
tcEnabled[tcNum] = true;
uint16_t GCLK_CLKCTRL_IDs[] = { uint16_t GCLK_CLKCTRL_IDs[] = {
GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0 GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0
GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1 GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1

View file

@ -65,10 +65,10 @@ int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral )
case PIO_ANALOG: case PIO_ANALOG:
case PIO_SERCOM: case PIO_SERCOM:
case PIO_SERCOM_ALT: case PIO_SERCOM_ALT:
case PIO_TIMER:
case PIO_TIMER_ALT:
case PIO_EXTINT: case PIO_EXTINT:
#if defined(__SAMD51__) #if defined(__SAMD51__)
case PIO_TC:
case PIO_TCC:
case PIO_TCC_PDEC: case PIO_TCC_PDEC:
case PIO_COM: case PIO_COM:
case PIO_SDHC: case PIO_SDHC:
@ -78,6 +78,8 @@ int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral )
case PIO_AC_CLK: case PIO_AC_CLK:
case PIO_CCL: case PIO_CCL:
#else #else
case PIO_TIMER:
case PIO_TIMER_ALT:
case PIO_COM: case PIO_COM:
case PIO_AC_CLK: case PIO_AC_CLK:
#endif #endif

View file

@ -28,7 +28,8 @@
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings(); const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad PadTx, SercomRXPad PadRx) SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI,
SercomSpiTXPad PadTx, SercomRXPad PadRx, int8_t dmaChannelRx, int8_t dmaChannelTx)
{ {
initialized = false; initialized = false;
assert(p_sercom != NULL); assert(p_sercom != NULL);
@ -39,6 +40,9 @@ SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint
_uc_pinSCK = uc_pinSCK; _uc_pinSCK = uc_pinSCK;
_uc_pinMosi = uc_pinMOSI; _uc_pinMosi = uc_pinMOSI;
_dmaChannelRx = dmaChannelRx;
_dmaChannelTx = dmaChannelTx;
// SERCOM pads // SERCOM pads
_padTx=PadTx; _padTx=PadTx;
_padRx=PadRx; _padRx=PadRx;
@ -53,6 +57,64 @@ void SPIClass::begin()
pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType); pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType); pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
if(_dmaChannelRx > -1 && _dmaChannelTx > -1){
descrx = &_descriptor[_dmaChannelRx];
desctx = &_descriptor[_dmaChannelTx];
descrx->BTCTRL.bit.VALID = true;
descrx->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_DISABLE;
descrx->BTCTRL.bit.BLOCKACT = DMA_BLOCK_ACTION_NOACT;
descrx->BTCTRL.bit.BEATSIZE = DMA_BEAT_SIZE_BYTE;
descrx->BTCTRL.bit.SRCINC = false;
descrx->BTCTRL.bit.DSTINC = true;
descrx->BTCTRL.bit.STEPSEL = DMA_STEPSEL_DST;
descrx->BTCTRL.bit.STEPSIZE = DMA_ADDRESS_INCREMENT_STEP_SIZE_1;
descrx->BTCNT.reg = 0;
descrx->SRCADDR.reg = (uint32_t)0;
desctx->BTCTRL.bit.VALID = true;
desctx->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_DISABLE;
desctx->BTCTRL.bit.BLOCKACT = DMA_BLOCK_ACTION_NOACT;
desctx->BTCTRL.bit.BEATSIZE = DMA_BEAT_SIZE_BYTE;
desctx->BTCTRL.bit.SRCINC = true;
desctx->BTCTRL.bit.DSTINC = false;
desctx->BTCTRL.bit.STEPSEL = DMA_STEPSEL_DST;
desctx->BTCTRL.bit.STEPSIZE = DMA_ADDRESS_INCREMENT_STEP_SIZE_1;
desctx->BTCNT.reg = 0;
desctx->SRCADDR.reg = (uint32_t)0;
#ifdef __SAMD51__
DMAC->Channel[_dmaChannelRx].CHCTRLA.bit.ENABLE = 0;
DMAC->Channel[_dmaChannelRx].CHCTRLA.bit.SWRST = 1;
DMAC->Channel[_dmaChannelTx].CHCTRLA.bit.ENABLE = 0;
DMAC->Channel[_dmaChannelTx].CHCTRLA.bit.SWRST = 1;
DMAC->Channel[_dmaChannelRx].CHPRILVL.bit.PRILVL = 0;
DMAC->Channel[_dmaChannelRx].CHCTRLA.bit.TRIGACT = DMA_TRIGGER_ACTON_BEAT;
DMAC->Channel[_dmaChannelRx].CHCTRLA.bit.BURSTLEN = DMAC_CHCTRLA_BURSTLEN_SINGLE_Val; // Single-beat burst length
DMAC->Channel[_dmaChannelTx].CHPRILVL.bit.PRILVL = 0;
DMAC->Channel[_dmaChannelTx].CHCTRLA.bit.TRIGACT = DMA_TRIGGER_ACTON_BEAT;
DMAC->Channel[_dmaChannelTx].CHCTRLA.bit.BURSTLEN = DMAC_CHCTRLA_BURSTLEN_SINGLE_Val; // Single-beat burst length
DMAC->SWTRIGCTRL.reg &= ~(1UL << _dmaChannelTx);
DMAC->SWTRIGCTRL.reg &= ~(1UL << _dmaChannelRx);
#else
DMAC->CHID.bit.ID = _dmaChannelRx;
DMAC->CHCTRLA.bit.ENABLE = 0;
DMAC->CHCTRLA.bit.SWRST = 1;
DMAC->CHCTRLB.bit.LVL = 0;
DMAC->CHCTRLB.bit.TRIGACT = DMA_TRIGGER_ACTON_BEAT;
DMAC->CHID.bit.ID = _dmaChannelTx;
DMAC->CHCTRLA.bit.ENABLE = 0;
DMAC->CHCTRLA.bit.SWRST = 1;
DMAC->CHCTRLB.bit.LVL = 0;
DMAC->CHCTRLB.bit.TRIGACT = DMA_TRIGGER_ACTON_BEAT;
#endif
_p_sercom->initSPIDMA(_dmaChannelRx, _dmaChannelTx, descrx, desctx);
}
config(DEFAULT_SPI_SETTINGS); config(DEFAULT_SPI_SETTINGS);
} }
@ -206,13 +268,46 @@ uint16_t SPIClass::transfer16(uint16_t data) {
return t.val; return t.val;
} }
void SPIClass::transfer(void *buf, size_t count) void SPIClass::transfer(void *rx, void *tx, size_t count)
{ {
uint8_t *buffer = reinterpret_cast<uint8_t *>(buf); if(count > 2 && count < 65536 && _dmaChannelRx > -1 && _dmaChannelTx > -1){
for (size_t i=0; i<count; i++) { //use a synchronous DMA transfer
*buffer = transfer(*buffer); descrx->BTCTRL.bit.VALID = true;
buffer++; descrx->DSTADDR.reg = (uint32_t)rx + count;
descrx->BTCNT.reg = count;
desctx->BTCTRL.bit.VALID = true;
desctx->SRCADDR.reg = (uint32_t)tx + count;
desctx->BTCNT.reg = count;
#ifdef __SAMD51__
DMAC->Channel[_dmaChannelTx].CHCTRLA.bit.ENABLE = 1;
if(rx != NULL)
DMAC->Channel[_dmaChannelRx].CHCTRLA.bit.ENABLE = 1;
#else
DMAC->CHID.bit.ID = _dmaChannelTx;
DMAC->CHCTRLA.bit.ENABLE = 1;
DMAC->CHID.bit.ID = _dmaChannelRx;
DMAC->CHCTRLA.bit.ENABLE = 1;
#endif
//wait for the transfer to finish
while(_writeback[_dmaChannelTx].BTCTRL.bit.VALID || !_p_sercom->isDataRegisterEmptySPI());
while(!_p_sercom->isTransmitCompleteSPI());
} }
else{
//use a normal transfer
uint8_t *rxBuffer = reinterpret_cast<uint8_t *>(rx);
uint8_t *txBuffer = reinterpret_cast<uint8_t *>(tx);
for (size_t i=0; i<count; i++) {
*rxBuffer++ = transfer(*txBuffer++);
}
}
}
void SPIClass::transfer(void *buf, size_t count){
transfer(buf, buf, count);
} }
void SPIClass::attachInterrupt() { void SPIClass::attachInterrupt() {
@ -238,21 +333,46 @@ void SPIClass::detachInterrupt() {
#define PAD_SPI_TX SPI_PAD_2_SCK_3 #define PAD_SPI_TX SPI_PAD_2_SCK_3
#define PAD_SPI_RX SERCOM_RX_PAD_0 #define PAD_SPI_RX SERCOM_RX_PAD_0
#endif // PERIPH_SPI #endif // PERIPH_SPI
#ifdef SPI_HAS_DMA
SPIClass SPI (&PERIPH_SPI, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI, PAD_SPI_TX, PAD_SPI_RX, SPI_DMA_CHANNEL_RX, SPI_DMA_CHANNEL_TX);
#else
SPIClass SPI (&PERIPH_SPI, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI, PAD_SPI_TX, PAD_SPI_RX); SPIClass SPI (&PERIPH_SPI, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI, PAD_SPI_TX, PAD_SPI_RX);
#endif #endif
#endif
#if SPI_INTERFACES_COUNT > 1 #if SPI_INTERFACES_COUNT > 1
#ifdef SPI1_HAS_DMA
SPIClass SPI1(&PERIPH_SPI1, PIN_SPI1_MISO, PIN_SPI1_SCK, PIN_SPI1_MOSI, PAD_SPI1_TX, PAD_SPI1_RX, SPI1_DMA_CHANNEL_RX, SPI1_DMA_CHANNEL_TX);
#else
SPIClass SPI1(&PERIPH_SPI1, PIN_SPI1_MISO, PIN_SPI1_SCK, PIN_SPI1_MOSI, PAD_SPI1_TX, PAD_SPI1_RX); SPIClass SPI1(&PERIPH_SPI1, PIN_SPI1_MISO, PIN_SPI1_SCK, PIN_SPI1_MOSI, PAD_SPI1_TX, PAD_SPI1_RX);
#endif #endif
#endif
#if SPI_INTERFACES_COUNT > 2 #if SPI_INTERFACES_COUNT > 2
SPIClass SPI2(&PERIPH_SPI2, PIN_SPI2_MISO, PIN_SPI2_SCK, PIN_SPI2_MOSI, PAD_SPI2_TX, PAD_SPI2_RX); #ifdef SPI2_HAS_DMA
SPIClass SPI2(&PERIPH_SPI2, PIN_SPI2_MISO, PIN_SPI2_SCK, PIN_SPI2_MOSI, PAD_SPI2_TX, PAD_SPI2_RX, SPI2_DMA_CHANNEL_RX, SPI2_DMA_CHANNEL_TX);
#else
SPIClass SPI2(&PERIPH_SPI2, PIN_SPI1_MISO, PIN_SPI2_SCK, PIN_SPI2_MOSI, PAD_SPI2_TX, PAD_SPI2_RX);
#endif
#endif #endif
#if SPI_INTERFACES_COUNT > 3 #if SPI_INTERFACES_COUNT > 3
#ifdef SPI3_HAS_DMA
SPIClass SPI3(&PERIPH_SPI3, PIN_SPI3_MISO, PIN_SPI3_SCK, PIN_SPI3_MOSI, PAD_SPI3_TX, PAD_SPI3_RX, SPI3_DMA_CHANNEL_RX, SPI3_DMA_CHANNEL_TX);
#else
SPIClass SPI3(&PERIPH_SPI3, PIN_SPI3_MISO, PIN_SPI3_SCK, PIN_SPI3_MOSI, PAD_SPI3_TX, PAD_SPI3_RX); SPIClass SPI3(&PERIPH_SPI3, PIN_SPI3_MISO, PIN_SPI3_SCK, PIN_SPI3_MOSI, PAD_SPI3_TX, PAD_SPI3_RX);
#endif #endif
#endif
#if SPI_INTERFACES_COUNT > 4 #if SPI_INTERFACES_COUNT > 4
#ifdef SPI4_HAS_DMA
SPIClass SPI4(&PERIPH_SPI4, PIN_SPI4_MISO, PIN_SPI4_SCK, PIN_SPI4_MOSI, PAD_SPI4_TX, PAD_SPI4_RX, SPI4_DMA_CHANNEL_RX, SPI4_DMA_CHANNEL_TX);
#else
SPIClass SPI4(&PERIPH_SPI4, PIN_SPI4_MISO, PIN_SPI4_SCK, PIN_SPI4_MOSI, PAD_SPI4_TX, PAD_SPI4_RX); SPIClass SPI4(&PERIPH_SPI4, PIN_SPI4_MISO, PIN_SPI4_SCK, PIN_SPI4_MOSI, PAD_SPI4_TX, PAD_SPI4_RX);
#endif #endif
#endif
#if SPI_INTERFACES_COUNT > 5 #if SPI_INTERFACES_COUNT > 5
#ifdef SPI5_HAS_DMA
SPIClass SPI5(&PERIPH_SPI5, PIN_SPI5_MISO, PIN_SPI5_SCK, PIN_SPI5_MOSI, PAD_SPI5_TX, PAD_SPI5_RX, SPI5_DMA_CHANNEL_RX, SPI5_DMA_CHANNEL_TX);
#else
SPIClass SPI5(&PERIPH_SPI5, PIN_SPI5_MISO, PIN_SPI5_SCK, PIN_SPI5_MOSI, PAD_SPI5_TX, PAD_SPI5_RX); SPIClass SPI5(&PERIPH_SPI5, PIN_SPI5_MISO, PIN_SPI5_SCK, PIN_SPI5_MOSI, PAD_SPI5_TX, PAD_SPI5_RX);
#endif #endif
#endif

View file

@ -21,6 +21,7 @@
#define _SPI_H_INCLUDED #define _SPI_H_INCLUDED
#include <Arduino.h> #include <Arduino.h>
#include "dma.h"
// SPI_HAS_TRANSACTION means SPI has // SPI_HAS_TRANSACTION means SPI has
// - beginTransaction() // - beginTransaction()
@ -91,12 +92,13 @@ class SPISettings {
class SPIClass { class SPIClass {
public: public:
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad); SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad PadTx, SercomRXPad PadRx, int8_t dmaChannelRx=-1, int8_t dmaChannelTx=-1);
byte transfer(uint8_t data); byte transfer(uint8_t data);
uint16_t transfer16(uint16_t data); uint16_t transfer16(uint16_t data);
void transfer(void *buf, size_t count); void transfer(void *buf, size_t count);
void transfer(void *rx, void *tx, size_t count);
// Transaction Functions // Transaction Functions
void usingInterrupt(int interruptNumber); void usingInterrupt(int interruptNumber);
@ -122,6 +124,10 @@ class SPIClass {
uint8_t _uc_pinMiso; uint8_t _uc_pinMiso;
uint8_t _uc_pinMosi; uint8_t _uc_pinMosi;
uint8_t _uc_pinSCK; uint8_t _uc_pinSCK;
DmacDescriptor *descrx;
DmacDescriptor *desctx;
int8_t _dmaChannelRx;
int8_t _dmaChannelTx;
SercomSpiTXPad _padTx; SercomSpiTXPad _padTx;
SercomRXPad _padRx; SercomRXPad _padRx;

View file

@ -146,6 +146,13 @@ static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
/* /*
* Wire Interfaces * Wire Interfaces
*/ */

View file

@ -151,6 +151,13 @@ static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
#define PIN_SPI1_MISO (36u) #define PIN_SPI1_MISO (36u)
#define PIN_SPI1_MOSI (37u) #define PIN_SPI1_MOSI (37u)

View file

@ -143,6 +143,13 @@ static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
/* /*
* Wire Interfaces * Wire Interfaces
*/ */

View file

@ -130,6 +130,13 @@ static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
/* /*
* Wire Interfaces * Wire Interfaces

View file

@ -145,6 +145,13 @@ static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
#define PIN_SPI1_MISO (36u) #define PIN_SPI1_MISO (36u)
#define PIN_SPI1_MOSI (37u) #define PIN_SPI1_MOSI (37u)

View file

@ -142,6 +142,13 @@ static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
/* /*
* Wire Interfaces * Wire Interfaces
*/ */

View file

@ -151,6 +151,12 @@ static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
#define PIN_SPI1_MISO (36u) #define PIN_SPI1_MISO (36u)
#define PIN_SPI1_MOSI (37u) #define PIN_SPI1_MOSI (37u)

View file

@ -143,6 +143,13 @@ static const uint8_t ATN = PIN_ATN;
#define PAD_SPI_TX SPI_PAD_0_SCK_1 #define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_2 #define PAD_SPI_RX SERCOM_RX_PAD_2
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX))
static const uint8_t SS = PIN_A2 ; static const uint8_t SS = PIN_A2 ;
static const uint8_t MOSI = PIN_SPI_MOSI ; static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;

View file

@ -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"

Binary file not shown.

View file

@ -0,0 +1,216 @@
/*
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+0x4000, LENGTH = 0x100000-0x4000 /* First 16KB used by bootloader */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000
}
/* 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(*(.sketch_boot))
. = ALIGN(0x4000);
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")
}

View file

@ -0,0 +1,215 @@
/*
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 = 0x100000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000
}
/* 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__ = .;
. = ALIGN(4);
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")
}

View file

@ -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]

View file

@ -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"

View file

@ -0,0 +1,207 @@
/*
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
* TODO: sercoms, PWM, adc channel, interrupt defs
*/
const PinDescription g_APinDescription[]=
{
// 0..13 - Digital pins
// ----------------------
// 0/1 - SERCOM/UART (Serial1)
{ PORTB, 25, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // RX: SERCOM0/PAD[1]
{ PORTB, 24, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // TX: SERCOM0/PAD[0]
// 2..12
// Digital Low
{ PORTC, 18, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH2, TCC0_CH2, EXTERNAL_INT_2 },
{ PORTC, 19, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 },
{ PORTC, 20, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_4 },
{ PORTC, 21, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH5, TCC0_CH5, EXTERNAL_INT_5 },
{ PORTD, 20, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_10 },
{ PORTD, 21, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_11 },
// Digital High
{ PORTB, 18, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_2 },
{ PORTB, 19, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_3 },
{ PORTB, 22, PIO_TC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TC), No_ADC_Channel, PWM12_CH0, TC7_CH0, EXTERNAL_INT_6 },
{ PORTB, 23, PIO_TC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TC), No_ADC_Channel, PWM12_CH1, TC7_CH1, EXTERNAL_INT_7 },
{ PORTB, 0, PIO_TC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TC), No_ADC_Channel, PWM12_CH0, TC7_CH0, EXTERNAL_INT_0 },
// 13 (LED)
{ PORTB, 1, PIO_TC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TC), No_ADC_Channel, PWM12_CH1, TC7_CH1, EXTERNAL_INT_1 },
// 14..21 - Analog pins
// --------------------
{ PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 },
{ PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 },
{ PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 },
{ PORTC, 0, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel26, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 },
{ PORTC, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel27, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 },
{ PORTC, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel20, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 },
{ PORTC, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel21, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 },
{ PORTB, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel22, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 },
// 22..53 - Extra Digital Pins
// ----------------------
// 22..29
{ NOT_A_PORT, 0, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
{ NOT_A_PORT, 0, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
{ PORTC, 17, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_1 },
{ PORTC, 16, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_0 },
{ PORTA, 12, PIO_TCC_PDEC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC_PDEC), No_ADC_Channel, PWM1_CH2, TCC1_CH2, EXTERNAL_INT_12 },
{ PORTA, 13, PIO_TCC_PDEC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC_PDEC), No_ADC_Channel, PWM1_CH3, TCC1_CH3, EXTERNAL_INT_14 },
{ PORTA, 14, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_14 },
{ NOT_A_PORT, 0, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
// 30..37
{ PORTA, 23, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH7, TCC1_CH7, EXTERNAL_INT_7 },
{ PORTA, 22, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH6, TCC1_CH6, EXTERNAL_INT_6 },
{ PORTA, 21, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH5, TCC1_CH5, EXTERNAL_INT_5 },
{ PORTA, 20, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH4, TCC1_CH4, EXTERNAL_INT_4 },
{ PORTA, 19, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH3, TCC1_CH3, EXTERNAL_INT_3 },
{ PORTA, 18, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH2, TCC1_CH2, EXTERNAL_INT_2 },
{ PORTA, 17, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_1 },
{ PORTA, 16, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_0 },
// 38..45
{ PORTB, 15, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM4_CH1, TCC4_CH1, EXTERNAL_INT_15 },
{ PORTB, 14, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM4_CH0, TCC4_CH0, EXTERNAL_INT_14 },
{ PORTC, 13, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_13 },
{ PORTC, 12, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH2, TCC0_CH2, EXTERNAL_INT_12 },
{ PORTC, 15, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH5, TCC0_CH5, EXTERNAL_INT_15 },
{ PORTC, 14, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH4, TCC0_CH6, EXTERNAL_INT_14 },
{ PORTC, 11, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_11 },
{ PORTC, 10, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_10 },
// 46..53
{ PORTC, 6, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 },
{ PORTC, 7, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 },
{ PORTC, 4, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 },
{ PORTC, 5, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 },
{ PORTD, 11, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_11 }, //same as MISO
{ PORTD, 8, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_8 }, //same as MOSI
{ PORTD, 9, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH2, TCC0_CH2, EXTERNAL_INT_9 }, //same as SCK
{ PORTD, 10, PIO_TCC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_10 }, //same as SS
// 54..61 - Additional ADC
{ PORTB, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel23, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 },
{ PORTB, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel24, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 },
{ PORTB, 7, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel25, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 },
{ PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel16, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 },
{ PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel17, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 },
{ PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_TC), ADC_Channel4, PWM5_CH0, TC0_CH0, EXTERNAL_INT_4 },
{ PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_TC), ADC_Channel6, PWM6_CH0, TC1_CH0, EXTERNAL_INT_6 },
{ PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_TC), ADC_Channel7, PWM6_CH1, TC1_CH1, EXTERNAL_INT_7 },
// 62..63 - I2C pins (SDA/SCL)
// ----------------------
{ PORTB, 20, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH2, TCC1_CH2, EXTERNAL_INT_4 }, //sda
{ PORTB, 21, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH3, TCC1_CH3, EXTERNAL_INT_5 }, //scl
// 64..66 - SPI pins (ICSP:MISO,SCK,MOSI)
// ----------------------
{ PORTD, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_6 },
{ PORTD, 8, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_3 },
{ PORTD, 9, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH2, TCC0_CH2, EXTERNAL_INT_4 },
//67..74 - UARTS
{ PORTB, 16, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM3_CH0, TCC3_CH0, EXTERNAL_INT_0 },
{ PORTB, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM3_CH1, TCC3_CH1, EXTERNAL_INT_1 },
{ PORTC, 22, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_6 },
{ PORTC, 23, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_6 },
{ PORTB, 12, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TC), No_ADC_Channel, PWM9_CH0, TC4_CH0, EXTERNAL_INT_12 },
{ PORTB, 13, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TC), No_ADC_Channel, PWM9_CH1, TC4_CH1, EXTERNAL_INT_13 },
{ PORTB, 20, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH2, TCC1_CH2, EXTERNAL_INT_4 }, //same as sda
{ PORTB, 21, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TCC), No_ADC_Channel, PWM1_CH3, TCC1_CH3, EXTERNAL_INT_5 }, //same as scl
// 75..76 - RX/TX LEDS
// --------------------
{ PORTC, 31, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only
{ PORTC, 30, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only
// 77..79 - USB
// --------------------
{ PORTA, 27, PIO_COM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable
{ PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // USB/DP
// 80..83 - SD SPI pins (SD:MISO,SCK,MOSI,CS)
// ----------------------
{ PORTB, 29, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
{ PORTB, 27, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
{ PORTB, 26, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
{ PORTB, 28, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
// 84 (AREF)
{ PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // DAC/VREFP
// ----------------------
// 85..86 - Alternate use of A0 and A1 (DAC output)
{ PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT[0]
{ PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // DAC/VOUT[1]
// 87 - LED #13 duplicate placeholder
{ PORTB, 1, PIO_TC, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM_TC), No_ADC_Channel, PWM12_CH1, TC7_CH1, EXTERNAL_INT_1 },
// 88 - Internal NeoPixel
{ PORTC, 24, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only
// ----------------------
// 89 - 94 QSPI (SCK, CS, IO0, IO1, IO2, IO3)
{ PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 },
{ PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 },
{ PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI },
{ PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 },
{ PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 },
{ PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 },
} ;
const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } ;
// Multi-serial objects instantiation
SERCOM sercom0( SERCOM0 ) ;
SERCOM sercom1( SERCOM1 ) ;
SERCOM sercom2( SERCOM2 ) ;
SERCOM sercom3( SERCOM3 ) ;
SERCOM sercom4( SERCOM4 ) ;
SERCOM sercom5( SERCOM5 ) ;
SERCOM sercom6( SERCOM6 ) ;
SERCOM sercom7( SERCOM7 ) ;
Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ;
void SERCOM0_0_Handler()
{
Serial1.IrqHandler();
}
void SERCOM0_1_Handler()
{
Serial1.IrqHandler();
}
void SERCOM0_2_Handler()
{
Serial1.IrqHandler();
}
void SERCOM0_3_Handler()
{
Serial1.IrqHandler();
}

View file

@ -0,0 +1,314 @@
/*
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_METRO_M4_MEGA_
#define _VARIANT_METRO_M4_MEGA_
// The definitions here needs a SAMD core >=1.6.10
#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Frequency of the board main oscillator */
#define VARIANT_MAINOSC (32768ul)
/** Master clock frequency */
#define VARIANT_MCK (120000000ul)
#define VARIANT_GCLK0_FREQ (120000000UL)
#define VARIANT_GCLK1_FREQ (48000000UL)
#define VARIANT_GCLK2_FREQ (100000000UL)
/*----------------------------------------------------------------------------
* 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 (95u)
#define NUM_DIGITAL_PINS (20u)
#define NUM_ANALOG_INPUTS (16u)
#define NUM_ANALOG_OUTPUTS (2u)
#define analogInputToDigitalPin(p) ((p < 6u) ? (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 (75u)
#define PIN_LED_TXL (76u)
#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)
#define PIN_A8 (PIN_A0 + 8)
#define PIN_A9 (PIN_A0 + 9)
#define PIN_A10 (PIN_A0 + 10)
#define PIN_A11 (PIN_A0 + 11)
#define PIN_A12 (PIN_A0 + 12)
#define PIN_A13 (PIN_A0 + 13)
#define PIN_A14 (PIN_A0 + 14)
#define PIN_A15 (PIN_A0 + 15)
#define PIN_DAC0 PIN_A0
#define PIN_DAC1 PIN_A1
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 ;
static const uint8_t A8 = PIN_A8;
static const uint8_t A9 = PIN_A9;
static const uint8_t A10 = PIN_A10;
static const uint8_t A11 = PIN_A11;
static const uint8_t A12 = PIN_A12;
static const uint8_t A13 = PIN_A13;
static const uint8_t A14 = PIN_A14 ;
static const uint8_t A15 = PIN_A15 ;
static const uint8_t DAC0 = PIN_DAC0;
static const uint8_t DAC1 = PIN_DAC1;
#define ADC_RESOLUTION 12
// Other pins
/*
* Serial interfaces
*/
// Serial1
#define PIN_SERIAL1_RX (0ul)
#define PIN_SERIAL1_TX (1ul)
#define PAD_SERIAL1_TX (UART_TX_PAD_0)
#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1)
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 2
#define PIN_SPI_MISO (64u)
#define PIN_SPI_MOSI (66u)
#define PIN_SPI_SCK (65u)
#define PERIPH_SPI sercom7
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_3
#define SPI_HAS_DMA
#define SPI_DMA_CHANNEL_RX (DMAC_CH_NUM-2)
#define SPI_DMA_CHANNEL_TX (DMAC_CH_NUM-1)
#define PIN_SPI1_MISO (80u)
#define PIN_SPI1_MOSI (82u)
#define PIN_SPI1_SCK (81u)
#define PERIPH_SPI1 sercom2
#define PAD_SPI1_TX SPI_PAD_0_SCK_1
#define PAD_SPI1_RX SERCOM_RX_PAD_3
#define SPI1_HAS_DMA
#define SPI1_DMA_CHANNEL_RX (DMAC_CH_NUM-4)
#define SPI1_DMA_CHANNEL_TX (DMAC_CH_NUM-3)
#define DMAC_RESERVED_CHANNELS ((1UL << SPI_DMA_CHANNEL_RX) | \
(1UL << SPI_DMA_CHANNEL_TX) | \
(1UL << SPI1_DMA_CHANNEL_RX) | \
(1UL << SPI1_DMA_CHANNEL_TX) )
static const uint8_t SS = 53 ;
static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ;
static const uint8_t SS1 = 83 ;
static const uint8_t MOSI1 = PIN_SPI1_MOSI ;
static const uint8_t MISO1 = PIN_SPI1_MISO ;
static const uint8_t SCK1 = PIN_SPI1_SCK ;
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 2
#define PIN_WIRE_SDA (62u)
#define PIN_WIRE_SCL (63u)
#define PERIPH_WIRE sercom3
#define WIRE_IT_HANDLER SERCOM3_Handler
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
#define PIN_WIRE1_SDA (24u)
#define PIN_WIRE1_SCL (25u)
#define PERIPH_WIRE1 sercom6
#define WIRE1_IT_HANDLER SERCOM6_Handler
static const uint8_t SDA1 = PIN_WIRE1_SDA;
static const uint8_t SCL1 = PIN_WIRE1_SCL;
/*
* USB
*/
#define PIN_USB_HOST_ENABLE (77ul)
#define PIN_USB_DM (78ul)
#define PIN_USB_DP (79ul)
/*
* I2S Interfaces TODO:
*/
#define I2S_INTERFACES_COUNT 1
#define I2S_DEVICE 0
#define I2S_CLOCK_GENERATOR 3
#define PIN_I2S_SDO (8u)
#define PIN_I2S_SDI (1u)
#define PIN_I2S_SCK (3u)
#define PIN_I2S_FS (9u)
#define PIN_I2S_MCK (2u)
//QSPI Pins
#define PIN_QSPI_SCK (89u)
#define PIN_QSPI_CS (90u)
#define PIN_QSPI_IO0 (91u)
#define PIN_QSPI_IO1 (92u)
#define PIN_QSPI_IO2 (93u)
#define PIN_QSPI_IO3 (94u)
//PCC Pins
#define PIN_PCC_DEN1 (26u)
#define PIN_PCC_DEN2 (27u)
#define PIN_PCC_CLK (28u)
#define PIN_PCC_D0 (37u)
#define PIN_PCC_D1 (36u)
#define PIN_PCC_D2 (35u)
#define PIN_PCC_D3 (34u)
#define PIN_PCC_D4 (33u)
#define PIN_PCC_D5 (32u)
#define PIN_PCC_D6 (31u)
#define PIN_PCC_D7 (30u)
#define PIN_PCC_D8 (39u)
#define PIN_PCC_D9 (38u)
#define PIN_PCC_D10 (41u)
#define PIN_PCC_D11 (40u)
#define PIN_PCC_D12 (43u)
#define PIN_PCC_D13 (42u)
//TODO: meaningful value for this
#define VARIANT_QSPI_BAUD_DEFAULT 5000000
#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 SERCOM sercom6;
extern SERCOM sercom7;
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_METRO_M4_ */