ide: the Atmel Studio solution master has, on the libavr port

master opens in Studio, so this branch should too. The solution builds
example/main.cpp — the port's only executable, the driver itself being an
INTERFACE library — for the ATmega328P that solution targeted, and the
acceptance is not that it builds but that it builds the same firmware: .text
comes out byte-identical to CMake's at 1242 B.

One project, one chip. Studio carries avrdevice as a project property, so the
attiny85 half of the presets would need a second project rather than a second
configuration; CMake stays the build system and covers both.

libavr is found beside this repo, anchored to the project directory rather than
written relative to the generated makefile, which runs from the configuration's
output directory. No LIBAVR_ROOT: a variable exported in a shell is invisible to
Studio launched from the Start menu.

Both configurations verified headless with LIBAVR_ROOT unset, and the flag
mirror checked against the CMake build's own compile_commands.json.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 19:33:39 +02:00
committed by BlackMark
parent cdca5219d0
commit dc89d0779a
4 changed files with 168 additions and 0 deletions

7
.gitignore vendored
View File

@@ -1,2 +1,9 @@
build/
.cache/
# Atmel Studio: generated per machine, its build outputs, and per-user state
ide/*.componentinfo.xml
ide/Debug/
ide/Release/
ide/.vs/
ide/*.log

View File

@@ -24,6 +24,37 @@ cmake --build --preset attiny85-generated
Presets cover attiny85/atmega328p in both libavr modes (generated and
reflect). The legacy yazoalfa-based driver lives on the `master` branch.
## Atmel Studio
`master` carries a Studio solution, so this branch does too: `ide/ds3231.atsln`
builds `example/main.cpp` for the ATmega328P — the chip that solution targeted —
to a **byte-identical `.text`** (1242 B) against the CMake build, with the flags
mirrored by hand. One project, one chip: `avrdevice` is a project-level property
in Studio, so the attiny85 half of the presets has no equivalent here, and CMake
remains the build system.
Studio expects libavr checked out **beside this repo** and finds it at
`$(MSBuildProjectDirectory)\..\..\libavr\include` — anchored to the project,
because a plain relative path is resolved against the generated makefile's
directory (the configuration's output directory), not the project's. There is no
`LIBAVR_ROOT` escape hatch: a variable exported in a shell is invisible to Studio
launched from the Start menu. It also needs a GCC 16.1 toolchain registered as
flavour `avr-g++-16.1.0`, nothing older reaching `-std=c++26`.
One generated file is required before the project will load, and one command
checks the flags have not drifted (both from libavr's `tools/atmelstudio/`):
```sh
python ../libavr/tools/atmelstudio/componentinfo.py \
ide/ds3231.componentinfo.xml --device ATmega328P
python ../libavr/tools/atmelstudio/check-flags.py --solution ide/ds3231.atsln \
--compile-commands build/atmega328p-generated/compile_commands.json \
--log build/atmelstudio.log
```
Release is what the gate compares, the presets defining no debug build; Debug
carries the `-Og -gdwarf-4` pair libavr's own debug preset uses.
Differences from legacy: weekday-rate alarms now actually set the DY bit
(the old `setAlarmHelper` always cleared it), reads/writes are single
coherent bus transactions, and errors are reported instead of ignored.

22
ide/ds3231.atsln Normal file
View File

@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Atmel Studio Solution File, Format Version 11.00
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "ds3231", "ds3231.cppproj", "{7B3E5A41-9C26-4D18-8F52-6A0D31C74BE9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AVR = Debug|AVR
Release|AVR = Release|AVR
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7B3E5A41-9C26-4D18-8F52-6A0D31C74BE9}.Debug|AVR.ActiveCfg = Debug|AVR
{7B3E5A41-9C26-4D18-8F52-6A0D31C74BE9}.Debug|AVR.Build.0 = Debug|AVR
{7B3E5A41-9C26-4D18-8F52-6A0D31C74BE9}.Release|AVR.ActiveCfg = Release|AVR
{7B3E5A41-9C26-4D18-8F52-6A0D31C74BE9}.Release|AVR.Build.0 = Release|AVR
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

108
ide/ds3231.cppproj Normal file
View File

@@ -0,0 +1,108 @@
<?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>7b3e5a41-9c26-4d18-8f52-6a0d31c74be9</ProjectGuid>
<avrdevice>ATmega328P</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>CPP</Language>
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
<OutputFileExtension>.elf</OutputFileExtension>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<AssemblyName>ds3231</AssemblyName>
<Name>ds3231</Name>
<RootNamespace>ds3231</RootNamespace>
<ToolchainFlavour>avr-g++-16.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 />
</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>
<avrgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>$(MSBuildProjectDirectory)\..\include</Value>
<Value>$(MSBuildProjectDirectory)\..\..\libavr\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</avrgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>
<avrgcccpp.compiler.optimization.PrepareDataForGarbageCollection>True</avrgcccpp.compiler.optimization.PrepareDataForGarbageCollection>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-std=c++26 -Wextra -mrelax -fno-exceptions -fno-rtti -fno-threadsafe-statics</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.optimization.GarbageCollectUnusedSections>True</avrgcccpp.linker.optimization.GarbageCollectUnusedSections>
<avrgcccpp.linker.miscellaneous.LinkerFlags>-mrelax</avrgcccpp.linker.miscellaneous.LinkerFlags>
</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>
<avrgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>$(MSBuildProjectDirectory)\..\include</Value>
<Value>$(MSBuildProjectDirectory)\..\..\libavr\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</avrgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>
<avrgcccpp.compiler.optimization.PrepareDataForGarbageCollection>True</avrgcccpp.compiler.optimization.PrepareDataForGarbageCollection>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-std=c++26 -Wextra -mrelax -fno-exceptions -fno-rtti -fno-threadsafe-statics -gdwarf-4</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.optimization.GarbageCollectUnusedSections>True</avrgcccpp.linker.optimization.GarbageCollectUnusedSections>
<avrgcccpp.linker.miscellaneous.LinkerFlags>-mrelax</avrgcccpp.linker.miscellaneous.LinkerFlags>
</AvrGccCpp>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\example\main.cpp">
<SubType>compile</SubType>
<Link>example\main.cpp</Link>
</Compile>
<Compile Include="..\include\ds3231\ds3231.hpp">
<SubType>compile</SubType>
<Link>include\ds3231\ds3231.hpp</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="example" />
<Folder Include="include" />
<Folder Include="include\ds3231" />
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\Vs\Compiler.targets" />
</Project>