From e49a483788f4293a1223518537531e4fc31913f4 Mon Sep 17 00:00:00 2001 From: Nick Van Doorn Date: Sat, 25 Nov 2017 09:22:51 -0800 Subject: Initial commit --- util.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 36 +++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 util.c create mode 100644 util.h diff --git a/util.c b/util.c new file mode 100644 index 0000000..8bb9ba1 --- /dev/null +++ b/util.c @@ -0,0 +1,126 @@ +#include "legato.h" +#include "util.h" + +le_result_t readFromFile (const char *path, void *value, + int (*scanCallback) (FILE *f, const char *formatter, void *val)) { + FILE *f = fopen(path, "r"); + if (f == NULL) { + LE_WARN("Couldn't open '%s' - %m", path); + return LE_IO_ERROR; + } + int numScanned = scanCallback(f, "%lf", value); + if (numScanned != 1) return LE_FORMAT_ERROR; + fclose(f); + return LE_OK; +} + +int scanIntCallback (FILE *f, const char *formatter, void *value) { + int *val = value; + return fscanf(f, "%d", val); +} + +int scanDoubleCallback (FILE *f, const char *formatter, void *value) { + double *val = value; + return fscanf(f, "%lf", val); +} + +// TODO camel case these methods +le_result_t ioutil_readIntFromFile (const char *path, int *value) { + return readFromFile(path, value, scanIntCallback); +} + +le_result_t ioutil_readDoubleFromFile (const char *path, double *value) { + return readFromFile(path, value, scanDoubleCallback); +} + +le_result_t ioutil_writeToFile (const char *path, void *value, size_t size, size_t count) { + LE_INFO("Attempting to write to %s", path); + FILE *f = fopen(path, "w"); + if (f == NULL) { + LE_WARN("Failed to open %s for writing", path); + return LE_IO_ERROR; + } + size_t nWritten = fwrite(value, size, count, f); + LE_INFO("Wrote %d bytes", nWritten); + fclose(f); + return LE_OK; +} + +le_result_t gpio_exportPin (int pin) { + return ioutil_writeToFile ("/sys/class/gpio/export", &pin, sizeof(int), 1); +} + +le_result_t gpio_unexportPin (int pin) { + return ioutil_writeToFile ("/sys/class/gpio/unexport", &pin, sizeof(int), 1); +} + +void getGpioPath (char *outputStr, int pin, char *subDir) { + sprintf(outputStr, "/sys/class/gpio/gpio%d/%s", pin, subDir); +} + +le_result_t gpio_setDirection (int pin, char *direction) { + char path[50]; + getGpioPath(path, pin, "direction"); + return ioutil_writeToFile(path, direction, sizeof(char), strlen(direction)); +} + +le_result_t gpio_setInput (int pin) { + return gpio_setDirection(pin, "in"); +} + +le_result_t gpio_setOutput (int pin) { + return gpio_setDirection(pin, "out"); +} + +le_result_t gpio_setActiveState (int pin, bool isActiveLow) { + // Any non zero value toggles the existing value + // so we must read the existing value first + char path[50]; + int isActiveLowSet; + getGpioPath(path, pin, "active_low"); + le_result_t readRes = ioutil_readIntFromFile(path, &isActiveLowSet); + le_result_t writeRes = LE_OK; + if (isActiveLow != isActiveLowSet) { + writeRes = ioutil_writeToFile(path, "1", sizeof(char), 1); + } + return readRes == LE_OK && writeRes == LE_OK ? + LE_OK : LE_FAULT; +} + +le_result_t gpio_isActive (int pin, bool *isActive) { + char path[50]; + getGpioPath(path, pin, "value"); + int val; + return ioutil_readIntFromFile(path, &val); + LE_FATAL_IF(val != 0 || val != 1, "value is not boolean"); + *isActive = (bool)val; +} + +le_result_t gpio_setValue (int pin, bool state) { + char path[50]; + getGpioPath(path, pin, "value"); + return ioutil_writeToFile(path, &state, sizeof(bool), 1); +} + +le_result_t gpio_setLow (int pin) { + return gpio_setValue(pin, LOW); +} + +le_result_t gpio_setHigh (int pin) { + return gpio_setValue(pin, HIGH); +} + +void delayMicro (unsigned long microsecs) { + unsigned long retTime = getTimeMicrosecs() + microsecs; + while (getTimeMicrosecs() < retTime); +} + +void delayMilli (unsigned long millisecs) { + delayMicro(millisecs * 1000); +} + +long getTimeMicrosecs () { + struct timeval currentTime; + gettimeofday(¤tTime, NULL); + return currentTime.tv_sec * (int)1e6 + currentTime.tv_usec; +} \ No newline at end of file diff --git a/util.h b/util.h new file mode 100644 index 0000000..6881eda --- /dev/null +++ b/util.h @@ -0,0 +1,36 @@ +#ifndef UTIL_H +#define UTIL_H + +#include "legato.h" + +#define HIGH 1 +#define LOW 0 + +// ioutil +le_result_t readFromFile (const char *path, void *value, + int (*scanCallback) (FILE *f, const char *formatter, void *val)); +int scanIntCallback (FILE *f, const char *formatter, void *value); +int scanDoubleCallback (FILE *f, const char *formatter, void *value); +le_result_t ioutil_readIntFromFile (const char *path, int *value); +le_result_t ioutil_readDoubleFromFile (const char *filePath, double *value); +le_result_t ioutil_writeToFile (const char *path, void *value, size_t size, size_t count); + +// gpio +void getGpioPath (char *outputStr, int pin, char *subDir); +le_result_t gpio_exportPin (int pin); +le_result_t gpio_unexportPin (int pin); +le_result_t gpio_setDirection (int pin, char *direction); +le_result_t gpio_setInput (int pin); +le_result_t gpio_setOutput (int pin); +le_result_t gpio_setActiveState (int pin, bool isActiveLow); +le_result_t gpio_isActive (int pin, bool *isActive); +le_result_t gpio_setValue (int pin, bool state); +le_result_t gpio_setLow (int pin); +le_result_t gpio_setHigh (int pin); + +// time util +void delayMicro (unsigned long microsecs); +void delayMilli (unsigned long millisecs); +long getTimeMicrosecs (); + +#endif -- cgit v1.2.3