Skip to content
Snippets Groups Projects
Commit e7d9d285 authored by Cristian Maglie's avatar Cristian Maglie Committed by Cristian Maglie
Browse files

Merge branch 'zero' into adc-dac-fix

Conflicts:
	hardware/arduino/samd/cores/arduino/wiring.c
	hardware/arduino/samd/cores/arduino/wiring_analog.c
parents df015207 56c096bd
No related branches found
No related tags found
No related merge requests found
......@@ -60,39 +60,42 @@ extern void delay( uint32_t dwMs ) ;
*
* \param dwUs the number of microseconds to pause (uint32_t)
*/
static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
static inline void delayMicroseconds(uint32_t usec){
if (usec == 0) return;
uint32_t n = usec * (VARIANT_MCK / 3000000);
#if 0
__asm__ volatile(
"L_%=_delayMicroseconds:" "\n\t"
"subs %0, %0, #1" "\n\t"
"bne L_%=_delayMicroseconds" "\n"
: "+r" (n) :
);
#else
for ( ; n != 0 ; n-- )
static __inline__ void delayMicroseconds( uint32_t ) __attribute__((always_inline, unused)) ;
static __inline__ void delayMicroseconds( uint32_t usec )
{
if ( usec == 0 )
{
return ;
}
#endif
}
/*
__attribute__((naked)) static void delay_loop(unsigned n)
{
__asm volatile ("1: subs r0, r0, #1");
__asm volatile (" bne 1b");
__asm volatile (" bx lr");
}
/*
* The following loop:
*
* for (; ul; ul--) {
* __asm__ volatile("");
* }
*
* produce the following assembly code:
*
* loop:
* subs r3, #1 // 1 Core cycle
* bne.n loop // 1 Core cycle + 1 if branch is taken
*/
void delay_microseconds(unsigned n)
{
// Bogus assumption:
// Assume 8 cycles/iteration and running at 80MHz
delay_loop(n * 10);
// VARIANT_MCK / 1000000 == cycles needed to delay 1uS
// 3 == cycles used in a loop
uint32_t n = usec * (VARIANT_MCK / 1000000) / 3;
__asm__ __volatile__(
"1: \n"
" sub %0, #1 \n" // substract 1 from %0 (n)
" bne 1b \n" // if result is not 0 jump to 1
: "+r" (n) // '%0' is n variable with RW constraints
: // no input
: // no clobber
);
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile
}
*/
#ifdef __cplusplus
}
......
......@@ -16,9 +16,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//#include "Arduino.h"
#include "variant.h"
//#include "wiring_constants.h"
#include "wiring_analog.h"
#include "wiring_digital.h"
#include "wiring.h"
......@@ -27,7 +26,7 @@ extern "C" {
#endif
/*
* System Core Clock is at 1MHz at Reset.
* System Core Clock is at 1MHz (8MHz/8) at Reset.
* It is switched to 48MHz in the Reset Handler (startup.c)
*/
uint32_t SystemCoreClock=1000000ul ;
......@@ -80,7 +79,7 @@ void init( void )
PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ;
// Clock TC/TCC for Pulse and Analog
PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 | PM_APBCMASK_TC6 | PM_APBCMASK_TC7 ;
PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 ;
// Clock ADC/DAC for Analog
PM->APBCMASK.reg |= PM_APBCMASK_ADC | PM_APBCMASK_DAC ;
......@@ -114,10 +113,7 @@ void init( void )
ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_64 | // 64 samples
ADC_AVGCTRL_ADJRES(0x04ul); // Adjusting result by 4
while( ADC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains
ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
analogReference( AR_DEFAULT ) ; // Analog Reference is AREF pin (3.3v)
// Initialize DAC
// Setting clock
......
......@@ -18,13 +18,14 @@
#include "wiring_analog.h"
#include "wiring_digital.h"
#include "variant.h"
#ifdef __cplusplus
extern "C" {
#endif
static int _readResolution = 10;
static int _writeResolution = 8;
static int _writeResolution = 10;
void analogReadResolution( int res )
{
......@@ -68,6 +69,12 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to
}
}
/*
* Internal Reference is at 1.0v
* External Reference should be between 1v and VDDANA-0.6v=2.7v
*
* Warning : On Arduino Zero board the input/output voltage for SAMD21G18 is 3.3 volts maximum
*/
void analogReference( eAnalogReference ulMode )
{
while ( ADC->STATUS.bit.SYNCBUSY == 1 );
......@@ -106,7 +113,12 @@ uint32_t analogRead( uint32_t ulPin )
{
uint32_t valueRead = 0;
if (ulPin < A0) ulPin += A0;
if ( ulPin < A0 )
{
ulPin += A0 ;
}
pinPeripheral(ulPin, g_APinDescription[ulPin].ulPinType);
if (ulPin == A0) // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
{
......@@ -134,7 +146,7 @@ uint32_t analogRead( uint32_t ulPin )
// Control A
/*
* Bit 1 ENABLE: Enable
* Bit 1 ENABLE: Enable
* 0: The ADC is disabled.
* 1: The ADC is enabled.
* Due to synchronization, there is a delay from writing CTRLA.ENABLE until the peripheral is enabled/disabled. The
......
......@@ -19,7 +19,7 @@
#ifndef _WIRING_ANALOG_
#define _WIRING_ANALOG_
#include <Arduino.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
......

Microsoft Visual Studio Solution File, Format Version 11.00
# Atmel Studio Solution File, Format Version 11.00
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "test", "test.cppproj", "{B3F859AD-E162-4C2F-9684-EAC6932FEC80}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Release|ARM = Release|ARM
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Debug|ARM.ActiveCfg = Debug|ARM
{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Debug|ARM.Build.0 = Debug|ARM
{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Release|ARM.ActiveCfg = Release|ARM
{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Release|ARM.Build.0 = Release|ARM
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<ProjectVersion>6.2</ProjectVersion>
<ToolchainName>com.Atmel.ARMGCC.CPP</ToolchainName>
<ProjectGuid>{b3f859ad-e162-4c2f-9684-eac6932fec80}</ProjectGuid>
<avrdevice>ATSAMD21G18A</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>CPP</Language>
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
<OutputFileExtension>.elf</OutputFileExtension>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<AssemblyName>test</AssemblyName>
<Name>test</Name>
<RootNamespace>test</RootNamespace>
<ToolchainFlavour>Native</ToolchainFlavour>
<KeepTimersRunning>true</KeepTimersRunning>
<OverrideVtor>false</OverrideVtor>
<CacheFlash>false</CacheFlash>
<ProgFlashFromRam>true</ProgFlashFromRam>
<RamSnippetAddress>0x20000000</RamSnippetAddress>
<UncachedRange />
<OverrideVtorValue>exception_table</OverrideVtorValue>
<BootSegment>2</BootSegment>
<eraseonlaunchrule>1</eraseonlaunchrule>
<AsfFrameworkConfig>
<framework-data xmlns="">
<options />
<configurations />
<files />
<documentation help="" />
<offline-documentation help="" />
<dependencies>
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.17.0" />
</dependencies>
</framework-data>
</AsfFrameworkConfig>
<avrtool>com.atmel.avrdbg.tool.edbg</avrtool>
<avrtoolinterface>SWD</avrtoolinterface>
<com_atmel_avrdbg_tool_samice>
<ToolOptions>
<InterfaceProperties>
</InterfaceProperties>
<InterfaceName>SWD</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.samice</ToolType>
<ToolNumber>28010306</ToolNumber>
<ToolName>SAM-ICE</ToolName>
</com_atmel_avrdbg_tool_samice>
<UseGdb>True</UseGdb>
<com_atmel_avrdbg_tool_edbg>
<ToolOptions>
<InterfaceProperties>
<SwdClock>4000000</SwdClock>
</InterfaceProperties>
<InterfaceName>SWD</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.edbg</ToolType>
<ToolNumber>ATML2320021800000009</ToolNumber>
<ToolName>EDBG</ToolName>
</com_atmel_avrdbg_tool_edbg>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
<ArmGccCpp>
<armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
<armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
<armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
<armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
<armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
<armgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</armgcc.compiler.symbols.DefSymbols>
<armgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
<Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
<Value>../../../../arduino</Value>
<Value>../../../../arduino/USB</Value>
<Value>../../../../../variants/arduino_zero</Value>
<Value>../../../../../libraries/SPI</Value>
<Value>../../../../../libraries/Wire</Value>
</ListValues>
</armgcc.compiler.directories.IncludePaths>
<armgcc.compiler.optimization.level>Optimize for size (-Os)</armgcc.compiler.optimization.level>
<armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
<armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
<armgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</armgcccpp.compiler.symbols.DefSymbols>
<armgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
<Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
<Value>../../../../arduino</Value>
<Value>../../../../arduino/USB</Value>
<Value>../../../../../variants/arduino_zero</Value>
<Value>../../../../../libraries/SPI</Value>
<Value>../../../../../libraries/Wire</Value>
</ListValues>
</armgcccpp.compiler.directories.IncludePaths>
<armgcccpp.compiler.optimization.level>Optimize for size (-Os)</armgcccpp.compiler.optimization.level>
<armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>
<armgcccpp.compiler.warnings.AllWarnings>True</armgcccpp.compiler.warnings.AllWarnings>
<armgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</armgcccpp.linker.libraries.Libraries>
<armgcccpp.linker.libraries.LibrarySearchPaths>
<ListValues>
<Value>../cmsis/linkerScripts</Value>
</ListValues>
</armgcccpp.linker.libraries.LibrarySearchPaths>
<armgcccpp.linker.optimization.GarbageCollectUnusedSections>True</armgcccpp.linker.optimization.GarbageCollectUnusedSections>
<armgcccpp.linker.miscellaneous.LinkerFlags>-Tsamd21g18a_flash.ld</armgcccpp.linker.miscellaneous.LinkerFlags>
<armgcccpp.preprocessingassembler.general.IncludePaths>
<ListValues>
<Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
<Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
<Value>../../../../arduino</Value>
<Value>../../../../arduino/USB</Value>
<Value>../../../../../variants/arduino_zero</Value>
<Value>../../../../../libraries/SPI</Value>
<Value>../../../../../libraries/Wire</Value>
</ListValues>
</armgcccpp.preprocessingassembler.general.IncludePaths>
</ArmGccCpp>
</ToolchainSettings>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<ArmGccCpp>
<armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
<armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
<armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
<armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
<armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
<armgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</armgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<armgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
</ListValues>
</armgcc.compiler.symbols.DefSymbols>
<armgcc.compiler.directories.DefaultIncludePath>False</armgcc.compiler.directories.DefaultIncludePath>
<armgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
<Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
<Value>../../../../arduino</Value>
<Value>../../../../arduino/USB</Value>
<Value>../../../../../variants/arduino_zero</Value>
<Value>../../../../../libraries/SPI</Value>
<Value>../../../../../libraries/Wire</Value>
</ListValues>
</armgcc.compiler.directories.IncludePaths>
<armgcc.compiler.optimization.level>Optimize (-O1)</armgcc.compiler.optimization.level>
<armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
<armgcc.compiler.optimization.PrepareDataForGarbageCollection>True</armgcc.compiler.optimization.PrepareDataForGarbageCollection>
<armgcc.compiler.optimization.DebugLevel>Maximum (-g3)</armgcc.compiler.optimization.DebugLevel>
<armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
<armgcc.compiler.miscellaneous.OtherFlags>-std=c99</armgcc.compiler.miscellaneous.OtherFlags>
<armgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</armgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<armgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
<Value>USB_VID=0x2341</Value>
<Value>USB_PID=0x004d</Value>
</ListValues>
</armgcccpp.compiler.symbols.DefSymbols>
<armgcccpp.compiler.directories.DefaultIncludePath>False</armgcccpp.compiler.directories.DefaultIncludePath>
<armgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
<Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
<Value>../../../../arduino</Value>
<Value>../../../../arduino/USB</Value>
<Value>../../../../../variants/arduino_zero</Value>
<Value>../../../../../libraries/SPI</Value>
<Value>../../../../../libraries/Wire</Value>
</ListValues>
</armgcccpp.compiler.directories.IncludePaths>
<armgcccpp.compiler.optimization.level>Optimize (-O1)</armgcccpp.compiler.optimization.level>
<armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>
<armgcccpp.compiler.optimization.PrepareDataForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareDataForGarbageCollection>
<armgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</armgcccpp.compiler.optimization.DebugLevel>
<armgcccpp.compiler.warnings.AllWarnings>True</armgcccpp.compiler.warnings.AllWarnings>
<armgcccpp.compiler.miscellaneous.OtherFlags>-std=c++98</armgcccpp.compiler.miscellaneous.OtherFlags>
<armgcccpp.linker.general.UseNewlibNano>True</armgcccpp.linker.general.UseNewlibNano>
<armgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</armgcccpp.linker.libraries.Libraries>
<armgcccpp.linker.libraries.LibrarySearchPaths>
<ListValues>
<Value>../../../../../variants/arduino_zero/linker_scripts/gcc</Value>
</ListValues>
</armgcccpp.linker.libraries.LibrarySearchPaths>
<armgcccpp.linker.optimization.GarbageCollectUnusedSections>True</armgcccpp.linker.optimization.GarbageCollectUnusedSections>
<armgcccpp.linker.memorysettings.ExternalRAM />
<armgcccpp.linker.miscellaneous.LinkerFlags>--specs=nosys.specs -Tflash_with_bootloader.ld</armgcccpp.linker.miscellaneous.LinkerFlags>
<armgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>../../../arduino</Value>
</ListValues>
</armgcccpp.assembler.general.IncludePaths>
<armgcccpp.assembler.debugging.DebugLevel>Default (-g)</armgcccpp.assembler.debugging.DebugLevel>
<armgcccpp.preprocessingassembler.general.DefaultIncludePath>False</armgcccpp.preprocessingassembler.general.DefaultIncludePath>
<armgcccpp.preprocessingassembler.general.IncludePaths>
<ListValues>
<Value>../../../arduino</Value>
</ListValues>
</armgcccpp.preprocessingassembler.general.IncludePaths>
<armgcccpp.preprocessingassembler.debugging.DebugLevel>Default (-Wa,-g)</armgcccpp.preprocessingassembler.debugging.DebugLevel>
</ArmGccCpp>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
<Folder Include="core" />
<Folder Include="Wire" />
<Folder Include="SPI" />
<Folder Include="variant" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\..\libraries\SPI\SPI.cpp">
<SubType>compile</SubType>
<Link>SPI\SPI.cpp</Link>
</Compile>
<Compile Include="..\..\..\..\libraries\SPI\SPI.h">
<SubType>compile</SubType>
<Link>SPI\SPI.h</Link>
</Compile>
<Compile Include="..\..\..\..\libraries\Wire\Wire.cpp">
<SubType>compile</SubType>
<Link>Wire\Wire.cpp</Link>
</Compile>
<Compile Include="..\..\..\..\libraries\Wire\Wire.h">
<SubType>compile</SubType>
<Link>Wire\Wire.h</Link>
</Compile>
<Compile Include="..\..\..\..\variants\arduino_zero\pins_arduino.h">
<SubType>compile</SubType>
<Link>variant\pins_arduino.h</Link>
</Compile>
<Compile Include="..\..\..\..\variants\arduino_zero\variant.cpp">
<SubType>compile</SubType>
<Link>variant\variant.cpp</Link>
</Compile>
<Compile Include="..\..\..\..\variants\arduino_zero\variant.h">
<SubType>compile</SubType>
<Link>variant\variant.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Arduino.h">
<SubType>compile</SubType>
<Link>core\Arduino.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\binary.h">
<SubType>compile</SubType>
<Link>core\binary.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Client.h">
<SubType>compile</SubType>
<Link>core\Client.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\delay.c">
<SubType>compile</SubType>
<Link>core\delay.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\delay.h">
<SubType>compile</SubType>
<Link>core\delay.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\HardwareSerial.h">
<SubType>compile</SubType>
<Link>core\HardwareSerial.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\hooks.c">
<SubType>compile</SubType>
<Link>core\hooks.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\IPAddress.cpp">
<SubType>compile</SubType>
<Link>core\IPAddress.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\IPAddress.h">
<SubType>compile</SubType>
<Link>core\IPAddress.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\itoa.c">
<SubType>compile</SubType>
<Link>core\itoa.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\itoa.h">
<SubType>compile</SubType>
<Link>core\itoa.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\main.cpp">
<SubType>compile</SubType>
<Link>core\main.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\Print.cpp">
<SubType>compile</SubType>
<Link>core\Print.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\Print.h">
<SubType>compile</SubType>
<Link>core\Print.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Printable.h">
<SubType>compile</SubType>
<Link>core\Printable.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Reset.cpp">
<SubType>compile</SubType>
<Link>core\Reset.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\Reset.h">
<SubType>compile</SubType>
<Link>core\Reset.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\RingBuffer.cpp">
<SubType>compile</SubType>
<Link>core\RingBuffer.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\RingBuffer.h">
<SubType>compile</SubType>
<Link>core\RingBuffer.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\SERCOM.cpp">
<SubType>compile</SubType>
<Link>core\SERCOM.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\SERCOM.h">
<SubType>compile</SubType>
<Link>core\SERCOM.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Server.h">
<SubType>compile</SubType>
<Link>core\Server.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\startup.c">
<SubType>compile</SubType>
<Link>core\startup.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\Stream.cpp">
<SubType>compile</SubType>
<Link>core\Stream.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\Stream.h">
<SubType>compile</SubType>
<Link>core\Stream.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Tone.h">
<SubType>compile</SubType>
<Link>core\Tone.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Uart.cpp">
<SubType>compile</SubType>
<Link>core\Uart.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\Uart.h">
<SubType>compile</SubType>
<Link>core\Uart.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\Udp.h">
<SubType>compile</SubType>
<Link>core\Udp.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\WCharacter.h">
<SubType>compile</SubType>
<Link>core\WCharacter.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\WInterrupts.c">
<SubType>compile</SubType>
<Link>core\WInterrupts.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\WInterrupts.h">
<SubType>compile</SubType>
<Link>core\WInterrupts.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring.c">
<SubType>compile</SubType>
<Link>core\wiring.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring.h">
<SubType>compile</SubType>
<Link>core\wiring.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_analog.c">
<SubType>compile</SubType>
<Link>core\wiring_analog.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_analog.h">
<SubType>compile</SubType>
<Link>core\wiring_analog.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_constants.h">
<SubType>compile</SubType>
<Link>core\wiring_constants.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_digital.c">
<SubType>compile</SubType>
<Link>core\wiring_digital.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_digital.h">
<SubType>compile</SubType>
<Link>core\wiring_digital.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_private.h">
<SubType>compile</SubType>
<Link>core\wiring_private.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_pulse.h">
<SubType>compile</SubType>
<Link>core\wiring_pulse.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_shift.c">
<SubType>compile</SubType>
<Link>core\wiring_shift.c</Link>
</Compile>
<Compile Include="..\..\..\arduino\wiring_shift.h">
<SubType>compile</SubType>
<Link>core\wiring_shift.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\WMath.cpp">
<SubType>compile</SubType>
<Link>core\WMath.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\WMath.h">
<SubType>compile</SubType>
<Link>core\WMath.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\WString.cpp">
<SubType>compile</SubType>
<Link>core\WString.cpp</Link>
</Compile>
<Compile Include="..\..\..\arduino\WString.h">
<SubType>compile</SubType>
<Link>core\WString.h</Link>
</Compile>
<Compile Include="..\..\..\arduino\WVariant.h">
<SubType>compile</SubType>
<Link>core\WVariant.h</Link>
</Compile>
<Compile Include="..\test.cpp">
<SubType>compile</SubType>
<Link>test.cpp</Link>
</Compile>
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>
\ No newline at end of file
/*
Copyright (c) 2014 Arduino. 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 "Arduino.h"
/*
* Firmata is a generic protocol for communicating with microcontrollers
* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/*
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
Copyright (C) 2009-2011 Jeff Hoefs. 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.
See file LICENSE.txt for further informations on licensing terms.
formatted using the GNU C formatting and indenting
*/
/*
* TODO: use Program Control to load stored profiles from EEPROM
*/
//#include <Servo.h>
#include <Wire.h>
#include <Firmata.h>
// move the following defines to Firmata.h?
#define I2C_WRITE B00000000
#define I2C_READ B00001000
#define I2C_READ_CONTINUOUSLY B00010000
#define I2C_STOP_READING B00011000
#define I2C_READ_WRITE_MODE_MASK B00011000
#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
#define MAX_QUERIES 8
#define MINIMUM_SAMPLING_INTERVAL 10
#define REGISTER_NOT_SPECIFIED -1
/*==============================================================================
* GLOBAL VARIABLES
*============================================================================*/
/* analog inputs */
int analogInputsToReport = 0; // bitwise array to store pin reporting
/* digital input ports */
byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
/* pins configuration */
byte pinConfig[TOTAL_PINS]; // configuration of every pin
byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
int pinState[TOTAL_PINS]; // any value that has been written
/* timer variables */
unsigned long currentMillis; // store the current value from millis()
unsigned long previousMillis; // for comparison with currentMillis
int samplingInterval = 19; // how often to run the main loop (in ms)
/* i2c data */
struct i2c_device_info {
byte addr;
byte reg;
byte bytes;
};
/* for i2c read continuous more */
i2c_device_info query[MAX_QUERIES];
byte i2cRxData[32];
boolean isI2CEnabled = false;
signed char queryIndex = -1;
unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
//Servo servos[MAX_SERVOS];
/*==============================================================================
* FUNCTIONS
*============================================================================*/
void readAndReportData(byte address, int theRegister, byte numBytes) {
// allow I2C requests that don't require a register read
// for example, some devices using an interrupt pin to signify new data available
// do not always require the register read so upon interrupt you call Wire.requestFrom()
if (theRegister != REGISTER_NOT_SPECIFIED) {
Wire.beginTransmission(address);
#if ARDUINO >= 100
Wire.write((byte)theRegister);
#else
Wire.send((byte)theRegister);
#endif
Wire.endTransmission();
// do not set a value of 0
if (i2cReadDelayTime > 0) {
// delay is necessary for some devices such as WiiNunchuck
delayMicroseconds(i2cReadDelayTime);
}
} else {
theRegister = 0; // fill the register with a dummy value
}
Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom
// check to be sure correct number of bytes were returned by slave
if (numBytes == Wire.available()) {
i2cRxData[0] = address;
i2cRxData[1] = theRegister;
for (int i = 0; i < numBytes; i++) {
#if ARDUINO >= 100
i2cRxData[2 + i] = Wire.read();
#else
i2cRxData[2 + i] = Wire.receive();
#endif
}
}
else {
if (numBytes > Wire.available()) {
Firmata.sendString("I2C Read Error: Too many bytes received");
} else {
Firmata.sendString("I2C Read Error: Too few bytes received");
}
}
// send slave address, register and received bytes
Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
}
void outputPort(byte portNumber, byte portValue, byte forceSend)
{
// pins not configured as INPUT are cleared to zeros
portValue = portValue & portConfigInputs[portNumber];
// only send if the value is different than previously sent
if (forceSend || previousPINs[portNumber] != portValue) {
Firmata.sendDigitalPort(portNumber, portValue);
previousPINs[portNumber] = portValue;
}
}
/* -----------------------------------------------------------------------------
* check all the active digital inputs for change of state, then add any events
* to the Serial output queue using Serial.print() */
void checkDigitalInputs(void)
{
/* Using non-looping code allows constants to be given to readPort().
* The compiler will apply substantial optimizations if the inputs
* to readPort() are compile-time constants. */
if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
}
// -----------------------------------------------------------------------------
/* sets the pin mode to the correct state and sets the relevant bits in the
* two bit-arrays that track Digital I/O and PWM status
*/
void setPinModeCallback(byte pin, int mode)
{
if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
// disable i2c so pins can be used for other functions
// the following if statements should reconfigure the pins properly
disableI2CPins();
}
/*
if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
servos[PIN_TO_SERVO(pin)].detach();
}
*/
if (IS_PIN_ANALOG(pin)) {
reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
}
if (IS_PIN_DIGITAL(pin)) {
if (mode == INPUT) {
portConfigInputs[pin / 8] |= (1 << (pin & 7));
} else {
portConfigInputs[pin / 8] &= ~(1 << (pin & 7));
}
}
pinState[pin] = 0;
switch (mode) {
case ANALOG:
if (IS_PIN_ANALOG(pin)) {
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
}
pinConfig[pin] = ANALOG;
}
break;
case INPUT:
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
pinConfig[pin] = INPUT;
}
break;
case OUTPUT:
if (IS_PIN_DIGITAL(pin)) {
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
pinConfig[pin] = OUTPUT;
}
break;
case PWM:
if (IS_PIN_PWM(pin)) {
pinMode(PIN_TO_PWM(pin), OUTPUT);
analogWrite(PIN_TO_PWM(pin), 0);
pinConfig[pin] = PWM;
}
break;
/*
case SERVO:
if (IS_PIN_SERVO(pin)) {
pinConfig[pin] = SERVO;
if (!servos[PIN_TO_SERVO(pin)].attached()) {
servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
}
}
break;
*/
case I2C:
if (IS_PIN_I2C(pin)) {
// mark the pin as i2c
// the user must call I2C_CONFIG to enable I2C for a device
pinConfig[pin] = I2C;
}
break;
default:
Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
}
// TODO: save status to EEPROM here, if changed
}
void analogWriteCallback(byte pin, int value)
{
if (pin < TOTAL_PINS) {
switch (pinConfig[pin]) {
/*
case SERVO:
if (IS_PIN_SERVO(pin))
servos[PIN_TO_SERVO(pin)].write(value);
pinState[pin] = value;
break;
*/
case PWM:
if (IS_PIN_PWM(pin))
analogWrite(PIN_TO_PWM(pin), value);
pinState[pin] = value;
break;
}
}
}
void digitalWriteCallback(byte port, int value)
{
byte pin, lastPin, mask = 1, pinWriteMask = 0;
if (port < TOTAL_PORTS) {
// create a mask of the pins on this port that are writable.
lastPin = port * 8 + 8;
if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
for (pin = port * 8; pin < lastPin; pin++) {
// do not disturb non-digital pins (eg, Rx & Tx)
if (IS_PIN_DIGITAL(pin)) {
// only write to OUTPUT and INPUT (enables pullup)
// do not touch pins in PWM, ANALOG, SERVO or other modes
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
pinWriteMask |= mask;
pinState[pin] = ((byte)value & mask) ? 1 : 0;
}
}
mask = mask << 1;
}
writePort(port, (byte)value, pinWriteMask);
}
}
// -----------------------------------------------------------------------------
/* sets bits in a bit array (int) to toggle the reporting of the analogIns
*/
//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
//}
void reportAnalogCallback(byte analogPin, int value)
{
if (analogPin < TOTAL_ANALOG_PINS) {
if (value == 0) {
analogInputsToReport = analogInputsToReport &~ (1 << analogPin);
} else {
analogInputsToReport = analogInputsToReport | (1 << analogPin);
}
}
// TODO: save status to EEPROM here, if changed
}
void reportDigitalCallback(byte port, int value)
{
if (port < TOTAL_PORTS) {
reportPINs[port] = (byte)value;
}
// do not disable analog reporting on these 8 pins, to allow some
// pins used for digital, others analog. Instead, allow both types
// of reporting to be enabled, but check if the pin is configured
// as analog when sampling the analog inputs. Likewise, while
// scanning digital pins, portConfigInputs will mask off values from any
// pins configured as analog
}
/*==============================================================================
* SYSEX-BASED commands
*============================================================================*/
void sysexCallback(byte command, byte argc, byte *argv)
{
byte mode;
byte slaveAddress;
byte slaveRegister;
byte data;
unsigned int delayTime;
switch (command) {
case I2C_REQUEST:
mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
Firmata.sendString("10-bit addressing mode is not yet supported");
return;
}
else {
slaveAddress = argv[0];
}
switch (mode) {
case I2C_WRITE:
Wire.beginTransmission(slaveAddress);
for (byte i = 2; i < argc; i += 2) {
data = argv[i] + (argv[i + 1] << 7);
#if ARDUINO >= 100
Wire.write(data);
#else
Wire.send(data);
#endif
}
Wire.endTransmission();
delayMicroseconds(70);
break;
case I2C_READ:
if (argc == 6) {
// a slave register is specified
slaveRegister = argv[2] + (argv[3] << 7);
data = argv[4] + (argv[5] << 7); // bytes to read
readAndReportData(slaveAddress, (int)slaveRegister, data);
}
else {
// a slave register is NOT specified
data = argv[2] + (argv[3] << 7); // bytes to read
readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
}
break;
case I2C_READ_CONTINUOUSLY:
if ((queryIndex + 1) >= MAX_QUERIES) {
// too many queries, just ignore
Firmata.sendString("too many queries");
break;
}
queryIndex++;
query[queryIndex].addr = slaveAddress;
query[queryIndex].reg = argv[2] + (argv[3] << 7);
query[queryIndex].bytes = argv[4] + (argv[5] << 7);
break;
case I2C_STOP_READING:
byte queryIndexToSkip;
// if read continuous mode is enabled for only 1 i2c device, disable
// read continuous reporting for that device
if (queryIndex <= 0) {
queryIndex = -1;
} else {
// if read continuous mode is enabled for multiple devices,
// determine which device to stop reading and remove it's data from
// the array, shifiting other array data to fill the space
for (byte i = 0; i < queryIndex + 1; i++) {
if (query[i].addr = slaveAddress) {
queryIndexToSkip = i;
break;
}
}
for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) {
if (i < MAX_QUERIES) {
query[i].addr = query[i + 1].addr;
query[i].reg = query[i + 1].addr;
query[i].bytes = query[i + 1].bytes;
}
}
queryIndex--;
}
break;
default:
break;
}
break;
case I2C_CONFIG:
delayTime = (argv[0] + (argv[1] << 7));
if (delayTime > 0) {
i2cReadDelayTime = delayTime;
}
if (!isI2CEnabled) {
enableI2CPins();
}
break;
/*
case SERVO_CONFIG:
if (argc > 4) {
// these vars are here for clarity, they'll optimized away by the compiler
byte pin = argv[0];
int minPulse = argv[1] + (argv[2] << 7);
int maxPulse = argv[3] + (argv[4] << 7);
if (IS_PIN_SERVO(pin)) {
if (servos[PIN_TO_SERVO(pin)].attached())
servos[PIN_TO_SERVO(pin)].detach();
servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
setPinModeCallback(pin, SERVO);
}
}
break;
*/
case SAMPLING_INTERVAL:
if (argc > 1) {
samplingInterval = argv[0] + (argv[1] << 7);
if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
samplingInterval = MINIMUM_SAMPLING_INTERVAL;
}
} else {
//Firmata.sendString("Not enough data");
}
break;
case EXTENDED_ANALOG:
if (argc > 1) {
int val = argv[1];
if (argc > 2) val |= (argv[2] << 7);
if (argc > 3) val |= (argv[3] << 14);
analogWriteCallback(argv[0], val);
}
break;
case CAPABILITY_QUERY:
Firmata.write(START_SYSEX);
Firmata.write(CAPABILITY_RESPONSE);
for (byte pin = 0; pin < TOTAL_PINS; pin++) {
if (IS_PIN_DIGITAL(pin)) {
Firmata.write((byte)INPUT);
Firmata.write(1);
Firmata.write((byte)OUTPUT);
Firmata.write(1);
}
if (IS_PIN_ANALOG(pin)) {
Firmata.write(ANALOG);
Firmata.write(10);
}
if (IS_PIN_PWM(pin)) {
Firmata.write(PWM);
Firmata.write(8);
}
if (IS_PIN_SERVO(pin)) {
Firmata.write(SERVO);
Firmata.write(14);
}
if (IS_PIN_I2C(pin)) {
Firmata.write(I2C);
Firmata.write(1); // to do: determine appropriate value
}
Firmata.write(127);
}
Firmata.write(END_SYSEX);
break;
case PIN_STATE_QUERY:
if (argc > 0) {
byte pin = argv[0];
Firmata.write(START_SYSEX);
Firmata.write(PIN_STATE_RESPONSE);
Firmata.write(pin);
if (pin < TOTAL_PINS) {
Firmata.write((byte)pinConfig[pin]);
Firmata.write((byte)pinState[pin] & 0x7F);
if (pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin] >> 7) & 0x7F);
if (pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin] >> 14) & 0x7F);
}
Firmata.write(END_SYSEX);
}
break;
case ANALOG_MAPPING_QUERY:
Firmata.write(START_SYSEX);
Firmata.write(ANALOG_MAPPING_RESPONSE);
for (byte pin = 0; pin < TOTAL_PINS; pin++) {
Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
}
Firmata.write(END_SYSEX);
break;
}
}
void enableI2CPins()
{
byte i;
// is there a faster way to do this? would probaby require importing
// Arduino.h to get SCL and SDA pins
for (i = 0; i < TOTAL_PINS; i++) {
if (IS_PIN_I2C(i)) {
// mark pins as i2c so they are ignore in non i2c data requests
setPinModeCallback(i, I2C);
}
}
isI2CEnabled = true;
// is there enough time before the first I2C request to call this here?
Wire.begin();
}
/* disable the i2c pins so they can be used for other functions */
void disableI2CPins() {
isI2CEnabled = false;
// disable read continuous mode for all devices
queryIndex = -1;
// uncomment the following if or when the end() method is added to Wire library
// Wire.end();
}
/*==============================================================================
* SETUP()
*============================================================================*/
void systemResetCallback()
{
// initialize a defalt state
// TODO: option to load config from EEPROM instead of default
if (isI2CEnabled) {
disableI2CPins();
}
for (byte i = 0; i < TOTAL_PORTS; i++) {
reportPINs[i] = false; // by default, reporting off
portConfigInputs[i] = 0; // until activated
previousPINs[i] = 0;
}
// pins with analog capability default to analog input
// otherwise, pins default to digital output
for (byte i = 0; i < TOTAL_PINS; i++) {
if (IS_PIN_ANALOG(i)) {
// turns off pullup, configures everything
setPinModeCallback(i, ANALOG);
} else {
// sets the output to 0, configures portConfigInputs
setPinModeCallback(i, OUTPUT);
}
}
// by default, do not report any analog inputs
analogInputsToReport = 0;
/* send digital inputs to set the initial state on the host computer,
* since once in the loop(), this firmware will only send on change */
/*
TODO: this can never execute, since no pins default to digital input
but it will be needed when/if we support EEPROM stored config
for (byte i=0; i < TOTAL_PORTS; i++) {
outputPort(i, readPort(i, portConfigInputs[i]), true);
}
*/
}
void setup()
{
Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
Firmata.attach(START_SYSEX, sysexCallback);
Firmata.attach(SYSTEM_RESET, systemResetCallback);
Firmata.begin(57600);
systemResetCallback(); // reset to default config
}
/*==============================================================================
* LOOP()
*============================================================================*/
void loop()
{
byte pin, analogPin;
/* DIGITALREAD - as fast as possible, check for changes and output them to the
* FTDI buffer using Serial.print() */
checkDigitalInputs();
/* SERIALREAD - processing incoming messagse as soon as possible, while still
* checking digital inputs. */
while (Firmata.available())
Firmata.processInput();
/* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
* 60 bytes. use a timer to sending an event character every 4 ms to
* trigger the buffer to dump. */
currentMillis = millis();
if (currentMillis - previousMillis > samplingInterval) {
previousMillis += samplingInterval;
/* ANALOGREAD - do all analogReads() at the configured sampling interval */
for (pin = 0; pin < TOTAL_PINS; pin++) {
if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) {
analogPin = PIN_TO_ANALOG(pin);
if (analogInputsToReport & (1 << analogPin)) {
Firmata.sendAnalog(analogPin, analogRead(analogPin));
}
}
}
// report i2c data for all device with read continuous mode enabled
if (queryIndex > -1) {
for (byte i = 0; i < queryIndex + 1; i++) {
readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
}
}
}
}
......@@ -22,52 +22,47 @@
* +------------+------------------+--------+-----------------+------------------------------
* | | Digital Low | | |
* +------------+------------------+--------+-----------------+------------------------------
* | 0 | 0 -> RX | PA10 | | EIC/EXTINT[10] ADC/AIN[18] PTC/X[2] *SERCOM0/PAD[2] TCC1/WO[0] TCC0/WO[2]
* | 1 | 1 <- TX | PA11 | | EIC/EXTINT[11] ADC/AIN[19] PTC/X[3] *SERCOM0/PAD[3] SERCOM2/PAD[3] TCC1/WO[1] TCC0/WO[3]
* | 2 | ~2 | PA08 | | EIC/NMI ADC/AIN[16] PTC/X[0] SERCOM0/PAD[0] SERCOM2/PAD[0] *TCC0/WO[0] TCC1/WO[2]
* | 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 | PA14 | | EIC/EXTINT[14] SERCOM2/PAD[2] SERCOM4/PAD[2] *TC3/WO[0] TCC0/WO[4]
* | 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]
* | 0 | 0 -> RX | PA10 | | EIC/EXTINT[10] ADC/AIN[18] PTC/X[2] *SERCOM0/PAD[2] TCC1/WO[0] TCC0/WO[2]
* | 1 | 1 <- TX | PA11 | | EIC/EXTINT[11] ADC/AIN[19] PTC/X[3] *SERCOM0/PAD[3] SERCOM2/PAD[3] TCC1/WO[1] TCC0/WO[3]
* | 2 | ~2 | PA08 | | EIC/NMI ADC/AIN[16] PTC/X[0] SERCOM0/PAD[0] SERCOM2/PAD[0] *TCC0/WO[0] TCC1/WO[2]
* | 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 | PA14 | | EIC/EXTINT[14] SERCOM2/PAD[2] SERCOM4/PAD[2] *TC3/WO[0] TCC0/WO[4]
* | 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] PTC/Y[4] ADC/AIN[6] AC/AIN[2] SERCOM0/PAD[2] *TCC1/WO[0]
* | 9 | ~9 | PA07 | | EIC/EXTINT[7] PTC/Y[5] DC/AIN[7] AC/AIN[3] 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]
* | 8 | ~8 | PA06 | | EIC/EXTINT[6] PTC/Y[4] ADC/AIN[6] AC/AIN[2] SERCOM0/PAD[2] *TCC1/WO[0]
* | 9 | ~9 | PA07 | | EIC/EXTINT[7] PTC/Y[5] ADC/AIN[7] AC/AIN[3] 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 | | |
* +------------+------------------+--------+-----------------+------------------------------
* | | GND | | |
* | 42 | AREF | PA03 | | *DAC/VREFP PTC/Y[1]
* | 14 | A0 | PA02 | | EIC/EXTINT[2] *ADC/AIN[0] PTC/Y[0] DAC/VOUT
* | 15 | A1 | PB08 | | EIC/EXTINT[8] *ADC/AIN[2] PTC/Y[14] SERCOM4/PAD[0] TC4/WO[0]
* | 16 | A2 | PB09 | | EIC/EXTINT[9] *ADC/AIN[3] PTC/Y[15] SERCOM4/PAD[1] TC4/WO[1]
* | 17 | A3 | PA04 | | EIC/EXTINT[4] *ADC/AIN[4] AC/AIN[0] PTC/Y[2] SERCOM0/PAD[0] TCC0/WO[0]
* | 18 | A4 | PA05 | | EIC/EXTINT[5] *ADC/AIN[5] AC/AIN[1] PTC/Y[5] SERCOM0/PAD[1] TCC0/WO[1]
* | 19 | A5 | PB02 | | EIC/EXTINT[2] *ADC/AIN[10] PTC/Y[8] SERCOM5/PAD[0]
* +------------+------------------+--------+-----------------+------------------------------
* | | Wire | | |
* +------------+------------------+--------+-----------------+------------------------------
* | 16 | SDA | PA22 | | EIC/EXTINT[6] PTC/X[10] *SERCOM3/PAD[0] SERCOM5/PAD[0] TC4/WO[0] TCC0/WO[4]
* | 17 | SCL | PA23 | | EIC/EXTINT[7] PTC/X[11] *SERCOM3/PAD[1] SERCOM5/PAD[1] TC4/WO[1] TCC0/WO[5]
* | 20 | SDA | PA22 | | EIC/EXTINT[6] PTC/X[10] *SERCOM3/PAD[0] SERCOM5/PAD[0] TC4/WO[0] TCC0/WO[4]
* | 21 | SCL | PA23 | | EIC/EXTINT[7] PTC/X[11] *SERCOM3/PAD[1] SERCOM5/PAD[1] TC4/WO[1] TCC0/WO[5]
* +------------+------------------+--------+-----------------+------------------------------
* | |SPI (Legacy ICSP) | | |
* +------------+------------------+--------+-----------------+------------------------------
* | 18 | 1 | PA12 | MISO | EIC/EXTINT[12] SERCOM2/PAD[0] *SERCOM4/PAD[0] TCC2/WO[0] TCC0/WO[6]
* | 22 | 1 | PA12 | MISO | EIC/EXTINT[12] SERCOM2/PAD[0] *SERCOM4/PAD[0] TCC2/WO[0] TCC0/WO[6]
* | | 2 | | 5V0 |
* | 20 | 3 | PB11 | SCK | EIC/EXTINT[11] *SERCOM4/PAD[3] TC5/WO[1] TCC0/WO[5]
* | 21 | 4 | PB10 | MOSI | EIC/EXTINT[10] *SERCOM4/PAD[2] TC5/WO[0] TCC0/WO[4]
* | 23 | 3 | PB11 | SCK | EIC/EXTINT[11] *SERCOM4/PAD[3] TC5/WO[1] TCC0/WO[5]
* | 24 | 4 | PB10 | MOSI | EIC/EXTINT[10] *SERCOM4/PAD[2] TC5/WO[0] TCC0/WO[4]
* | | 5 | | RESET |
* | | 6 | | GND |
* +------------+------------------+--------+-----------------+------------------------------
* | | Analog Connector | | |
* +------------+------------------+--------+-----------------+------------------------------
* | 14 | A0 | PA02 | | EIC/EXTINT[2] *ADC/AIN[0] PTC/Y[0] DAC/VOUT
* | 15 | A1 | PB08 | | EIC/EXTINT[8] *ADC/AIN[2] PTC/Y[14] SERCOM4/PAD[0] TC4/WO[0]
* | 16 | A2 | PB09 | | EIC/EXTINT[9] *ADC/AIN[3] PTC/Y[15] SERCOM4/PAD[1] TC4/WO[1]
* | 17 | A3 | PA04 | | EIC/EXTINT[4] *ADC/AIN[4] AC/AIN[0] PTC/Y[2] SERCOM0/PAD[0] TCC0/WO[0]
* | 18 | A4 | PA05 | | EIC/EXTINT[5] *ADC/AIN[5] AC/AIN[1] PTC/Y[5] SERCOM0/PAD[1] TCC0/WO[1]
* | 19 | A5 | PB02 | | EIC/EXTINT[2] *ADC/AIN[10] PTC/Y[8] SERCOM5/PAD[0]
* +------------+------------------+--------+-----------------+------------------------------
* | | LEDs | | |
* +------------+------------------+--------+-----------------+------------------------------
* | 25 | | PB03 | RX |
......@@ -97,6 +92,11 @@
* | 40 | | PA06 | EDBG_GPIO2 | Pin 8
* | 41 | | PA07 | EDBG_GPIO3 | Pin 9
* +------------+------------------+--------+-----------------+------------------------------
* | | | | |
* +------------+------------------+--------+-----------------+------------------------------
* | | GND | | |
* | 42 | AREF | PA03 | | EXTINT[3] *ADC+DAC/VREFA PTC/Y[1]
* +------------+------------------+--------+-----------------+------------------------------
* | |32.768KHz Crystal | | |
* +------------+------------------+--------+-----------------+------------------------------
* | | | PA00 | XIN32 | EXTINT[0] SERCOM1/PAD[0] TCC2/WO[0]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment