1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
import { CPU } from '../cpu/cpu';
import { AVRIOPort, portBConfig, PinState } from './gpio';
describe('GPIO', () => {
it('should invoke the listeners when the port is written to', () => {
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
const listener = jest.fn();
port.addListener(listener);
cpu.writeData(0x24, 0x0f); // DDRB <- 0x0f
cpu.writeData(0x25, 0x55); // PORTB <- 0x55
expect(listener).toHaveBeenCalledWith(0x05, 0);
expect(cpu.data[0x23]).toEqual(0x5); // PINB should return port value
});
it('should toggle the pin when writing to the PIN register', () => {
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
const listener = jest.fn();
port.addListener(listener);
cpu.writeData(0x24, 0x0f); // DDRB <- 0x0f
cpu.writeData(0x25, 0x55); // PORTB <- 0x55
cpu.writeData(0x23, 0x01); // PINB <- 0x0f
expect(listener).toHaveBeenCalledWith(0x04, 0x5);
expect(cpu.data[0x23]).toEqual(0x4); // PINB should return port value
});
describe('removeListener', () => {
it('should remove the given listener', () => {
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
const listener = jest.fn();
port.addListener(listener);
cpu.writeData(0x24, 0x0f); // DDRB <- 0x0f
port.removeListener(listener);
cpu.writeData(0x25, 0x99); // PORTB <- 0x99
expect(listener).not.toHaveBeenCalled();
});
});
describe('pinState', () => {
it('should return PinState.High when the pin set to output and HIGH', () => {
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
cpu.writeData(0x24, 0x1); // DDRB <- 0x1
cpu.writeData(0x25, 0x1); // PORTB <- 0x1
expect(port.pinState(0)).toEqual(PinState.High);
});
it('should return PinState.Low when the pin set to output and LOW', () => {
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
cpu.writeData(0x24, 0x8); // DDRB <- 0x8
cpu.writeData(0x25, 0xf7); // PORTB <- 0xF7 (~8)
expect(port.pinState(3)).toEqual(PinState.Low);
});
it('should return PinState.Input by default (reset state)', () => {
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
expect(port.pinState(1)).toEqual(PinState.Input);
});
it('should return PinState.InputPullUp when the pin is set to input with pullup', () => {
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
cpu.writeData(0x24, 0); // DDRB <- 0
cpu.writeData(0x25, 0x2); // PORTB <- 0x2
expect(port.pinState(1)).toEqual(PinState.InputPullUp);
});
it('should reflect the current port state when called inside a listener', () => {
// Related issue: https://github.com/wokwi/avr8js/issues/9
const cpu = new CPU(new Uint16Array(1024));
const port = new AVRIOPort(cpu, portBConfig);
const listener = jest.fn(() => {
expect(port.pinState(0)).toBe(PinState.High);
});
port.addListener(listener);
expect(port.pinState(0)).toBe(PinState.Input);
cpu.writeData(0x24, 0x01); // DDRB <- 0x01
cpu.writeData(0x25, 0x01); // PORTB <- 0x01
expect(listener).toHaveBeenCalled();
});
});
});
|