-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sio): start working on GPIO implementation #20
- Loading branch information
Showing
3 changed files
with
191 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { RP2040 } from './rp2040'; | ||
|
||
export enum GPIOPinState { | ||
Low, | ||
High, | ||
Input, | ||
InputPullUp, | ||
InputPullDown, | ||
} | ||
|
||
export class GPIOPin { | ||
constructor(readonly rp2040: RP2040, readonly index: number) {} | ||
|
||
get value() { | ||
const { index, rp2040 } = this; | ||
const bitmask = 1 << index; | ||
if (rp2040.sio.gpioOutputEnable & bitmask) { | ||
return rp2040.sio.gpioValue & bitmask ? GPIOPinState.High : GPIOPinState.Low; | ||
} else { | ||
// TODO account for pullup/pulldown | ||
return GPIOPinState.Input; | ||
} | ||
} | ||
|
||
// TODO add a way to listen for value changes | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { RP2040 } from './rp2040'; | ||
|
||
const CPUID = 0x000; | ||
|
||
// GPIO | ||
const GPIO_IN = 0x004; // Input value for GPIO pins | ||
const GPIO_HI_IN = 0x008; // Input value for QSPI pins | ||
const GPIO_OUT = 0x010; // GPIO output value | ||
const GPIO_OUT_SET = 0x014; // GPIO output value set | ||
const GPIO_OUT_CLR = 0x018; // GPIO output value clear | ||
const GPIO_OUT_XOR = 0x01c; // GPIO output value XOR | ||
const GPIO_OE = 0x020; // GPIO output enable | ||
const GPIO_OE_SET = 0x024; // GPIO output enable set | ||
const GPIO_OE_CLR = 0x028; // GPIO output enable clear | ||
const GPIO_OE_XOR = 0x02c; // GPIO output enable XOR | ||
const GPIO_HI_OUT = 0x030; // QSPI output value | ||
const GPIO_HI_OUT_SET = 0x034; // QSPI output value set | ||
const GPIO_HI_OUT_CLR = 0x038; // QSPI output value clear | ||
const GPIO_HI_OUT_XOR = 0x03c; // QSPI output value XOR | ||
const GPIO_HI_OE = 0x040; // QSPI output enable | ||
const GPIO_HI_OE_SET = 0x044; // QSPI output enable set | ||
const GPIO_HI_OE_CLR = 0x048; // QSPI output enable clear | ||
const GPIO_HI_OE_XOR = 0x04c; // QSPI output enable XOR | ||
|
||
const GPIO_MASK = 0x3fffffff; | ||
|
||
export class RPSIO { | ||
gpioValue = 0; | ||
gpioOutputEnable = 0; | ||
qspiGpioValue = 0; | ||
qspiGpioOutputEnable = 0; | ||
|
||
constructor(private readonly rp2040: RP2040) {} | ||
|
||
readUint32(offset: number) { | ||
switch (offset) { | ||
case GPIO_IN: | ||
return 0; // TODO implement! | ||
case GPIO_HI_IN: | ||
return 0; // TODO implement! | ||
case GPIO_OUT: | ||
return this.gpioValue; | ||
case GPIO_OE: | ||
return this.gpioOutputEnable; | ||
case GPIO_HI_OUT: | ||
return this.qspiGpioValue; | ||
case GPIO_HI_OE: | ||
return this.qspiGpioOutputEnable; | ||
case GPIO_OUT_SET: | ||
case GPIO_OUT_CLR: | ||
case GPIO_OUT_XOR: | ||
case GPIO_OE_SET: | ||
case GPIO_OE_CLR: | ||
case GPIO_OE_XOR: | ||
case GPIO_HI_OUT_SET: | ||
case GPIO_HI_OUT_CLR: | ||
case GPIO_HI_OUT_XOR: | ||
case GPIO_HI_OE_SET: | ||
case GPIO_HI_OE_CLR: | ||
case GPIO_HI_OE_XOR: | ||
return 0; // TODO verify with silicone | ||
case CPUID: | ||
// Returns the current CPU core id (always 0 for now) | ||
return 0; | ||
} | ||
console.warn(`Read from invalid SIO address: ${offset.toString(16)}`); | ||
return 0xffffffff; | ||
} | ||
|
||
writeUint32(offset: number, value: number) { | ||
switch (offset) { | ||
case GPIO_OUT: | ||
this.gpioValue = value & GPIO_MASK; | ||
break; | ||
case GPIO_OUT_SET: | ||
this.gpioValue |= value & GPIO_MASK; | ||
break; | ||
case GPIO_OUT_CLR: | ||
this.gpioValue &= ~value; | ||
break; | ||
case GPIO_OUT_XOR: | ||
this.gpioValue ^= value & GPIO_MASK; | ||
break; | ||
case GPIO_OE: | ||
this.gpioOutputEnable = value & GPIO_MASK; | ||
break; | ||
case GPIO_OE_SET: | ||
this.gpioOutputEnable |= value & GPIO_MASK; | ||
break; | ||
case GPIO_OE_CLR: | ||
this.gpioOutputEnable &= ~value; | ||
break; | ||
case GPIO_OE_XOR: | ||
this.gpioOutputEnable ^= value & GPIO_MASK; | ||
break; | ||
case GPIO_HI_OUT: | ||
this.qspiGpioValue = value & GPIO_MASK; | ||
break; | ||
case GPIO_HI_OUT_SET: | ||
this.qspiGpioValue |= value & GPIO_MASK; | ||
break; | ||
case GPIO_HI_OUT_CLR: | ||
this.qspiGpioValue &= ~value; | ||
break; | ||
case GPIO_HI_OUT_XOR: | ||
this.qspiGpioValue ^= value & GPIO_MASK; | ||
break; | ||
case GPIO_HI_OE: | ||
this.qspiGpioOutputEnable = value & GPIO_MASK; | ||
break; | ||
case GPIO_HI_OE_SET: | ||
this.qspiGpioOutputEnable |= value & GPIO_MASK; | ||
break; | ||
case GPIO_HI_OE_CLR: | ||
this.qspiGpioOutputEnable &= ~value; | ||
break; | ||
case GPIO_HI_OE_XOR: | ||
this.qspiGpioOutputEnable ^= value & GPIO_MASK; | ||
break; | ||
} | ||
} | ||
} |