velxio/test/test_circuit/src/avr/programs.js

97 lines
2.9 KiB
JavaScript

/**
* Hand-assembled AVR programs used by the end-to-end tests.
*
* We cannot invoke avr-gcc in this sandbox, so we hand-roll the opcodes.
* Each builder returns a Uint16Array ready to feed to AVRHarness.loadProgram().
*/
import { LDI, OUT, STS, LDS, RJMP, SBRC, assemble } from './asm.js';
/**
* ADC-read-and-store sketch:
* setup:
* - ADMUX = 0x60 ; AVCC ref, ADLAR=1, channel 0 (A0)
* - ADCSRA = 0x87 ; enable, /128 prescaler
* loop:
* - start conversion, wait
* - copy ADCH → r20 (keeps latest reading in a known register)
* - copy ADCL → r21
* - loop
*
* After running a few thousand cycles, the host can read the ADC result
* from either r20 (high byte, left-adjusted = top 8 bits of the 10-bit value)
* or ADCH/ADCL via cpu.data[].
*/
export function adcReadProgram() {
return assemble([
LDI(16, 0x60), STS(0x7C, 16), // ADMUX
LDI(16, 0x87), STS(0x7A, 16), // ADCSRA
// loop
LDI(17, 0xC7), STS(0x7A, 17), // start conversion
LDS(17, 0x7A), // read ADCSRA
SBRC(17, 6), // skip RJMP if ADSC clear
RJMP(-4),
LDS(20, 0x79), // ADCH → r20
LDS(21, 0x78), // ADCL → r21
RJMP(-12), // back to 'start conversion' (word 6)
]);
}
/**
* Pot-to-PWM sketch:
* setup:
* - DDRD |= (1<<6) ; pin 6 as output (OC0A / Timer0A PWM)
* - TCCR0A = 0x83 ; Fast PWM 8-bit, COM0A1 non-inverting
* - TCCR0B = 0x01 ; no prescaler
* - ADMUX = 0x60 ; AVCC ref, ADLAR=1, channel 0 (A0)
* - ADCSRA = 0x87 ; ADC enable, prescaler 128
* loop:
* - ADCSRA |= (1<<ADSC) ; start conversion (write 0xC7)
* - wait while ADSC set
* - load ADCH (upper 8 bits of 10-bit result = ADCL>>2)
* - OCR0A = ADCH ; PWM duty = ADC high byte
* - loop
*/
export function potToPwmProgram() {
// Word layout:
// 0: LDI r16, 0x40
// 1: OUT DDRD (0x0A), r16
// 2: LDI r16, 0x83
// 3: OUT TCCR0A (0x24), r16
// 4: LDI r16, 0x01
// 5: OUT TCCR0B (0x25), r16
// 6: LDI r16, 0x40
// 7-8: STS ADMUX (0x7C), r16
// 9: LDI r16, 0x87
// 10-11: STS ADCSRA (0x7A), r16
// ── loop @ 12 ──
// 12: LDI r17, 0xC7
// 13-14: STS ADCSRA (0x7A), r17
// ── wait @ 15 ──
// 15-16: LDS r17, ADCSRA (0x7A)
// 17: SBRC r17, 6 ; skip if ADSC bit is CLEAR (conversion done)
// 18: RJMP -4 ; back to 15
// 19-20: LDS r17, ADCH (0x79)
// 21: OUT OCR0A (0x27), r17
// 22: RJMP -11 ; back to 12
return assemble([
LDI(16, 0x40),
OUT(0x0A, 16),
LDI(16, 0x83),
OUT(0x24, 16),
LDI(16, 0x01),
OUT(0x25, 16),
LDI(16, 0x60),
STS(0x7C, 16),
LDI(16, 0x87),
STS(0x7A, 16),
LDI(17, 0xC7),
STS(0x7A, 17),
LDS(17, 0x7A),
SBRC(17, 6),
RJMP(-4),
LDS(17, 0x79),
OUT(0x27, 17),
RJMP(-11),
]);
}