bool CGpio::InitU401Pins() { char buf[256]; int gpioNumber, direction; FILE *cmd = NULL; #ifndef WIN32 cmd = fopen("/opt/u401_cfg.txt", "r"); #else cmd = fopen("E:\\u401_cfg.txt", "r"); #endif if (cmd == NULL) { _log.Log(LOG_ERROR, "%s: Failed to open /opt/u401_cfg.txt", __func__); return false; } while (fgets(buf, sizeof(buf), cmd) != 0) { // Decode U401 GPIOs as below: // // GPIO,DIR // 0,out, // 7,in, std::string exportLine(buf); //std::cout << "Processing line: " << exportLine; std::vector<std::string> sresults; StringSplit(exportLine, ",", sresults); if (sresults.empty()) continue; if (sresults[0] == "GPIO") continue; if (sresults.size() == 3) { gpioNumber = atoi(sresults[0].c_str()); if ((gpioNumber >= 0) && (gpioNumber < MAX_GPIO_U401)) { if (sresults[1] == "out") pins.push_back(CGpioPin(gpioNumber + CGPIO_STARTID_U401, CGPIOPIN_U401, "gpio" + sresults[0], CGPIO_DIR_OUT, true)); else pins.push_back(CGpioPin(gpioNumber + CGPIO_STARTID_U401, CGPIOPIN_U401, "gpio" + sresults[0], CGPIO_DIR_IN, true)); } else { _log.Log(LOG_NORM, "GPIO: Ignoring unsupported pin '%s'", buf); } } } fclose(cmd); if (pins.size() > 0) { std::sort(pins.begin(), pins.end()); // debug //for(std::vector<CGpioPin>::iterator it = pins.begin(); it != pins.end(); ++it) { // CGpioPin pin=*it; // std::cout << "Pin " << pin.GetId() << " : " << pin.GetLabel() << ", " << pin.GetDirection() << ", " << pin.GetIsExported() << std::endl; //} } else { _log.Log(LOG_ERROR, "%s: Failed to detect any pins", __func__); return false; } return true; }
bool CGpio::InitPins() { int fd; bool db_state = false; char path[GPIO_MAX_PATH]; char szIdx[10]; char label[12]; std::vector<std::vector<std::string> > result; boost::mutex::scoped_lock lock(m_pins_mutex); pins.clear(); for (int gpio_pin = GPIO_PIN_MIN; gpio_pin <= GPIO_PIN_MAX; gpio_pin++) { snprintf(path, GPIO_MAX_PATH, "%s%d", GPIO_PATH, gpio_pin); fd = open(path, O_RDONLY); if (fd != -1) /* GPIO export found */ { result = m_sql.safe_query("SELECT nValue FROM DeviceStatus WHERE (HardwareID==%d) AND (Unit==%d)", m_HwdID, gpio_pin); if (result.size() > 0) db_state = atoi(result[0][0].c_str()); snprintf(label, sizeof(label), "GPIO pin %d", gpio_pin); pins.push_back(CGpioPin(gpio_pin, label, GPIORead(gpio_pin, "value"), GPIORead(gpio_pin, "direction"), GPIORead(gpio_pin, "edge"), GPIORead(gpio_pin, "active_low"), -1, db_state)); //_log.Log(LOG_NORM, "GPIO: Pin %d added (value: %d, direction: %d, edge: %d, active_low: %d, db_state: %d)", // gpio_pin, GPIORead(gpio_pin, "value"), GPIORead(gpio_pin, "direction"), GPIORead(gpio_pin, "edge"), GPIORead(gpio_pin, "active_low"), db_state); close(fd); if (GPIORead(gpio_pin, "direction") != 0) continue; snprintf(path, GPIO_MAX_PATH, "%s%d/value", GPIO_PATH, gpio_pin); fd = pins.back().SetReadValueFd(open(path, O_RDWR)); // O_RDWR seems mandatory to clear interrupt (not sure why?) if (fd != -1) { pinPass = gpio_pin; m_thread_interrupt[gpio_pin] = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CGpio::InterruptHandler, this))); while (pinPass != -1) sleep_milliseconds(1); } } } return (pins.size() > 0); }
/* * static * One-shot method to initialize pins * */ bool CGpio::InitPins() { char buf[256]; bool exports[MAX_GPIO+1] = { false }; int gpioNumber; FILE *cmd = NULL; // 1. List exports and parse the result #ifndef WIN32 cmd = popen("gpio exports", "r"); #else cmd = fopen("E:\\exports.txt", "r"); #endif while (fgets(buf, sizeof(buf), cmd) != 0) { // Decode GPIO pin number from the output formatted as follows: // // GPIO Pins exported: // 17: out 0 none // 18: in 1 none // // 00000000001111111111 // 01234567890123456789 std::string exportLine(buf); //std::cout << "Processing line: " << exportLine; std::vector<std::string> sresults; StringSplit(exportLine, " :", sresults); if (sresults.empty()) continue; if (sresults[0] == "GPIO") continue; if (sresults.size() >= 4) { gpioNumber = atoi(sresults[0].c_str()); if ((gpioNumber >= 0) && (gpioNumber <= MAX_GPIO)) { exports[gpioNumber] = true; } else { _log.Log(LOG_NORM, "GPIO: Ignoring unsupported pin '%s'", buf); } } } #ifndef WIN32 pclose(cmd); #else fclose(cmd); #endif // 2. List the full pin set and parse the result #ifndef WIN32 cmd = popen("gpio readall", "r"); #else cmd = fopen("E:\\readall.txt", "r"); #endif while (fgets(buf, sizeof(buf), cmd) != 0) { // Decode IN and OUT lines from the output formatted as follows: // // Old style (wiringPi<=2.16): // +----------+-Rev1-+------+--------+------+-------+ // | wiringPi | GPIO | Phys | Name | Mode | Value | // +----------+------+------+--------+------+-------+ // | 0 | 17 | 11 | GPIO 0 | IN | Low | // | 1 | 18 | 12 | GPIO 1 | IN | Low | // | 2 | 21 | 13 | GPIO 2 | IN | Low | // | 3 | 22 | 15 | GPIO 3 | IN | Low | // ... // // New style: // +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+ // | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM | // +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+ // | | | 3.3v | | | 1 || 2 | | | 5v | | | // | 2 | 8 | SDA.1 | IN | 1 | 3 || 4 | | | 5V | | | // | 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | | // | 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT0 | TxD | 15 | 14 | // ... // // 0000000000111111111122222222223333333333444444444455555555556666666666777777777 // 0123456789012345678901234567890123456789012345678901234567890123456789012345678 std::string line(buf); std::vector<std::string> fields; //std::cout << "Processing line: " << line; StringSplit(line, "|", fields); if (fields.size()<7) continue; //std::cout << "# fields: " << fields.size() << std::endl; // trim each field for (size_t i = 0; i < fields.size(); i++) { fields[i]=stdstring_trim(fields[i]); //std::cout << "fields[" << i << "] = '" << fields[i] << "'" << std::endl; } if (fields.size() == 7) { // Old style if (fields[0] != "wiringPi") { gpioNumber = atoi(fields[1].c_str()); if ((gpioNumber >= 0) && (gpioNumber <= MAX_GPIO)) { pins.push_back(CGpioPin(gpioNumber, "gpio" + fields[1] + " (" + fields[3] + ") on pin " + fields[2], fields[4] == "IN", fields[4] == "OUT", exports[gpioNumber])); } else { _log.Log(LOG_NORM, "GPIO: Ignoring unsupported pin '%s'", fields[1].c_str()); } } } else if (fields.size() == 14) { // New style if (fields[1].length() > 0) { gpioNumber = atoi(fields[1].c_str()); if ((gpioNumber >= 0) && (gpioNumber <= MAX_GPIO)) { pins.push_back(CGpioPin(gpioNumber, "gpio" + fields[1] + " (" + fields[3] + ") on pin " + fields[6], (fields[4] == "IN"), (fields[4] == "OUT"), exports[gpioNumber])); } else { _log.Log(LOG_NORM, "GPIO: Ignoring unsupported pin '%s'", fields[1].c_str()); } } if (fields[12].length() > 0) { gpioNumber = atoi(fields[12].c_str()); if ((gpioNumber >= 0) && (gpioNumber <= MAX_GPIO)) { pins.push_back(CGpioPin(gpioNumber, "gpio" + fields[12] + " (" + fields[10] + ") on pin " + fields[7], fields[9] == "IN", fields[9] == "OUT", exports[gpioNumber])); } else { _log.Log(LOG_NORM, "GPIO: Ignoring unsupported pin '%s'", fields[12].c_str()); } } } } #ifndef WIN32 pclose(cmd); #else fclose(cmd); #endif if (pins.size() > 0) { std::sort(pins.begin(), pins.end()); // debug //for(std::vector<CGpioPin>::iterator it = pins.begin(); it != pins.end(); ++it) { // CGpioPin pin=*it; // std::cout << "Pin " << pin.GetId() << " : " << pin.GetLabel() << ", " << pin.GetIsInput() << ", " << pin.GetIsOutput() << ", " << pin.GetIsExported() << std::endl; //} } else { _log.Log(LOG_ERROR, "GPIO: Failed to detect any pins, make sure you exported them!"); return false; } return true; }