Merge pull request #149 from tbowmo/development
Initial support for SAMD device in development branch
This commit is contained in:
@@ -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
|
||||
+210
@@ -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 );
|
||||
@@ -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
|
||||
+143
@@ -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);
|
||||
}
|
||||
|
||||
+71
@@ -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();
|
||||
}
|
||||
|
||||
*/
|
||||
+39
@@ -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)
|
||||
#######################################
|
||||
|
||||
@@ -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"
|
||||
+211
@@ -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")
|
||||
}
|
||||
+212
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user