Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/proposals/browser-emulation-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,12 @@ PB2, PB4, PB3; Referenzen VCC, 1,1 V, 2,56 V), Watchdog, Ein-Wort-Vektoren,
8 MHz; kein USART. Die Referenzauswahl des ADC liest `REFS2` selbst an Bit 4,
weil avr8js 0.21.1 es an Bit 3 erwartet (P0.5: sonst 102 statt 200 bei
2,56 V); der Fehler wird upstream gemeldet.
Umgesetzt (`mcu/attiny85.ts`, exportiert als `ATTINY85`; registriert erst mit
der Board-Hardware in P6.4). Weitere Funde: INT0 und PCINT teilen GIMSK/GIFR,
avr8js verdrahtet das nur für je einen (das Profil umhüllt die Hooks);
`ATtinyTimer1` erzeugt in der PWM-Konfiguration von ATTinyCore kein Signal an
OC1x (Register stimmen, das Tastverhältnis kommt aus ihnen; offen, siehe
README des Pakets). Die Meldungen an avr8js macht ein Mensch.

**P6.3 Software-UART (M).**
TX-Pin des Cores dekodieren, Baudrate aus der Bitbreite (größte
Expand All @@ -1145,6 +1151,12 @@ Analogkomparators (ACSR, Vektor 7) mit einer Wellenform an PB1 in simulierter
Zeit; Baudrate aus der Ausgabe, sonst aus dem Serial Monitor. Das
Benutzerhandbuch nennt die Grenzen des Boards: Halbduplex, kein Empfang, wenn
PB1 anders genutzt wird (P0.5).
Umgesetzt als `io/software-uart.ts` (`SoftwareUart` mit der Schnittstelle des
USART für `SerialPorts`): Erkennung verlangt 90 % passende Abstände (die
Pin-Initialisierung erzeugt Kurzimpulse, der Core dehnt einzelne Bits), die
Bitbreite wird aus den Abständen gemittelt, Startbits werden in Bitmitte
geprüft. Anbindung an die Serial-Schicht, die Baudrate des Serial Monitors und
das Benutzerhandbuch folgen mit der Board-Hardware (P6.4/P6.5).

**P6.4 Board-Hardware und Regeln (M).**
Pins 0–5, PB5 als RESET sichtbar, aber nicht nutzbar; A0–A3; PWM 0, 1, 4;
Expand Down
2 changes: 2 additions & 0 deletions docs/proposals/browser-emulation-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
| P7.1 | erledigt bis auf die Messung am Referenz-Host (wartet auf Mensch) | (dieser PR) | Compile-Phase in `npm run capacity:calibrate` (vier Schritte, Tabelle im Bericht, `--skip-compile`), Compile-Container tragen im Testprofil das Label des Kapazitätslaufs; CAPACITY_MODEL „Compile capacity (browser emulation)“: Modell, Kenngrößen nach 4.12, Messung auf M2 Pro (30 gleichzeitige neue Compiles p95 6,3 s, ≈ 275 Compiles/min, unverändertes Beispiel 8 ms); Messung auf der Referenz-VM: [human-tests.md, Teil 3](human-tests.md) |
| P2.3 | erledigt | (dieser PR) | ATTinyCore 1.5.2 gepinnt (Version, HTTPS-Archiv, SHA-256), Installation ohne Board-Manager ins Sketchbook mit `platform.local.txt` gegen die Post-Build-Hooks (Fund: sie schreiben in Core und Sketch; HEX identisch mit und ohne), Prüfskript und Canary-Test; Compile-Sandbox-Image mit ATTinyCore und vorkompiliertem Core je FQBN; CI (Toolchain- und E2E-Job, Cache-Schlüssel, Deployment-Prüfschritt); Toolchain-Gate `toolchain-cores.test.ts` (alle vier Boards); INSTALL_LOCAL, README (Lizenzen LGPL 2.1). Abweichung: kein Board-Manager, weil `drazzy.com` und `azduino.com` abgelaufene Zertifikate liefern |
| P6.1 | erledigt | (dieser PR, mit P2.3) | ATTinyCore im Compile-Sandbox-Image; Vertragstest kompiliert für den ATtiny85 in der Sandbox |
| P6.2 | erledigt | (dieser PR) | `mcu/attiny85.ts`: Port B mit INT0 (PB2) und PCINT0, Timer 0 mit eigenen Registern und Ein-Wort-Vektoren, `ATtinyTimer1`, ADC mit 4 Kanälen und REFS2 an Bit 4 (avr8js-Fehler), EEPROM 512 B mit Schreibzeit für 8 MHz, Watchdog, Taktteiler, kein USART; RAMEND 0x25F. Tests `attiny85-profile.test.ts` (13) mit drei ATTinyCore-Fixtures (Ergebnisse im EEPROM). Funde: GIMSK/GIFR werden von INT0 und PCINT geteilt, avr8js verdrahtet nur je einen (behoben); `ATtinyTimer1` erzeugt in der PWM-Konfiguration von ATTinyCore kein OC1x-Signal (offen, Register stimmen); Spike-Spanne für `delay(587)` war zu eng (585–589 ms abgeleitet). Profil noch nicht in `mcuProfile` registriert: das hängt an einer Teständerung (siehe P6.4). Upstream-Meldungen an avr8js: wartet auf Mensch |
| P6.3 | erledigt (Modell) | (dieser PR) | `io/software-uart.ts`: TX-Decoder an PB0 (nur Ausgang, nicht OC0A) mit Baudraten-Erkennung (größte Standardrate, 90 % der Abstände ganzzahlige Bitvielfache) und gemessener Bitbreite, Rückfall auf die eingestellte Rate bei Ruhe, Startbit-Prüfung in Bitmitte; RX über ein Komparatormodell (ACSR, Bandlücke/AIN0 gegen PB1, Vektor 7), Empfänger aktiv mit `ACIE`; Schnittstelle wie `AVRUSART` für `SerialPorts`. Tests `software-uart.test.ts` (7: 9600/19200, UTF-8, Rückfall, Echo, gesperrte Eingabe, synthetische Flanken). Anbindung an Serial-Schicht und Serial-Monitor-Baudrate mit P6.4, Benutzerhandbuch mit P6.5 |
| Anleitung | bereit | (dieser PR) | [human-tests.md](human-tests.md): P0.3 mit `npm run spike:p03` (Messseite für Browser auf Geräten), P1.14-Aufnahmen mit `npm run record:hardware`, P7.1 Compile-Kapazität auf dem Referenz-Host |

Status: offen · in Arbeit · erledigt · wartet auf Mensch · blockiert
57 changes: 57 additions & 0 deletions packages/avr-emulator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,21 @@ at least 90 % line coverage for `src/`.
reports the diagnostic `serial-input-discarded`; the corpus case
`probes/serial_before_begin` is recorded on the board.
- **Watchdog reset:** avr8js resets only PC and SP; see the diagnostics section.
- **ADC reference on the ATtiny85** (`src/mcu/attiny85.ts`): avr8js reads
REFS2 at bit 3 of ADMUX, the ATtiny85 has it at bit 4 (bit 3 is MUX3). With
`analogReference(INTERNAL2V56)` avr8js would measure against VCC (spike
P0.5: 102 instead of 200 for 0.5 V). The profile reads REFS2 itself.
- **Shared interrupt registers on the ATtiny85:** INT0 and the pin-change
interrupt share GIMSK and GIFR. avr8js hooks GIMSK only for INT0 and gives
GIFR to the pin-change interrupt alone, so enabling PCIE did not raise a
pending pin change and writing 1 to INTF0 did not clear INT0. The profile
wraps both hooks.
- **Timer 1 PWM on the ATtiny85 (open):** `ATtinyTimer1` models PWM mode as
phase-correct counting and drives no OC1A/OC1B waveform when CTC1 is set,
which is how ATTinyCore configures it for `analogWrite` on PB1/PB4. On the
chip the counter runs from 0 to OCR1C, OC1x is set at 0 and cleared at OCR1x
(COM1x = 10). The registers are right, so a duty cycle derived from them is
right; a sketch that reads the pin level of a timer-1 PWM pin sees LOW.

## ATmega2560 profile

Expand Down Expand Up @@ -267,6 +282,48 @@ Known differences (not modelled by avr8js): compare-match C interrupts of the
them); sketches above 64 KB of PROGMEM may push the core's pin tables out of
the `lpm` range, as on the board (spike P0.6).

