Skip to content

Commit 958691d

Browse files
committed
fix: GPIO port listeners not invoked when writing to DDR registers
close #28
1 parent ccba5de commit 958691d

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

src/peripherals/gpio.spec.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,23 @@ describe('GPIO', () => {
66
const cpu = new CPU(new Uint16Array(1024));
77
const port = new AVRIOPort(cpu, portBConfig);
88
const listener = jest.fn();
9-
port.addListener(listener);
109
cpu.writeData(0x24, 0x0f); // DDRB <- 0x0f
10+
port.addListener(listener);
1111
cpu.writeData(0x25, 0x55); // PORTB <- 0x55
1212
expect(listener).toHaveBeenCalledWith(0x05, 0);
1313
expect(cpu.data[0x23]).toEqual(0x5); // PINB should return port value
1414
});
1515

16+
it('should invoke the listeners when DDR changes (issue #28)', () => {
17+
const cpu = new CPU(new Uint16Array(1024));
18+
const port = new AVRIOPort(cpu, portBConfig);
19+
const listener = jest.fn();
20+
cpu.writeData(0x25, 0x55); // PORTB <- 0x55
21+
port.addListener(listener);
22+
cpu.writeData(0x24, 0xf0); // DDRB <- 0xf0
23+
expect(listener).toHaveBeenCalledWith(0x50, 0);
24+
});
25+
1626
it('should toggle the pin when writing to the PIN register', () => {
1727
const cpu = new CPU(new Uint16Array(1024));
1828
const port = new AVRIOPort(cpu, portBConfig);
@@ -34,7 +44,7 @@ describe('GPIO', () => {
3444
cpu.writeData(0x24, 0x0f); // DDRB <- 0x0f
3545
port.removeListener(listener);
3646
cpu.writeData(0x25, 0x99); // PORTB <- 0x99
37-
expect(listener).not.toHaveBeenCalled();
47+
expect(listener).toBeCalledTimes(1);
3848
});
3949
});
4050

@@ -76,9 +86,9 @@ describe('GPIO', () => {
7686
const listener = jest.fn(() => {
7787
expect(port.pinState(0)).toBe(PinState.High);
7888
});
79-
port.addListener(listener);
8089
expect(port.pinState(0)).toBe(PinState.Input);
8190
cpu.writeData(0x24, 0x01); // DDRB <- 0x01
91+
port.addListener(listener);
8292
cpu.writeData(0x25, 0x01); // PORTB <- 0x01
8393
expect(listener).toHaveBeenCalled();
8494
});

src/peripherals/gpio.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ export class AVRIOPort {
9494
private listeners: GPIOListener[] = [];
9595

9696
constructor(private cpu: CPU, private portConfig: AVRPortConfig) {
97+
cpu.writeHooks[portConfig.DDR] = (value, oldValue) => {
98+
const portValue = cpu.data[portConfig.PORT];
99+
this.writeGpio(value & portValue, oldValue & oldValue);
100+
};
97101
cpu.writeHooks[portConfig.PORT] = (value: u8, oldValue: u8) => {
98102
const ddrMask = cpu.data[portConfig.DDR];
99103
cpu.data[portConfig.PORT] = value;

0 commit comments

Comments
 (0)