src/platforms/avr/README.md
AVR support for classic Arduino boards (e.g., ATmega328P/UNO) and many ATtiny/ATmega variants.
The AVR platform is organized by hardware capability to improve maintainability and reduce cognitive load:
platforms/avr/
├── attiny/ # ATtiny family (no MUL instruction, limited resources)
│ ├── math/ # ATtiny-specific math implementations (software multiply)
│ │ ├── math8_attiny.h
│ │ └── scale8_attiny.h
│ └── pins/ # ATtiny pin mappings (all ATtiny variants)
│ └── fastpin_attiny.h
│
└── atmega/ # ATmega family (with MUL instruction)
├── common/ # Shared across all ATmega variants
│ ├── avr_pin.h # Core _AVRPIN template
│ ├── math8_avr.h # Optimized math (MUL instruction)
│ ├── scale8_avr.h # Optimized scaling (AVR assembly)
│ ├── trig8.h # Trigonometry functions
│ ├── fastpin_avr_legacy_dispatcher.h # Pin routing dispatcher
│ └── fastpin_legacy_other.h # Less common ATmega variants
│
├── m328p/ # Arduino UNO, Nano (ATmega328P family)
│ └── fastpin_m328p.h
│
├── m32u4/ # Leonardo, Pro Micro (USB-capable ATmega32U4)
│ └── fastpin_m32u4.h
│
├── m2560/ # Arduino MEGA (high pin count)
│ └── fastpin_m2560.h
│
└── m4809/ # Modern ATmega with VPORT registers
├── fastpin_avr_atmega4809.h
└── fastpin_avr_nano_every.h
The hierarchical structure reflects actual hardware differences:
Instruction Set Differences:
FL_IS_AVR_ATTINY preprocessor defineRegister Architecture:
Shared AVR Code (remains in platforms/avr/ root):
All existing code continues to work unchanged. Dispatcher headers route to correct implementations transparently:
fastpin_avr.h → dispatches to VPORT or legacy pin mappingsmath8.h → dispatches to ATtiny or ATmega math implementationsscale8.h → dispatches to software or hardware multiply implementationsvolatile unsigned long timer_millis symbol for boards missing a timer implementation.timer_millis implementation for select ATtinyx/y parts; initialized via constructor.FASTLED_USE_PROGMEM==1, FASTLED_ALLOW_INTERRUPTS==0, F_CPU sanity).fastpin_avr.h, fastspi_avr.h, clockless_avr.h.atmega/common/fastpin_avr_legacy_dispatcher.h (deprecated, will be removed in v4.0).attiny/math/math8_attiny.h (software multiply) or atmega/common/math8_avr.h (hardware MUL) based on FL_IS_AVR_ATTINY.attiny/math/scale8_attiny.h or atmega/common/scale8_avr.h based on FL_IS_AVR_ATTINY.atmega/common/trig8.h (ATmega only, requires MUL instruction)._AVRPIN template used by FastPin<> specializations for direct port IO (hi/lo/toggle, masks, ports).AVR_HARDWARE_SPI, HAS_HARDWARE_PIN_SUPPORT, SPI pin IDs.writeBytes/writePixels helpers.fl:: (e.g., i16, u16, i32, u32) and pointer/size aliases.avr_uart_putchar/available/read utilities.Serial.FASTLED_AVR), interrupt policy defaults, PROGMEM default, MS_COUNTER binding for millis symbols, small-device flags.millis() typically use the weak timer_millis symbol from avr_millis_timer_null_counter.hpp (no extra ISR).avr_millis_timer0_impl_source.hpp to provide a minimal Timer0/TCA0 ISR that increments timer_millis.avr_millis_timer_source.cpp chooses between the two at compile time based on board macros.Covered across the hierarchical structure:
atmega/m328p/): Arduino UNO, Nano, Pro Mini, ATmega328P/PB/168P/8atmega/m32u4/): Arduino Leonardo, Pro Micro, Teensy 2.0atmega/m2560/): Arduino MEGA 2560, ATmega1280/2560atmega/m4809/): Arduino Nano Every (VPORT-based GPIO)atmega/common/): ATmega644P, ATmega1284P, AT90USB series, ATmega128RFA1, etc.attiny/): ATtiny25/45/85, ATtiny24/44/84, ATtiny13/13A, ATtiny4313/2313, ATtiny88attiny/): 0/1/2-series (ATtiny202-417, ATtiny1604-1616, ATtinyxy2/xy4/xy6/xy7)Quirks:
FASTLED_ALLOW_INTERRUPTS=0 on small AVRs for best signal integrity.FASTLED_USE_PROGMEM: Default 1 on AVR. Required for flash‑resident tables.FASTLED_ALLOW_INTERRUPTS: Default 0 on AVR. You may set to 1 on faster parts but expect tighter timing constraints.FASTLED_FORCE_SOFTWARE_SPI: Force software (bit‑bang) SPI even when hardware SPI is available (commented hint in fastspi_avr.h).FASTLED_DEFINE_AVR_MILLIS_TIMER0_IMPL: Force Timer0 millis provider implementation for boards lacking Arduino millis().FASTLED_DEFINE_TIMER_WEAK_SYMBOL: Control weak symbol export for timer_millis in avr_millis_timer_source.cpp.Define these before including FastLED.h.