| 1 | #include <stdlib.h> |
| 2 | #include <fcntl.h> |
| 3 | #include <signal.h> |
| 4 | #include <unistd.h> |
| 5 | #include <string.h> |
| 6 | #include <stdio.h> |
| 7 | |
| 8 | #include <sys/types.h> |
| 9 | #include <sys/gpio.h> |
| 10 | #include <sys/ioctl.h> |
| 11 | |
| 12 | #define UP(N) set_pin(N, 1) |
| 13 | #define DOWN(N) set_pin(N, 0) |
| 14 | |
| 15 | #define DEL 100000 |
| 16 | |
| 17 | #define MEM_WR 0x40 |
| 18 | #define ADDR_AUTO 0x44 |
| 19 | |
| 20 | #define DISP_ON 0x8f |
| 21 | #define DISP_OFF 0x80 |
| 22 | #define DISP_1 0x88 |
| 23 | #define DISP_2 0x89 |
| 24 | #define DISP_3 0x8a |
| 25 | #define DISP_4 0x8b |
| 26 | #define DISP_5 0x8c |
| 27 | #define DISP_6 0x8d |
| 28 | #define DISP_7 0x8e |
| 29 | #define DISP_8 0x8f |
| 30 | |
| 31 | |
| 32 | volatile int g0, g1, g2; |
| 33 | |
| 34 | void kd() { |
| 35 | /* struct timespec ts, rem; |
| 36 | |
| 37 | ts.tv_sec = 0; |
| 38 | ts.tv_nsec = DEL; |
| 39 | |
| 40 | rem.tv_sec = 0; |
| 41 | rem.tv_nsec = 0; |
| 42 | |
| 43 | nanosleep(&ts, &rem); |
| 44 | */ |
| 45 | } |
| 46 | |
| 47 | int name2dev(char *s) { |
| 48 | if (! strncmp(s, "ser", GPIOPINMAXNAME)) |
| 49 | return g1; |
| 50 | else if (! strncmp(s, "oe", GPIOPINMAXNAME)) |
| 51 | return g0; |
| 52 | else if (! strncmp(s, "rclk", GPIOPINMAXNAME)) |
| 53 | return g1; |
| 54 | else if (! strncmp(s, "srclk", GPIOPINMAXNAME)) |
| 55 | return g2; |
| 56 | else if (! strncmp(s, "srclr", GPIOPINMAXNAME)) |
| 57 | return g1; |
| 58 | else if (! strncmp(s, "dio", GPIOPINMAXNAME)) |
| 59 | return g2; |
| 60 | else if (! strncmp(s, "clk", GPIOPINMAXNAME)) |
| 61 | return g2; |
| 62 | else { |
| 63 | printf("no gpio pin w/ name %s, exiting..\n", s); |
| 64 | exit(2); |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | void inth(int f) { |
| 69 | close(g0); |
| 70 | close(g1); |
| 71 | close(g2); |
| 72 | |
| 73 | exit(9); |
| 74 | } |
| 75 | |
| 76 | void ack_wait() { |
| 77 | struct gpio_pin_set p; |
| 78 | struct gpio_pin_op o; |
| 79 | int read = 0; |
| 80 | |
| 81 | p.gp_pin = 6; |
| 82 | o.gp_pin = 6; |
| 83 | p.gp_flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN; |
| 84 | o.gp_value = 0; |
| 85 | |
| 86 | ioctl(name2dev("dio"), GPIOPINWRITE, &o); |
| 87 | ioctl(name2dev("dio"), GPIOPINSET, &p); |
| 88 | |
| 89 | while(!read) { |
| 90 | printf("waiting..\n"); |
| 91 | ioctl(name2dev("dio"), GPIOPINREAD, &o); |
| 92 | read = o.gp_value; |
| 93 | } |
| 94 | |
| 95 | p.gp_flags = GPIO_PIN_OUTPUT; |
| 96 | ioctl(name2dev("dio"), GPIOPINREAD, &o); |
| 97 | } |
| 98 | |
| 99 | void set_pin(char *name, int state) { |
| 100 | struct gpio_pin_op op; |
| 101 | |
| 102 | strlcpy(op.gp_name, name, GPIOPINMAXNAME); |
| 103 | op.gp_value = state; |
| 104 | |
| 105 | ioctl(name2dev(name), GPIOPINWRITE, &op); |
| 106 | } |
| 107 | |
| 108 | void config_pins() { |
| 109 | struct gpio_pin_set *ser, *oe, *rclk, *srclk, *srclr, *dio, *clk; |
| 110 | |
| 111 | ser = calloc(1, sizeof(struct gpio_pin_set)); |
| 112 | oe = calloc(1, sizeof(struct gpio_pin_set)); |
| 113 | rclk = calloc(1, sizeof(struct gpio_pin_set)); |
| 114 | srclk = calloc(1, sizeof(struct gpio_pin_set)); |
| 115 | srclr = calloc(1, sizeof(struct gpio_pin_set)); |
| 116 | dio = calloc(1, sizeof(struct gpio_pin_set)); |
| 117 | clk = calloc(1, sizeof(struct gpio_pin_set)); |
| 118 | |
| 119 | ser->gp_pin = 12; |
| 120 | ser->gp_flags = GPIO_PIN_OUTPUT; |
| 121 | strlcpy(ser->gp_name2, "ser", GPIOPINMAXNAME); |
| 122 | |
| 123 | oe->gp_pin = 26; |
| 124 | oe->gp_flags = GPIO_PIN_OUTPUT; |
| 125 | strlcpy(oe->gp_name2, "oe", GPIOPINMAXNAME); |
| 126 | |
| 127 | rclk->gp_pin = 14; |
| 128 | rclk->gp_flags = GPIO_PIN_OUTPUT; |
| 129 | strlcpy(rclk->gp_name2, "rclk", GPIOPINMAXNAME); |
| 130 | |
| 131 | srclk->gp_pin = 1; |
| 132 | srclk->gp_flags = GPIO_PIN_OUTPUT; |
| 133 | strlcpy(srclk->gp_name2, "srclk", GPIOPINMAXNAME); |
| 134 | |
| 135 | srclr->gp_pin = 31; |
| 136 | srclr->gp_flags = GPIO_PIN_OUTPUT; |
| 137 | strlcpy(srclr->gp_name2, "srclr", GPIOPINMAXNAME); |
| 138 | |
| 139 | dio->gp_pin = 8; |
| 140 | dio->gp_flags = GPIO_PIN_OUTPUT; |
| 141 | strlcpy(dio->gp_name2, "dio", GPIOPINMAXNAME); |
| 142 | |
| 143 | clk->gp_pin = 6; |
| 144 | clk->gp_flags = GPIO_PIN_OUTPUT; |
| 145 | strlcpy(clk->gp_name2, "clk", GPIOPINMAXNAME); |
| 146 | |
| 147 | ioctl(name2dev("ser"), GPIOPINSET, ser); |
| 148 | ioctl(name2dev("oe"), GPIOPINSET, oe); |
| 149 | ioctl(name2dev("rclk"), GPIOPINSET, rclk); |
| 150 | ioctl(name2dev("srclk"), GPIOPINSET, srclk); |
| 151 | ioctl(name2dev("srclr"), GPIOPINSET, srclr); |
| 152 | ioctl(name2dev("dio"), GPIOPINSET, dio); |
| 153 | ioctl(name2dev("clk"), GPIOPINSET, clk); |
| 154 | |
| 155 | free(ser); |
| 156 | free(oe); |
| 157 | free(rclk); |
| 158 | free(srclk); |
| 159 | free(srclr); |
| 160 | free(dio); |
| 161 | free(clk); |
| 162 | } |
| 163 | |
| 164 | void pincnt() { |
| 165 | g0 = open("/dev/gpio0", O_RDWR); |
| 166 | g1 = open("/dev/gpio1", O_RDWR); |
| 167 | g2 = open("/dev/gpio2", O_RDWR); |
| 168 | |
| 169 | struct gpio_info *inf0, *inf1, *inf2; |
| 170 | inf0 = calloc(1, sizeof(struct gpio_info)); |
| 171 | inf1 = calloc(1, sizeof(struct gpio_info)); |
| 172 | inf2 = calloc(1, sizeof(struct gpio_info)); |
| 173 | |
| 174 | ioctl(g0, GPIOINFO, inf0); |
| 175 | ioctl(g1, GPIOINFO, inf1); |
| 176 | ioctl(g2, GPIOINFO, inf2); |
| 177 | |
| 178 | printf("gpio0: %d\ngpio1: %d\ngpio2: %d\n", inf0->gpio_npins, inf1->gpio_npins, inf2->gpio_npins); |
| 179 | |
| 180 | free(inf0); |
| 181 | free(inf1); |
| 182 | free(inf2); |
| 183 | } |
| 184 | |
| 185 | void start() { |
| 186 | DOWN("dio"); |
| 187 | kd(); |
| 188 | } |
| 189 | |
| 190 | void stop() { |
| 191 | DOWN("dio"); |
| 192 | kd(); |
| 193 | UP("clk"); |
| 194 | kd(); |
| 195 | UP("dio"); |
| 196 | kd(); |
| 197 | } |
| 198 | |
| 199 | void byte(uint8_t b) { |
| 200 | for(int i = 0; i < 8; i++) { |
| 201 | DOWN("clk"); |
| 202 | kd(); |
| 203 | (b & 0x1) ? UP("dio") : DOWN("dio"); |
| 204 | kd(); |
| 205 | UP("clk"); |
| 206 | kd(); |
| 207 | b >>= 1; |
| 208 | } |
| 209 | |
| 210 | DOWN("clk"); |
| 211 | UP("dio"); |
| 212 | kd(); |
| 213 | UP("clk"); |
| 214 | kd(); |
| 215 | DOWN("dio"); |
| 216 | kd(); |
| 217 | DOWN("clk"); |
| 218 | kd(); |
| 219 | } |
| 220 | |
| 221 | void blink(int c, int ms) { |
| 222 | for(int i = 0; i < c; i++) { |
| 223 | byte(DISP_ON); |
| 224 | kd(); |
| 225 | byte(DISP_OFF); |
| 226 | kd(); |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | |