#include #include const char* registers[] = { "GSR", // ro; bits give status of ports "OCR", // rw; bits control status of output ports; read returns last command "PIR", // rw; inverts polarity of input ports "GCR", // rw; 0 -> output, 1 -> input; is 0xFF after boot "PUR", // rw; enables internal pull-up resistors; 0xFF after boot -> XRA1200P "IER", // rw; enables input interrupt "TSCR",// rw; enables three-state mode for output "ISR", // ro; status of input interrupts "REIR",// rw; enables rising edge interrupt "FEIR",// rw; enables falling edge interrupt "IFR" // rw; time-filter for input pulses; transition 1075-225ns }; enum _registers { GSR, OCR, PIR, GCR, PUR, IER, TSCR, ISR, REIR, FEIR, IFR }; enum _ports { P1 = 1 << 0,, P2 = 1 << 1, P3 = 1 << 2, P4 = 1 << 3, LED = 1 << 4, HUB = 1 << 5, ALERT= 1 << 6, WP = 1 << 7 }; uchar cmd[8]; uchar reg[1]; uchar res[8]; int opendata(void) { if (access("/dev/i2c1/i2c.20.data", 0) != 0){ if (bind("#J20", "/dev", MBEFORE) < 0){ sysfatal("Cannot detect ClusterHat"); } } int fd = open("/dev/i2c1/i2c.20.data", ORDWR); if (fd < 0){ sysfatal("cannot open i2c.20.data file"); } return fd; } uchar readreg(int data, uchar reg) { cmd[0] = reg; pwrite(data, cmd, 1, 0); pread(data, res, 1, 0); return res[0]; } void sendcmd(int data, uchar c, uchar v) { cmd[0] = c; cmd[1] = v; pwrite(data, cmd, 2, 0); } void setuphat(int data) { uchar gcr = readreg(data, GCR); int wp_link = 0; if(gcr == 0xFF) { // first boot setup uchar ocr = readreg(data, OCR); // detect if EEPROM WP is being pulled high uchar pur = readreg(data, PUR); if(pur == 0xFF) { sendcmd(data, PUR, 0x7F); uchar gsr = readreg(data, GSR); wp_link = gsr >> 7; if(wp_link == 1){ sendcmd(data, PUR, 0xFF); } else { sendcmd(data, GCR, 0x7F); } } else { sendcmd(data, GCR, 0x7F); wp_link = -1; } // Power On State for Pi ports p1-p4 uchar gsr = readreg(data, GSR); if ( gsr & 0xF == 0xF) { // POS set power ON ocr |= 0x0F; } else { // POS set power OFF ocr &= 0xF0; } // default state for other pins ocr &= 0xFF - ALERT; ocr |= LED; ocr &= 0xFF - HUB; sendcmd(data, OCR, ocr); // set pins to output sendcmd(data, GCR, 0); } else { uchar gsr = readreg(data, GSR); wp_link = gsr >> 7; } } void printstatus(int data) { for(uchar i=0; i<0x0a; ++i){ uchar val = readreg(data, i); print("%4s: 0x%02X\n", registers[i], val); } } void setport(int data, uchar port, int v) { uchar ocr = readreg(data, OCR); if (v) { sendcmd(data, OCR, ocr | port); } else { sendcmd(data, OCR, ocr & (0xFF - port)); } } void main(int argc, char *argv[]) { int data = opendata(); setuphat(data); if (argc == 3) { const char *c = argv[1]; int v = atoi(argv[2]); if ((v != 1) && (v != 0)) { print("\"%s\" is not a valid value (0, 1)\n", argv[2]); exits(0); } uchar ocr = readreg(data, OCR); if (strcmp(c, "led") == 0) { setport(data, LED, v); } else if(strcmp(c, "p1") == 0) { setport(data, P1, v); } else if(strcmp(c, "p2") == 0) { setport(data, P2, v); } else if(strcmp(c, "p3") == 0) { setport(data, P3, v); } else if(strcmp(c, "p4") == 0) { setport(data, P4, v); } else if(strcmp(c, "hub") == 0) { setport(data, HUB, v); } else if(strcmp(c, "alert") == 0) { setport(data, ALERT, v); } else { print("\"%s\" is not a known command\n", c); exits(0); } } else { // TODO: print help } printstatus(data); close(data); }