16 Commits

Author SHA1 Message Date
db37f4b410 Change C++ standard to C++20 and toolchain to 10.0.1 2026-08-05 22:05:30 +02:00
820a2d1aba Update uart submodule to expose baud rate 2026-08-05 22:03:22 +02:00
9b54969e02 Add interface test for stk500v2 library callbacks 2026-08-05 21:54:32 +02:00
be1a88f4ab Add unfinished extraction of stk500v2 protocol into library 2026-08-05 21:46:39 +02:00
14ac91c815 Update uart submodule 2020-04-13 17:20:31 +02:00
621d34cc18 Update uart submodule 2020-04-13 13:08:34 +02:00
0a65626975 Update uart submodule to fix 115200 baud with 16 MHz 2020-04-13 00:22:02 +02:00
9390f7830b Add small blink example as bootloader payload test 2020-04-12 18:45:33 +02:00
b21673e326 Uncomment setting stack pointer to allow jumping into bootloader 2020-04-12 18:43:53 +02:00
3afda0ebf9 Replace function call to user code with jump 2020-04-12 16:05:16 +02:00
807b1f336f Finish bootloader by adding jump to user code 2020-04-12 15:32:31 +02:00
5f8d6a6f85 Fix chip erase followed immediately by flash programming 2020-04-12 15:12:02 +02:00
41f81247ce Improve semantics for chip erase state enum 2020-04-12 15:07:58 +02:00
a72bf67b07 Fix flash memory address being a word-address 2020-04-12 13:10:00 +02:00
3a04b1f488 Add topcard detection for avrdude 2020-04-12 12:01:53 +02:00
8979066420 Fix receiveByte timeout and add global timeout 2020-04-12 11:47:11 +02:00
15 changed files with 1071 additions and 280 deletions

3
.gitmodules vendored
View File

@@ -22,3 +22,6 @@
[submodule "stk500v2/flash"] [submodule "stk500v2/flash"]
path = stk500v2/flash path = stk500v2/flash
url = git@git.blackmark.me:avr/flash.git url = git@git.blackmark.me:avr/flash.git
[submodule "blink/io"]
path = blink/io
url = git@git.blackmark.me:avr/io.git

239
blink/blink.cppproj Normal file
View File

@@ -0,0 +1,239 @@
<?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>{d887fc8e-ee68-4248-8382-92dbc9a54145}</ProjectGuid>
<avrdevice>ATmega328P</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>CPP</Language>
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
<OutputFileExtension>.elf</OutputFileExtension>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<AssemblyName>blink</AssemblyName>
<Name>blink</Name>
<RootNamespace>blink</RootNamespace>
<ToolchainFlavour>avr-g++-9.1.0</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 />
<avrtool>com.atmel.avrdbg.tool.atmelice</avrtool>
<avrtoolserialnumber>J41800099437</avrtoolserialnumber>
<avrdeviceexpectedsignature>0x1E950F</avrdeviceexpectedsignature>
<com_atmel_avrdbg_tool_stk500>
<ToolOptions>
<InterfaceProperties>
<IspClock>125000</IspClock>
</InterfaceProperties>
<InterfaceName>ISP</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.stk500</ToolType>
<ToolNumber>
</ToolNumber>
<ToolName>STK500</ToolName>
</com_atmel_avrdbg_tool_stk500>
<avrtoolinterface>ISP</avrtoolinterface>
<avrtoolinterfaceclock>125000</avrtoolinterfaceclock>
<AsfFrameworkConfig>
<framework-data xmlns="">
<options />
<configurations />
<files />
<documentation help="" />
<offline-documentation help="" />
<dependencies>
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.47.0" />
</dependencies>
</framework-data>
</AsfFrameworkConfig>
<com_atmel_avrdbg_tool_atmelice>
<ToolOptions>
<InterfaceProperties>
<IspClock>125000</IspClock>
</InterfaceProperties>
<InterfaceName>ISP</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.atmelice</ToolType>
<ToolNumber>J41800099437</ToolNumber>
<ToolName>Atmel-ICE</ToolName>
</com_atmel_avrdbg_tool_atmelice>
<custom>
<ToolOptions>
<InterfaceProperties>
<IspClock>125000</IspClock>
</InterfaceProperties>
<InterfaceName>
</InterfaceName>
</ToolOptions>
<ToolType>custom</ToolType>
<ToolNumber>
</ToolNumber>
<ToolName>Custom Programming Tool</ToolName>
</custom>
<com_atmel_avrdbg_tool_simulator>
<ToolOptions xmlns="">
<InterfaceProperties>
</InterfaceProperties>
<InterfaceName>
</InterfaceName>
</ToolOptions>
<ToolType xmlns="">com.atmel.avrdbg.tool.simulator</ToolType>
<ToolNumber xmlns="">
</ToolNumber>
<ToolName xmlns="">Simulator</ToolName>
</com_atmel_avrdbg_tool_simulator>
<AAFDebugger>
<AAFDebugFiles>
</AAFDebugFiles>
</AAFDebugger>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p</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\ATmega_DFP\1.4.346\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</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>NDEBUG</Value>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
</AvrGccCpp>
</ToolchainSettings>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p</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>DEBUG</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</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>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcccpp.compiler.optimization.DebugLevel>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
</AvrGccCpp>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
<Compile Include="bootloader.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="bootloader.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="clock.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="io\io.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="main.cpp">
<SubType>compile</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="io" />
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>

46
blink/bootloader.cpp Normal file
View File

