Skip to content

Conversation

@GlassOnTin
Copy link

@GlassOnTin GlassOnTin commented Dec 10, 2025

Summary

Adds a cycle-accurate AVR emulator test infrastructure using simavr. Tests run actual compiled firmware hex files, providing true integration testing rather than mocked unit tests.

Quick Start

# 1. Clone simavr with ATtiny1634 support
git clone https://github.com/GlassOnTin/simavr.git

# 2. Build simavr
cd simavr/simavr && make && cd ../..

# 3. Build firmware and run tests
cd sim && make test

Requirements

# Ubuntu/Debian
sudo apt install gcc make libelf-dev avr-libc gcc-avr

Test Framework

sim/tests/anduril-test.h/c - Test API providing:

  • Button simulation: anduril_click(), anduril_multi_click(), anduril_button_set()
  • PWM state reading: anduril_get_pwm() returns main2, led3, led4 values
  • Timing control: anduril_run_ticks() advances WDT cycles
  • Test macros: TEST_BEGIN, TEST_PASS, TEST_FAIL, ASSERT

Test Suites (18 tests)

Suite Tests Coverage
test_basic_ui.c 8 On/off, hold, 2C turbo, 4C lockout/unlock
test_ramping.c 6 Ramp up/down, floor/ceiling limits, memory
test_channel_modes.c 4 3C mode switching, persistence, cycling

ATtiny1634 Core

Custom simavr core (sim/simavr-core/) for the ATtiny1634 MCU:

  • 16KB Flash, 1KB SRAM, 256B EEPROM
  • Timer0 (8-bit), Timer1 (16-bit) with PWM support
  • GPIO ports A, B, C with proper pin mapping

Usage

make test           # Run all 18 tests
make test-basic     # Run basic UI tests only
make test-ramping   # Run ramping tests only
make test-channel   # Run channel mode tests only
make test-verbose   # Run with debug output

Directory Structure

anduril/
├── sim/
│   ├── README.md           # Full documentation
│   ├── Makefile
│   ├── tests/
│   │   ├── anduril-test.h  # Test framework API
│   │   ├── anduril-test.c  # Test framework implementation
│   │   ├── test_basic_ui.c
│   │   ├── test_ramping.c
│   │   └── test_channel_modes.c
│   └── simavr-core/
│       └── sim_tiny1634.*  # ATtiny1634 core
├── simavr/                 # Clone here (sibling to sim/)
└── hex/
    └── anduril.*.hex       # Compiled firmware

Dependencies

Requires simavr with ATtiny1634 support. Until upstream merges the core:

Test Plan

  • All 18 tests pass on D4K-3ch firmware
  • Tests detect regressions (verified by intentionally breaking firmware)
  • Verbose mode shows button presses and interrupt timing
  • README with setup instructions and API documentation
  • CI integration (future work)

Adds a cycle-accurate AVR emulator test infrastructure using simavr
with ATtiny1634 support. Tests run actual compiled firmware hex files,
providing true integration testing of the firmware.

## Test Framework (sim/tests/)

- anduril-test.h/c: Test API with button simulation, PWM reading, timing
- Macros: TEST_BEGIN, TEST_PASS, TEST_FAIL, ASSERT
- Helpers: anduril_click(), anduril_multi_click(), anduril_get_pwm()

## Test Suites (18 tests total)

- test_basic_ui.c (8 tests): on/off, hold, turbo, lockout
- test_ramping.c (6 tests): ramp up/down, floor/ceiling, memory
- test_channel_modes.c (4 tests): 3C switching, persistence, cycling

## ATtiny1634 Core (sim/simavr-core/)

Custom simavr core for ATtiny1634 MCU used in Anduril flashlights:
- 16KB Flash, 1KB SRAM, 256B EEPROM
- Timer0 (8-bit), Timer1 (16-bit) with PWM
- GPIO ports A, B, C

## Makefile Targets

- make test: Run all 18 tests
- make test-basic/ramping/channel: Run individual suites
- make test-verbose: Debug output with button/interrupt traces

## Dependencies

Requires simavr with ATtiny1634 core support:
- Fork: https://github.com/GlassOnTin/simavr
- Upstream PR: buserror/simavr#568
@ToyKeeper
Copy link
Owner

Hi, it looks like you've been doing some really cool stuff with Anduril. Thanks!

I'm looking forward to checking it out in detail, and hopefully merging it. It might take me a while though, since I've got a lot going on and have a lot to catch up on. Just wanted to let you know, for now, that I see it and it is not being ignored. I'm just slow.

The simavr stuff in particular seems really nice. I briefly tried to simulate things once for testing purposes, and didn't get very far... so it's awesome to see that concept actually implemented. I also set up an automated hardware testing thing at one point, but it didn't end up being very practical for this purpose because button-press and measurement latency was too high, so it never got past an early proof of concept. So I've just been testing manually all this time.

Automated tests will be particularly relevant for some big upcoming changes I'm hoping to do. Specifically, I'd like to expand the simple/advanced mode concept so the user can instead choose from several entirely different interfaces. But that'll greatly expand the amount of testing needed, so automation is very welcome.

@GlassOnTin
Copy link
Author

I'd be happy to write a few tests or discuss them with you when you're looking to implement your new features.

Test Driven Development is a helpful strategy at times when pushing the feature boundaries!

@SiteRelEnby
Copy link
Contributor

Taking a look into this PR, this has been vaguely on my mind for ages but no real experience with simavr, got a bit of time at the moment so might take a dive into it.

@SiteRelEnby
Copy link
Contributor

@GlassOnTin really nice work, managed to build some interesting stuff on top of this already. Did run into a use-after-free that caused a few heisenbugs on our part, opened a PR against simavr here: buserror/simavr#569 - would appreciate it if you could test with your toolchain to see if it works with that fix as a sanity check as this is way outside my usual context of dev work 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants