From ce9a5b6ea51883f871c88fe47fd59b3ffac246ca Mon Sep 17 00:00:00 2001 From: glopesdev Date: Wed, 18 Feb 2026 15:20:28 +0000 Subject: [PATCH 1/7] Use external Makefile to build firmware project This will ensure the same steps are used when building the firmware either from Atmel Studio or through the CI pipeline. --- .gitignore | 1 + Firmware/Behavior/Behavior.cproj | 176 +++++++++++++++---------------- Firmware/Behavior/Makefile | 62 +++++++++++ 3 files changed, 151 insertions(+), 88 deletions(-) create mode 100644 Firmware/Behavior/Makefile diff --git a/.gitignore b/.gitignore index fd28932..00cb6ad 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,6 @@ desktop.ini bin obj Debug +Release packages *.componentinfo.xml \ No newline at end of file diff --git a/Firmware/Behavior/Behavior.cproj b/Firmware/Behavior/Behavior.cproj index 619de21..f1dfa4e 100644 --- a/Firmware/Behavior/Behavior.cproj +++ b/Firmware/Behavior/Behavior.cproj @@ -60,100 +60,100 @@ - -mmcu=atxmega128a1u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega128a1u" - True - True - True - True - True - False - True - True - - - NDEBUG - - - - - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include - - - Optimize for size (-Os) - True - True - True - - - libm - - - - - C:\Users\Filipe Carvalho\Documents\BitBucket\Device.Synchronizer\Firmware_\Synchronizer\Synchronizer\Synchronizer - C:\Users\Filipe Carvalho\Documents\BitBucket\Device.Synchronizer\Firmware_\Synchronizer\Synchronizer - C:\Users\Filipe Carvalho\Documents\BitBucket\Device.Synchronizer\Firmware\Synchronizer - C:\Users\Filipe Carvalho\Documents\BitBucket\Device.Behavior\Firmware\Behavior - C:\Users\CR Filipe\Documents\BitBucket\Device.Behavior\Firmware\Behavior - C:\Users\Filipe Carvalho\Documents\BitBucket\Device.Wear.Basestation\Firmware\Master - C:\Users\Filipe Carvalho\Documents\BitBucket.FilCarvalho\Harp\Corelibrary.Atxmega\Downloads - C:\Users\Work\Documents\device.behavior\Firmware\Behavior - - - - - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include - - - + -mmcu=atxmega128a1u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega128a1u" + True + True + True + True + True + False + True + True + + + NDEBUG + + + + + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include + + + Optimize for size (-Os) + True + True + True + + + libm + libATxmega128A1U-1.15.a + + + + + .. + + + + + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include + + + - -mmcu=atxmega128a1u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega128a1u" - True - True - True - True - True - False - True - True - - - DEBUG - - - - - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include - - - Optimize most (-O3) - True - True - Default (-g2) - True - - - libm - libATxmega128A1U-1.15.a - - - - - .. - - - - - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include - - - Default (-Wa,-g) - + -mmcu=atxmega128a1u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega128a1u" + True + True + True + True + True + False + True + True + + + DEBUG + + + + + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include + + + Optimize most (-O3) + True + True + Default (-g2) + True + + + libm + libATxmega128A1U-1.15.a + + + + + .. + + + + + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include + + + Default (-Wa,-g) + + True + + + all + clean + Makefile diff --git a/Firmware/Behavior/Makefile b/Firmware/Behavior/Makefile new file mode 100644 index 0000000..ac7fd4f --- /dev/null +++ b/Firmware/Behavior/Makefile @@ -0,0 +1,62 @@ +PRJ_NAME = Behavior +CORE = ATxmega128A1U +MCU = atxmega128a1u +CORE_VERSION = 1.15 + +# Files and directories +BUILD_DIR = bin +SRCS = $(wildcard *.c) +OBJS = $(SRCS:%.c=$(BUILD_DIR)/%.o) +LIBS = -l$(CORE)-$(CORE_VERSION) + + +# Compiler flags +CC = avr-gcc +CFLAGS = \ +-x c \ +-funsigned-char \ +-funsigned-bitfields \ +-ffunction-sections \ +-fdata-sections \ +-fpack-struct \ +-fshort-enums \ +-mrelax \ +-O3 \ +-Wall \ +-mmcu=$(MCU) \ +-std=gnu99 + +# Linker flags +LDFLAGS = \ +-Wl,--start-group \ +-Wl,-lm \ +-Wl,$(LIBS) \ +-Wl,--end-group \ +-Wl,-L"." \ +-Wl,--gc-sections \ +-mrelax \ +-mmcu=$(MCU) + +# Object copy flags +OBJCOPY = avr-objcopy +OBJCOPY_FLAGS = \ +-O ihex \ +-R .eeprom \ +-R .fuse \ +-R .lock \ +-R .signature \ +-R .user_signatures \ + +all: $(BUILD_DIR)/$(PRJ_NAME)-harp$(CORE_VERSION).hex + +$(BUILD_DIR): + mkdir "$(BUILD_DIR)" + +$(BUILD_DIR)/%.o: %.c $(BUILD_DIR) + $(CC) $(CFLAGS) -c $(INCS) -MD -MP -MF "$(@:.o=.d)" -MT"$(@:.o=.d)" -MT"$@" -o $@ $< + +$(BUILD_DIR)/%.elf: $(OBJS) + $(CC) -o $@ $(OBJS) -Wl,-Map="$(@:.elf=.map)" $(LDFLAGS) $(LIBS) + +$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf + $(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ From 03745436b177cb474e0ed3068797dd88cd7f6c59 Mon Sep 17 00:00:00 2001 From: glopesdev Date: Wed, 18 Feb 2026 15:26:45 +0000 Subject: [PATCH 2/7] Add firmware build to CI workflow Currently uses the same AVR-GCC toolchain version to ensure reproducible builds. --- .github/workflows/Harp.Behavior.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Harp.Behavior.yml b/.github/workflows/Harp.Behavior.yml index df4c0e2..6bde819 100644 --- a/.github/workflows/Harp.Behavior.yml +++ b/.github/workflows/Harp.Behavior.yml @@ -13,6 +13,7 @@ env: DOTNET_GENERATE_ASPNET_CERTIFICATE: false ContinuousIntegrationBuild: true CiBuildVersion: ${{github.event.release.tag_name || 'api42.42.42'}} + AVR_TOOLCHAIN_URL: https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/SoftwareTools/avr8-gnu-toolchain-3.6.2.1778-win32.any.x86.zip jobs: build: strategy: @@ -22,7 +23,7 @@ jobs: include: - configuration: Release collect-packages: true - name: Build + name: Build Interface runs-on: windows-latest if: github.event_name != 'release' || startsWith(github.event.release.tag_name, 'api') steps: @@ -39,6 +40,12 @@ jobs: - name: Set up T4 run: dotnet tool install -g dotnet-t4 --version 3.0.0 + - name: Set up AVR-GCC + run: | + Invoke-WebRequest -Uri $env:AVR_TOOLCHAIN_URL -OutFile $HOME\avr8-gnu-toolchain-win32_x86_64.zip + Expand-Archive $HOME\avr8-gnu-toolchain-win32_x86_64.zip -DestinationPath $HOME -Force + echo "$(Resolve-Path $HOME\avr8-gnu-toolchain-win32_x86\bin)" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + # ----------------------------------------------------------------------- Regenerate - name: Restore generators run: dotnet restore Generators @@ -52,6 +59,12 @@ jobs: git add . --intent-to-add --ignore-removal git diff --name-status --exit-code + # ----------------------------------------------------------------------- Build firmware + - name: Build firmware + working-directory: Firmware/Behavior + shell: bash + run: make all + # ----------------------------------------------------------------------- Build interface package - name: Restore interface run: dotnet restore Interface @@ -72,6 +85,14 @@ jobs: if-no-files-found: error path: Interface/bin/${{matrix.configuration}}/** + - name: Collect Firmware binaries + uses: actions/upload-artifact@v4 + if: matrix.collect-packages && steps.pack.outcome == 'success' && always() + with: + name: Firmware + if-no-files-found: error + path: Firmware/Behavior/bin/*.hex + publish-packages-nuget-org: name: Publish packages to NuGet.org runs-on: ubuntu-latest From f8a7719c666d927989db9947044d67611f736538 Mon Sep 17 00:00:00 2001 From: glopesdev Date: Wed, 18 Feb 2026 15:47:53 +0000 Subject: [PATCH 3/7] Add clean target --- Firmware/Behavior/Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Firmware/Behavior/Makefile b/Firmware/Behavior/Makefile index ac7fd4f..fe66777 100644 --- a/Firmware/Behavior/Makefile +++ b/Firmware/Behavior/Makefile @@ -5,11 +5,11 @@ CORE_VERSION = 1.15 # Files and directories BUILD_DIR = bin +BUILD_NAME = $(PRJ_NAME)-harp$(CORE_VERSION) SRCS = $(wildcard *.c) OBJS = $(SRCS:%.c=$(BUILD_DIR)/%.o) LIBS = -l$(CORE)-$(CORE_VERSION) - # Compiler flags CC = avr-gcc CFLAGS = \ @@ -47,7 +47,13 @@ OBJCOPY_FLAGS = \ -R .signature \ -R .user_signatures \ -all: $(BUILD_DIR)/$(PRJ_NAME)-harp$(CORE_VERSION).hex +all: $(BUILD_DIR)/$(BUILD_NAME).hex + +clean: + rm -f $(OBJS) $(OBJS:.o=.d) + rm -f $(BUILD_DIR)/$(BUILD_NAME).elf + rm -f $(BUILD_DIR)/$(BUILD_NAME).hex + rm -f $(BUILD_DIR)/$(BUILD_NAME).map $(BUILD_DIR): mkdir "$(BUILD_DIR)" From ef6c2da7e4f1eb0554ca08d3c07f3183b86de24b Mon Sep 17 00:00:00 2001 From: glopesdev Date: Sun, 22 Feb 2026 08:13:44 +0000 Subject: [PATCH 4/7] Allow building different hardware variants Define version numbers using conditional preprocessor flags which are then set via Makefile variants. --- Firmware/Behavior/Makefile | 10 +++++++++- Firmware/Behavior/app.c | 10 +++++----- Firmware/Behavior/app.h | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Firmware/Behavior/Makefile b/Firmware/Behavior/Makefile index fe66777..e4b8119 100644 --- a/Firmware/Behavior/Makefile +++ b/Firmware/Behavior/Makefile @@ -2,10 +2,14 @@ PRJ_NAME = Behavior CORE = ATxmega128A1U MCU = atxmega128a1u CORE_VERSION = 1.15 +FIRMWARE_VERSION ?= 3.3 +HARDWARE_VERSION ?= 2.0 # Files and directories BUILD_DIR = bin -BUILD_NAME = $(PRJ_NAME)-harp$(CORE_VERSION) +BUILD_NAME = $(PRJ_NAME)-fw$(FIRMWARE_VERSION)-harp$(CORE_VERSION)-hw$(HARDWARE_VERSION)-ass0 +FW_VERSION_WORDS = $(subst ., ,$(FIRMWARE_VERSION)) +HW_VERSION_WORDS = $(subst ., ,$(HARDWARE_VERSION)) SRCS = $(wildcard *.c) OBJS = $(SRCS:%.c=$(BUILD_DIR)/%.o) LIBS = -l$(CORE)-$(CORE_VERSION) @@ -24,6 +28,10 @@ CFLAGS = \ -O3 \ -Wall \ -mmcu=$(MCU) \ +-DMAJOR_FW_VERSION=$(word 1,$(FW_VERSION_WORDS)) \ +-DMINOR_FW_VERSION=$(word 2,$(FW_VERSION_WORDS)) \ +-DMAJOR_HW_VERSION=$(word 1,$(HW_VERSION_WORDS)) \ +-DMINOR_HW_VERSION=$(word 2,$(HW_VERSION_WORDS)) \ -std=gnu99 # Linker flags diff --git a/Firmware/Behavior/app.c b/Firmware/Behavior/app.c index 3c1cc36..4d6ada6 100644 --- a/Firmware/Behavior/app.c +++ b/Firmware/Behavior/app.c @@ -33,11 +33,11 @@ static const uint8_t default_device_name[] = "Behavior"; void hwbp_app_initialize(void) { /* Define versions */ - uint8_t hwH = 2; - uint8_t hwL = 0; - uint8_t fwH = 3; - uint8_t fwL = 3; - uint8_t ass = 0; + uint8_t hwH = MAJOR_HW_VERSION; + uint8_t hwL = MINOR_HW_VERSION; + uint8_t fwH = MAJOR_FW_VERSION; + uint8_t fwL = MINOR_FW_VERSION; + uint8_t ass = ASSEMBLY_VERSION; /* Start core */ core_func_start_core( diff --git a/Firmware/Behavior/app.h b/Firmware/Behavior/app.h index f6dbf9a..8686bcf 100644 --- a/Firmware/Behavior/app.h +++ b/Firmware/Behavior/app.h @@ -3,6 +3,26 @@ #include +/************************************************************************/ +/* Define versions */ +/************************************************************************/ +#ifndef MAJOR_HW_VERSION +#define MAJOR_HW_VERSION 2 +#endif +#ifndef MINOR_HW_VERSION +#define MINOR_HW_VERSION 0 +#endif +#ifndef MAJOR_FW_VERSION +#define MAJOR_FW_VERSION 3 +#endif +#ifndef MINOR_FW_VERSION +#define MINOR_FW_VERSION 3 +#endif +#ifndef ASSEMBLY_VERSION +#define ASSEMBLY_VERSION 0 +#endif + + /************************************************************************/ /* Enable the interrupts */ /************************************************************************/ From 5d29c4b26d7af6e4cdea4ebc679820e7d4ca02d7 Mon Sep 17 00:00:00 2001 From: glopesdev Date: Sun, 22 Feb 2026 08:54:24 +0000 Subject: [PATCH 5/7] Extend CI/CD to build firmware for all hardware --- .github/workflows/Harp.Behavior.yml | 60 ++++++++++++++++++----------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/.github/workflows/Harp.Behavior.yml b/.github/workflows/Harp.Behavior.yml index 6bde819..062e56f 100644 --- a/.github/workflows/Harp.Behavior.yml +++ b/.github/workflows/Harp.Behavior.yml @@ -15,7 +15,43 @@ env: CiBuildVersion: ${{github.event.release.tag_name || 'api42.42.42'}} AVR_TOOLCHAIN_URL: https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/SoftwareTools/avr8-gnu-toolchain-3.6.2.1778-win32.any.x86.zip jobs: - build: + build-firmware: + strategy: + fail-fast: false + matrix: + hardware-target: ['1.1', '1.2', '2.0'] + name: Build Firmware (hw${{matrix.hardware-target}}) + runs-on: windows-latest + if: github.event_name != 'release' + steps: + # ----------------------------------------------------------------------- Checkout + - name: Checkout + uses: actions/checkout@v4 + + # ----------------------------------------------------------------------- Set up tools + - name: Set up AVR-GCC + run: | + Invoke-WebRequest -Uri $env:AVR_TOOLCHAIN_URL -OutFile $HOME\avr8-gnu-toolchain-win32_x86_64.zip + Expand-Archive $HOME\avr8-gnu-toolchain-win32_x86_64.zip -DestinationPath $HOME -Force + echo "$(Resolve-Path $HOME\avr8-gnu-toolchain-win32_x86\bin)" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + # ----------------------------------------------------------------------- Build firmware + - name: Build firmware + working-directory: Firmware/Behavior + id: build + shell: bash + run: make all HARDWARE_VERSION=${{matrix.hardware-target}} + + # ----------------------------------------------------------------------- Collect artifacts + - name: Collect Firmware binaries + uses: actions/upload-artifact@v4 + if: steps.build.outcome == 'success' && always() + with: + name: Firmware-hw${{matrix.hardware-target}} + if-no-files-found: error + path: Firmware/Behavior/bin/*.hex + + build-interface: strategy: fail-fast: false matrix: @@ -40,12 +76,6 @@ jobs: - name: Set up T4 run: dotnet tool install -g dotnet-t4 --version 3.0.0 - - name: Set up AVR-GCC - run: | - Invoke-WebRequest -Uri $env:AVR_TOOLCHAIN_URL -OutFile $HOME\avr8-gnu-toolchain-win32_x86_64.zip - Expand-Archive $HOME\avr8-gnu-toolchain-win32_x86_64.zip -DestinationPath $HOME -Force - echo "$(Resolve-Path $HOME\avr8-gnu-toolchain-win32_x86\bin)" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - # ----------------------------------------------------------------------- Regenerate - name: Restore generators run: dotnet restore Generators @@ -59,12 +89,6 @@ jobs: git add . --intent-to-add --ignore-removal git diff --name-status --exit-code - # ----------------------------------------------------------------------- Build firmware - - name: Build firmware - working-directory: Firmware/Behavior - shell: bash - run: make all - # ----------------------------------------------------------------------- Build interface package - name: Restore interface run: dotnet restore Interface @@ -85,14 +109,6 @@ jobs: if-no-files-found: error path: Interface/bin/${{matrix.configuration}}/** - - name: Collect Firmware binaries - uses: actions/upload-artifact@v4 - if: matrix.collect-packages && steps.pack.outcome == 'success' && always() - with: - name: Firmware - if-no-files-found: error - path: Firmware/Behavior/bin/*.hex - publish-packages-nuget-org: name: Publish packages to NuGet.org runs-on: ubuntu-latest @@ -100,7 +116,7 @@ jobs: # Needed to attach files to releases contents: write environment: public-release - needs: build + needs: [build-firmware, build-interface] if: github.event_name == 'release' steps: # ----------------------------------------------------------------------- Set up .NET From 5832f2914eb347d9fb21ec33e33ff1930301f016 Mon Sep 17 00:00:00 2001 From: glopesdev Date: Thu, 5 Mar 2026 22:00:44 +0000 Subject: [PATCH 6/7] Append run number as preview identifier This is temporary for backwards compatibility until we review firmware file naming conventions. --- .github/workflows/Harp.Behavior.yml | 2 +- Firmware/Behavior/Makefile | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Harp.Behavior.yml b/.github/workflows/Harp.Behavior.yml index 062e56f..24545be 100644 --- a/.github/workflows/Harp.Behavior.yml +++ b/.github/workflows/Harp.Behavior.yml @@ -40,7 +40,7 @@ jobs: working-directory: Firmware/Behavior id: build shell: bash - run: make all HARDWARE_VERSION=${{matrix.hardware-target}} + run: make all HARDWARE_VERSION=${{matrix.hardware-target}} PREVIEW_VERSION=${{github.run_number}} # ----------------------------------------------------------------------- Collect artifacts - name: Collect Firmware binaries diff --git a/Firmware/Behavior/Makefile b/Firmware/Behavior/Makefile index e4b8119..2f4c010 100644 --- a/Firmware/Behavior/Makefile +++ b/Firmware/Behavior/Makefile @@ -7,7 +7,8 @@ HARDWARE_VERSION ?= 2.0 # Files and directories BUILD_DIR = bin -BUILD_NAME = $(PRJ_NAME)-fw$(FIRMWARE_VERSION)-harp$(CORE_VERSION)-hw$(HARDWARE_VERSION)-ass0 +PREVIEW_SUFFIX = $(if $(PREVIEW_VERSION),-preview$(PREVIEW_VERSION),) +BUILD_NAME = $(PRJ_NAME)-fw$(FIRMWARE_VERSION)-harp$(CORE_VERSION)-hw$(HARDWARE_VERSION)-ass0$(PREVIEW_SUFFIX) FW_VERSION_WORDS = $(subst ., ,$(FIRMWARE_VERSION)) HW_VERSION_WORDS = $(subst ., ,$(HARDWARE_VERSION)) SRCS = $(wildcard *.c) From 40d6160cff307b43f3b0639359a55c8714960b98 Mon Sep 17 00:00:00 2001 From: glopesdev Date: Fri, 6 Mar 2026 09:00:31 +0000 Subject: [PATCH 7/7] Use preview version as default in local builds To drop the preview suffix entirely, release tags are expected to start with the character 'v'. --- Firmware/Behavior/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firmware/Behavior/Makefile b/Firmware/Behavior/Makefile index 2f4c010..eda32d5 100644 --- a/Firmware/Behavior/Makefile +++ b/Firmware/Behavior/Makefile @@ -4,10 +4,11 @@ MCU = atxmega128a1u CORE_VERSION = 1.15 FIRMWARE_VERSION ?= 3.3 HARDWARE_VERSION ?= 2.0 +PREVIEW_VERSION ?= 0 # Files and directories BUILD_DIR = bin -PREVIEW_SUFFIX = $(if $(PREVIEW_VERSION),-preview$(PREVIEW_VERSION),) +PREVIEW_SUFFIX = $(if $(PREVIEW_VERSION:v%=),-preview$(PREVIEW_VERSION),) BUILD_NAME = $(PRJ_NAME)-fw$(FIRMWARE_VERSION)-harp$(CORE_VERSION)-hw$(HARDWARE_VERSION)-ass0$(PREVIEW_SUFFIX) FW_VERSION_WORDS = $(subst ., ,$(FIRMWARE_VERSION)) HW_VERSION_WORDS = $(subst ., ,$(HARDWARE_VERSION))