### Configure Hardware Interrupts - TypeScript Source: https://context7.com/wokwi/avr8js/llms.txt Illustrates AVR8JS interrupt configuration and management. Covers external interrupts via AVRIOPort, timer overflow interrupts, and manual flag manipulation. Shows interrupt enable/disable patterns and edge detection setup. ```typescript import { CPU, AVRInterruptConfig, AVRIOPort, portDConfig, INT0, INT1 } from 'avr8js'; const cpu = new CPU(program); const portD = new AVRIOPort(cpu, portDConfig); // External interrupts are automatically configured by AVRIOPort // INT0 on PD2, INT1 on PD3 // Manually trigger interrupt (e.g., timer overflow) const TIMER0_OVF: AVRInterruptConfig = { address: 0x20, // Interrupt vector address flagRegister: 0x35, // TIFR0 flagMask: 0x01, // TOV0 bit enableRegister: 0x6E, // TIMSK0 enableMask: 0x01, // TOIE0 bit }; // Set interrupt flag (will trigger if enabled) cpu.setInterruptFlag(TIMER0_OVF); // Check interrupt status console.log(`Interrupts enabled: ${cpu.interruptsEnabled}`); console.log(`Next pending interrupt: ${cpu.nextInterrupt}`); // Clear interrupt programmatically cpu.clearInterrupt(TIMER0_OVF, true); // Simulate button generating external interrupt function simulateButtonPress() { // Press button (falling edge on INT0) portD.setPin(2, false); // Release after 50ms setTimeout(() => { portD.setPin(2, true); }, 50); } // Configure interrupt mode via registers (done by Arduino code) // EICRA: External Interrupt Control Register A // ISC01:ISC00 = 10 (falling edge), 11 (rising edge), 01 (any change) cpu.writeData(0x69, 0x02); // Falling edge on INT0 cpu.writeData(0x3D, 0x01); // Enable INT0 (EIMSK) ``` -------------------------------- ### Complete AVR Runner Implementation with avr8js Source: https://context7.com/wokwi/avr8js/llms.txt Provides a comprehensive implementation of an AVR runner, integrating CPU, timers, GPIO, and USART. It includes a main execution loop and setup for peripherals. Dependencies include the 'avr8js' library and its various configuration objects. ```typescript import { CPU, avrInstruction, AVRTimer, AVRIOPort, AVRUSART, timer0Config, timer1Config, timer2Config, portBConfig, portCConfig, portDConfig, usart0Config, PinState } from 'avr8js'; class AVRRunner { readonly program = new Uint16Array(0x8000); // 32KB flash readonly cpu: CPU; readonly timer0: AVRTimer; readonly timer1: AVRTimer; readonly timer2: AVRTimer; readonly portB: AVRIOPort; readonly portC: AVRIOPort; readonly portD: AVRIOPort; readonly usart: AVRUSART; readonly clockSpeed = 16000000; // 16 MHz private running = false; constructor(hexData: string) { // Load Intel HEX into program memory this.loadHex(hexData, new Uint8Array(this.program.buffer)); // Initialize CPU and peripherals this.cpu = new CPU(this.program); this.timer0 = new AVRTimer(this.cpu, timer0Config); this.timer1 = new AVRTimer(this.cpu, timer1Config); this.timer2 = new AVRTimer(this.cpu, timer2Config); this.portB = new AVRIOPort(this.cpu, portBConfig); this.portC = new AVRIOPort(this.cpu, portCConfig); this.portD = new AVRIOPort(this.cpu, portDConfig); this.usart = new AVRUSART(this.cpu, usart0Config, this.clockSpeed); this.setupPeripherals(); } private setupPeripherals() { // Monitor LED pins (Arduino pins 12 and 13) this.portB.addListener((value) => { const led13 = this.portB.pinState(5) === PinState.High; // PB5 const led12 = this.portB.pinState(4) === PinState.High; // PB4 this.updateLED(13, led13); this.updateLED(12, led12); }); // Handle serial output this.usart.onByteTransmit = (byte) => { this.handleSerialOutput(String.fromCharCode(byte)); }; } execute(onUpdate?: (cpu: CPU) => void) { this.running = true; const workUnit = 500000; // Execute 500k cycles per iteration const run = () => { if (!this.running) return; const targetCycles = this.cpu.cycles + workUnit; while (this.cpu.cycles < targetCycles) { avrInstruction(this.cpu); this.cpu.tick(); } onUpdate?.(this.cpu); // Use microtask for better performance queueMicrotask(run); }; run(); } stop() { this.running = false; } // Stub methods (implement based on your needs) private loadHex(hex: string, target: Uint8Array) { /* ... */ } private updateLED(pin: number, state: boolean) { /* ... */ } private handleSerialOutput(char: string) { /* ... */ } } // Usage const runner = new AVRRunner(hexFileContent); runner.execute((cpu) => { const runtime = cpu.cycles / runner.clockSpeed; console.log(`Runtime: ${runtime.toFixed(3)}s, Cycles: ${cpu.cycles}`); }); ``` -------------------------------- ### Schedule CPU Clock Events for Timing - TypeScript Source: https://context7.com/wokwi/avr8js/llms.txt Shows AVR8JS clock event scheduling for precise timing control. Demonstrates one-time events, recurring callbacks, and event management. Includes ADC simulation example with rescheduling and cancellation patterns. ```typescript import { CPU, AVRClockEventCallback } from 'avr8js'; const cpu = new CPU(program); // Schedule one-time event const callback: AVRClockEventCallback = () => { console.log('Event triggered at cycle', cpu.cycles); // Trigger ADC conversion complete cpu.data[0x7A] |= 0x10; // Set ADIF flag }; // Execute after 1000 CPU cycles cpu.addClockEvent(callback, 1000); // Schedule recurring event let adcValue = 0; const adcReadCallback = () => { // Simulate ADC reading adcValue = (adcValue + 1) % 1024; cpu.data[0x78] = adcValue & 0xFF; // ADCL cpu.data[0x79] = adcValue >> 8; // ADCH // Reschedule for next reading (13 ADC clocks * prescaler) cpu.addClockEvent(adcReadCallback, 13 * 128); }; // Start ADC sampling cpu.addClockEvent(adcReadCallback, 13 * 128); // Update or cancel scheduled events const updateableCallback = () => { console.log('Tick'); }; cpu.addClockEvent(updateableCallback, 1000); // Reschedule to fire sooner cpu.updateClockEvent(updateableCallback, 500); // Cancel event cpu.clearClockEvent(updateableCallback); ``` -------------------------------- ### Configure Timers for PWM and Interrupts Source: https://context7.com/wokwi/avr8js/llms.txt This example demonstrates setting up hardware timers (Timer0 and Timer1) for functionalities like Pulse Width Modulation (PWM) and periodic interrupts. It shows how to monitor timer registers and how PWM output on specific pins is controlled through port manipulation, mimicking Arduino's `analogWrite()` behavior. ```typescript import { CPU, AVRTimer, AVRIOPort, timer0Config, timer1Config, portDConfig } from 'avr8js'; const cpu = new CPU(program); const portD = new AVRIOPort(cpu, portDConfig); // Initialize 8-bit timer (Timer0) const timer0 = new AVRTimer(cpu, timer0Config); // Initialize 16-bit timer (Timer1) for servo control const timer1 = new AVRTimer(cpu, timer1Config); // Monitor PWM output on pins portD.addListener((value) => { const pwmPin6 = (value & 0x40) !== 0; // PD6 = Arduino pin 6 const pwmPin5 = (value & 0x20) !== 0; // PD5 = Arduino pin 5 console.log(`PWM Pin 6: ${pwmPin6 ? 'HIGH' : 'LOW'}`); console.log(`PWM Pin 5: ${pwmPin5 ? 'HIGH' : 'LOW'}`); }); // Timer registers are memory-mapped, accessed via CPU.data // Arduino analogWrite() configures these automatically // Example: Monitor timer counter value setInterval(() => { const tcnt0 = cpu.data[timer0Config.TCNT]; const ocr0a = cpu.data[timer0Config.OCRA]; console.log(`Timer0 Counter: ${tcnt0}, Compare A: ${ocr0a}`); }, 1000); ``` -------------------------------- ### Control and Monitor GPIO Ports with Interrupts Source: https://context7.com/wokwi/avr8js/llms.txt This code illustrates configuring and interacting with GPIO ports using AVR8js. It shows how to set up ports, listen for pin changes (e.g., for LEDs), simulate button presses that trigger interrupts, and check the state of individual pins. Dependencies include CPU, AVRIOPort, and port configuration objects. ```typescript import { CPU, AVRIOPort, portBConfig, portDConfig, PinState, INT0 } from 'avr8js'; const cpu = new CPU(program); // Initialize GPIO ports const portB = new AVRIOPort(cpu, portBConfig); const portD = new AVRIOPort(cpu, portDConfig); // Listen for port changes (e.g., LED control) portB.addListener((value, oldValue) => { const pin13Changed = (value & 0x20) !== (oldValue & 0x20); if (pin13Changed) { const pin13High = (value & 0x20) !== 0; console.log(`LED on pin 13: ${pin13High ? 'ON' : 'OFF'}`); // Update visual LED element ledElement.value = pin13High; } }); // Simulate button press on pin 2 (external interrupt) function pressButton() { portD.setPin(2, true); // Button pressed setTimeout(() => portD.setPin(2, false), 100); // Release after 100ms } // Check pin state const pin5State = portB.pinState(5); switch (pin5State) { case PinState.High: console.log('Pin 5 is OUTPUT HIGH'); break; case PinState.Low: console.log('Pin 5 is OUTPUT LOW'); break; case PinState.InputPullUp: console.log('Pin 5 is INPUT with pull-up enabled'); break; case PinState.Input: console.log('Pin 5 is INPUT (high impedance)'); break; } ``` -------------------------------- ### Implement Custom Peripherals with Memory Hooks - TypeScript Source: https://context7.com/wokwi/avr8js/llms.txt Demonstrates read and write hooks for creating custom memory-mapped peripherals. Shows custom register implementation, SPI peripheral simulation, and state management. Includes hook registration, value interception, and default behavior prevention. ```typescript import { CPU } from 'avr8js'; const cpu = new CPU(program); // Custom register at address 0x50 const CUSTOM_REG = 0x50; let customPeripheralState = 0; // Write hook - triggered when CPU writes to address cpu.writeHooks[CUSTOM_REG] = (value, oldValue, addr, mask) => { console.log(`Write to custom register: 0x${value.toString(16)}`); // Custom logic if (value & 0x80) { console.log('Custom peripheral enabled'); customPeripheralState = value & 0x7F; } // Store value in memory cpu.data[addr] = value; // Return true to prevent default write behavior return true; }; // Read hook - triggered when CPU reads from address cpu.readHooks[CUSTOM_REG] = (addr) => { console.log('Read from custom register'); // Return status byte return (customPeripheralState & 0x7F) | (Math.random() > 0.5 ? 0x80 : 0); }; // Example: Simple SPI peripheral simulation const SPI_DATA = 0x4E; const SPI_STATUS = 0x4D; let spiBuffer = 0; cpu.writeHooks[SPI_DATA] = (value) => { spiBuffer = value; // Simulate SPI transfer complete after 1 cycle cpu.addClockEvent(() => { cpu.data[SPI_STATUS] |= 0x80; // Set transfer complete flag console.log(`SPI transferred: 0x${value.toString(16)}`); }, 16); // 16 cycles for 8-bit transfer at fclk/16 return true; }; cpu.readHooks[SPI_DATA] = () => { const result = spiBuffer; cpu.data[SPI_STATUS] &= ~0x80; // Clear flag on read return result; }; ``` -------------------------------- ### Initialize and Execute AVR CPU with Program Memory Source: https://context7.com/wokwi/avr8js/llms.txt This snippet demonstrates how to initialize an AVR8js CPU instance with program memory loaded from an Intel HEX file and how to execute instructions within a simulation loop. It accesses core CPU state like program counter (PC), cycle count, stack pointer (SP), and status register (SREG). ```typescript import { CPU, avrInstruction } from 'avr8js'; // Load compiled program (Intel HEX converted to Uint16Array) const FLASH_SIZE = 0x8000; // 32KB for ATmega328p const program = new Uint16Array(FLASH_SIZE); // ... load your hex file into program memory ... // Create CPU with program and 2KB SRAM const cpu = new CPU(program, 2048); // Main execution loop - execute instructions and tick peripherals function runSimulation() { // Execute one instruction avrInstruction(cpu); // Tick for interrupts and clock events cpu.tick(); // Access CPU state console.log(`PC: ${cpu.pc}, Cycles: ${cpu.cycles}, SP: ${cpu.SP}`); console.log(`SREG: 0x${cpu.SREG.toString(16)}`); // Continue execution requestAnimationFrame(runSimulation); } runSimulation(); ``` -------------------------------- ### USART Serial Communication with avr8js Source: https://context7.com/wokwi/avr8js/llms.txt Demonstrates setting up and using USART for serial communication in avr8js. It covers transmitting data to the host, receiving data from the host, and monitoring configuration changes. Dependencies include the 'avr8js' library. ```typescript import { CPU, AVRUSART, usart0Config, AVRIOPort, portDConfig } from 'avr8js'; const cpu = new CPU(program); const portD = new AVRIOPort(cpu, portDConfig); const clockFrequency = 16000000; // 16 MHz // Initialize USART const usart = new AVRUSART(cpu, usart0Config, clockFrequency); // Capture transmitted data (from Arduino to host) usart.onByteTransmit = (value) => { const char = String.fromCharCode(value); console.log(`TX: ${char} (0x${value.toString(16)})`); serialOutput.textContent += char; }; // Capture complete lines let lineBuffer = ''; usart.onLineTransmit = (line) => { console.log(`Serial: ${line}`); logElement.innerHTML += `
${line}
`; }; // Send data to Arduino (simulate serial input) function sendToArduino(text) { for (const char of text) { const byteValue = char.charCodeAt(0); const success = usart.writeByte(byteValue); if (!success) { console.warn('USART RX buffer full, byte dropped'); } } } // Monitor configuration changes usart.onConfigurationChange = () => { console.log(`Baud rate: ${usart.baudRate}`); console.log(`Data bits: ${usart.bitsPerChar}`); console.log(`Stop bits: ${usart.stopBits}`); console.log(`Parity: ${usart.parityEnabled ? (usart.parityOdd ? 'Odd' : 'Even') : 'None'}`); }; // Example: Send command when button clicked document.getElementById('send-btn').addEventListener('click', () => { sendToArduino('START\n'); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.