summaryrefslogtreecommitdiff
path: root/include/arch
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-10-23 10:07:31 +0200
committerDaniel Friesel <derf@finalrewind.org>2018-10-23 10:07:31 +0200
commit7dac0cccc846d4452293b47b40d43f6b50ebcc33 (patch)
tree8efcb0c13a5ddfd6616caf76ad109fec290977ca /include/arch
parent1865935a9e7d335b7afff3a6a159a4fd81db1275 (diff)
POSIX: Improve GPIO emulation
Diffstat (limited to 'include/arch')
-rw-r--r--include/arch/posix/driver/gpio.h122
1 files changed, 116 insertions, 6 deletions
diff --git a/include/arch/posix/driver/gpio.h b/include/arch/posix/driver/gpio.h
index 0995729..12e9121 100644
--- a/include/arch/posix/driver/gpio.h
+++ b/include/arch/posix/driver/gpio.h
@@ -1,17 +1,127 @@
#ifndef GPIO_H
#define GPIO_H
+#include <stdio.h>
+
class GPIO {
private:
GPIO(const GPIO &copy);
- unsigned char ledstate;
+ unsigned int pin_dir, pin_pull, pin_out, pull_dir;
+#ifdef GPIO_TRACE
+ void print_pinstate() {
+ unsigned int mask = 1;
+ for (unsigned char i=0; i < 32; i++) {
+ if (i == 0) {
+ fputs("▶ LED ", stdout);
+ }
+ else if (i == 8) {
+ fputs(" GPIO ", stdout);
+ }
+ else if (i == 16) {
+ fputs(" ", stdout);
+ }
+ else if (i == 24) {
+ fputs(" ", stdout);
+ }
+ if (pin_dir & mask) {
+ if (pin_out & (1<<i)) {
+ fputs("█", stdout);
+ } else {
+ putc(' ', stdout);
+ }
+ } else {
+ if (pin_pull & mask) {
+ if (pull_dir & mask) {
+ fputs("↑", stdout);
+ } else {
+ fputs("↓", stdout);
+ }
+ } else {
+ fputs("·", stdout);
+ }
+ }
+ mask <<= 1;
+ }
+ putc('\n', stdout);
+ }
+#else
+ inline void print_pinstate() {}
+#endif
public:
- GPIO () : ledstate(0) {}
- void setup() {}
- void led_on(unsigned char id);
- void led_off(unsigned char id);
- void led_toggle(unsigned char id);
+ GPIO () : pin_dir(0), pin_pull(0), pin_out(0), pull_dir(0) {}
+
+ enum Pin : unsigned char {
+ pl0 = 0, pl1, pl2, pl3, pl4, pl5, pl6, pl7,
+ px00, px01, px02, px03, px04, px05, px06, px07,
+ px08, px09, px10, px11, px12, px13, px14, px15,
+ px16, px17, px18, px19, px20, px21, px22, px23
+ };
+
+ inline void setup() {
+ pin_dir |= 0x0000ff;
+ }
+ inline void led_on(unsigned char id) {
+ if (id <= pl7) {
+ pin_out |= (1 << id);
+ }
+ print_pinstate();
+ }
+ inline void led_off(unsigned char id) {
+ if (id <= pl7) {
+ pin_out &= ~(1 << id);
+ }
+ print_pinstate();
+ }
+ inline void led_toggle(unsigned char id) {
+ if (id <= pl7) {
+ if (pin_out & (1 << id)) {
+ led_off(id);
+ } else {
+ led_on(id);
+ }
+ }
+ }
+ inline void input(unsigned char const pin) {
+ pin_dir &= ~(1<<pin);
+ print_pinstate();
+ }
+ inline void input(unsigned char const pin, unsigned char const pull) {
+ pin_dir &= ~(1<<pin);
+ pin_pull |= (1<<pin);
+ if (pull) {
+ pull_dir |= (1<<pin);
+ } else {
+ pull_dir &= ~(1<<pin);
+ }
+ print_pinstate();
+ }
+ inline void output(unsigned char const pin) {
+ pin_dir |= (1<<pin);
+ print_pinstate();
+ }
+ inline void output(unsigned char const pin, unsigned char const value) {
+ pin_dir |= (1<<pin);
+ if (value)
+ pin_out |= (1<<pin);
+ else
+ pin_out &= ~(1<<pin);
+ print_pinstate();
+ }
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+ inline unsigned char read(unsigned char const pin) {
+ return 1;
+ }
+#pragma GCC diagnostic pop
+ inline void write(unsigned char const pin, unsigned char value) {
+ if (value)
+ pin_out |= (1<<pin);
+ else
+ pin_out &= ~(1<<pin);
+ print_pinstate();
+ }
+ inline void enable_int() {}
+ inline void disable_int() {}
};
extern GPIO gpio;