Skip to content

Commit 6a9f238

Browse files
committed
feat(gpio): add pinState() method
close #8
1 parent b6f04e0 commit 6a9f238

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

src/gpio.spec.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { CPU } from './cpu';
2-
import { AVRIOPort, portBConfig } from './gpio';
2+
import { AVRIOPort, portBConfig, PinState } from './gpio';
33

44
describe('GPIO', () => {
55
it('should invoke the listeners when the port is written to', () => {
@@ -37,4 +37,36 @@ describe('GPIO', () => {
3737
expect(listener).not.toHaveBeenCalled();
3838
});
3939
});
40+
41+
describe('pinState', () => {
42+
it('should return PinState.High when the pin set to output and HIGH', () => {
43+
const cpu = new CPU(new Uint16Array(1024));
44+
const port = new AVRIOPort(cpu, portBConfig);
45+
cpu.writeData(0x24, 0x1); // DDRB <- 0x1
46+
cpu.writeData(0x25, 0x1); // PORTB <- 0x1
47+
expect(port.pinState(0)).toEqual(PinState.High);
48+
});
49+
50+
it('should return PinState.Low when the pin set to output and LOW', () => {
51+
const cpu = new CPU(new Uint16Array(1024));
52+
const port = new AVRIOPort(cpu, portBConfig);
53+
cpu.writeData(0x24, 0x8); // DDRB <- 0x8
54+
cpu.writeData(0x25, 0xf7); // PORTB <- 0xF7 (~8)
55+
expect(port.pinState(3)).toEqual(PinState.Low);
56+
});
57+
58+
it('should return PinState.Input by default (reset state)', () => {
59+
const cpu = new CPU(new Uint16Array(1024));
60+
const port = new AVRIOPort(cpu, portBConfig);
61+
expect(port.pinState(1)).toEqual(PinState.Input);
62+
});
63+
64+
it('should return PinState.InputPullUp when the pin is set to input with pullup', () => {
65+
const cpu = new CPU(new Uint16Array(1024));
66+
const port = new AVRIOPort(cpu, portBConfig);
67+
cpu.writeData(0x24, 0); // DDRB <- 0
68+
cpu.writeData(0x25, 0x2); // PORTB <- 0x2
69+
expect(port.pinState(1)).toEqual(PinState.InputPullUp);
70+
});
71+
});
4072
});

src/gpio.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Part of AVR8js
44
* Reference: http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
55
*
6-
* Copyright (C) 2019, Uri Shaked
6+
* Copyright (C) 2019, 2020, Uri Shaked
77
*/
88
import { CPU } from './cpu';
99
import { u8 } from './types';
@@ -83,10 +83,17 @@ export const portLConfig: AVRPortConfig = {
8383
PORT: 0x10b
8484
};
8585

86+
export enum PinState {
87+
Low,
88+
High,
89+
Input,
90+
InputPullUp
91+
}
92+
8693
export class AVRIOPort {
8794
private listeners: GPIOListener[] = [];
8895

89-
constructor(cpu: CPU, portConfig: AVRPortConfig) {
96+
constructor(private cpu: CPU, private portConfig: AVRPortConfig) {
9097
cpu.writeHooks[portConfig.PORT] = (value: u8, oldValue: u8) => {
9198
const ddrMask = cpu.data[portConfig.DDR];
9299
value &= ddrMask;
@@ -114,6 +121,25 @@ export class AVRIOPort {
114121
this.listeners = this.listeners.filter((l) => l !== listener);
115122
}
116123

124+
/**
125+
* Get the state of a given GPIO pin
126+
*
127+
* @param index Pin index to return from 0 to 7
128+
* @returns PinState.Low or PinState.High if the pin is set to output, PinState.Input if the pin is set
129+
* to input, and PinState.InputPullUp if the pin is set to input and the internal pull-up resistor has
130+
* been enabled.
131+
*/
132+
pinState(index: number) {
133+
const ddr = this.cpu.data[this.portConfig.DDR];
134+
const port = this.cpu.data[this.portConfig.PORT];
135+
const bitMask = 1 << index;
136+
if (ddr & bitMask) {
137+
return port & bitMask ? PinState.High : PinState.Low;
138+
} else {
139+
return port & bitMask ? PinState.InputPullUp : PinState.Input;
140+
}
141+
}
142+
117143
private writeGpio(value: u8, oldValue: u8) {
118144
for (const listener of this.listeners) {
119145
listener(value, oldValue);

src/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* AVR8js
3+
*
4+
* Copyright (C) 2019, 2020, Uri Shaked
5+
*/
6+
17
export { CPU, ICPU, CPUMemoryHook, CPUMemoryHooks } from './cpu';
28
export { avrInstruction } from './instruction';
39
export { avrInterrupt } from './interrupt';
@@ -16,6 +22,7 @@ export {
1622
portHConfig,
1723
portJConfig,
1824
portKConfig,
19-
portLConfig
25+
portLConfig,
26+
PinState
2027
} from './gpio';
2128
export { AVRUSART, usart0Config } from './usart';

0 commit comments

Comments
 (0)