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