SearchA-ZD › Digispark (ATtiny85)

Digispark (ATtiny85)

2012 Open source · MIT PD firmware · open Online

Digispark (ATtiny85) is a Digispark — the thumbnail-sized Digistump ATtiny85 USB development board (a 2012 Kickstarter hit) — running in the browser on avr8js, Wokwi's open-source AVR instruction-set simulator (pure TypeScript/JavaScript, MIT — the same core, byte-for-byte, that powers this site's Arduino Uno and Arduboy exhibits). Small original public-domain programs, hand-written in AVR assembly and assembled to flash images, boot by default and drive the whole on-board surface — which on an ATtiny85 is LEDs only (the part has no UART, and the bare board has no piezo): the built-in LED on P1 blinks, breathes with a software-PWM fade, or is toggled by a Timer0 compare-match interrupt, and a Knight Rider chase runs across the broken-out pins P0-P4. Because the CPU, SRAM and peripherals are ordinary JavaScript, the whole ATtiny85 plugs into this site's shared debugger — the same AVR disassembler, live R0-R31 / SP / PC / SREG, side-effect-free flash and data memory, single-instruction step, execution breakpoints and write-watchpoints.

Visit avr8js on GitHub ↗

Visit the official site ↗

Runs on: Web browser

Digispark (ATtiny85) Online Emulator

Play Digispark (ATtiny85) using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Blink (onboard LED)Digispark (ATtiny85)DigisparkopenOpen ⛶
Soft-PWM fade (onboard LED)Digispark (ATtiny85)DigisparkopenOpen ⛶
Knight Rider (LED chase)Digispark (ATtiny85)DigisparkopenOpen ⛶
Timer0 blink (interrupt-driven)Digispark (ATtiny85)DigisparkopenOpen ⛶

Chips

Notes

Embedding

avr8js is Wokwi's AVR simulator, published as a TypeScript/JavaScript library. Bundle the published ESM once to a browser global (window.avr8js) with esbuild, then build the machine around the core yourself so the debugger can drive it. Nothing in the core is patched — this is the SAME avr8js.global.js the Arduino Uno and Arduboy exhibits use, byte-for-byte.

The ATtiny85 is a different part from the Arduino's ATmega328P. avr8js ships peripheral configs for the 328P, so the Digispark board model builds ATtiny85 configs instead: PORTB is the tiny's one GPIO port (PINB/DDRB/PORTB at I/O 6/ 7/ 8 → data $36/$37/$38), and Timer0 is a standard 8-bit timer (TCCR0A=$2A, TCCR0B=$33, OCR0A=$29, shared TIMSK=$39/TIFR=$38) whose TIMSK/TIFR bit layout differs from the 328P (TOV0=bit 1, OCF0A=bit 4). Interrupt vectors use the ATtiny85 RJMP table, so a vector's word address equals its index (TIMER0_COMPA = word 10).

var flash = b64ToU16(SK.b64);              // compiled ATtiny85 flash image
var prog  = new Uint16Array(0x1000);      // 8 KB flash = 4096 words
prog.set(flash);
var cpu   = new avr8js.CPU(prog, 512);      // 512 B SRAM (RAMEND $025F)
var board = DIGISPARK.buildBoard(cpu, avr8js);  // PORTB + Timer0 + ADC
(function frame(){
  for (var i = 0; i < BUDGET; i++) {
    if (breakpoints.has(cpu.pc * 2)) break;   // PC is a WORD index
    avr8js.avrInstruction(cpu);              // one AVR instruction
    cpu.tick();                              // service Timer0 / interrupts
  }
  requestAnimationFrame(frame);
})();

Everything is plain JavaScript state — no wasm heap. cpu.data is the whole data space (R0-R31 at $00- F, the I/O registers, then 512 B of SRAM); cpu.progBytes is flash as bytes; avrInstruction(cpu) is the single-step primitive; port.pinState(i) reads a GPIO pin (drives the LEDs). To render the software-PWM fade smoothly the run loop integrates each pin's duty cycle over the frame rather than sampling it once, so a pin that is being PWM'd shows as a partial brightness.

Debugger integration

The plug-in (digispark-debug.js) describes the ATtiny85 to the shared debugger and nothing more. It reuses /debugger/src/cpus/avr.js — the same AVR disassembler written for the Arduino Uno — unmodified.

  • Registers are read live each refresh: all of R0-R31, the pointer pairs X/Y/Z, SP, PC (as a flash byte address), and SREG broken out into its I T H S V N Z C flags. Every one has a set() that writes straight back into cpu.data.
  • Memory is exposed as three chips, all read side-effect-free: Flash (8 KB / 4096 words, cpu.progBytes, disassembled with the avr decoder), the Data space (registers + I/O + 512 B SRAM, straight off cpu.data), and the I/O registers alone as a focused window over $20-$5F.
  • Single step is one avrInstruction(cpu). Breakpoints are host-side checks of cpu.pc*2 against a set of flash byte addresses. Write-watchpoints wrap cpu.writeData and pause the moment a watched data-space address (e.g. PORTB at $38) is written.

Architecture

The Digispark (Digistump, 2012) is a thumbnail-sized USB development board — a Kickstarter hit that put the tiny AVR on a board you plug straight into a USB port. This build models its heart, the ATtiny85:

  • AVR CPU — the same 8-bit RISC core as the Arduino's ATmega328P (32 registers R0-R31, a 16-bit program counter, an 8-bit SREG, Harvard flash/SRAM), run one instruction at a time by avr8js. The debugger uses the very same AVR decoder.
  • 8 KB flash (word-addressed; ~6 KB usable on a real Digispark because the USB bootloader occupies the top 2 KB) and 512 B SRAM; SP resets to $025F.
  • PORTB — the tiny's single GPIO port. The Digispark breaks out P0-P5; the built-in LED sits on P1 on the mass-produced Model B / rev3 (the older Model A had it on P0).
  • Timer0 — a standard 8-bit timer used here for a compare-match (CTC) interrupt that toggles the LED. (The ATtiny85's other timer, Timer1, is an unusual PLL-clocked async part that avr8js does not model.)

The ATtiny85 has no hardware UART and the bare Digispark has no piezo, so the whole on-board surface is LEDs — no serial monitor, no sound. The bundled programs are small original public-domain AVR programs, hand-written in AVR assembly and assembled with avr8js's own assembler. Because they are real AVR machine code, every instruction single-steps in the debugger.