aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUri Shaked2020-01-08 12:20:38 +0200
committerUri Shaked2020-01-08 12:20:38 +0200
commit6a9f238969fc0e877c7bef103a4953dabf0f2936 (patch)
tree1f3b639f2309e26624beec31649e7c4037526945
parentchore: release 0.5.0 (diff)
downloadavr8js-6a9f238969fc0e877c7bef103a4953dabf0f2936.tar.gz
avr8js-6a9f238969fc0e877c7bef103a4953dabf0f2936.tar.bz2
avr8js-6a9f238969fc0e877c7bef103a4953dabf0f2936.zip
feat(gpio): add pinState() method
close #8
-rw-r--r--src/gpio.spec.ts34
-rw-r--r--src/gpio.ts30
-rw-r--r--src/index.ts9
3 files changed, 69 insertions, 4 deletions
diff --git a/src/gpio.spec.ts b/src/gpio.spec.ts
index 03ebb84..e0ab7a1 100644
--- a/src/gpio.spec.ts
+++ b/src/gpio.spec.ts
@@ -1,5 +1,5 @@
import { CPU } from './cpu';
-import { AVRIOPort, portBConfig } from './gpio';
+import { AVRIOPort, portBConfig, PinState } from './gpio';
describe('GPIO', () => {
it('should invoke the listeners when the port is written to', () => {
@@ -37,4 +37,36 @@ describe('GPIO', () => {
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);
+ });
+ });
});
diff --git a/src/gpio.ts b/src/gpio.ts
index d39a918..293c559 100644
--- a/src/gpio.ts
+++ b/src/gpio.ts
@@ -3,7 +3,7 @@
* Part of AVR8js
* Reference: http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
*
- * Copyright (C) 2019, Uri Shaked
+ * Copyright (C) 2019, 2020, Uri Shaked
*/
import { CPU } from './cpu';
import { u8 } from './types';
@@ -83,10 +83,17 @@ export const portLConfig: AVRPortConfig = {
PORT: 0x10b
};
+export enum PinState {
+ Low,
+ High,
+ Input,
+ InputPullUp
+}
+
export class AVRIOPort {
private listeners: GPIOListener[] = [];
- constructor(cpu: CPU, portConfig: AVRPortConfig) {
+ constructor(private cpu: CPU, private portConfig: AVRPortConfig) {
cpu.writeHooks[portConfig.PORT] = (value: u8, oldValue: u8) => {
const ddrMask = cpu.data[portConfig.DDR];
value &= ddrMask;
@@ -114,6 +121,25 @@ export class AVRIOPort {
this.listeners = this.listeners.filter((l) => l !== listener);
}
+ /**
+ * Get the state of a given GPIO pin
+ *
+ * @param index Pin index to return from 0 to 7
+ * @returns PinState.Low or PinState.High if the pin is set to output, PinState.Input if the pin is set
+ * to input, and PinState.InputPullUp if the pin is set to input and the internal pull-up resistor has
+ * been enabled.
+ */
+ pinState(index: number) {
+ const ddr = this.cpu.data[this.portConfig.DDR];
+ const port = this.cpu.data[this.portConfig.PORT];
+ const bitMask = 1 << index;
+ if (ddr & bitMask) {
+ return port & bitMask ? PinState.High : PinState.Low;
+ } else {
+ return port & bitMask ? PinState.InputPullUp : PinState.Input;
+ }
+ }
+
private writeGpio(value: u8, oldValue: u8) {
for (const listener of this.listeners) {
listener(value, oldValue);
diff --git a/src/index.ts b/src/index.ts
index bdf7621..ead8081 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,9 @@
+/**
+ * AVR8js
+ *
+ * Copyright (C) 2019, 2020, Uri Shaked
+ */
+
export { CPU, ICPU, CPUMemoryHook, CPUMemoryHooks } from './cpu';
export { avrInstruction } from './instruction';
export { avrInterrupt } from './interrupt';
@@ -16,6 +22,7 @@ export {
portHConfig,
portJConfig,
portKConfig,
- portLConfig
+ portLConfig,
+ PinState
} from './gpio';
export { AVRUSART, usart0Config } from './usart';
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.