## ATtiny85 profile

`src/mcu/attiny85.ts` (plan P6.2, spike P0.5): one port (B), timer 0 with its
own registers and vectors, avr8js' `ATtinyTimer1`, a 4-channel ADC (ADC0–3 on
PB5, PB2, PB4, PB3; references VCC, AREF, 1.1 V, 2.56 V), 512 bytes EEPROM
with write times for 8 MHz, watchdog and clock prescaler; no USART (the core's
`Serial` is a software UART). Vectors have one word each (RJMP), vector n at
word n. Data space up to RAMEND 0x25F (`new CPU(progMem, 0x160)`). The
profile is exported as `ATTINY85`; `mcuProfile("attiny85")` returns it once
the board hardware exists (P6.4). Tests: `tests/attiny85-profile.test.ts` with
the fixtures `attiny85-tiny_*.hex`.

## Software UART (ATtiny85)

`src/io/software-uart.ts` (plan P6.3): the ATtiny85 has no USART; ATTinyCore's
`Serial` (`TinySoftwareSerial`) sends on PB0 and receives on PB1 through the
analog comparator. `SoftwareUart` offers the members of `AVRUSART` that
`SerialPorts` uses (`onByteTransmit`, `writeByte`, `rxEnable`, `rxBusy`,
`baudRate`, …), so the ATtiny85 board can use the same serial port (P6.4).

