#include #include #include #include "config.h" #include "udp.h" #include "debug.h" #include "z21prot.h" #include "z21emu.h" #include "i2csensor.h" using namespace std; struct s_rbussensor rbus[RBUS_MAXSENSORBYTES] = { 0 }; struct s_xlanturnout xlturn[XLAN_TURNOUT_MAX] = { 0 }; void i2cloop(I2C *i2c); void i2cscan(I2C *i2c); void i2ccfgprint(); int i2ccfgload(const char *fname); int debug = 0; void help(); int main (int argc, char **argv) { // time_t t1, t2; string cfgfile = DEFAULT_CONFIG; Z21Server z21server; I2C i2c; int i; int numofclients = 0; for (i = 1; i < argc; i++) { if (strcmp (argv[i], "-help") == 0) { help(); exit (0); } if (strcmp (argv[i], "-scan") == 0) { i2cscan(&i2c); i2ccfgprint(); exit (0); } if (strcmp (argv[i], "-debug") == 0) { debug = 1; } if (strcmp (argv[i], "-config") == 0) { i++; cfgfile = argv[i]; printf ("using configfile: %s\n", cfgfile.c_str()); } } if (i2ccfgload(cfgfile.c_str()) == 0) { i2cscan(&i2c); } z21server.Start(); while ( 1 ) { // // for detection of changed values for (i = 0; i < RBUS_MAXSENSORBYTES; i++) rbus[i].last = rbus[i].status; /* t2 = time (NULL); if (t2-t1 > 1) { rbus_status[2]++; rbus_status[15]--; t1 = t2; } */ if (numofclients > 0) i2cloop (&i2c); numofclients = z21server.Loop(); usleep(25000); }; return 0; }; void i2cloop (I2C *i2c) { int index; // sensorbox number --> sbox + 0x30 = i2c address // // digital in for (index = 0; index < RBUS_MAXSENSORBYTES; index++) { if (rbus[index].i2c_addr != 0) { if (!i2c->ReadByte(rbus[index].i2c_addr, rbus[index].i2c_reg, &rbus[index].status)) { if (debug) printf ("i2cloop: Read ADDR:%02x REG:%02x Value:%2x Error\n", rbus[index].i2c_addr, rbus[index].i2c_reg, rbus[index].status); rbus[index].status = 0xFF; // error } else if (debug) { printf ("i2cloop: Read ADDR:%02x REG:%02x Value:%2x\n", rbus[index].i2c_addr, rbus[index].i2c_reg, rbus[index].status); } } } // // digital out for (index = 0; index < XLAN_TURNOUTBYTES; index++) { if (xlturn[index].last != xlturn[index].output) { // ignore if addr is not set if (xlturn[index].i2c_addr == 0) xlturn[index].last = xlturn[index].output; // send data else if (i2c->SendByte(xlturn[index].i2c_addr, xlturn[index].i2c_reg, xlturn[index].output)) { xlturn[index].last = xlturn[index].output; } } } } // // scan all i2c devices read version and create configuration void i2cscan(I2C *i2c) { int dicnt; int docnt; int addr; unsigned char ver; for (dicnt = 0, docnt = 0, addr = 0x20; addr < 0x7f; addr++) { if (i2c->ReadByte(addr, 0x20, &ver)) { if (ver == 1) { if (dicnt < RBUS_MAXSENSORBYTES) { rbus[dicnt].i2c_addr = addr; rbus[dicnt].i2c_reg = 0x0; dicnt++; } if (dicnt < RBUS_MAXSENSORBYTES) { rbus[dicnt].i2c_addr = addr; rbus[dicnt].i2c_reg = 0x1; dicnt++; } } else if (ver == 2) { if (dicnt < RBUS_MAXSENSORBYTES) { rbus[dicnt].i2c_addr = addr; rbus[dicnt].i2c_reg = 0x0; dicnt++; } if (docnt < RBUS_MAXSENSORBYTES) { xlturn[docnt].i2c_addr = addr; xlturn[docnt].i2c_reg = 0x1; docnt++; } } else if (ver == 3 || ver == 4) { if (dicnt < RBUS_MAXSENSORBYTES) { rbus[dicnt].i2c_addr = addr; rbus[dicnt].i2c_reg = 0x0; dicnt++; } if (dicnt < RBUS_MAXSENSORBYTES) { rbus[dicnt].i2c_addr = addr; rbus[dicnt].i2c_reg = 0x1; dicnt++; } if (dicnt < RBUS_MAXSENSORBYTES) { rbus[dicnt].i2c_addr = addr; rbus[dicnt].i2c_reg = 0x2; dicnt++; } if (dicnt < RBUS_MAXSENSORBYTES) { rbus[dicnt].i2c_addr = addr; rbus[dicnt].i2c_reg = 0x3; dicnt++; } } } } }; void i2ccfgprint() { int i; printf ("# autoscan configuration\n"); printf ("#\n"); printf ("# digital input configuration\n"); printf ("#\n"); printf ("# di NUM addr ADDR reg REG\n"); for (i = 0; i < RBUS_MAXSENSORBYTES; i++) if (rbus[i].i2c_addr != 0) printf ("di %d addr %x reg %x\n", i, rbus[i].i2c_addr, rbus[i].i2c_reg); printf ("#\n"); printf ("# digital output configuration\n"); printf ("#\n"); printf ("# do NUM addr ADDR reg REG\n"); for (i = 0; i < XLAN_TURNOUTBYTES; i++) if (xlturn[i].i2c_addr != 0) printf ("do %d addr %x reg %x\n", i, xlturn[i].i2c_addr, xlturn[i].i2c_reg); }; #define STR_TOK_NOSPACE(_pnt_) while (_pnt_[0] != 0 && (_pnt_[0] == ' ' || _pnt_[0] == '\t')) _pnt_++ #define STR_TOK_NEXT(_pnt_) while (_pnt_[0] != 0 && _pnt_[0] != ' ' && _pnt_[0] != '\t') _pnt_++ int i2ccfgload(const char *fname) { FILE *f; char buf[1024]; char *pos; int index = -1; int type; int addr; int reg; printf ("loading file: %s\n", fname); f = fopen (fname, (char*)"r"); if (f == NULL) { printf ("error:%s\n", strerror(errno)); return 0; } while (fgets (buf, sizeof (buf), f) != NULL) { pos = buf; if (pos[0] == '#') continue; type = I2CREGTYPE_UNDEF; addr = 0; reg = 0; index = -1; while (pos != NULL && pos[0] != 0) { STR_TOK_NOSPACE(pos); if (strncmp ("di", pos, strlen ("di")) == 0) { STR_TOK_NEXT(pos); sscanf (pos, "%d", &index); type = I2CREGTYPE_DI; printf (" di %d", index); } if (strncmp ("do", pos, strlen ("do")) == 0) { STR_TOK_NEXT(pos); sscanf (pos, "%d", &index); type = I2CREGTYPE_DO; printf (" do %d", index); } if (strncmp ("addr", pos, strlen ("addr")) == 0) { STR_TOK_NEXT(pos); sscanf (pos, "%x", &addr); printf (" addr %x", addr); } if (strncmp ("reg", pos, strlen ("reg")) == 0) { STR_TOK_NEXT(pos); sscanf (pos, "%x", ®); printf (" reg %x", reg); } else STR_TOK_NEXT(pos); } if (type == I2CREGTYPE_DI && index >= 0 && index < RBUS_MAXSENSORBYTES) { rbus[index].i2c_addr = addr; rbus[index].i2c_reg = reg; printf ("--> DI (%d) OK\n", index); } else if (type == I2CREGTYPE_DO && index >= 0 && index < XLAN_TURNOUTBYTES) { xlturn[index].i2c_addr = addr; xlturn[index].i2c_reg = reg; printf ("--> DO (%d) OK\n", index); } else { printf (" error\n"); } } fclose (f); return 0; }; #undef STR_TOK_NEXT void help () { printf ("z21emu:\n"); printf ("=======\n"); printf ("\n"); printf ("parameters: without any parameters the config will be read from file.\n"); printf (" if no file is found, autoscan is used first.\n"); printf (" -scan scanning i2c bus and print out a sample device config\n"); printf (" -debug enabling debugging\n"); printf (" -config FILE finename used for configuration (default %s/\n", DEFAULT_CONFIG); printf ("\n"); } void xlan_turnout (int addr, bool enable) { int addrbyte = (addr-1)/8; int bit = (addr-1)%8; if (addr == 0) return; if (addrbyte < 0 || addrbyte >= XLAN_TURNOUTBYTES) return; if (enable) xlturn[addrbyte].output |= (1 << bit); else xlturn[addrbyte].output &= ~(1 << bit); }