Skip to content

Latest commit

 

History

History
133 lines (110 loc) · 9.05 KB

File metadata and controls

133 lines (110 loc) · 9.05 KB

FastLED Platform: avr

AVR support for classic Arduino boards (e.g., ATmega328P/UNO) and many ATtiny/ATmega variants.

Directory Structure

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

Rationale: Hardware Capability Separation

The hierarchical structure reflects actual hardware differences:

  1. Instruction Set Differences:

    • ATtiny (classic): No MUL instruction → software multiplication required
    • ATmega (all): MUL instruction → optimized assembly multiplication
    • Impact: Math/scale8 implementations route correctly via FL_IS_AVR_ATTINY preprocessor define
  2. Register Architecture:

    • Legacy AVR: DDR/PORT/PIN registers for GPIO
    • Modern ATmega4809: VPORT registers for faster GPIO
    • Impact: Pin manipulation templates differ significantly
  3. Shared AVR Code (remains in platforms/avr/ root):

    • Interrupt control, I/O abstractions, delay primitives
    • SPI backend infrastructure, clockless LED controllers
    • Millis timer implementations, platform entry points

Backward Compatibility

All existing code continues to work unchanged. Dispatcher headers route to correct implementations transparently:

  • fastpin_avr.h → dispatches to VPORT or legacy pin mappings
  • math8.h → dispatches to ATtiny or ATmega math implementations
  • scale8.h → dispatches to software or hardware multiply implementations

What's here (quick pass)

  • avr_millis_timer_null_counter.hpp: Defines a weak (or strong on some ATtiny) volatile unsigned long timer_millis symbol for boards missing a timer implementation.
  • avr_millis_timer0_impl_source.hpp: Minimal Timer0/TCA0 ISR-based timer_millis implementation for select ATtinyx/y parts; initialized via constructor.
  • avr_millis_timer_source.cpp: Chooses between weak symbol vs. implementation based on macros/board, includes the two headers above.
  • clockless_avr.h: AVR clockless LED controller with tight-timing bit-banging (WS2811/WS2812). Docs on interrupt impact and timing macros.
  • compile_test.hpp: Compile-time checks for AVR config (e.g., FASTLED_USE_PROGMEM==1, FASTLED_ALLOW_INTERRUPTS==0, F_CPU sanity).
  • fastled_avr.h: Aggregator header enabling PROGMEM and including fastpin_avr.h, fastspi_avr.h, clockless_avr.h.
  • fastpin_avr.h: Top-level dispatcher that routes to VPORT (ATmega4809/Nano Every) or legacy DDR/PORT/PIN pin mappings (all other AVRs).
  • fastpin_avr_legacy.h: Backward-compatibility shim that forwards to atmega/common/fastpin_avr_legacy_dispatcher.h (deprecated, will be removed in v4.0).
  • math8.h: Math dispatcher that routes to attiny/math/math8_attiny.h (software multiply) or atmega/common/math8_avr.h (hardware MUL) based on FL_IS_AVR_ATTINY.
  • scale8.h: Cross-platform scale dispatcher. On AVR, routes to attiny/math/scale8_attiny.h or atmega/common/scale8_avr.h based on FL_IS_AVR_ATTINY.
  • trig8.h: Cross-platform trig dispatcher. On AVR, routes to atmega/common/trig8.h (ATmega only, requires MUL instruction).
  • atmega/common/avr_pin.h: Core _AVRPIN template used by FastPin<> specializations for direct port IO (hi/lo/toggle, masks, ports).
  • atmega/common/fastpin_avr_legacy_dispatcher.h: Legacy pin dispatcher that routes to family-specific pin mappings (m328p, m32u4, m2560, attiny, or other).
  • atmega/m328p/fastpin_m328p.h: Pin mappings for Arduino UNO, Nano, Pro Mini (ATmega328P/168P/8 family).
  • atmega/m32u4/fastpin_m32u4.h: Pin mappings for Arduino Leonardo, Pro Micro, Teensy 2.0 (ATmega32U4, USB-capable).
  • atmega/m2560/fastpin_m2560.h: Pin mappings for Arduino MEGA 2560 (ATmega2560/1280, high pin count).
  • atmega/m4809/fastpin_avr_atmega4809.h: Pin mappings using VPORT for ATmega4809 parts; defines AVR_HARDWARE_SPI, HAS_HARDWARE_PIN_SUPPORT, SPI pin IDs.
  • atmega/m4809/fastpin_avr_nano_every.h: Pin mappings using VPORT for Arduino Nano Every (ATmega4809 variant); hardware SPI constants.
  • atmega/common/fastpin_legacy_other.h: Pin mappings for less common ATmega variants (ATmega644P, AT90USB, ATmega128RFA1, etc.).
  • attiny/pins/fastpin_attiny.h: Pin mappings for all ATtiny variants (classic 25/45/85 and modern tinyAVR 0/1/2-series).
  • attiny/math/math8_attiny.h: Software multiply implementation for ATtiny (no MUL instruction).
  • attiny/math/scale8_attiny.h: Software scaling implementation for ATtiny (no MUL instruction).
  • atmega/common/math8_avr.h: Optimized math implementation for ATmega (uses hardware MUL instruction).
  • atmega/common/scale8_avr.h: Optimized scaling implementation for ATmega (uses hardware MUL instruction and AVR assembly).
  • atmega/common/trig8.h: Trigonometry functions for ATmega (requires hardware MUL instruction).
  • fastspi_avr.h: SPI backends for AVR: UART MSPI (USART0/1) and hardware SPI (SPI/SPDR, SPI0) variants; writeBytes/writePixels helpers.
  • int.h: AVR-friendly integer typedefs in fl:: (e.g., i16, u16, i32, u32) and pointer/size aliases.
  • io_avr_lowlevel.h: Low-level UART register helpers (UDR/UCSR mapping) plus avr_uart_putchar/available/read utilities.
  • io_avr.h: Simple print/println and input helpers that use low-level UART if available, else fallback to Arduino Serial.
  • led_sysdefs_avr.h: AVR platform defines (FASTLED_AVR), interrupt policy defaults, PROGMEM default, MS_COUNTER binding for millis symbols, small-device flags.

