Merge pull request #149 from tbowmo/development

Initial support for SAMD device in development branch
This commit is contained in:
Henrik Ekblad
2015-08-04 23:11:55 +02:00
27 changed files with 2733 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
# 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
mysensors_gw_native.name=Sensebender GW (Native USB Port)
mysensors_gw_native.vid.0=0x2341
mysensors_gw_native.pid.0=0x804d
mysensors_gw_native.vid.1=0x2341
mysensors_gw_native.pid.1=0x004d
mysensors_gw_native.upload.tool=bossac
mysensors_gw_native.upload.protocol=sam-ba
mysensors_gw_native.upload.maximum_size=262144
mysensors_gw_native.upload.use_1200bps_touch=true
mysensors_gw_native.upload.wait_for_upload_port=true
mysensors_gw_native.upload.native_usb=true
mysensors_gw_native.build.mcu=cortex-m0plus
mysensors_gw_native.build.f_cpu=48000000L
mysensors_gw_native.build.usb_product="Arduino Zero"
mysensors_gw_native.build.usb_manufacturer="Arduino LLC"
mysensors_gw_native.build.board=SAMD_ZERO
mysensors_gw_native.build.core=arduino:arduino
mysensors_gw_native.build.extra_flags=-D__SAMD21G18A__ {build.usb_flags}
mysensors_gw_native.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld
mysensors_gw_native.build.openocdscript=openocd_scripts/mysensors_gw.cfg
mysensors_gw_native.build.variant=mysensors_gw
mysensors_gw_native.build.variant_system_lib=
mysensors_gw_native.build.vid=0x2341
mysensors_gw_native.build.pid=0x804d
mysensors_gw_native.bootloader.tool=openocd
mysensors_gw_native.bootloader.file=zero/samd21_sam_ba.bin
@@ -0,0 +1,210 @@
/*
This sketch easily and quickly finds the right ADC correction values for a particular Arduino ZERO board.
The correction values that are found are only valid for the board where the sketch is executed.
This example code is in the public domain.
Written 6 May 2015 by Claudio Indellicati
*/
/*
How to use this sketch
1) Remove any connection cable, shield or jumper from your Arduino ZERO
2) Connect pin A1 to the nearest GND pin using the shortest jumper possible
3) Connect pin A2 to the 3.3V pin using the shortest jumper possible
4) Connect the Arduino ZERO to your PC using a USB cable plugged in the USB programming port of the board
5) Upload this sketch and leave the board powered on for at least one minute
6) Open the Serial Monitor and press the reset button on the Arduino ZERO
7) At the and of the procedure you can find logged
- the offset and gain values for the board where the sketch has been just executed
- the instruction line to copy/paste in the final sketch
*/
#include "SAMD_AnalogCorrection.h"
#define ADC_GND_PIN A1
#define ADC_3V3_PIN A2
#define ADC_READS_SHIFT 8
#define ADC_READS_COUNT (1 << ADC_READS_SHIFT)
#define ADC_MIN_GAIN 0x0400
#define ADC_UNITY_GAIN 0x0800
#define ADC_MAX_GAIN (0x1000 - 1)
#define ADC_RESOLUTION_BITS 12
#define ADC_RANGE (1 << ADC_RESOLUTION_BITS)
#define ADC_TOP_VALUE (ADC_RANGE - 1)
#define MAX_TOP_VALUE_READS 10
void setup()
{
Serial.begin(9600);
Serial.println("\r\nCalibrating ADC with factory values");
analogReadResolution(ADC_RESOLUTION_BITS);
Serial.println("\r\nReading GND and 3.3V ADC levels");
Serial.print(" ");
readGndLevel();
Serial.print(" ");
read3V3Level();
int offsetCorrectionValue = 0;
uint16_t gainCorrectionValue = ADC_UNITY_GAIN;
Serial.print("\r\nOffset correction (@gain = ");
Serial.print(gainCorrectionValue);
Serial.println(" (unity gain))");
// Set default correction values and enable correction
analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);
for (int offset = 0; offset < (int)(ADC_OFFSETCORR_MASK >> 1); ++offset)
{
analogReadCorrection(offset, gainCorrectionValue);
Serial.print(" Offset = ");
Serial.print(offset);
Serial.print(", ");
if (readGndLevel() == 0)
{
offsetCorrectionValue = offset;
break;
}
}
Serial.println("\r\nGain correction");
uint8_t topValueReadsCount = 0U;
uint16_t minGain = 0U,
maxGain = 0U;
analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);
Serial.print(" Gain = ");
Serial.print(gainCorrectionValue);
Serial.print(", ");
uint16_t highLevelRead = read3V3Level();
if (highLevelRead < ADC_TOP_VALUE)
{
for (uint16_t gain = ADC_UNITY_GAIN + 1; gain <= ADC_MAX_GAIN; ++gain)
{
analogReadCorrection(offsetCorrectionValue, gain);
Serial.print(" Gain = ");
Serial.print(gain);
Serial.print(", ");
highLevelRead = read3V3Level();
if (highLevelRead == ADC_TOP_VALUE)
{
if (minGain == 0U)
minGain = gain;
if (++topValueReadsCount >= MAX_TOP_VALUE_READS)
{
maxGain = minGain;
break;
}
maxGain = gain;
}
if (highLevelRead > ADC_TOP_VALUE)
break;
}
}
else if (highLevelRead >= ADC_TOP_VALUE)
{
if (highLevelRead == ADC_TOP_VALUE)
maxGain = ADC_UNITY_GAIN;
for (uint16_t gain = ADC_UNITY_GAIN - 1; gain >= ADC_MIN_GAIN; --gain)
{
analogReadCorrection(offsetCorrectionValue, gain);
Serial.print(" Gain = ");
Serial.print(gain);
Serial.print(", ");
highLevelRead = read3V3Level();
if (highLevelRead == ADC_TOP_VALUE)
{
if (maxGain == 0U)
maxGain = gain;
minGain = gain;
}
if (highLevelRead < ADC_TOP_VALUE)
break;
}
}
gainCorrectionValue = (minGain + maxGain) >> 1;
analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);
Serial.println("\r\nReadings after corrections");
Serial.print(" ");
readGndLevel();
Serial.print(" ");
read3V3Level();
Serial.println("\r\n==================");
Serial.println("\r\nCorrection values:");
Serial.print(" Offset = ");
Serial.println(offsetCorrectionValue);
Serial.print(" Gain = ");
Serial.println(gainCorrectionValue);
Serial.println("\r\nAdd the next line to your sketch:");
Serial.print(" analogReadCorrection(");
Serial.print(offsetCorrectionValue);
Serial.print(", ");
Serial.print(gainCorrectionValue);
Serial.println(");");
Serial.println("\r\n==================");
}
void loop()
{
}
uint16_t readGndLevel()
{
uint32_t readAccumulator = 0;
for (int i = 0; i < ADC_READS_COUNT; ++i)
readAccumulator += analogRead(ADC_GND_PIN);
uint16_t readValue = readAccumulator >> ADC_READS_SHIFT;
Serial.print("ADC(GND) = ");
Serial.println(readValue);
return readValue;
}
uint16_t read3V3Level()
{
uint32_t readAccumulator = 0;
for (int i = 0; i < ADC_READS_COUNT; ++i)
readAccumulator += analogRead(ADC_3V3_PIN);
uint16_t readValue = readAccumulator >> ADC_READS_SHIFT;
if (readValue < (ADC_RANGE >> 1))
readValue += ADC_RANGE;
Serial.print("ADC(3.3V) = ");
Serial.println(readValue);
return readValue;
}
@@ -0,0 +1,8 @@
name=SAMD_AnalogCorrection
version=1.0
author=Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Sets and enables the digital correction logic of the SAMD ADC.
paragraph=Useful to correct the values returned by the ADC.
url=
architectures=samd
@@ -0,0 +1,31 @@
/*
Copyright (c) 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 "SAMD_AnalogCorrection.h"
void analogReadCorrection (int offset, uint16_t gain)
{
// Set correction values
ADC->OFFSETCORR.reg = ADC_OFFSETCORR_OFFSETCORR(offset);
ADC->GAINCORR.reg = ADC_GAINCORR_GAINCORR(gain);
// Enable digital correction logic
ADC->CTRLB.bit.CORREN = 1;
while(ADC->STATUS.bit.SYNCBUSY);
}
@@ -0,0 +1,24 @@
/*
Copyright (c) 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
*/
#pragma once
#include <Arduino.h>
void analogReadCorrection (int offset, uint16_t gain);
@@ -0,0 +1,200 @@
/*
* SPI Master library for Arduino Zero.
* Copyright (c) 2015 Arduino LLC
*
* 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 "SPI.h"
#include <Arduino.h>
#include <wiring_private.h>
#include <assert.h>
#define SPI_IMODE_NONE 0
#define SPI_IMODE_EXTINT 1
#define SPI_IMODE_GLOBAL 2
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
{
initialized = false;
assert(p_sercom != NULL);
_p_sercom = p_sercom;
_uc_pinMiso = uc_pinMISO;
_uc_pinSCK = uc_pinSCK;
_uc_pinMosi = uc_pinMOSI;
}
void SPIClass::begin()
{
init();
// PIO init
pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
config(DEFAULT_SPI_SETTINGS);
}
void SPIClass::init()
{
if (initialized)
return;
interruptMode = SPI_IMODE_NONE;
interruptSave = 0;
interruptMask = 0;
initialized = true;
}
void SPIClass::config(SPISettings settings)
{
_p_sercom->disableSPI();
_p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, settings.bitOrder);
_p_sercom->initSPIClock(settings.dataMode, settings.clockFreq);
_p_sercom->enableSPI();
}
void SPIClass::end()
{
_p_sercom->resetSPI();
initialized = false;
}
#ifndef interruptsStatus
#define interruptsStatus() __interruptsStatus()
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void)
{
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html
return (__get_PRIMASK() ? 0 : 1);
}
#endif
void SPIClass::usingInterrupt(int interruptNumber)
{
if ((interruptNumber == NOT_AN_INTERRUPT) || (interruptNumber == EXTERNAL_INT_NMI))
return;
uint8_t irestore = interruptsStatus();
noInterrupts();
if (interruptNumber >= EXTERNAL_NUM_INTERRUPTS)
interruptMode = SPI_IMODE_GLOBAL;
else
{
interruptMode |= SPI_IMODE_EXTINT;
interruptMask |= (1 << interruptNumber);
}
if (irestore)
interrupts();
}
void SPIClass::beginTransaction(SPISettings settings)
{
if (interruptMode != SPI_IMODE_NONE)
{
if (interruptMode & SPI_IMODE_GLOBAL)
{
interruptSave = interruptsStatus();
noInterrupts();
}
else if (interruptMode & SPI_IMODE_EXTINT)
EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT(interruptMask);
}
config(settings);
}
void SPIClass::endTransaction(void)
{
if (interruptMode != SPI_IMODE_NONE)
{
if (interruptMode & SPI_IMODE_GLOBAL)
{
if (interruptSave)
interrupts();
}
else if (interruptMode & SPI_IMODE_EXTINT)
EIC->INTENSET.reg = EIC_INTENSET_EXTINT(interruptMask);
}
}
void SPIClass::setBitOrder(BitOrder order)
{
if (order == LSBFIRST) {
_p_sercom->setDataOrderSPI(LSB_FIRST);
} else {
_p_sercom->setDataOrderSPI(MSB_FIRST);
}
}
void SPIClass::setDataMode(uint8_t mode)
{
switch (mode)
{
case SPI_MODE0:
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_0);
break;
case SPI_MODE1:
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_1);
break;
case SPI_MODE2:
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_2);
break;
case SPI_MODE3:
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_3);
break;
default:
break;
}
}
void SPIClass::setClockDivider(uint8_t div)
{
if (div < SPI_MIN_CLOCK_DIVIDER) {
_p_sercom->setBaudrateSPI(SPI_MIN_CLOCK_DIVIDER);
} else {
_p_sercom->setBaudrateSPI(div);
}
}
byte SPIClass::transfer(uint8_t data)
{
// Writing the data
_p_sercom->writeDataSPI(data);
// Read data
return _p_sercom->readDataSPI() & 0xFF;
}
void SPIClass::attachInterrupt() {
// Should be enableInterrupt()
}
void SPIClass::detachInterrupt() {
// Should be disableInterrupt()
}
SPIClass SPI( &sercom4, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI );
+153
View File
@@ -0,0 +1,153 @@
/*
* SPI Master library for Arduino Zero.
* Copyright (c) 2015 Arduino LLC
*
* 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 _SPI_H_INCLUDED
#define _SPI_H_INCLUDED
#include <Arduino.h>
// SPI_HAS_TRANSACTION means SPI has
// - beginTransaction()
// - endTransaction()
// - usingInterrupt()
// - SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1
#define SPI_MODE0 0x02
#define SPI_MODE1 0x00
#define SPI_MODE2 0x03
#define SPI_MODE3 0x01
#if defined(__SAMD21G18A__)
// 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
#define SPI_MIN_CLOCK_DIVIDER 4
// Other SAMD21xxxxx MCU may be affected as well
#else
#define SPI_MIN_CLOCK_DIVIDER 2
#endif
class SPISettings {
public:
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
}
// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
private:
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
this->clockFreq = (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER) ? F_CPU / SPI_MIN_CLOCK_DIVIDER : clock);
this->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST);
switch (dataMode)
{
case SPI_MODE0:
this->dataMode = SERCOM_SPI_MODE_0; break;
case SPI_MODE1:
this->dataMode = SERCOM_SPI_MODE_1; break;
case SPI_MODE2:
this->dataMode = SERCOM_SPI_MODE_2; break;
case SPI_MODE3:
this->dataMode = SERCOM_SPI_MODE_3; break;
default:
this->dataMode = SERCOM_SPI_MODE_0; break;
}
}
uint32_t clockFreq;
SercomSpiClockMode dataMode;
SercomDataOrder bitOrder;
friend class SPIClass;
};
class SPIClass {
public:
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI);
byte transfer(uint8_t data);
inline void transfer(void *buf, size_t count);
// Transaction Functions
void usingInterrupt(int interruptNumber);
void beginTransaction(SPISettings settings);
void endTransaction(void);
// SPI Configuration methods
void attachInterrupt();
void detachInterrupt();
void begin();
void end();
void setBitOrder(BitOrder order);
void setDataMode(uint8_t uc_mode);
void setClockDivider(uint8_t uc_div);
private:
void init();
void config(SPISettings settings);
SERCOM *_p_sercom;
uint8_t _uc_pinMiso;
uint8_t _uc_pinMosi;
uint8_t _uc_pinSCK;
bool initialized;
uint8_t interruptMode;
char interruptSave;
uint32_t interruptMask;
};
void SPIClass::transfer(void *buf, size_t count)
{
// TODO: Optimize for faster block-transfer
uint8_t *buffer = reinterpret_cast<uint8_t *>(buf);
for (size_t i=0; i<count; i++)
buffer[i] = transfer(buffer[i]);
}
#if SPI_INTERFACES_COUNT > 0
extern SPIClass SPI;
#endif
// For compatibility with sketches designed for AVR @ 16 MHz
// New programs should use SPI.beginTransaction to set the SPI clock
#if F_CPU == 48000000
#define SPI_CLOCK_DIV2 6
#define SPI_CLOCK_DIV4 12
#define SPI_CLOCK_DIV8 24
#define SPI_CLOCK_DIV16 48
#define SPI_CLOCK_DIV32 96
#define SPI_CLOCK_DIV64 192
#define SPI_CLOCK_DIV128 255
#endif
#endif
@@ -0,0 +1,143 @@
/*
SCP1000 Barometric Pressure Sensor Display
Shows the output of a Barometric Pressure Sensor on a
Uses the SPI library. For details on the sensor, see:
http://www.sparkfun.com/commerce/product_info.php?products_id=8161
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
Circuit:
SCP1000 sensor attached to pins 6, 7, 10 - 13:
DRDY: pin 6
CSB: pin 7
MOSI: pin 11
MISO: pin 12
SCK: pin 13
created 31 July 2010
modified 14 August 2010
by Tom Igoe
*/
// the sensor communicates using SPI, so include the library:
#include <SPI.h>
//Sensor's memory register addresses:
const int PRESSURE = 0x1F; //3 most significant bits of pressure
const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure
const int TEMPERATURE = 0x21; //16 bit temperature reading
const byte READ = 0b11111100; // SCP1000's read command
const byte WRITE = 0b00000010; // SCP1000's write command
// pins used for the connection with the sensor
// the other you need are controlled by the SPI library):
const int dataReadyPin = 6;
const int chipSelectPin = 7;
void setup() {
Serial.begin(9600);
// start the SPI library:
SPI.begin();
// initalize the data ready and chip select pins:
pinMode(dataReadyPin, INPUT);
pinMode(chipSelectPin, OUTPUT);
//Configure SCP1000 for low noise configuration:
writeRegister(0x02, 0x2D);
writeRegister(0x01, 0x03);
writeRegister(0x03, 0x02);
// give the sensor time to set up:
delay(100);
}
void loop() {
//Select High Resolution Mode
writeRegister(0x03, 0x0A);
// don't do anything until the data ready pin is high:
if (digitalRead(dataReadyPin) == HIGH) {
//Read the temperature data
int tempData = readRegister(0x21, 2);
// convert the temperature to celsius and display it:
float realTemp = (float)tempData / 20.0;
Serial.print("Temp[C]=");
Serial.print(realTemp);
//Read the pressure data highest 3 bits:
byte pressure_data_high = readRegister(0x1F, 1);
pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
//Read the pressure data lower 16 bits:
unsigned int pressure_data_low = readRegister(0x20, 2);
//combine the two parts into one 19-bit number:
long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
// display the temperature:
Serial.println("\tPressure [Pa]=" + String(pressure));
}
}
//Read from or write to register from the SCP1000:
unsigned int readRegister(byte thisRegister, int bytesToRead ) {
byte inByte = 0; // incoming byte from the SPI
unsigned int result = 0; // result to return
Serial.print(thisRegister, BIN);
Serial.print("\t");
// SCP1000 expects the register name in the upper 6 bits
// of the byte. So shift the bits left by two bits:
thisRegister = thisRegister << 2;
// now combine the address and the command into one byte
byte dataToSend = thisRegister & READ;
Serial.println(thisRegister, BIN);
// take the chip select low to select the device:
digitalWrite(chipSelectPin, LOW);
// send the device the register you want to read:
SPI.transfer(dataToSend);
// send a value of 0 to read the first byte returned:
result = SPI.transfer(0x00);
// decrement the number of bytes left to read:
bytesToRead--;
// if you still have another byte to read:
if (bytesToRead > 0) {
// shift the first byte left, then get the second byte:
result = result << 8;
inByte = SPI.transfer(0x00);
// combine the byte you just got with the previous one:
result = result | inByte;
// decrement the number of bytes left to read:
bytesToRead--;
}
// take the chip select high to de-select:
digitalWrite(chipSelectPin, HIGH);
// return the result:
return(result);
}
//Sends a write command to SCP1000
void writeRegister(byte thisRegister, byte thisValue) {
// SCP1000 expects the register address in the upper 6 bits
// of the byte. So shift the bits left by two bits:
thisRegister = thisRegister << 2;
// now combine the register address and the command into one byte:
byte dataToSend = thisRegister | WRITE;
// take the chip select low to select the device:
digitalWrite(chipSelectPin, LOW);
SPI.transfer(dataToSend); //Send register location
SPI.transfer(thisValue); //Send value to record into register
// take the chip select high to de-select:
digitalWrite(chipSelectPin, HIGH);
}
@@ -0,0 +1,71 @@
/*
Digital Pot Control
This example controls an Analog Devices AD5206 digital potentiometer.
The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
A - connect this to voltage
W - this is the pot's wiper, which changes when you set it
B - connect this to ground.
The AD5206 is SPI-compatible,and to command it, you send two bytes,
one with the channel number (0 - 5) and one with the resistance value for the
channel (0 - 255).
The circuit:
* All A pins of AD5206 connected to +5V
* All B pins of AD5206 connected to ground
* An LED and a 220-ohm resisor in series connected from each W pin to ground
* CS - to digital pin 10 (SS pin)
* SDI - to digital pin 11 (MOSI pin)
* CLK - to digital pin 13 (SCK pin)
created 10 Aug 2010
by Tom Igoe
Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
*/
// inslude the SPI library:
#include <SPI.h>
// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 10;
void setup() {
// set the slaveSelectPin as an output:
pinMode (slaveSelectPin, OUTPUT);
// initialize SPI:
SPI.begin();
}
void loop() {
// go through the six channels of the digital pot:
for (int channel = 0; channel < 6; channel++) {
// change the resistance on this channel from min to max:
for (int level = 0; level < 255; level++) {
digitalPotWrite(channel, level);
delay(10);
}
// wait a second at the top:
delay(100);
// change the resistance on this channel from max to min:
for (int level = 0; level < 255; level++) {
digitalPotWrite(channel, 255 - level);
delay(10);
}
}
}
void digitalPotWrite(int address, int value) {
// take the SS pin low to select the chip:
digitalWrite(slaveSelectPin, LOW);
// send in the address and value via SPI:
SPI.transfer(address);
SPI.transfer(value);
// take the SS pin high to de-select the chip:
digitalWrite(slaveSelectPin, HIGH);
}
@@ -0,0 +1,31 @@
#######################################
# Syntax Coloring Map SPI
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SPI KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
transfer KEYWORD2
#setBitOrder KEYWORD2
setDataMode KEYWORD2
setClockDivider KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
SPI_MODE0 LITERAL1
SPI_MODE1 LITERAL1
SPI_MODE2 LITERAL1
SPI_MODE3 LITERAL1
SPI_CONTINUE LITERAL1
SPI_LAST LITERAL1
@@ -0,0 +1,355 @@
/*
* TWI/I2C library for Arduino Zero
* Copyright (c) 2015 Arduino LLC. All rights 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
*/
extern "C" {
#include <string.h>
}
#include <Arduino.h>
#include <wiring_private.h>
#include "Wire.h"
TwoWire::TwoWire(SERCOM * s)
{
this->sercom = s;
transmissionBegun = false;
}
void TwoWire::begin(void) {
//Master Mode
sercom->initMasterWIRE(TWI_CLOCK);
sercom->enableWIRE();
pinPeripheral(PIN_WIRE_SDA, g_APinDescription[PIN_WIRE_SDA].ulPinType);
pinPeripheral(PIN_WIRE_SCL, g_APinDescription[PIN_WIRE_SCL].ulPinType);
}
void TwoWire::begin(uint8_t address) {
//Slave mode
sercom->initSlaveWIRE(address);
sercom->enableWIRE();
}
void TwoWire::setClock(uint32_t frequency) {
// dummy funtion
}
uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit)
{
if(quantity == 0)
{
return 0;
}
size_t byteRead = 0;
if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG))
{
// Read first data
rxBuffer.store_char(sercom->readDataWIRE());
// Connected to slave
//while(toRead--)
for(byteRead = 0; byteRead < quantity; ++byteRead)
{
if( byteRead == quantity - 1) // Stop transmission
{
sercom->prepareNackBitWIRE(); // Prepare NACK to stop slave transmission
//sercom->readDataWIRE(); // Clear data register to send NACK
sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); // Send Stop
}
else // Continue transmission
{
sercom->prepareAckBitWIRE(); // Prepare Acknowledge
sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_READ); // Prepare the ACK command for the slave
rxBuffer.store_char( sercom->readDataWIRE() ); // Read data and send the ACK
}
}
}
return byteRead;
}
uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity)
{
return requestFrom(address, quantity, true);
}
void TwoWire::beginTransmission(uint8_t address) {
// save address of target and clear buffer
txAddress = address;
txBuffer.clear();
transmissionBegun = true;
}
// Errors:
// 0 : Success
// 1 : Data too long
// 2 : NACK on transmit of address
// 3 : NACK on transmit of data
// 4 : Other error
uint8_t TwoWire::endTransmission(bool stopBit)
{
transmissionBegun = false ;
// Check if there are data to send
if ( txBuffer.available() == 0)
{
return 4 ;
}
// Start I2C transmission
if ( !sercom->startTransmissionWIRE( txAddress, WIRE_WRITE_FLAG ) )
{
sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
return 2 ; // Address error
}
// Send all buffer
while( txBuffer.available() )
{
// Trying to send data
if ( !sercom->sendDataMasterWIRE( txBuffer.read_char() ) )
{
sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
return 3 ; // Nack or error
}
if(txBuffer.available() == 0)
{
sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
}
}
return 0;
}
uint8_t TwoWire::endTransmission()
{
return endTransmission(true);
}
size_t TwoWire::write(uint8_t ucData)
{
if(sercom->isMasterWIRE())
{
// No writing, without begun transmission or a full buffer
if ( !transmissionBegun || txBuffer.isFull() )
{
return 0 ;
}
txBuffer.store_char( ucData ) ;
return 1 ;
}
else
{
if(sercom->sendDataSlaveWIRE( ucData ))
{
return 1;
}
}
return 0;
}
size_t TwoWire::write(const uint8_t *data, size_t quantity)
{
//Try to store all data
for(size_t i = 0; i < quantity; ++i)
{
//Return the number of data stored, when the buffer is full (if write return 0)
if(!write(data[i]))
return i;
}
//All data stored
return quantity;
}
int TwoWire::available(void)
{
return rxBuffer.available();
}
int TwoWire::read(void)
{
return rxBuffer.read_char();
}
int TwoWire::peek(void)
{
return rxBuffer.peek();
}
void TwoWire::flush(void)
{
// Do nothing, use endTransmission(..) to force
// data transfer.
}
void TwoWire::onReceive(void(*function)(int))
{
onReceiveCallback = function;
}
void TwoWire::onRequest(void(*function)(void))
{
onRequestCallback = function;
}
void TwoWire::onService(void)
{
if ( sercom->isSlaveWIRE() )
{
//Received data
if(sercom->isDataReadyWIRE())
{
//Store data
rxBuffer.store_char(sercom->readDataWIRE());
//Stop or Restart detected
if(sercom->isStopDetectedWIRE() || sercom->isRestartDetectedWIRE())
{
//Calling onReceiveCallback, if exists
if(onReceiveCallback)
{
onReceiveCallback(available());
}
}
}
//Address Match
if(sercom->isAddressMatch())
{
//Is a request ?
if(sercom->isMasterReadOperationWIRE())
{
//Calling onRequestCallback, if exists
if(onRequestCallback)
{
onRequestCallback();
}
}
}
}
}
/*
void TwoWire::onService(void)
{
// Retrieve interrupt status
uint32_t sr = TWI_GetStatus(twi);
if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) {
TWI_DisableIt(twi, TWI_IDR_SVACC);
TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK
| TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP);
srvBufferLength = 0;
srvBufferIndex = 0;
// Detect if we should go into RECV or SEND status
// SVREAD==1 means *master* reading -> SLAVE_SEND
if (!TWI_STATUS_SVREAD(sr)) {
status = SLAVE_RECV;
} else {
status = SLAVE_SEND;
// Alert calling program to generate a response ASAP
if (onRequestCallback)
onRequestCallback();
else
// create a default 1-byte response
write((uint8_t) 0);
}
}
if (status != SLAVE_IDLE) {
if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) {
if (status == SLAVE_RECV && onReceiveCallback) {
// Copy data into rxBuffer
// (allows to receive another packet while the
// user program reads actual data)
for (uint8_t i = 0; i < srvBufferLength; ++i)
rxBuffer[i] = srvBuffer[i];
rxBufferIndex = 0;
rxBufferLength = srvBufferLength;
// Alert calling program
onReceiveCallback( rxBufferLength);
}
// Transfer completed
TWI_EnableIt(twi, TWI_SR_SVACC);
TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
| TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
status = SLAVE_IDLE;
}
}
if (status == SLAVE_RECV) {
if (TWI_STATUS_RXRDY(sr)) {
if (srvBufferLength < BUFFER_LENGTH)
srvBuffer[srvBufferLength++] = TWI_ReadByte(twi);
}
}
if (status == SLAVE_SEND) {
if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
uint8_t c = 'x';
if (srvBufferIndex < srvBufferLength)
c = srvBuffer[srvBufferIndex++];
TWI_WriteByte(twi, c);
}
}
}
*/
#if WIRE_INTERFACES_COUNT > 0
/*static void Wire_Init(void) {
pmc_enable_periph_clk(WIRE_INTERFACE_ID);
PIO_Configure(
g_APinDescription[PIN_WIRE_SDA].pPort,
g_APinDescription[PIN_WIRE_SDA].ulPinType,
g_APinDescription[PIN_WIRE_SDA].ulPin,
g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
PIO_Configure(
g_APinDescription[PIN_WIRE_SCL].pPort,
g_APinDescription[PIN_WIRE_SCL].ulPinType,
g_APinDescription[PIN_WIRE_SCL].ulPin,
g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);
NVIC_DisableIRQ(WIRE_ISR_ID);
NVIC_ClearPendingIRQ(WIRE_ISR_ID);
NVIC_SetPriority(WIRE_ISR_ID, 0);
NVIC_EnableIRQ(WIRE_ISR_ID);
}*/
TwoWire Wire(&sercom3);
void SERCOM3_Handler(void) {
Wire.onService();
}
#endif
@@ -0,0 +1,104 @@
/*
* TWI/I2C library for Arduino Zero
* Copyright (c) 2015 Arduino LLC. All rights 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 TwoWire_h
#define TwoWire_h
#include "Stream.h"
#include "variant.h"
#include "SERCOM.h"
#include "RingBuffer.h"
#define BUFFER_LENGTH 32
class TwoWire : public Stream
{
public:
TwoWire(SERCOM *s);
void begin();
void begin(uint8_t);
void setClock(uint32_t); // dummy function
void beginTransmission(uint8_t);
uint8_t endTransmission(bool stopBit);
uint8_t endTransmission(void);
uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit);
uint8_t requestFrom(uint8_t address, size_t quantity);
size_t write(uint8_t data);
size_t write(const uint8_t * data, size_t quantity);
virtual int available(void);
virtual int read(void);
virtual int peek(void);
virtual void flush(void);
void onReceive(void(*)(int));
void onRequest(void(*)(void));
using Print::write;
void onService(void);
private:
SERCOM * sercom;
bool transmissionBegun;
// RX Buffer
RingBuffer rxBuffer;
//TX buffer
RingBuffer txBuffer;
uint8_t txAddress;
// Service buffer
//uint8_t srvBuffer[BUFFER_LENGTH];
//uint8_t srvBufferIndex;
//uint8_t srvBufferLength;
// Callback user functions
void (*onRequestCallback)(void);
void (*onReceiveCallback)(int);
// TWI state
//enum TwoWireStatus
//{
// UNINITIALIZED,
// MASTER_IDLE,
// MASTER_SEND,
// MASTER_RECV,
// SLAVE_IDLE,
// SLAVE_RECV,
// SLAVE_SEND
//};
//TwoWireStatus status;
// TWI clock frequency
static const uint32_t TWI_CLOCK = 100000;
// Timeouts
//static const uint32_t RECV_TIMEOUT = 100000;
//static const uint32_t XMIT_TIMEOUT = 100000;
};
extern TwoWire Wire;
#endif
@@ -0,0 +1,87 @@
// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder
// by Nicholas Zambetti <http://www.zambetti.com>
// and James Tichenor <http://www.jamestichenor.net>
// Demonstrates use of the Wire library reading data from the
// Devantech Utrasonic Rangers SFR08 and SFR10
// Created 29 April 2006
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial communication at 9600bps
}
int reading = 0;
void loop()
{
// step 1: instruct sensor to read echoes
Wire.beginTransmission(112); // transmit to device #112 (0x70)
// the address specified in the datasheet is 224 (0xE0)
// but i2c adressing uses the high 7 bits so it's 112
Wire.write(byte(0x00)); // sets register pointer to the command register (0x00)
Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50)
// use 0x51 for centimeters
// use 0x52 for ping microseconds
Wire.endTransmission(); // stop transmitting
// step 2: wait for readings to happen
delay(70); // datasheet suggests at least 65 milliseconds
// step 3: instruct sensor to return a particular echo reading
Wire.beginTransmission(112); // transmit to device #112
Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02)
Wire.endTransmission(); // stop transmitting
// step 4: request reading from sensor
Wire.requestFrom(112, 2); // request 2 bytes from slave device #112
// step 5: receive reading from sensor
if(2 <= Wire.available()) // if two bytes were received
{
reading = Wire.read(); // receive high byte (overwrites previous reading)
reading = reading << 8; // shift high byte to be high 8 bits
reading |= Wire.read(); // receive low byte as lower 8 bits
Serial.println(reading); // print the reading
}
delay(250); // wait a bit since people have to read the output :)
}
/*
// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08)
// usage: changeAddress(0x70, 0xE6);
void changeAddress(byte oldAddress, byte newAddress)
{
Wire.beginTransmission(oldAddress);
Wire.write(byte(0x00));
Wire.write(byte(0xA0));
Wire.endTransmission();
Wire.beginTransmission(oldAddress);
Wire.write(byte(0x00));
Wire.write(byte(0xAA));
Wire.endTransmission();
Wire.beginTransmission(oldAddress);
Wire.write(byte(0x00));
Wire.write(byte(0xA5));
Wire.endTransmission();
Wire.beginTransmission(oldAddress);
Wire.write(byte(0x00));
Wire.write(newAddress);
Wire.endTransmission();
}
*/
@@ -0,0 +1,39 @@
// I2C Digital Potentiometer
// by Nicholas Zambetti <http://www.zambetti.com>
// and Shawn Bonkowski <http://people.interaction-ivrea.it/s.bonkowski/>
// Demonstrates use of the Wire library
// Controls AD5171 digital potentiometer via I2C/TWI
// Created 31 March 2006
// This example code is in the public domain.
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
}
byte val = 0;
void loop()
{
Wire.beginTransmission(44); // transmit to device #44 (0x2c)
// device address is specified in datasheet
Wire.write(byte(0x00)); // sends instruction byte
Wire.write(val); // sends potentiometer value byte
Wire.endTransmission(); // stop transmitting
val++; // increment value
if(val == 64) // if reached 64th position (max)
{
val = 0; // start over from lowest value
}
delay(500);
}
@@ -0,0 +1,32 @@
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop()
{
Wire.requestFrom(2, 6); // request 6 bytes from slave device #2
while(Wire.available()) // slave may send less than requested
{
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
delay(500);
}
@@ -0,0 +1,31 @@
// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
}
byte x = 0;
void loop()
{
Wire.beginTransmission(4); // transmit to device #4
Wire.write("x is "); // sends five bytes
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting
x++;
delay(500);
}
@@ -0,0 +1,38 @@
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop()
{
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
@@ -0,0 +1,32 @@
// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(2); // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
}
void loop()
{
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
Wire.write("hello "); // respond with message of 6 bytes
// as expected by master
}
@@ -0,0 +1,32 @@
#######################################
# Syntax Coloring Map For Wire
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
beginTransmission KEYWORD2
endTransmission KEYWORD2
requestFrom KEYWORD2
send KEYWORD2
receive KEYWORD2
onReceive KEYWORD2
onRequest KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
Wire KEYWORD2
Wire1 KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
+143
View File
@@ -0,0 +1,143 @@
# 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
# Arduino SAMD Core and platform.
#
# For more info:
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
name=Mysensors SAMD (32-bits ARM Cortex-M0+) Boards
version=1.0.0
# Compile variables
# -----------------
compiler.warning_flags=-w
compiler.warning_flags.none=-w
compiler.warning_flags.default=
compiler.warning_flags.more=-Wall
compiler.warning_flags.all=-Wall -Wextra
compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
compiler.c.cmd=arm-none-eabi-gcc
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD
compiler.c.elf.cmd=arm-none-eabi-gcc
compiler.c.elf.flags=-Os -Wl,--gc-sections -save-temps
compiler.S.cmd=arm-none-eabi-gcc
compiler.S.flags=-c -g -x assembler-with-cpp
compiler.cpp.cmd=arm-none-eabi-g++
compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD
compiler.ar.cmd=arm-none-eabi-ar
compiler.ar.flags=rcs
compiler.objcopy.cmd=arm-none-eabi-objcopy
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
compiler.elf2hex.flags=-O binary
compiler.elf2hex.cmd=arm-none-eabi-objcopy
compiler.ldflags=-mcpu={build.mcu} -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align
compiler.size.cmd=arm-none-eabi-size
compiler.define=-DARDUINO=
# this can be overriden in boards.txt
build.extra_flags=
# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
#compiler.c.elf.extra_flags=-v
compiler.cpp.extra_flags=
compiler.S.extra_flags=
compiler.ar.extra_flags=
compiler.elf2hex.extra_flags=
compiler.arm.cmsis.path="-I{runtime.tools.CMSIS.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS.path}/Device/ATMEL/"
# USB Flags
# ---------
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
# Default usb manufacturer will be replaced at compile time using
# numeric vendor ID if available or by board's specific value.
build.usb_manufacturer="Unknown"
# Compile patterns
# ----------------
## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.arm.cmsis.path} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {compiler.arm.cmsis.path} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {compiler.arm.cmsis.path} {includes} "{source_file}" -o "{object_file}"
## Create archives
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}"
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group -lm "{build.path}/{archive_file}" -Wl,--end-group
## Create output (bin file)
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
## Save hex
recipe.output.tmp_file={build.project_name}.bin
recipe.output.save_file={build.project_name}.{build.variant}.bin
## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=\.text\s+([0-9]+).*
# Uploader tools
# --------------
#
# BOSSA
#
tools.bossac.path={runtime.tools.bossac-1.6-arduino.path}
tools.bossac.cmd=bossac
tools.bossac.cmd.windows=bossac.exe
tools.bossac.upload.params.verbose=-i -d
tools.bossac.upload.params.quiet=
tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -i -e -w -v "{build.path}/{build.project_name}.bin" -R
#
# OpenOCD sketch upload
#
tools.openocd.path={runtime.tools.openocd.path}
tools.openocd.cmd=bin/openocd
tools.openocd.cmd.windows=bin/openocd.exe
tools.openocd.upload.params.verbose=-d2
tools.openocd.upload.params.quiet=-d0
tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.bin}} verify reset 0x00002000; shutdown"
tools.openocd.program.params.verbose=-d2
tools.openocd.program.params.quiet=-d0
tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.elf}} verify reset; shutdown"
tools.openocd.erase.params.verbose=-d3
tools.openocd.erase.params.quiet=-d0
tools.openocd.erase.pattern=
tools.openocd.bootloader.params.verbose=-d2
tools.openocd.bootloader.params.quiet=-d0
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{{runtime.platform.path}/bootloaders/{bootloader.file}}} verify reset; shutdown"
@@ -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"
@@ -0,0 +1,211 @@
/*
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 :
{
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(4);
/* 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")
}
@@ -0,0 +1,212 @@
/*
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 :
{
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(4);
/* 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")
}
@@ -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]
@@ -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"
@@ -0,0 +1,221 @@
/*
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
*/
/*
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* + Pin number + ZERO Board pin | PIN | Label/Name | Comments (* is for default peripheral in use)
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | Digital Low | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 0 | 0 -> RX | PA11 | | EIC/EXTINT[11] ADC/AIN[19] PTC/X[3] *SERCOM0/PAD[3] SERCOM2/PAD[3] TCC0/WO[3] TCC1/WO[1]
* | 1 | 1 <- TX | PA10 | | EIC/EXTINT[10] ADC/AIN[18] PTC/X[2] *SERCOM0/PAD[2] TCC0/WO[2] TCC1/WO[0]
* | 2 | 2 | PA14 | | EIC/EXTINT[14] SERCOM2/PAD[2] SERCOM4/PAD[2] TC3/WO[0] TCC0/WO[4]
* | 3 | ~3 | PA09 | | EIC/EXTINT[9] ADC/AIN[17] PTC/X[1] SERCOM0/PAD[1] SERCOM2/PAD[1] *TCC0/WO[1] TCC1/WO[3]
* | 4 | ~4 | PA08 | | EIC/NMI ADC/AIN[16] PTC/X[0] SERCOM0/PAD[0] SERCOM2/PAD[0] *TCC0/WO[0] TCC1/WO[2]
* | 5 | ~5 | PA15 | | EIC/EXTINT[15] SERCOM2/PAD[3] SERCOM4/PAD[3] *TC3/WO[1] TCC0/WO[5]
* | 6 | ~6 | PA20 | | EIC/EXTINT[4] PTC/X[8] SERCOM5/PAD[2] SERCOM3/PAD[2] *TCC0/WO[6]
* | 7 | 7 | PA21 | | EIC/EXTINT[5] PTC/X[9] SERCOM5/PAD[3] SERCOM3/PAD[3] TCC0/WO[7]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | Digital High | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 8 | ~8 | PA06 | | EIC/EXTINT[6] ADC/AIN[6] AC/AIN[2] PTC/Y[4] SERCOM0/PAD[2] *TCC1/WO[0]
* | 9 | ~9 | PA07 | | EIC/EXTINT[7] ADC/AIN[7] AC/AIN[3] PTC/Y[5] SERCOM0/PAD[3] *TCC1/WO[1]
* | 10 | ~10 | PA18 | | EIC/EXTINT[2] PTC/X[6] +SERCOM1/PAD[2] SERCOM3/PAD[2] *TC3/WO[0] TCC0/WO[2]
* | 11 | ~11 | PA16 | | EIC/EXTINT[0] PTC/X[4] +SERCOM1/PAD[0] SERCOM3/PAD[0] *TCC2/WO[0] TCC0/WO[6]
* | 12 | ~12 | PA19 | | EIC/EXTINT[3] PTC/X[7] +SERCOM1/PAD[3] SERCOM3/PAD[3] TC3/WO[1] *TCC0/WO[3]
* | 13 | ~13 | PA17 | LED | EIC/EXTINT[1] PTC/X[5] +SERCOM1/PAD[1] SERCOM3/PAD[1] *TCC2/WO[1] TCC0/WO[7]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | Analog Connector | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 14 | A0 | PA02 | A0 | EIC/EXTINT[2] *ADC/AIN[0] DAC/VOUT PTC/Y[0]
* | 15 | A1 | PB08 | A1 | EIC/EXTINT[8] *ADC/AIN[2] PTC/Y[14] SERCOM4/PAD[0] TC4/WO[0]
* | 16 | A2 | PB09 | A2 | EIC/EXTINT[9] *ADC/AIN[3] PTC/Y[15] SERCOM4/PAD[1] TC4/WO[1]
* | 17 | A3 | PA04 | A3 | EIC/EXTINT[4] *ADC/AIN[4] AC/AIN[0] PTC/Y[2] SERCOM0/PAD[0] TCC0/WO[0]
* | 18 | A4 | PA05 | A4 | EIC/EXTINT[5] *ADC/AIN[5] AC/AIN[1] PTC/Y[5] SERCOM0/PAD[1] TCC0/WO[1]
* | 19 | A5 | PB02 | A5 | EIC/EXTINT[2] *ADC/AIN[10] PTC/Y[8] SERCOM5/PAD[0]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | Wire | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 20 | SDA | PA22 | SDA | EIC/EXTINT[6] PTC/X[10] *SERCOM3/PAD[0] SERCOM5/PAD[0] TC4/WO[0] TCC0/WO[4]
* | 21 | SCL | PA23 | SCL | EIC/EXTINT[7] PTC/X[11] *SERCOM3/PAD[1] SERCOM5/PAD[1] TC4/WO[1] TCC0/WO[5]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | |SPI (Legacy ICSP) | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 22 | 1 | PA12 | MISO | EIC/EXTINT[12] SERCOM2/PAD[0] *SERCOM4/PAD[0] TCC2/WO[0] TCC0/WO[6]
* | | 2 | | 5V0 |
* | 23 | 4 | PB10 | MOSI | EIC/EXTINT[10] *SERCOM4/PAD[2] TC5/WO[0] TCC0/WO[4]
* | 24 | 3 | PB11 | SCK | EIC/EXTINT[11] *SERCOM4/PAD[3] TC5/WO[1] TCC0/WO[5]
* | | 5 | | RESET |
* | | 6 | | GND |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | LEDs | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 25 | | PB03 | RX |
* | 26 | | PA27 | TX |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | USB | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 27 | | PA28 | USB_HOST_ENABLE | EIC/EXTINT[8]
* | 28 | | PA24 | USB_NEGATIVE | *USB/DM
* | 29 | | PA25 | USB_POSITIVE | *USB/DP
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | EDBG | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 30 | | PB22 | EDBG_UART TX | *SERCOM5/PAD[2]
* | 31 | | PB23 | EDBG_UART RX | *SERCOM5/PAD[3]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 32 | | PA22 | EDBG_SDA | Pin 20 (SDA)
* | 33 | | PA23 | EDBG_SCL | Pin 21 (SCL)
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 34 | | PA19 | EDBG_MISO | EIC/EXTINT[3] *SERCOM1/PAD[3] SERCOM3/PAD[3] TC3/WO[1] TCC0/WO[3]
* | 35 | | PA16 | EDBG_MOSI | EIC/EXTINT[0] *SERCOM1/PAD[0] SERCOM3/PAD[0] TCC2/WO[0] TCC0/WO[6]
* | 36 | | PA18 | EDBG_SS | EIC/EXTINT[2] *SERCOM1/PAD[2] SERCOM3/PAD[2] TC3/WO[0] TCC0/WO[2]
* | 37 | | PA17 | EDBG_SCK | EIC/EXTINT[1] *SERCOM1/PAD[1] SERCOM3/PAD[1] TCC2/WO[1] TCC0/WO[7]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | 38 | ATN | PA13 | EDBG_GPIO0 | EIC/EXTINT[13] SERCOM2/PAD[1] SERCOM4/PAD[1] *TCC2/WO[1] TCC0/WO[7]
* | 39 | | PA21 | EDBG_GPIO1 | Pin 7
* | 40 | | PA06 | EDBG_GPIO2 | Pin 8
* | 41 | | PA07 | EDBG_GPIO3 | Pin 9
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | GND | | |
* | 42 | AREF | PA03 | | EIC/EXTINT[3] *[ADC|DAC]/VREFA ADC/AIN[1] PTC/Y[1]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | |32.768KHz Crystal | | |
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
* | | | PA00 | XIN32 | EIC/EXTINT[0] SERCOM1/PAD[0] TCC2/WO[0]
* | | | PA01 | XOUT32 | EIC/EXTINT[1] SERCOM1/PAD[1] TCC2/WO[1]
* +------------+------------------+--------+-----------------+--------------------------------------------------------------------------------------------------------
*/
#include "variant.h"
/*
* Pins descriptions
*/
const PinDescription g_APinDescription[]=
{
// 0..13 - Digital pins
// ----------------------
// 0/1 - SERCOM/UART (Serial1)
{ PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // RX: SERCOM0/PAD[3]
{ PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2]
// 2..12
// Digital Low
{ PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 },
{ PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1]
{ PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0]
{ 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]
{ PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // TCC0/WO[6]
{ PORTA, 21, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 },
// Digital High
{ PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_4 }, // TCC1/WO[0]
{ PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_5 }, // TCC1/WO[1]
{ 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, 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, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3]
// 13 (LED)
{ PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM2_CH1, NOT_ON_TIMER, EXTERNAL_INT_1 }, // TCC2/WO[1]
// 14..19 - Analog pins
// --------------------
{ PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0]
{ PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // ADC/AIN[2]
{ PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // ADC/AIN[3]
{ PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // ADC/AIN[4]
{ PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // ADC/AIN[5]
{ PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10]
// 20..21 I2C pins (SDA/SCL and also EDBG:SDA/SCL)
// ----------------------
{ PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // SDA: SERCOM3/PAD[0]
{ PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCL: SERCOM3/PAD[1]
// 22..24 - SPI pins (ICSP:MISO,SCK,MOSI)
// ----------------------
{ PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0]
{ PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2]
{ PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3]
// 25..26 - RX/TX LEDS (PB03/PA27)
// --------------------
{ PORTB, 3, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only
{ PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only
// 27..29 - USB
// --------------------
{ PORTA, 28, PIO_COM, PIN_ATTR_NONE, 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_NONE }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP
// 30..41 - EDBG
// ----------------------
// 30/31 - EDBG/UART
{ PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // TX: SERCOM5/PAD[2]
{ PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // RX: SERCOM5/PAD[3]
// 32/33 I2C (SDA/SCL and also EDBG:SDA/SCL)
{ PORTA, 22, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SDA: SERCOM3/PAD[0]
{ PORTA, 23, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCL: SERCOM3/PAD[1]
// 34..37 - EDBG/SPI
{ PORTA, 19, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MISO: SERCOM1/PAD[3]
{ PORTA, 16, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MOSI: SERCOM1/PAD[0]
{ PORTA, 18, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SS: SERCOM1/PAD[2]
{ PORTA, 17, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCK: SERCOM1/PAD[1]
// 38..41 - EDBG/Digital
{ PORTA, 13, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER, EXTERNAL_INT_13 }, // EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7]
{ PORTA, 21, PIO_PWM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH7, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 7
{ PORTA, 6, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH0, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 8
{ PORTA, 7, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH1, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 9
// 42 (AREF)
{ PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP
// ----------------------
// 43 - Alternate use of A0 (DAC output)
{ PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT
} ;
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 ) ;
Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ;
Uart Serial( &sercom5, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ) ;
void SERCOM0_Handler()
{
Serial1.IrqHandler();
}
void SERCOM5_Handler()
{
Serial.IrqHandler();
}
@@ -0,0 +1,201 @@
/*
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_ARDUINO_ZERO_
#define _VARIANT_ARDUINO_ZERO_
/*----------------------------------------------------------------------------
* 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 (26u)
#define NUM_DIGITAL_PINS (14u)
#define NUM_ANALOG_INPUTS (6u)
#define NUM_ANALOG_OUTPUTS (1u)
#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)
// Interrupts
#define digitalPinToInterrupt(P) ( g_APinDescription[P].ulExtInt )
// 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 (15ul)
#define PIN_A2 (16ul)
#define PIN_A3 (17ul)
#define PIN_A4 (18ul)
#define PIN_A5 (19ul)
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 ;
#define ADC_RESOLUTION 12
// Other pins
#define PIN_ATN (38ul)
static const uint8_t ATN = PIN_ATN;
/*
* Serial interfaces
*/
// Serial (EDBG)
#define PIN_SERIAL_RX (31ul)
#define PIN_SERIAL_TX (30ul)
#define PAD_SERIAL_TX (UART_TX_PAD_2)
#define PAD_SERIAL_RX (SERCOM_RX_PAD_3)
// Serial1
#define PIN_SERIAL1_RX (0ul)
#define PIN_SERIAL1_TX (1ul)
#define PAD_SERIAL1_TX (UART_TX_PAD_2)
#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3)
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (22u)
#define PIN_SPI_MOSI (23u)
#define PIN_SPI_SCK (24u)
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 ;
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (20u)
#define PIN_WIRE_SCL (21u)
/*
* USB
*/
#define PIN_USB_HOST_ENABLE (27ul)
#define PIN_USB_DM (28ul)
#define PIN_USB_DP (29ul)
#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 Serial;
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 SerialUSB
#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_ARDUINO_ZERO_ */