migrate code to AS7, including fucked up arduino import
arduino as a library will not build with -flto. I can't figure it out. so we waste some space compared to what platformio was building. oh well. there's still over 1K of space left for programs.
This commit is contained in:
86
fw/HackSpaceCon_AS7/HSC_Wand/HSC_Wand.componentinfo.xml
Normal file
86
fw/HackSpaceCon_AS7/HSC_Wand/HSC_Wand.componentinfo.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Store xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="AtmelPackComponentManagement">
|
||||
<ProjectComponents>
|
||||
<ProjectComponent z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
|
||||
<CApiVersion></CApiVersion>
|
||||
<CBundle></CBundle>
|
||||
<CClass>Device</CClass>
|
||||
<CGroup>Startup</CGroup>
|
||||
<CSub></CSub>
|
||||
<CVariant></CVariant>
|
||||
<CVendor>Atmel</CVendor>
|
||||
<CVersion>1.10.0</CVersion>
|
||||
<DefaultRepoPath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs</DefaultRepoPath>
|
||||
<DependentComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
|
||||
<Description></Description>
|
||||
<Files xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.10.348\include\</AbsolutePath>
|
||||
<Attribute></Attribute>
|
||||
<Category>include</Category>
|
||||
<Condition>C</Condition>
|
||||
<FileContentHash i:nil="true" />
|
||||
<FileVersion></FileVersion>
|
||||
<Name>include/</Name>
|
||||
<SelectString></SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.10.348\include\avr\iotn402.h</AbsolutePath>
|
||||
<Attribute></Attribute>
|
||||
<Category>header</Category>
|
||||
<Condition>C</Condition>
|
||||
<FileContentHash>g0XngzH9uwBI0kp8K6DswA==</FileContentHash>
|
||||
<FileVersion></FileVersion>
|
||||
<Name>include/avr/iotn402.h</Name>
|
||||
<SelectString></SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.10.348\templates\main.c</AbsolutePath>
|
||||
<Attribute>template</Attribute>
|
||||
<Category>source</Category>
|
||||
<Condition>C Exe</Condition>
|
||||
<FileContentHash>KjvOcFWd++tbnsEMfVPd/w==</FileContentHash>
|
||||
<FileVersion></FileVersion>
|
||||
<Name>templates/main.c</Name>
|
||||
<SelectString>Main file (.c)</SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.10.348\templates\main.cpp</AbsolutePath>
|
||||
<Attribute>template</Attribute>
|
||||
<Category>source</Category>
|
||||
<Condition>C Exe</Condition>
|
||||
<FileContentHash>uK6xwpZG+RPPFiJUJnueCQ==</FileContentHash>
|
||||
<FileVersion></FileVersion>
|
||||
<Name>templates/main.cpp</Name>
|
||||
<SelectString>Main file (.cpp)</SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
<d4p1:anyType i:type="FileInfo">
|
||||
<AbsolutePath>C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.10.348\gcc\dev\attiny402</AbsolutePath>
|
||||
<Attribute></Attribute>
|
||||
<Category>libraryPrefix</Category>
|
||||
<Condition>GCC</Condition>
|
||||
<FileContentHash i:nil="true" />
|
||||
<FileVersion></FileVersion>
|
||||
<Name>gcc/dev/attiny402</Name>
|
||||
<SelectString></SelectString>
|
||||
<SourcePath></SourcePath>
|
||||
</d4p1:anyType>
|
||||
</Files>
|
||||
<PackName>ATtiny_DFP</PackName>
|
||||
<PackPath>C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATtiny_DFP/1.10.348/Atmel.ATtiny_DFP.pdsc</PackPath>
|
||||
<PackVersion>1.10.348</PackVersion>
|
||||
<PresentInProject>true</PresentInProject>
|
||||
<ReferenceConditionId>ATtiny402</ReferenceConditionId>
|
||||
<RteComponents xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
|
||||
<d4p1:string></d4p1:string>
|
||||
</RteComponents>
|
||||
<Status>Resolved</Status>
|
||||
<VersionMode>Fixed</VersionMode>
|
||||
<IsComponentInAtProject>true</IsComponentInAtProject>
|
||||
</ProjectComponent>
|
||||
</ProjectComponents>
|
||||
</Store>
|
||||
226
fw/HackSpaceCon_AS7/HSC_Wand/HSC_Wand.cppproj
Normal file
226
fw/HackSpaceCon_AS7/HSC_Wand/HSC_Wand.cppproj
Normal file
@@ -0,0 +1,226 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectVersion>7.0</ProjectVersion>
|
||||
<ToolchainName>com.Atmel.AVRGCC8.CPP</ToolchainName>
|
||||
<ProjectGuid>dce6c7e3-ee26-4d79-826b-08594b9ad897</ProjectGuid>
|
||||
<avrdevice>ATtiny402</avrdevice>
|
||||
<avrdeviceseries>none</avrdeviceseries>
|
||||
<OutputType>Executable</OutputType>
|
||||
<Language>CPP</Language>
|
||||
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
|
||||
<OutputFileExtension>.elf</OutputFileExtension>
|
||||
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
|
||||
<AssemblyName>HackSpaceCon_AS7</AssemblyName>
|
||||
<Name>HSC_Wand</Name>
|
||||
<RootNamespace>HackSpaceCon_AS7</RootNamespace>
|
||||
<ToolchainFlavour>Native</ToolchainFlavour>
|
||||
<KeepTimersRunning>true</KeepTimersRunning>
|
||||
<OverrideVtor>false</OverrideVtor>
|
||||
<CacheFlash>true</CacheFlash>
|
||||
<ProgFlashFromRam>true</ProgFlashFromRam>
|
||||
<RamSnippetAddress>0x20000000</RamSnippetAddress>
|
||||
<UncachedRange />
|
||||
<preserveEEPROM>true</preserveEEPROM>
|
||||
<OverrideVtorValue>exception_table</OverrideVtorValue>
|
||||
<BootSegment>2</BootSegment>
|
||||
<ResetRule>0</ResetRule>
|
||||
<eraseonlaunchrule>0</eraseonlaunchrule>
|
||||
<EraseKey />
|
||||
<AsfFrameworkConfig>
|
||||
<framework-data xmlns="">
|
||||
<options />
|
||||
<configurations />
|
||||
<files />
|
||||
<documentation help="" />
|
||||
<offline-documentation help="" />
|
||||
<dependencies>
|
||||
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.52.0" />
|
||||
</dependencies>
|
||||
</framework-data>
|
||||
</AsfFrameworkConfig>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGccCpp>
|
||||
<avrgcc.common.Device>-mmcu=attiny402 -B "%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\gcc\dev\attiny402"</avrgcc.common.Device>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>NDEBUG</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.symbols.DefSymbols>
|
||||
<avrgcc.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\include\</Value>
|
||||
<Value>..\include\libraries\EEPROM\src</Value>
|
||||
<Value>..\include\libraries\Event\src</Value>
|
||||
<Value>..\include\libraries\Logic\src</Value>
|
||||
<Value>..\include\libraries\megaTinyCore\examples\TuningSource</Value>
|
||||
<Value>..\include\libraries\megaTinyCore\src</Value>
|
||||
<Value>..\include\libraries\SoftwareSerial\src</Value>
|
||||
<Value>..\include\libraries\SPI\src</Value>
|
||||
<Value>..\include\libraries\tinyNeoPixel</Value>
|
||||
<Value>..\include\libraries\tinyNeoPixel_Static</Value>
|
||||
<Value>..\include\libraries\Wire\src</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.directories.IncludePaths>
|
||||
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>NDEBUG</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<avrgcccpp.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\include\</Value>
|
||||
<Value>..\include\libraries\EEPROM\src</Value>
|
||||
<Value>..\include\libraries\Event\src</Value>
|
||||
<Value>..\include\libraries\Logic\src</Value>
|
||||
<Value>..\include\libraries\megaTinyCore\examples\TuningSource</Value>
|
||||
<Value>..\include\libraries\megaTinyCore\src</Value>
|
||||
<Value>..\include\libraries\SoftwareSerial\src</Value>
|
||||
<Value>..\include\libraries\SPI\src</Value>
|
||||
<Value>..\include\libraries\tinyNeoPixel</Value>
|
||||
<Value>..\include\libraries\tinyNeoPixel_Static</Value>
|
||||
<Value>..\include\libraries\Wire\src</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.directories.IncludePaths>
|
||||
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
|
||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.linker.libraries.Libraries>
|
||||
<avrgcccpp.assembler.general.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\include\</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.assembler.general.IncludePaths>
|
||||
</AvrGccCpp>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGccCpp>
|
||||
<avrgcc.common.Device>-mmcu=attiny402 -B "%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\gcc\dev\attiny402"</avrgcc.common.Device>
|
||||
<avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
|
||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcc.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>DEBUG</Value>
|
||||
<Value>ARDUINO=108019</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.symbols.DefSymbols>
|
||||
<avrgcc.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\include\</Value>
|
||||
<Value>../../Arduino/megatinycore</Value>
|
||||
<Value>../../Arduino/variants/txy2</Value>
|
||||
</ListValues>
|
||||
</avrgcc.compiler.directories.IncludePaths>
|
||||
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
|
||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||
<avrgcc.compiler.miscellaneous.OtherFlags>-std=gnu11</avrgcc.compiler.miscellaneous.OtherFlags>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>DEBUG</Value>
|
||||
<Value>ARDUINO=108019</Value>
|
||||
<Value>ARDUINO_AVR_ATtinyxy4</Value>
|
||||
<Value>ARDUINO_attinyxy4</Value>
|
||||
<Value>F_CPU=8000000UL</Value>
|
||||
<Value>MEGATINYCORE="2.6.10"</Value>
|
||||
<Value>MEGATINYCORE_MAJOR=2UL</Value>
|
||||
<Value>MEGATINYCORE_MINOR=6UL</Value>
|
||||
<Value>MEGATINYCORE_PATCH=10UL</Value>
|
||||
<Value>MEGATINYCORE_RELEASED=1</Value>
|
||||
<Value>MILLIS_USE_TIMERA0</Value>
|
||||
<Value>CLOCK_SOURCE=0</Value>
|
||||
<Value>TWI_MORS</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<avrgcccpp.compiler.directories.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\include\</Value>
|
||||
<Value>../../Arduino/megatinycore</Value>
|
||||
<Value>../../Arduino/variants/txy2</Value>
|
||||
<Value>../../Arduino/arduino_libraries/tinyNeoPixel_static</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.directories.IncludePaths>
|
||||
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
|
||||
<avrgcccpp.compiler.optimization.OtherFlags>-flto -fno-threadsafe-statics</avrgcccpp.compiler.optimization.OtherFlags>
|
||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcccpp.compiler.optimization.DebugLevel>Default (-g2)</avrgcccpp.compiler.optimization.DebugLevel>
|
||||
<avrgcccpp.compiler.warnings.InhibitAllWarnings>True</avrgcccpp.compiler.warnings.InhibitAllWarnings>
|
||||
<avrgcccpp.compiler.miscellaneous.OtherFlags>-std=gnu++17</avrgcccpp.compiler.miscellaneous.OtherFlags>
|
||||
<avrgcccpp.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.linker.libraries.Libraries>
|
||||
<avrgcccpp.linker.miscellaneous.LinkerFlags>-Os -fuse-linker-plugin</avrgcccpp.linker.miscellaneous.LinkerFlags>
|
||||
<avrgcccpp.assembler.general.IncludePaths>
|
||||
<ListValues>
|
||||
<Value>%24(PackRepoDir)\atmel\ATtiny_DFP\1.10.348\include\</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.assembler.general.IncludePaths>
|
||||
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
|
||||
</AvrGccCpp>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="hsv2rgb.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="hsv2rgb.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="isr.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="wand_program.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="rgbled.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="rgbled.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Arduino\Arduino.cppproj">
|
||||
<Name>Arduino</Name>
|
||||
<Project>{47694d30-4990-4f03-a1f7-e94eb79783f0}</Project>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
||||
</Project>
|
||||
177
fw/HackSpaceCon_AS7/HSC_Wand/hsv2rgb.cpp
Normal file
177
fw/HackSpaceCon_AS7/HSC_Wand/hsv2rgb.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 B. Stultiens
|
||||
* modified by true for 12-bit values
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hsv2rgb.h"
|
||||
|
||||
|
||||
/*
|
||||
void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b)
|
||||
{
|
||||
uint8_t sextant;
|
||||
uint8_t bb;
|
||||
uint16_t ww;
|
||||
uint8_t h_fraction;
|
||||
|
||||
if (!(s)) {
|
||||
*(r) = *(g) = *(b) = (v);
|
||||
return;
|
||||
}
|
||||
|
||||
sextant = h >> 8;
|
||||
HSV_SEXTANT_TEST(sextant); // Optional: Limit hue sextants to defined space
|
||||
|
||||
HSV_POINTER_SWAP(sextant, r, g, b); // Swap pointers depending which sextant we are in
|
||||
|
||||
*g = v; // Top level
|
||||
|
||||
// Perform actual calculations
|
||||
|
||||
// Bottom level: v * (1.0 - s)
|
||||
// --> (v * (255 - s) + error_corr) / 256
|
||||
|
||||
bb = ~s;
|
||||
ww = v * bb;
|
||||
ww += 1; // Error correction
|
||||
ww += ww >> 8; // Error correction
|
||||
*b = ww >> 8;
|
||||
|
||||
h_fraction = h & 0xff; // 0...255
|
||||
|
||||
if(!(sextant & 1)) {
|
||||
// *r = ...slope_up...;
|
||||
|
||||
// Slope up: v * (1.0 - s * (1.0 - h))
|
||||
// --> (v * (255 - (s * (256 - h) + error_corr1) / 256) + error_corr2) / 256
|
||||
|
||||
ww = !h_fraction ? ((uint16_t)s << 8) : (s * (uint8_t)(-h_fraction));
|
||||
ww += ww >> 8; // Error correction 1
|
||||
bb = ww >> 8;
|
||||
bb = ~bb;
|
||||
ww = v * bb;
|
||||
ww += v >> 1; // Error correction 2
|
||||
*r = ww >> 8;
|
||||
} else {
|
||||
// *r = ...slope_down...;
|
||||
|
||||
// Slope down: v * (1.0 - s * h)
|
||||
// --> (v * (255 - (s * h + error_corr1) / 256) + error_corr2) / 256
|
||||
|
||||
ww = s * h_fraction;
|
||||
ww += ww >> 8; // Error correction 1
|
||||
bb = ww >> 8;
|
||||
bb = ~bb;
|
||||
ww = v * bb;
|
||||
ww += v >> 1; // Error correction 2
|
||||
*r = ww >> 8;
|
||||
|
||||
// A perfect match for h_fraction == 0 implies:
|
||||
// *r = (ww >> 8) + (h_fraction ? 0 : 1)
|
||||
// However, this is an extra calculation that may not be required.
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void hsv2rgb_32b_8(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g , uint8_t *b)
|
||||
{
|
||||
HSV_MONOCHROMATIC_TEST(s, v, r, g, b); // Exit with grayscale if s == 0
|
||||
|
||||
uint8_t sextant = h >> 8;
|
||||
|
||||
HSV_SEXTANT_TEST(sextant); // Optional: Limit hue sextants to defined space
|
||||
|
||||
HSV_POINTER_SWAP(sextant, r, g, b); // Swap pointers depending which sextant we are in
|
||||
|
||||
*g = v; // Top level
|
||||
|
||||
// Perform actual calculations
|
||||
|
||||
// Bottom level: v * (1.0 - s)
|
||||
// --> (v * (255 - s) + error_corr + 1) / 256
|
||||
|
||||
uint16_t ww; // Intermediate result
|
||||
ww = v * (255 - s); // We don't use ~s to prevent size-promotion side effects
|
||||
ww += 1; // Error correction
|
||||
ww += ww >> 8; // Error correction
|
||||
*b = ww >> 8;
|
||||
|
||||
uint8_t h_fraction = h & 0xff; // 0...255
|
||||
uint32_t d; // Intermediate result
|
||||
|
||||
if(!(sextant & 1)) {
|
||||
// *r = ...slope_up...;
|
||||
d = v * (uint32_t)((255 << 8) - (uint16_t)(s * (256 - h_fraction)));
|
||||
d += d >> 8; // Error correction
|
||||
d += v; // Error correction
|
||||
*r = d >> 16;
|
||||
} else {
|
||||
// *r = ...slope_down...;
|
||||
d = v * (uint32_t)((255 << 8) - (uint16_t)(s * h_fraction));
|
||||
d += d >> 8; // Error correction
|
||||
d += v; // Error correction
|
||||
*r = d >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void hsv2rgb_32b_16(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b)
|
||||
{
|
||||
HSV_MONOCHROMATIC_TEST(s, v, r, g, b); // Exit with grayscale if s == 0
|
||||
|
||||
uint8_t sextant = h >> 8;
|
||||
|
||||
HSV_SEXTANT_TEST(sextant); // Optional: Limit hue sextants to defined space
|
||||
|
||||
HSV_POINTER_SWAP(sextant, r, g, b); // Swap pointers depending which sextant we are in
|
||||
|
||||
*g = v; // Top level
|
||||
|
||||
// Bottom level: v * (1.0 - s)
|
||||
// --> (v * (255 - s) + error_corr + 1) / 256
|
||||
|
||||
uint16_t ww; // Intermediate result
|
||||
ww = v * (255 - s); // We don't use ~s to prevent size-promotion side effects
|
||||
ww += 1; // Error correction
|
||||
ww += ww >> 8; // Error correction
|
||||
*b = ww >> 8;
|
||||
|
||||
uint8_t h_fraction = h & 0xff; // 0...255
|
||||
uint32_t d; // Intermediate result
|
||||
|
||||
if(!(sextant & 1)) {
|
||||
// *r = ...slope_up...;
|
||||
d = v * (uint32_t)((255 << 8) - (uint16_t)(s * (256 - h_fraction)));
|
||||
d += d >> 8; // Error correction
|
||||
d += v; // Error correction
|
||||
*r = d >> 16;
|
||||
} else {
|
||||
// *r = ...slope_down...;
|
||||
d = v * (uint32_t)((255 << 8) - (uint16_t)(s * h_fraction));
|
||||
d += d >> 8; // Error correction
|
||||
d += v; // Error correction
|
||||
*r = d >> 16;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
132
fw/HackSpaceCon_AS7/HSC_Wand/hsv2rgb.h
Normal file
132
fw/HackSpaceCon_AS7/HSC_Wand/hsv2rgb.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 B. Stultiens
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __HSV2RGB_H__
|
||||
#define __HSV2RGB_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct color_rgb {
|
||||
uint16_t r;
|
||||
uint16_t g;
|
||||
uint16_t b;
|
||||
} color_rgb;
|
||||
|
||||
typedef struct color_hsv {
|
||||
uint16_t h;
|
||||
uint16_t s;
|
||||
uint16_t v;
|
||||
} color_hsv;
|
||||
|
||||
|
||||
#define HSV2RGB_BITS 8 // 10
|
||||
#define HSV2RGB_COUNT ((1 < HSV2RGB_BITS)-1)
|
||||
|
||||
#define HSV_HUE_SEXTANT (1 << HSV2RGB_BITS)
|
||||
#define HSV_HUE_STEPS (6 * HSV_HUE_SEXTANT)
|
||||
|
||||
#define HSV_HUE_MIN 0
|
||||
#define HSV_HUE_MAX (HSV_HUE_STEPS - 1)
|
||||
#define HSV_SAT_MIN 0
|
||||
#define HSV_SAT_MAX 255
|
||||
#define HSV_VAL_MIN 0
|
||||
#define HSV_VAL_MAX 255
|
||||
|
||||
/* Options: */
|
||||
#define HSV_USE_SEXTANT_TEST /* Limit the hue to 0...360 degrees */
|
||||
|
||||
#define hsv2rgb(h,s,v,r,g,b) hsv2rgb_32b_8(h,s,v,r,g,b)
|
||||
|
||||
|
||||
//void hsv2rgb_8b(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b);
|
||||
void hsv2rgb_32b_8(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g , uint8_t *b);
|
||||
//void hsv2rgb_32b_16(uint16_t h, uint16_t s, uint16_t v, uint16_t *r, uint16_t *g , uint16_t *b);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Macros that are common to all implementations
|
||||
*/
|
||||
#ifdef HSV_USE_SEXTANT_TEST
|
||||
#define HSV_SEXTANT_TEST(sextant) \
|
||||
if((sextant) > 5) { \
|
||||
(sextant) = 5; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define HSV_SEXTANT_TEST(sextant)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pointer swapping:
|
||||
* sext. r g b r<>b g<>b r <> g result
|
||||
* 0 0 0 v u c !u v c u v c
|
||||
* 0 0 1 d v c d v c
|
||||
* 0 1 0 c v u u v c u v c
|
||||
* 0 1 1 c d v v d c d v c d v c
|
||||
* 1 0 0 u c v u v c u v c
|
||||
* 1 0 1 v c d v d c d v c d v c
|
||||
*
|
||||
* if(sextant & 2)
|
||||
* r <-> b
|
||||
*
|
||||
* if(sextant & 4)
|
||||
* g <-> b
|
||||
*
|
||||
* if(!(sextant & 6) {
|
||||
* if(!(sextant & 1))
|
||||
* r <-> g
|
||||
* } else {
|
||||
* if(sextant & 1)
|
||||
* r <-> g
|
||||
* }
|
||||
*/
|
||||
#define HSV_SWAPPTR(a,b) do { uint8_t *tmp = (a); (a) = (b); (b) = tmp; } while(0)
|
||||
//#define HSV_SWAPPTR(a,b) do { uint16_t *tmp = (a); (a) = (b); (b) = tmp; } while(0)
|
||||
#define HSV_POINTER_SWAP(sextant,r,g,b) \
|
||||
do { \
|
||||
if((sextant) & 2) { \
|
||||
HSV_SWAPPTR((r), (b)); \
|
||||
} \
|
||||
if((sextant) & 4) { \
|
||||
HSV_SWAPPTR((g), (b)); \
|
||||
} \
|
||||
if(!((sextant) & 6)) { \
|
||||
if(!((sextant) & 1)) { \
|
||||
HSV_SWAPPTR((r), (g)); \
|
||||
} \
|
||||
} else { \
|
||||
if((sextant) & 1) { \
|
||||
HSV_SWAPPTR((r), (g)); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
#define HSV_MONOCHROMATIC_TEST(s,v,r,g,b) \
|
||||
do { \
|
||||
if(!(s)) { \
|
||||
*(r) = *(g) = *(b) = (v); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
#endif
|
||||
43
fw/HackSpaceCon_AS7/HSC_Wand/isr.cpp
Normal file
43
fw/HackSpaceCon_AS7/HSC_Wand/isr.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
hackspacecon wand firmware
|
||||
|
||||
interrupt routines
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "rgbled.h"
|
||||
|
||||
extern uint8_t run_rgbprog;
|
||||
|
||||
|
||||
// TCB0 general interrupt
|
||||
ISR(TCB0_INT_vect)
|
||||
{
|
||||
uint8_t intflags = TCB0.INTFLAGS;
|
||||
|
||||
// in this program, this interrupt is only used for timing.
|
||||
// we'll now return to executing loop()
|
||||
|
||||
// reset the INTFLAGS - necessary on this series
|
||||
TCB0.INTFLAGS = intflags;
|
||||
}
|
||||
|
||||
// button interrupt
|
||||
ISR(PORTA_PORT_vect)
|
||||
{
|
||||
uint8_t intflags = PORTA.INTFLAGS;
|
||||
|
||||
// shitty debounce; this is bad practice
|
||||
delay(5);
|
||||
|
||||
// was our pin changed?
|
||||
if (intflags & PIN3_bm) {
|
||||
// start or re-start running a program
|
||||
run_rgbprog = 1; // run a new program
|
||||
}
|
||||
|
||||
// reset the INTFLAGS - necessary on this series
|
||||
PORTA.INTFLAGS = intflags;
|
||||
}
|
||||
146
fw/HackSpaceCon_AS7/HSC_Wand/rgbled.cpp
Normal file
146
fw/HackSpaceCon_AS7/HSC_Wand/rgbled.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
hackspacecon wand firmware
|
||||
|
||||
rgb led control and programs
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "rgbled.h"
|
||||
|
||||
#include "hsv2rgb.h"
|
||||
|
||||
|
||||
|
||||
tinyNeoPixel rgb = tinyNeoPixel(RGB_COUNT, PIN_PA1, NEO_GRB, rgbled);
|
||||
|
||||
|
||||
|
||||
// rgb program prototypes
|
||||
uint8_t rgbp_rainbow(uint8_t init);
|
||||
uint8_t rgbp_circlefade(uint8_t init);
|
||||
|
||||
// rgb program function pointer array
|
||||
uint8_t (*rgb_program[PROG_COUNT])(uint8_t) = {
|
||||
rgbp_rainbow,
|
||||
rgbp_circlefade
|
||||
};
|
||||
|
||||
|
||||
|
||||
uint8_t rgbled[3 * RGB_COUNT];
|
||||
|
||||
|
||||
// configures and enables the 50Hz timer interrupt that is used for RGB program updates
|
||||
void conf_rgb_timer()
|
||||
{
|
||||
// this timer will run at half speed.
|
||||
// so 8MHz / 2 (prescale) / 1 (CLK_PER) = 4MHz
|
||||
// this will allow a full cycle time of ~61Hz.
|
||||
|
||||
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0); // disable CLK_PER divider
|
||||
|
||||
disable_rgb_timer();
|
||||
|
||||
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // prescale timer to run at half speed
|
||||
TCB0.CCMP = 0xffff; // count to full
|
||||
TCB0.CNT = 0;
|
||||
}
|
||||
|
||||
|
||||
// globals for all rgb programs
|
||||
uint16_t prog_timeout;
|
||||
uint16_t hue;
|
||||
uint8_t r, g, b;
|
||||
|
||||
|
||||
// rgb program 0: rainbow puke
|
||||
#define RAINBOW_HUE_INC 40 // how much to increment the hue every frame
|
||||
#define RAINBOW_OFFSET (1536/5) // offset between each LED
|
||||
#define RAINBOW_TIMEOUT 240 // how long to show this program
|
||||
#define RAINBOW_SAT 0xff // saturation
|
||||
#define RAINBOW_VAL 0x40 // value (brightness); keep low enough to keep average current down
|
||||
|
||||
uint16_t rainbow_hue = 0;
|
||||
|
||||
uint8_t rgbp_rainbow(uint8_t init)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
// set our timer when initializing. otherwise every call is identical
|
||||
if (init) {
|
||||
prog_timeout = RAINBOW_TIMEOUT;
|
||||
}
|
||||
|
||||
if (--prog_timeout) {
|
||||
// copy stored hue to working hue
|
||||
hue = rainbow_hue;
|
||||
|
||||
for (i = 0; i < RGB_COUNT; i++) {
|
||||
// each LED will increment its hue
|
||||
hue += RAINBOW_OFFSET;
|
||||
|
||||
// hue wheel is 256*6 large, so bound the value
|
||||
if (hue >= 1536) hue -= 1536;
|
||||
|
||||
// compute rgb from hue/sat/value
|
||||
hsv2rgb(hue, RAINBOW_SAT, RAINBOW_VAL, &r, &g, &b);
|
||||
|
||||
// apply it to this LED
|
||||
rgb.setPixelColor(i, r, g, b);
|
||||
}
|
||||
|
||||
// increment stored hue wheel for the next cycle through the program
|
||||
rainbow_hue += RAINBOW_HUE_INC;
|
||||
if (rainbow_hue > 1536) rainbow_hue -= 1536;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// done with program
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// rgb program 2: circle loops with fading
|
||||
#define CF_TIMEOUT 90 // how long to show this program (max 255, ideally (20*loopcount)+10)
|
||||
#define CF_BRIGHTNESS 64 // how bright to make the LED. don't make too bright or badge will brown out
|
||||
#define CF_FADERATE 12 // how much to fade all LEDs each frame
|
||||
|
||||
uint8_t circlefade_idx = 0;
|
||||
|
||||
uint8_t rgbp_circlefade(uint8_t init)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t t;
|
||||
|
||||
// set our timer when initializing. otherwise every call is identical
|
||||
if (init) {
|
||||
prog_timeout = CF_TIMEOUT;
|
||||
circlefade_idx = 4; // top LED
|
||||
}
|
||||
|
||||
if (--prog_timeout) {
|
||||
t = (uint8_t)(CF_TIMEOUT - prog_timeout); // get time elapsed
|
||||
t &= 0x3; // light a new LED every 4th loop
|
||||
|
||||
// fade each LED down every frame
|
||||
for (i = 0; i < (sizeof(rgbled) / sizeof(rgbled[0])); i++) {
|
||||
if (rgbled[i] >= CF_FADERATE) {
|
||||
rgbled[i] -= CF_FADERATE;
|
||||
} else {
|
||||
rgbled[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// set the next LED in sequence on to full brightness every 4 cycles
|
||||
if (prog_timeout >= 10) { // as long as >10 loops remain,
|
||||
if (!t) { // then on a loop boundary, light the next LED
|
||||
rgb.setPixelColor(circlefade_idx, CF_BRIGHTNESS, CF_BRIGHTNESS, CF_BRIGHTNESS);
|
||||
|
||||
if (++circlefade_idx >= RGB_COUNT) { // then work on the next LED in sequence
|
||||
circlefade_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
fw/HackSpaceCon_AS7/HSC_Wand/rgbled.h
Normal file
37
fw/HackSpaceCon_AS7/HSC_Wand/rgbled.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
hackspacecon wand firmware
|
||||
|
||||
rgb led control and programs
|
||||
*/
|
||||
|
||||
#ifndef __RGBLED_H__
|
||||
#define __RGBLED_H__
|
||||
|
||||
|
||||
|
||||
#include <tinyNeoPixel_Static.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
#define RGB_COUNT 5
|
||||
#define PROG_COUNT 2
|
||||
|
||||
|
||||
|
||||
#define enable_rgb_timer() {TCB0.CNT = 0; TCB0.CTRLA |= 1;};
|
||||
#define disable_rgb_timer() {TCB0.CTRLA &= ~1;};
|
||||
|
||||
|
||||
|
||||
extern tinyNeoPixel rgb;
|
||||
|
||||
extern uint8_t rgbled[3 * RGB_COUNT];
|
||||
extern uint8_t (*rgb_program[PROG_COUNT])(uint8_t);
|
||||
|
||||
|
||||
|
||||
void conf_rgb_timer();
|
||||
|
||||
|
||||
#endif
|
||||
162
fw/HackSpaceCon_AS7/HSC_Wand/wand_program.cpp
Normal file
162
fw/HackSpaceCon_AS7/HSC_Wand/wand_program.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
hackspacecon wand firmware
|
||||
|
||||
initially written by true
|
||||
rgb programs and further hacking by 000000widow
|
||||
|
||||
----
|
||||
|
||||
this version was hacked to work with AS7.
|
||||
|
||||
the resulting binary at time of porting takes an additional
|
||||
531 bytes of flash and 8 bytes of SRAM. I do not know why.
|
||||
|
||||
|
||||
operation workflow:
|
||||
|
||||
- at initial reset (battery inserted), set up GPIO and peripherals. this
|
||||
includes setting up button wake interrupt. sleep MCU into standby mode.
|
||||
|
||||
- when button state changes, MCU will wake up and process the interrupt.
|
||||
if button is pushed (btn gpio is low), prepare to run next RGB program.
|
||||
|
||||
- rgb program setup involves turning on power to the LEDs and enabling
|
||||
TCB0 periodic timer to interrupt every ~61Hz. this timer interrupt
|
||||
does not handle the rgb program, but will wake the CPU which resumes
|
||||
processing in the loop() function.
|
||||
|
||||
- call the rgb program with the `init` parameter set to 1. idle the CPU.
|
||||
|
||||
- rgb prog timer will interrupt every ~61Hz. this will wake the CPU and
|
||||
send the previously rendered LED data, then call the rgb prog function.
|
||||
afterward, the CPU idles. process repeats until the rgb prog fn returns 0.
|
||||
|
||||
- every time the rgb program is run, the rgb data to send is updated.
|
||||
the data is not actually sent until next wakeup in less than 16.4ms.
|
||||
this allows the functions to have variable processing time, but the
|
||||
output to have a consistent ~61Hz (~16.4ms) timing.
|
||||
|
||||
- once rgb program has finalized, clean up state, disable LED power, and sleep
|
||||
the CPU in standby mode. MCU will wake again once the button is activated.
|
||||
|
||||
|
||||
todo:
|
||||
- test the code
|
||||
- set the RGB output data in the sample rainbow puke program
|
||||
- add more programs
|
||||
- support incrementing or randomly selecting the next program on each button push
|
||||
- run TCB0 in standby mode to save a little more power
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "rgbled.h"
|
||||
|
||||
|
||||
#define PIN_LED_PWRENA PIN_PA6
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
RGB_IDLE,
|
||||
RGB_INIT,
|
||||
RGB_RUNNING
|
||||
};
|
||||
|
||||
enum {
|
||||
PROG_RUN = 0,
|
||||
PROG_INIT = 1
|
||||
};
|
||||
|
||||
uint8_t run_rgbprog = RGB_IDLE;
|
||||
uint8_t rgbprog_idx = 0;
|
||||
|
||||
|
||||
|
||||
void idle_cpu()
|
||||
{
|
||||
SLPCTRL.CTRLA = SLPCTRL_SMODE_IDLE_gc | SLPCTRL_SEN_bm;
|
||||
__asm("sleep");
|
||||
}
|
||||
|
||||
void sleep_cpu()
|
||||
{
|
||||
SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc | SLPCTRL_SEN_bm;
|
||||
__asm("sleep");
|
||||
}
|
||||
|
||||
|
||||
// mcu init
|
||||
void setup() {
|
||||
// configure PA2 as falling edge interrupt for button
|
||||
// note: only PA2 and PA6 support async wakeup.
|
||||
// since we're using PA2, we're good to wakeup from a
|
||||
// falling edge (button pushed) event only.
|
||||
PORTA.DIRCLR = PIN2_bm;
|
||||
PORTA.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_FALLING_gc;
|
||||
|
||||
// configure other hardware pins as appropriate
|
||||
pinMode(PIN_PA3, INPUT_PULLUP); // unused, spare pad on board
|
||||
pinMode(PIN_PA7, INPUT_PULLUP); // unused, voltage passthru
|
||||
|
||||
digitalWrite(PIN_PA6, LOW);
|
||||
pinMode(PIN_PA6, OUTPUT); // LED boost regulator enable
|
||||
|
||||
digitalWrite(PIN_PA1, LOW);
|
||||
pinMode(PIN_PA1, OUTPUT); // LED data
|
||||
|
||||
// set up the RGB ~61Hz periodic timer
|
||||
conf_rgb_timer();
|
||||
|
||||
// enable global interrupts (though they should already be enabled?)
|
||||
sei();
|
||||
}
|
||||
|
||||
// mcu program loop
|
||||
void loop() {
|
||||
switch (run_rgbprog) {
|
||||
case RGB_INIT: { // just started running a program
|
||||
digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply,
|
||||
delay(20); // wait a moment for LEDs to stabilize,
|
||||
|
||||
rgbprog_idx++; // select the next program in sequence,
|
||||
if (rgbprog_idx >= PROG_COUNT) {
|
||||
rgbprog_idx = 0;
|
||||
}
|
||||
|
||||
rgb_program[rgbprog_idx](PROG_INIT);// initialize the program,
|
||||
run_rgbprog++; // and set to running mode.
|
||||
|
||||
enable_rgb_timer(); // then start the RGB program timebase.
|
||||
|
||||
idle_cpu(); // we can idle CPU after running the program
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RGB_RUNNING: { // continuing to run a program
|
||||
rgb.show(); // send updates to the led
|
||||
// then process the next program frame
|
||||
if (!rgb_program[rgbprog_idx](PROG_RUN)) {
|
||||
run_rgbprog = RGB_IDLE; // until the program says it's done
|
||||
break;
|
||||
}
|
||||
|
||||
idle_cpu(); // we can idle CPU after running the program
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: { // no longer running a program
|
||||
disable_rgb_timer(); // disable RGB program timer,
|
||||
digitalWrite(PIN_LED_PWRENA, LOW); // disable LED power supply,
|
||||
run_rgbprog = RGB_IDLE; // and clear run_rgbprog.
|
||||
|
||||
sleep_cpu(); // finally, go to sleep in standby mode
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user