@@ -0,0 +1,46 @@
#include "bootloader.hpp"
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
namespace {
typedef void (*jmp_fn)() __attribute__((noreturn));
jmp_fn boot = reinterpret_cast<jmp_fn>(0x0000);
jmp_fn bootloader = reinterpret_cast<jmp_fn>(0x7800 / 2);
} // namespace
bool Bootloader::handleReset()
{
wdt_reset();
uint8_t mcuStatus = MCUSR;
MCUSR &= ~(1 << WDRF);
wdt_disable();
return (mcuStatus & (1 << WDRF));
}
void Bootloader::reset()
{
wdt_enable(WDTO_15MS);
while (true)
;
}
bool Bootloader::check()
{
if (pgm_read_byte(reinterpret_cast<uint16_t>(bootloader) * 2) != 0xFF)
return true;
return false;
}
void Bootloader::call()
{
if (check())
bootloader();
else
boot();
}

24
blink/bootloader.hpp Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
class Bootloader {
public:
template <typename Fn>
static inline void init(Fn callback)
{
if (handleReset()) {
callback();
call();
}
}
static inline void enter()
{
reset();
}
private:
static bool handleReset();
static void reset();
static bool check();
static void call();
};

5
blink/clock.hpp Normal file
View File

@@ -0,0 +1,5 @@
#pragma once
//#define F_CPU 18'432'000
#define F_CPU 16'000'000
#include <util/delay.h>

1
blink/io Submodule

Submodule blink/io added at 80de36ee7e

30
blink/main.cpp Normal file
View File

@@ -0,0 +1,30 @@
#include "clock.hpp"
#include "io/io.hpp"
#include "bootloader.hpp"
int main()
{
io::Pin<io::P::B5> ledPin;
ledPin.dir(io::Dir::OUT);
ledPin = false;
Bootloader::init([&ledPin]() {
for (uint8_t i = 0; i < 10; ++i) {
ledPin = true;
_delay_ms(50);
ledPin = false;
_delay_ms(50);
}
});
for (uint8_t i = 0; i < 10; ++i) {
ledPin.toggle();
_delay_ms(1000);
}
Bootloader::enter();
return 0;
}

View File

@@ -7,6 +7,8 @@ Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "tsb", "tsb\tsb.cppproj", "{
EndProject EndProject
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "stk500v2", "stk500v2\stk500v2.cppproj", "{19798CCE-5D96-40E9-B769-D209715DCE0C}" Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "stk500v2", "stk500v2\stk500v2.cppproj", "{19798CCE-5D96-40E9-B769-D209715DCE0C}"
EndProject EndProject
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "blink", "blink\blink.cppproj", "{D887FC8E-EE68-4248-8382-92DBC9A54145}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AVR = Debug|AVR Debug|AVR = Debug|AVR
@@ -21,6 +23,10 @@ Global
{19798CCE-5D96-40E9-B769-D209715DCE0C}.Debug|AVR.Build.0 = Debug|AVR {19798CCE-5D96-40E9-B769-D209715DCE0C}.Debug|AVR.Build.0 = Debug|AVR
{19798CCE-5D96-40E9-B769-D209715DCE0C}.Release|AVR.ActiveCfg = Release|AVR {19798CCE-5D96-40E9-B769-D209715DCE0C}.Release|AVR.ActiveCfg = Release|AVR
{19798CCE-5D96-40E9-B769-D209715DCE0C}.Release|AVR.Build.0 = Release|AVR {19798CCE-5D96-40E9-B769-D209715DCE0C}.Release|AVR.Build.0 = Release|AVR
{D887FC8E-EE68-4248-8382-92DBC9A54145}.Debug|AVR.ActiveCfg = Debug|AVR
{D887FC8E-EE68-4248-8382-92DBC9A54145}.Debug|AVR.Build.0 = Debug|AVR
{D887FC8E-EE68-4248-8382-92DBC9A54145}.Release|AVR.ActiveCfg = Release|AVR
{D887FC8E-EE68-4248-8382-92DBC9A54145}.Release|AVR.Build.0 = Release|AVR
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#define F_CPU 18'432'000 //#define F_CPU 18'432'000
#define F_CPU 16'000'000
#include <util/delay.h> #include <util/delay.h>

View File

