Add simavr-based automated test suite#148
Add simavr-based automated test suite#148GlassOnTin wants to merge 6 commits intoToyKeeper:trunkfrom
Conversation
607604e to
f8cc989
Compare
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
f8cc989 to
ec77ed3
Compare
|
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. |
|
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! |
|
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. |
This commit adds a protocol-based simulator interface for external UIs and fixes a critical bug where the ADC was reading 0V, causing spurious low voltage protection (LVP) stepdowns. New Features: - sim-interface: Protocol-based interface exposing Anduril simulator over stdin/stdout for integration with external UIs (Python, web, etc.) - PROTOCOL.md: Complete documentation of the text-based protocol - Temperature simulation: SETTEMP/GETTEMP commands with proper sensor emulation - EEPROM access: GETEEPROM, DUMPEEPROM, SETEEPROM for state inspection - Debug mode: DEBUG=1 environment variable enables detailed ADC/PWM logging - Voltage control: SETVOLTAGE command for battery voltage simulation Critical Bug Fixes: - Fixed ADC reading 0V which caused firmware to think battery was dead, triggering constant LVP stepdowns from turbo - Root cause: ADC values must be injected BEFORE simavr samples them, not in response to ADC_IRQ_OUT_TRIGGER - Discovered simavr requires 3x voltage scaling for correct ADC conversions (e.g., 730mV input requires 2190mV to get correct 678 ADC result) - Fixed ADC register addresses for ATtiny1634: ADCL=0x20, ADCH=0x21, ADCSRA=0x23, ADMUX=0x24 Technical Details: - ADC now properly reads battery voltage (e.g., 3.7V → 730mV after divider → 678 ADC counts with 1.1V ref) - Temperature sensor emulation uses linear mapping: 25°C = 300mV, ±10mV/°C - Protocol supports both simple commands (CLICK, RESET) and parameterized commands (RUN:50, SETVOLTAGE:3700) - Responses: OK, ERROR:msg, PWM:main2,led3,led4, EEPROM:hexdata, BYE Protocol Command Summary: INIT:hexfile - Initialize simulator with firmware RESET - Reset AVR to power-on state CLICK - Single button click (~80ms press + ~128ms gap) MULTI:N - Multi-click sequence (2C, 3C, etc.) HOLD:N - Press and hold for N WDT ticks (~16ms each) PRESS/RELEASE - Manual button control RUN:N - Advance simulation by N ticks GETPWM - Read current PWM values SETVOLTAGE:mV - Set battery voltage (2000-4500mV) SETTEMP:C - Set temperature (-40 to 85°C) GETTEMP - Read current temperature GETEEPROM:offset,len - Read EEPROM bytes DUMPEEPROM - Read all 256 EEPROM bytes SETEEPROM:offset,value - Write EEPROM byte QUIT - Shutdown simulator Files Changed: - sim/Makefile: Added sim-interface build target - sim/sim-interface.c: New protocol handler (479 lines) - sim/PROTOCOL.md: Complete protocol documentation (711 lines) - sim/tests/anduril-test.c: Fixed ADC injection, added temp/EEPROM support - sim/tests/anduril-test.h: Added new API functions Testing: make sim-interface echo -e "INIT:../hex/anduril.hex\nRESET\nSETVOLTAGE:3700\nRUN:50\nGETPWM\nQUIT" | ./sim-interface This enables building external UIs (Python/Tkinter, web-based, etc.) that communicate with the simulator via a simple text protocol over stdin/stdout. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Move last_adcsra variable declaration outside #if TEST_VERBOSE block
to fix undeclared variable error with stricter GCC 14 compiler
- Use dynamic platform detection for simavr obj directory instead of
hardcoded x86_64-linux-gnu (fixes Void Linux and other distros)"
|
@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 😅 |
The CLICK_GAP_TICKS delay made UI clicks feel unresponsive and prevented rapid clicks from registering as multi-clicks (2C, 3C, etc). Now anduril_click() only simulates the button press duration, letting the UI/user control click timing naturally. Multi-click functions still use gaps for automated testing.
Extend simulator to read and report RGB aux LED states (PA5/PA4/PA3). Each aux LED can be: off (0), low via pullup (1), or high (2). Changes: - Extended pwm_state_t to include aux_r, aux_g, aux_b fields - Updated anduril_get_pwm() to read DDRA and PUEA registers - Extended GETPWM protocol to output 6 values instead of 3 - Detects off/low/high states by checking DDR and pullup registers This enables UI visualization of aux LED states including low-mode operation using the MCU's internal pullup resistors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add interactive simulator interface and fix critical ADC bug, fix tests for gcc 14.x
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
Requirements
# Ubuntu/Debian sudo apt install gcc make libelf-dev avr-libc gcc-avrTest Framework
sim/tests/anduril-test.h/c - Test API providing:
anduril_click(),anduril_multi_click(),anduril_button_set()anduril_get_pwm()returns main2, led3, led4 valuesanduril_run_ticks()advances WDT cyclesTEST_BEGIN,TEST_PASS,TEST_FAIL,ASSERTTest Suites (18 tests)
ATtiny1634 Core
Custom simavr core (sim/simavr-core/) for the ATtiny1634 MCU:
Usage
Directory Structure
Dependencies
Requires simavr with ATtiny1634 support. Until upstream merges the core:
Test Plan