Millis provider selection

  • Boards with a working Arduino core millis() typically use the weak timer_millis symbol from avr_millis_timer_null_counter.hpp (no extra ISR).
  • Select ATtiny parts (e.g., some x/y families) use 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.

Supported families (summary)

Covered across the hierarchical structure:

ATmega Family (with MUL instruction)

  • ATmega328P family (atmega/m328p/): Arduino UNO, Nano, Pro Mini, ATmega328P/PB/168P/8
  • ATmega32U4 family (atmega/m32u4/): Arduino Leonardo, Pro Micro, Teensy 2.0
  • ATmega2560 family (atmega/m2560/): Arduino MEGA 2560, ATmega1280/2560
  • ATmega4809 family (atmega/m4809/): Arduino Nano Every (VPORT-based GPIO)
  • Other ATmega variants (atmega/common/): ATmega644P, ATmega1284P, AT90USB series, ATmega128RFA1, etc.

ATtiny Family (no MUL instruction)

  • Classic ATtiny (attiny/): ATtiny25/45/85, ATtiny24/44/84, ATtiny13/13A, ATtiny4313/2313, ATtiny88
  • Modern tinyAVR (attiny/): 0/1/2-series (ATtiny202-417, ATtiny1604-1616, ATtinyxy2/xy4/xy6/xy7)

Quirks:

  • Strict ISR timing: for WS281x, set FASTLED_ALLOW_INTERRUPTS=0 on small AVRs for best signal integrity.
  • SPI routes differ (SPI vs SPI0, UART MSPI). The SPI backend handles these variants; verify MOSI/SCK pins per board.

Optional feature defines

  • 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.