- **TX:** edges of PB0 while it is an output and timer 0 does not drive it
(OC0A). The baud rate is the largest standard rate of which at least 90 % of
at least 8 in-frame edge distances are whole bit multiples (±20 %); the bit
width is then averaged from them (the core's delay loop runs a few percent
slow: 863 cycles per bit at 9600 baud and 8 MHz instead of 833). A start bit
must still be low at its middle, so the pulses of the pin set-up are no
bytes. Until the rate is found, an idle line (12 bit times) is decoded with
`configuredBaud` (the Serial Monitor's).
- **RX:** `writeByte` drives PB1 bit by bit in simulated time; the comparator
compares it with the bandgap (`ACBG`, as the core sets it) or AIN0 and
raises its interrupt (vector 7) on the configured edge. The receiver counts
as enabled while the comparator interrupt is enabled (`Serial.begin()`).
ACME (ADC multiplexer as negative input) is not modelled.
- **Limits of the board, not of the model:** half duplex (the core disables
interrupts while it sends, so input during output is lost); no reception
when the sketch uses PB1 otherwise; no output on PB0 while it is PWM.

Tests: `tests/software-uart.test.ts` (9600 and 19200 baud, UTF-8, the
fallback rate, echo over the comparator, input refused before `Serial.begin()`,
synthetic waveforms) with the fixtures `attiny85-tiny_serial*.hex` and
`attiny85-tiny_echo.hex`.

## License

MIT, like UnoSim.
3 changes: 3 additions & 0 deletions packages/avr-emulator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export { IoUsageObserver } from "./io/io-usage";
export type { IoFunction, IoUsage } from "./io/io-usage";
export { PinModel } from "./io/pin-model";
export { SERIAL_INPUT_LIMITS, SerialPorts } from "./io/serial-ports";
export { SoftwareUart } from "./io/software-uart";
export type { SoftwareUartPins } from "./io/software-uart";
export type { SerialFrameConfig, SerialOutput } from "./io/serial-ports";
export { Utf8StreamDecoder, encodeUtf8 } from "./io/utf8";
export type { Level, PinChanges, PinMode, PinSnapshot } from "./io/pin-model";
Expand All @@ -31,6 +33,7 @@ export type { Machine, MachineOptions } from "./machine";
export { ArrayEepromBackend, erasedEeprom } from "./mcu/eeprom";
export { ATMEGA2560 } from "./mcu/atmega2560";
export { ATMEGA328P } from "./mcu/atmega328p";
export { ATTINY85 } from "./mcu/attiny85";
export { mcuProfile } from "./mcu/registry";
export type { McuPeripherals, McuProfile } from "./mcu/types";
export { encodeBase64, decodeBase64 } from "./image/base64";
Expand Down
Loading
Loading