@@ -1,7 +1,11 @@
#include "clock.hpp" #include "clock.hpp"
#include "stk500v2.hpp"
#include "uart/uart.hpp" #include "uart/uart.hpp"
#include <math.h>
#include <avr/boot.h> #include <avr/boot.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/io.h> #include <avr/io.h>
@@ -9,7 +13,10 @@
#include "command.hpp" #include "command.hpp"
using uart_interface = uart::Hardware0<uart::Config<115200>, uart::Driven::BLOCKING>; static constexpr auto TIMEOUT = 5000;
static constexpr auto BAUD_RATE = 115200;
using uart_interface = uart::Hardware0<uart::Config<BAUD_RATE>, uart::Driven::BLOCKING>;
uart::Uart<uart_interface> serial; uart::Uart<uart_interface> serial;
struct Message { struct Message {
@@ -21,11 +28,26 @@ struct Message {
uint8_t checksum; uint8_t checksum;
}; };
static inline bool receiveByte(uint8_t &data, uint32_t timeout = 100000) static inline bool receiveByte(uint8_t &data, uint16_t &timeout)
{ {
for (uint32_t i = 0; i < timeout; ++i) { constexpr auto MICROSECOND = 1000.0 * 1000;
if (serial.rxByte(data)) constexpr auto SYMBOL_SIZE = 9;
constexpr auto BYTE_DELAY_US = (SYMBOL_SIZE * MICROSECOND) / BAUD_RATE;
constexpr auto NUM_MS_DELAY_STEPS = static_cast<uint16_t>(round(1000 / BYTE_DELAY_US));
uint16_t msDelay = NUM_MS_DELAY_STEPS;
while (timeout) {
if (serial.rxByte(data)) {
timeout = TIMEOUT;
return true; return true;
}
_delay_us(BYTE_DELAY_US);
if (--msDelay == 0) {
msDelay = NUM_MS_DELAY_STEPS;
--timeout;
}
} }
return false; return false;
@@ -42,23 +64,23 @@ static inline uint8_t calcChecksum(const Message &msg)
return checksum; return checksum;
} }
static inline bool receiveMessage(Message &msg) static inline bool receiveMessage(Message &msg, uint16_t &timeout)
{ {
if (!receiveByte(msg.start) || msg.start != MESSAGE_START) if (!receiveByte(msg.start, timeout) || msg.start != MESSAGE_START)
return false; return false;
if (!receiveByte(msg.number)) if (!receiveByte(msg.number, timeout))
return false; return false;
if (!receiveByte(*(reinterpret_cast<uint8_t *>(&msg.size) + 1))) if (!receiveByte(*(reinterpret_cast<uint8_t *>(&msg.size) + 1), timeout))
return false; return false;
if (!receiveByte(*reinterpret_cast<uint8_t *>(&msg.size)) || msg.size > sizeof(msg.body)) if (!receiveByte(*reinterpret_cast<uint8_t *>(&msg.size), timeout) || msg.size > sizeof(msg.body))
return false; return false;
if (!receiveByte(msg.token) || msg.token != TOKEN) if (!receiveByte(msg.token, timeout) || msg.token != TOKEN)
return false; return false;
for (uint16_t i = 0; i < msg.size; ++i) { for (uint16_t i = 0; i < msg.size; ++i) {
if (!receiveByte(msg.body[i])) if (!receiveByte(msg.body[i], timeout))
return false; return false;
} }
if (!receiveByte(msg.checksum) || msg.checksum != calcChecksum(msg)) if (!receiveByte(msg.checksum, timeout) || msg.checksum != calcChecksum(msg))
return false; return false;
return true; return true;
@@ -216,6 +238,8 @@ static inline void formatGetParameterAnswer(Message &msg)
msg.body[2] = 2; msg.body[2] = 2;
} else if (msg.body[1] == PARAM_OSC_CMATCH) { } else if (msg.body[1] == PARAM_OSC_CMATCH) {
msg.body[2] = 127; msg.body[2] = 127;
} else if (msg.body[1] == PARAM_TOPCARD_DETECT) {
msg.body[2] = 0xFF;
} else { } else {
msg.size = 2; msg.size = 2;
} }
@@ -299,13 +323,15 @@ static inline void formatLoadAddressAnswer(Message &msg)
static inline void formatReadFlashIspAnswer(Message &msg, uint32_t &addr) static inline void formatReadFlashIspAnswer(Message &msg, uint32_t &addr)
{ {
const uint16_t byteAddress = 2 * addr;
const uint16_t numBytes = static_cast<uint16_t>(msg.body[1]) << 8 | msg.body[2]; const uint16_t numBytes = static_cast<uint16_t>(msg.body[1]) << 8 | msg.body[2];
msg.size = 3 + numBytes; msg.size = 3 + numBytes;
msg.body[1] = STATUS_CMD_OK; msg.body[1] = STATUS_CMD_OK;
for (uint16_t i = 0; i < numBytes; ++i) { for (uint16_t i = 0; i < numBytes; ++i) {
msg.body[i + 2] = pgm_read_byte(static_cast<uint16_t>(addr + i)); msg.body[i + 2] = pgm_read_byte(static_cast<uint16_t>(byteAddress + i));
} }
addr += numBytes; const auto numWords = numBytes / 2;
addr += numWords;
msg.body[numBytes + 2] = STATUS_CMD_OK; msg.body[numBytes + 2] = STATUS_CMD_OK;
msg.checksum = calcChecksum(msg); msg.checksum = calcChecksum(msg);
@@ -381,17 +407,17 @@ static inline uint32_t getFlashSize()
return (FLASHEND - bootloaderSize + 1); return (FLASHEND - bootloaderSize + 1);
} }
static inline void performChipErase() static inline void performChipErase(uint16_t flashStartAddress = 0x0000)
{ {
constexpr auto getEepromEraseFuseBit = []() -> bool { constexpr auto getEepromEraseFuseBit = []() -> bool {
constexpr auto EESAVE = 3; constexpr auto EESAVE = 3;
return boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & (1 << EESAVE); return boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & (1 << EESAVE);
}; };
constexpr auto eraseFlash = []() { constexpr auto eraseFlash = [](const uint16_t &flashStartAddress) {
const auto flashSize = getFlashSize(); const auto flashSize = getFlashSize();
const auto byteAddress = 2 * flashStartAddress;
for (uint16_t i = 0; i < flashSize; i += SPM_PAGESIZE) { for (uint16_t i = byteAddress; i < flashSize; i += SPM_PAGESIZE) {
boot_page_erase(i); boot_page_erase(i);
boot_spm_busy_wait(); boot_spm_busy_wait();
} }
@@ -409,7 +435,7 @@ static inline void performChipErase()
} }
}; };
eraseFlash(); eraseFlash(flashStartAddress);
eraseEeprom(); eraseEeprom();
} }
@@ -437,10 +463,12 @@ static inline void formatReadEepromIspAnswer(Message &msg, uint32_t &addr)
static inline void formatProgramFlashIspAnswer(Message &msg, uint32_t &addr) static inline void formatProgramFlashIspAnswer(Message &msg, uint32_t &addr)
{ {
if (addr < getFlashSize()) const auto byteAddress = 2 * addr;
writeFlashPage(addr, msg.body + 10); if (byteAddress < getFlashSize())
writeFlashPage(byteAddress, msg.body + 10);
const uint16_t numBytes = static_cast<uint16_t>(msg.body[1]) << 8 | msg.body[2]; const uint16_t numBytes = static_cast<uint16_t>(msg.body[1]) << 8 | msg.body[2];
addr += numBytes; const auto numWords = numBytes / 2;
addr += numWords;
msg.size = 2; msg.size = 2;
msg.body[1] = STATUS_CMD_OK; msg.body[1] = STATUS_CMD_OK;
@@ -480,10 +508,12 @@ static inline void formatErrorAnswer(Message &msg)
} }
enum class ChipEraseState { enum class ChipEraseState {
NONE = 0b00, NONE = 0,
REQUEST = 0b01, REQUEST = (1 << 1),
RESPONSE = 0b10, RESPONSE = (1 << 2),
PERFORM = 0b11, PERFORM = REQUEST | RESPONSE,
PROGRAM = (1 << 3),
FINISH = REQUEST | RESPONSE | PROGRAM,
}; };
constexpr ChipEraseState operator|(const ChipEraseState &self, const ChipEraseState &other) constexpr ChipEraseState operator|(const ChipEraseState &self, const ChipEraseState &other)
@@ -497,7 +527,8 @@ constexpr ChipEraseState &operator|=(ChipEraseState &self, const ChipEraseState
return self; return self;
} }
static inline void handleMessage(Message &msg, uint32_t &addr, ChipEraseState &chipEraseFlag) static inline void handleMessage(Message &msg, uint32_t &addr, uint16_t &finishEraseAddress,
ChipEraseState &chipEraseFlag)
{ {
if (isSignOn(msg)) if (isSignOn(msg))
formatSignOnAnswer(msg); formatSignOnAnswer(msg);
@@ -524,11 +555,13 @@ static inline void handleMessage(Message &msg, uint32_t &addr, ChipEraseState &c
else if (isReadEepromIsp(msg)) else if (isReadEepromIsp(msg))
formatReadEepromIspAnswer(msg, addr); formatReadEepromIspAnswer(msg, addr);
else if (isChipEraseIsp(msg)) { else if (isChipEraseIsp(msg)) {
chipEraseFlag = ChipEraseState::REQUEST; chipEraseFlag |= ChipEraseState::REQUEST;
formatChipEraseIspAnswer(msg); formatChipEraseIspAnswer(msg);
} else if (isProgramFlashIsp(msg)) } else if (isProgramFlashIsp(msg)) {
chipEraseFlag |= ChipEraseState::PROGRAM;
formatProgramFlashIspAnswer(msg, addr); formatProgramFlashIspAnswer(msg, addr);
else if (isProgramEepromIsp(msg)) finishEraseAddress = addr;
} else if (isProgramEepromIsp(msg))
formatProgramEepromIspAnswer(msg, addr); formatProgramEepromIspAnswer(msg, addr);
else if (isLeaveProgmodeIsp(msg)) { else if (isLeaveProgmodeIsp(msg)) {
chipEraseFlag |= ChipEraseState::RESPONSE; chipEraseFlag |= ChipEraseState::RESPONSE;
@@ -537,24 +570,87 @@ static inline void handleMessage(Message &msg, uint32_t &addr, ChipEraseState &c
formatErrorAnswer(msg); formatErrorAnswer(msg);
transmitMessage(msg); transmitMessage(msg);
}
if (chipEraseFlag == ChipEraseState::PERFORM) { static inline void interfaceTest()
performChipErase(); {
chipEraseFlag = ChipEraseState::NONE; constexpr auto onSignOn = []() {};
} constexpr auto onSetParam = []() {};
constexpr auto onGetParam = [](stk500v2::Param param, uint8_t &result) {
using stk500v2::Param;
switch (param) {
case Param::HW_VER:
result = 1;
break;
case Param::SW_MAJOR:
result = 2;
break;
case Param::SW_MINOR:
result = 10;
break;
case Param::SCK_DURATION:
result = 2;
break;
case Param::VADJUST:
result = 25;
break;
case Param::VTARGET:
result = 49;
break;
case Param::OSC_PSCALE:
result = 2;
break;
case Param::OSC_CMATCH:
result = 127;
break;
case Param::TOPCARD_DETECT:
result = 0xFF;
break;
default:
return false;
}
return true;
};
constexpr auto callbacks = stk500v2::Callbacks<onSignOn, onSetParam, onGetParam>();
stk500v2::Stk500v2<uart_interface, TIMEOUT, callbacks> stk500;
stk500.init();
while (stk500.callback())
;
} }
int main() int main()
{ {
/*interfaceTest();
return 0;*/
serial.init(); serial.init();
Message msg; Message msg;
uint32_t addr = 0x0000; uint32_t addr = 0x0000;
uint16_t finishEraseAddress = 0x0000;
ChipEraseState chipEraseFlag = ChipEraseState::NONE; ChipEraseState chipEraseFlag = ChipEraseState::NONE;
uint16_t timeout = TIMEOUT;
while (true) { while (true) {
if (receiveMessage(msg)) { if (receiveMessage(msg, timeout)) {
handleMessage(msg, addr, chipEraseFlag); handleMessage(msg, addr, finishEraseAddress, chipEraseFlag);
}
if (timeout == 0) {
if (chipEraseFlag == ChipEraseState::PERFORM) {
performChipErase();
chipEraseFlag = ChipEraseState::NONE;
} else if (chipEraseFlag == ChipEraseState::FINISH) {
performChipErase(finishEraseAddress);
chipEraseFlag = ChipEraseState::NONE;
}
asm volatile("jmp 0x0000");
} }
} }
@@ -565,7 +661,7 @@ void startup() __attribute__((naked, section(".vectors")));
void startup() void startup()
{ {
asm volatile("clr __zero_reg__"); asm volatile("clr __zero_reg__");
// SP = RAMEND; SP = RAMEND;
SREG = 0; SREG = 0;
asm volatile("jmp main"); asm volatile("jmp main");
} }

View File

@@ -15,7 +15,7 @@
<AssemblyName>stk500v2</AssemblyName> <AssemblyName>stk500v2</AssemblyName>
<Name>stk500v2</Name> <Name>stk500v2</Name>
<RootNamespace>stk500v2</RootNamespace> <RootNamespace>stk500v2</RootNamespace>
<ToolchainFlavour>avr-g++-9.1.0</ToolchainFlavour> <ToolchainFlavour>avr-g++-10.0.1</ToolchainFlavour>
<KeepTimersRunning>true</KeepTimersRunning> <KeepTimersRunning>true</KeepTimersRunning>
<OverrideVtor>false</OverrideVtor> <OverrideVtor>false</OverrideVtor>
<CacheFlash>true</CacheFlash> <CacheFlash>true</CacheFlash>
@@ -95,147 +95,136 @@
</com_atmel_avrdbg_tool_simulator> </com_atmel_avrdbg_tool_simulator>
<AAFDebugger> <AAFDebugger>
<AAFDebugFiles> <AAFDebugFiles>
<DebugFile>
<path>\Debug\stk500v2.lss</path>
<AAFSetting>
<Label>Lss Files</Label>
<Extention>.lss</Extention>
<Regex>^\s*(?&lt;address&gt;[a-f0-9]*):\s*.*$</Regex>
<DebugEnabled>true</DebugEnabled>
<RegexGroups>address</RegexGroups>
<DebuggerExpression>$pc</DebuggerExpression>
</AAFSetting>
</DebugFile>
</AAFDebugFiles> </AAFDebugFiles>
</AAFDebugger> </AAFDebugger>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings> <ToolchainSettings>
<AvrGccCpp> <AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p</avrgcc.common.Device> <avrgcc.common.Device>-mmcu=atmega328p</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex> <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec> <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures> <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols> <avrgcc.compiler.symbols.DefSymbols>
<ListValues> <ListValues>
<Value>NDEBUG</Value> <Value>NDEBUG</Value>
</ListValues> </ListValues>
</avrgcc.compiler.symbols.DefSymbols> </avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths> <avrgcc.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues> </ListValues>
</avrgcc.compiler.directories.IncludePaths> </avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level> <avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum> <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings> <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings> <avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic> <avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags> <avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.symbols.DefSymbols> <avrgcccpp.compiler.symbols.DefSymbols>
<ListValues> <ListValues>
<Value>NDEBUG</Value> <Value>NDEBUG</Value>
</ListValues> </ListValues>
</avrgcccpp.compiler.symbols.DefSymbols> </avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths> <avrgcccpp.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues> </ListValues>
</avrgcccpp.compiler.directories.IncludePaths> </avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level> <avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum> <avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings> <avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic> <avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags> <avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++20</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.general.NoStartupOrDefaultLibs>True</avrgcccpp.linker.general.NoStartupOrDefaultLibs> <avrgcccpp.linker.general.NoStartupOrDefaultLibs>True</avrgcccpp.linker.general.NoStartupOrDefaultLibs>
<avrgcccpp.linker.libraries.Libraries> <avrgcccpp.linker.libraries.Libraries>
<ListValues> <ListValues>
<Value>libm</Value> <Value>libm</Value>
</ListValues> </ListValues>
</avrgcccpp.linker.libraries.Libraries> </avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.linker.memorysettings.Flash> <avrgcccpp.linker.memorysettings.Flash>
<ListValues> <ListValues>
<Value>.text=0x3C00</Value> <Value>.text=0x3C00</Value>
</ListValues> </ListValues>
</avrgcccpp.linker.memorysettings.Flash> </avrgcccpp.linker.memorysettings.Flash>
<avrgcccpp.assembler.general.IncludePaths> <avrgcccpp.assembler.general.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues> </ListValues>
</avrgcccpp.assembler.general.IncludePaths> </avrgcccpp.assembler.general.IncludePaths>
</AvrGccCpp> </AvrGccCpp>
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings> <ToolchainSettings>
<AvrGccCpp> <AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p</avrgcc.common.Device> <avrgcc.common.Device>-mmcu=atmega328p</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex> <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec> <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures> <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols> <avrgcc.compiler.symbols.DefSymbols>
<ListValues> <ListValues>
<Value>DEBUG</Value> <Value>DEBUG</Value>
</ListValues> </ListValues>
</avrgcc.compiler.symbols.DefSymbols> </avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths> <avrgcc.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues> </ListValues>
</avrgcc.compiler.directories.IncludePaths> </avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level> <avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum> <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel> <avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings> <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings> <avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic> <avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags> <avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.symbols.DefSymbols> <avrgcccpp.compiler.symbols.DefSymbols>
<ListValues> <ListValues>
<Value>DEBUG</Value> <Value>DEBUG</Value>
</ListValues> </ListValues>
</avrgcccpp.compiler.symbols.DefSymbols> </avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths> <avrgcccpp.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues> </ListValues>
</avrgcccpp.compiler.directories.IncludePaths> </avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcccpp.compiler.optimization.level> <avrgcccpp.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum> <avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcccpp.compiler.optimization.DebugLevel> <avrgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcccpp.compiler.optimization.DebugLevel>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings> <avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic> <avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags> <avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++20</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.general.NoStartupOrDefaultLibs>True</avrgcccpp.linker.general.NoStartupOrDefaultLibs> <avrgcccpp.linker.general.NoStartupOrDefaultLibs>True</avrgcccpp.linker.general.NoStartupOrDefaultLibs>
<avrgcccpp.linker.libraries.Libraries> <avrgcccpp.linker.libraries.Libraries>
<ListValues> <ListValues>
<Value>libm</Value> <Value>libm</Value>
</ListValues> </ListValues>
</avrgcccpp.linker.libraries.Libraries> </avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.linker.memorysettings.Flash> <avrgcccpp.linker.memorysettings.Flash>
<ListValues> <ListValues>
<Value>.text=0x3800</Value> <Value>.text=0x3800</Value>
</ListValues> </ListValues>
</avrgcccpp.linker.memorysettings.Flash> </avrgcccpp.linker.memorysettings.Flash>
<avrgcccpp.assembler.general.IncludePaths> <avrgcccpp.assembler.general.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</ListValues> </ListValues>
</avrgcccpp.assembler.general.IncludePaths> </avrgcccpp.assembler.general.IncludePaths>
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel> <avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
</AvrGccCpp> </AvrGccCpp>
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

344
stk500v2/stk500v2.hpp Normal file
View File

@@ -0,0 +1,344 @@
#pragma once
#include <math.h>
#include <stddef.h>
#include <stdint.h>
namespace stk500v2 {
enum class Msg : uint8_t {
START = 0x1B, // ASCII ESC
TOKEN = 0x0E,
};
inline constexpr bool operator==(const Msg &msg, const uint8_t &num)
{
return static_cast<uint8_t>(msg) == num;
}
enum class Cmd : uint8_t {
SIGN_ON = 0x01,
SET_PARAMETER = 0x02,
GET_PARAMETER = 0x03,
SET_DEVICE_PARAMETERS = 0x04,
OSCCAL = 0x05,
LOAD_ADDRESS = 0x06,
FIRMWARE_UPGRADE = 0x07,
};
inline constexpr bool operator==(const Cmd &cmd, const uint8_t &num)
{
return static_cast<uint8_t>(cmd) == num;
}
enum class IspCmd : uint8_t {
ENTER_PROGMODE = 0x10,
LEAVE_PROGMODE = 0x11,
CHIP_ERASE = 0x12,
PROGRAM_FLASH = 0x13,
READ_FLASH = 0x14,
PROGRAM_EEPROM = 0x15,
READ_EEPROM = 0x16,
PROGRAM_FUSE = 0x17,
READ_FUSE = 0x18,
PROGRAM_LOCK = 0x19,
READ_LOCK = 0x1A,
READ_SIGNATURE = 0x1B,
READ_OSCCAL = 0x1C,
SPI_MULTI = 0x1D,
};
enum class PpCmd : uint8_t {
ENTER_PROGMODE = 0x20,
LEAVE_PROGMODE = 0x21,
CHIP_ERASE = 0x22,
PROGRAM_FLASH = 0x23,
READ_FLASH = 0x24,
PROGRAM_EEPROM = 0x25,
READ_EEPROM = 0x26,
PROGRAM_FUSE = 0x27,
READ_FUSE = 0x28,
PROGRAM_LOCK = 0x29,
READ_LOCK = 0x2A,
READ_SIGNATURE = 0x2B,
READ_OSCCAL = 0x2C,
SET_CONTROL_STACK = 0x2D,
};
enum class HvspCmd : uint8_t {
ENTER_PROGMODE = 0x30,
LEAVE_PROGMODE = 0x31,
CHIP_ERASE = 0x32,
PROGRAM_FLASH = 0x33,
READ_FLASH = 0x34,
PROGRAM_EEPROM = 0x35,
READ_EEPROM = 0x36,
PROGRAM_FUSE = 0x37,
READ_FUSE = 0x38,
PROGRAM_LOCK = 0x39,
READ_LOCK = 0x3A,
READ_SIGNATURE = 0x3B,
READ_OSCCAL = 0x3C,
};
enum class Status : uint8_t {
// Success
CMD_OK = 0x00,
// Warnings
CMD_TOUT = 0x80,
RDY_BSY_TOUT = 0x81,
SET_PARAM_MISSING = 0x82,
// Errors
CMD_FAILED = 0xC0,
CKSUM_ERROR = 0xC1,
CMD_UNKNOWN = 0xC9,
};
enum class Param : uint8_t {
BUILD_NUMBER_LOW = 0x80,
BUILD_NUMBER_HIGH = 0x81,
HW_VER = 0x90,
SW_MAJOR = 0x91,
SW_MINOR = 0x92,
VTARGET = 0x94,
VADJUST = 0x95,
OSC_PSCALE = 0x96,
OSC_CMATCH = 0x97,
SCK_DURATION = 0x98,
TOPCARD_DETECT = 0x9A,
STATUS = 0x9C,
DATA = 0x9D,
RESET_POLARITY = 0x9E,
CONTROLLER_INIT = 0x9F,
};
enum class Answer : uint8_t {
CKSUM_ERROR = 0xB0,
};
template <size_t Size>
struct Message {
uint8_t start;
uint8_t number;
uint16_t size;
uint8_t token;
uint8_t body[Size];
uint8_t checksum;
};
template <auto SignOnFn, auto SetParamFn, auto GetParamFn>
struct Callbacks {
static constexpr auto onSignOn = SignOnFn;
static constexpr auto onSetParam = SetParamFn;
static constexpr auto onGetParam = GetParamFn;
};
template <class Uart, uint16_t Timeout, auto CallbackFns>
class Stk500v2 {
public:
inline void init()
{
m_serial.init();
}
inline bool callback()
{
if (receiveMessage()) {
handleMessage();
}
if (m_timeout)
return true;
return false;
}
private:
static constexpr auto MSG_BUFFER_SIZE = 275;
using msg_t = Message<MSG_BUFFER_SIZE>;
msg_t m_msg;
Uart m_serial;
uint16_t m_timeout = Timeout;
inline bool receiveByte(uint8_t &data)
{
constexpr auto MICROSECOND = 1000.0 * 1000;
constexpr auto SYMBOL_SIZE = 9;
constexpr auto BYTE_DELAY_US = (SYMBOL_SIZE * MICROSECOND) / Uart::BAUD_RATE;
constexpr auto NUM_MS_DELAY_STEPS = static_cast<uint16_t>(round(1000 / BYTE_DELAY_US));
uint16_t msDelay = NUM_MS_DELAY_STEPS;
while (m_timeout) {
if (m_serial.rxByte(data)) {
m_timeout = Timeout;
return true;
}
_delay_us(BYTE_DELAY_US);
if (--msDelay == 0) {
msDelay = NUM_MS_DELAY_STEPS;
--m_timeout;
}
}
return false;
}
inline uint8_t calcChecksum() const
{
uint8_t checksum = static_cast<uint8_t>(m_msg.start);
for (uint16_t i = 1; i < 5 + m_msg.size; ++i) {
checksum ^= *(reinterpret_cast<const uint8_t *>(&m_msg) + i);
}
return checksum;
}
inline bool receiveMessage()
{
constexpr auto CHECK_MESSAGE_FORMAT = true;
constexpr auto CHECK_MESSAGE_SIZE = true;
constexpr auto CHECK_MESSAGE_CHECKSUM = true;
if (!receiveByte(m_msg.start)) {
return false;
}
if constexpr (CHECK_MESSAGE_FORMAT) {
if (m_msg.start != Msg::START)
return false;
}
if (!receiveByte(m_msg.number))
return false;
if (!receiveByte(*(reinterpret_cast<uint8_t *>(&m_msg.size) + 1)))
return false;
if (!receiveByte(*reinterpret_cast<uint8_t *>(&m_msg.size)))
return false;
if constexpr (CHECK_MESSAGE_SIZE) {
if (m_msg.size > sizeof(m_msg.body))
return false;
}
if (!receiveByte(m_msg.token))
return false;
if constexpr (CHECK_MESSAGE_FORMAT) {
if (m_msg.token != Msg::TOKEN)
return false;
}
for (uint16_t i = 0; i < m_msg.size; ++i) {
if (!receiveByte(m_msg.body[i]))
return false;
}
if (!receiveByte(m_msg.checksum))
return false;
if constexpr (CHECK_MESSAGE_CHECKSUM) {
if (m_msg.checksum != calcChecksum())
return false;
}
return true;
}
inline void transmitMessage() const
{
m_serial.txByte(m_msg.start);
m_serial.txByte(m_msg.number);
m_serial.txByte(m_msg.size >> 8);
m_serial.txByte(m_msg.size & 0xFF);
m_serial.txByte(m_msg.token);
for (uint16_t i = 0; i < m_msg.size; ++i)
m_serial.txByte(m_msg.body[i]);
m_serial.txByte(m_msg.checksum);
}
inline void handleMessage()
{
constexpr auto CHECK_MESSAGE_LENGTH = true;
switch (m_msg.body[0]) {
case static_cast<uint8_t>(Cmd::SIGN_ON): {
if constexpr (CHECK_MESSAGE_LENGTH) {
if (m_msg.size != 1)
break;
}
CallbackFns.onSignOn();
sendReply<static_cast<uint8_t>(Cmd::SIGN_ON)>();
break;
}
case static_cast<uint8_t>(Cmd::SET_PARAMETER): {
if constexpr (CHECK_MESSAGE_LENGTH) {
if (m_msg.size != 3)
break;
}
CallbackFns.onSetParam();
sendReply<static_cast<uint8_t>(Cmd::SET_PARAMETER)>();
break;
}
case static_cast<uint8_t>(Cmd::GET_PARAMETER): {
if constexpr (CHECK_MESSAGE_LENGTH) {
if (m_msg.size != 2)
break;
}
const auto errorOccurred = CallbackFns.onGetParam(static_cast<Param>(m_msg.body[1]), m_msg.body[2]);
sendReply<static_cast<uint8_t>(Cmd::GET_PARAMETER)>(errorOccurred);
break;
}
case static_cast<uint8_t>(Cmd::SET_DEVICE_PARAMETERS):
break;
case static_cast<uint8_t>(Cmd::OSCCAL):
break;
case static_cast<uint8_t>(Cmd::LOAD_ADDRESS):
break;
case static_cast<uint8_t>(Cmd::FIRMWARE_UPGRADE):
break;
}
}
template <uint8_t Command>
inline void sendReply(bool errorOccurred = false)
{
if constexpr (Command == Cmd::SIGN_ON) {
m_msg.size = 3 + 8;
m_msg.body[1] = static_cast<uint8_t>(Status::CMD_OK);
m_msg.body[2] = 8;
m_msg.body[3] = 'S';
m_msg.body[4] = 'T';
m_msg.body[5] = 'K';
m_msg.body[6] = '5';
m_msg.body[7] = '0';
m_msg.body[8] = '0';
m_msg.body[9] = '_';
m_msg.body[10] = '2';
} else if (Command == Cmd::SET_PARAMETER) {
m_msg.size = 2;
m_msg.body[1] = static_cast<uint8_t>(Status::CMD_OK);
} else if (Command == Cmd::GET_PARAMETER) {
if (!errorOccurred) {
m_msg.size = 3;
m_msg.body[1] = static_cast<uint8_t>(Status::CMD_OK);
} else {
m_msg.size = 2;
m_msg.body[1] = static_cast<uint8_t>(Status::CMD_FAILED);
}
}
m_msg.checksum = calcChecksum();
transmitMessage();
}
};
} // namespace stk500v2

View File

@@ -28,9 +28,10 @@
<ResetRule>0</ResetRule> <ResetRule>0</ResetRule>
<eraseonlaunchrule>0</eraseonlaunchrule> <eraseonlaunchrule>0</eraseonlaunchrule>
<EraseKey /> <EraseKey />
<avrtool>com.atmel.avrdbg.tool.atmelice</avrtool> <avrtool>
</avrtool>
<avrtoolserialnumber>J41800099437</avrtoolserialnumber> <avrtoolserialnumber>J41800099437</avrtoolserialnumber>
<avrdeviceexpectedsignature>0x1E950F</avrdeviceexpectedsignature> <avrdeviceexpectedsignature>0x1E9705</avrdeviceexpectedsignature>
<com_atmel_avrdbg_tool_stk500> <com_atmel_avrdbg_tool_stk500>
<ToolOptions> <ToolOptions>
<InterfaceProperties> <InterfaceProperties>
@@ -93,122 +94,128 @@
</ToolNumber> </ToolNumber>
<ToolName xmlns="">Simulator</ToolName> <ToolName xmlns="">Simulator</ToolName>
</com_atmel_avrdbg_tool_simulator> </com_atmel_avrdbg_tool_simulator>
<AAFDebugger>
<AAFDebugFiles>
</AAFDebugFiles>
</AAFDebugger>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings> <ToolchainSettings>
<AvrGccCpp> <AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p</avrgcc.common.Device> <avrgcc.common.Device>-mmcu=atmega1284p</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex> <avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec> <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures> <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.symbols.DefSymbols> <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<ListValues> <avrgcc.compiler.symbols.DefSymbols>
<Value>NDEBUG</Value> <ListValues>
</ListValues> <Value>NDEBUG</Value>
</avrgcc.compiler.symbols.DefSymbols> </ListValues>
<avrgcc.compiler.directories.IncludePaths> </avrgcc.compiler.symbols.DefSymbols>
<ListValues> <avrgcc.compiler.directories.IncludePaths>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <ListValues>
</ListValues> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</avrgcc.compiler.directories.IncludePaths> </ListValues>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level> </avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum> <avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings> <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings> <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic> <avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags> <avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.symbols.DefSymbols> <avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<ListValues> <avrgcccpp.compiler.symbols.DefSymbols>
<Value>NDEBUG</Value> <ListValues>
</ListValues> <Value>NDEBUG</Value>
</avrgcccpp.compiler.symbols.DefSymbols> </ListValues>
<avrgcccpp.compiler.directories.IncludePaths> </avrgcccpp.compiler.symbols.DefSymbols>
<ListValues> <avrgcccpp.compiler.directories.IncludePaths>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <ListValues>
</ListValues> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</avrgcccpp.compiler.directories.IncludePaths> </ListValues>
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level> </avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum> <avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings> <avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic> <avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags> <avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.linker.libraries.Libraries> <avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags>
<ListValues> <avrgcccpp.linker.libraries.Libraries>
<Value>libm</Value> <ListValues>
</ListValues> <Value>libm</Value>
</avrgcccpp.linker.libraries.Libraries> </ListValues>
<avrgcccpp.assembler.general.IncludePaths> </avrgcccpp.linker.libraries.Libraries>
<ListValues> <avrgcccpp.assembler.general.IncludePaths>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <ListValues>
</ListValues> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</avrgcccpp.assembler.general.IncludePaths> </ListValues>
</AvrGccCpp> </avrgcccpp.assembler.general.IncludePaths>
</AvrGccCpp>
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings> <ToolchainSettings>
<AvrGccCpp> <AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p</avrgcc.common.Device> <avrgcc.common.Device>-mmcu=atmega1284p</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex> <avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> <avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec> <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures> <avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.symbols.DefSymbols> <avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<ListValues> <avrgcc.compiler.symbols.DefSymbols>
<Value>DEBUG</Value> <ListValues>
</ListValues> <Value>DEBUG</Value>
</avrgcc.compiler.symbols.DefSymbols> </ListValues>
<avrgcc.compiler.directories.IncludePaths> </avrgcc.compiler.symbols.DefSymbols>
<ListValues> <avrgcc.compiler.directories.IncludePaths>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <ListValues>
</ListValues> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</avrgcc.compiler.directories.IncludePaths> </ListValues>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level> </avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum> <avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel> <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings> <avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings> <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic> <avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags> <avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned> <avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.symbols.DefSymbols> <avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<ListValues> <avrgcccpp.compiler.symbols.DefSymbols>
<Value>DEBUG</Value> <ListValues>
</ListValues> <Value>DEBUG</Value>
</avrgcccpp.compiler.symbols.DefSymbols> </ListValues>
<avrgcccpp.compiler.directories.IncludePaths> </avrgcccpp.compiler.symbols.DefSymbols>
<ListValues> <avrgcccpp.compiler.directories.IncludePaths>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <ListValues>
</ListValues> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</avrgcccpp.compiler.directories.IncludePaths> </ListValues>
<avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level> </avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum> <avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcccpp.compiler.optimization.DebugLevel> <avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings> <avrgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcccpp.compiler.optimization.DebugLevel>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic> <avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags> <avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.linker.libraries.Libraries> <avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags>
<ListValues> <avrgcccpp.linker.libraries.Libraries>
<Value>libm</Value> <ListValues>
</ListValues> <Value>libm</Value>
</avrgcccpp.linker.libraries.Libraries> </ListValues>
<avrgcccpp.assembler.general.IncludePaths> </avrgcccpp.linker.libraries.Libraries>
<ListValues> <avrgcccpp.assembler.general.IncludePaths>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value> <ListValues>
</ListValues> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.4.346\include</Value>
</avrgcccpp.assembler.general.IncludePaths> </ListValues>
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel> </avrgcccpp.assembler.general.IncludePaths>
</AvrGccCpp> <avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
</AvrGccCpp>
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>