victorocampo

libgpio_sysfs.c

Nov 9th, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.07 KB | None | 0 0
  1. // C gpio libary using sysfs by Victor Ocampo <theshoutingparrot@protonmail.com>
  2.  
  3. #include "gpio_sysfs.h"
  4.  
  5. #include <stdio.h>
  6. #include <stdint.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <dirent.h>
  10. #include <unistd.h>
  11.  
  12.  
  13.  
  14. static uint8_t num_of_digits(int n) {
  15.     uint8_t i;
  16.     int x;
  17.  
  18.     x = 10;
  19.     i = 0;
  20.  
  21.     n = abs(n);
  22.  
  23.     while(i < 10) {
  24.         if(n < x) return(i+1);
  25.  
  26.         x *= 10;
  27.         i++;
  28.     }
  29.  
  30.     return(0);
  31. }
  32.  
  33. static uint8_t first_digit(unsigned int n) {
  34.     while(n >= 10)
  35.         n /= 10;
  36.  
  37.     return(n);
  38. }
  39.  
  40. static char *int_to_string(unsigned int n) {
  41.     uint8_t i, nofd, ldig;
  42.     unsigned int x;
  43.  
  44.     char *str;
  45.  
  46.     str = (char *)malloc(sizeof(char) * 12);
  47.     if(str == NULL) {
  48.         fputs("Malloc failed!", stderr);
  49.         exit(1);
  50.     }
  51.  
  52.     nofd = num_of_digits(n);
  53.    
  54.     x = 1;
  55.     for(i = 0; i<nofd-1; i++)
  56.         x *= 10;
  57.  
  58.     for(i=0; i<nofd; i++) {
  59.         ldig = first_digit(n);
  60.  
  61.         n -= ldig * x;
  62.         x /= 10;
  63.  
  64.         *(str+i) = ldig + '0';
  65.     }
  66.  
  67.     *(str+i) = '\0';
  68.  
  69.     return(str);
  70. }
  71.  
  72. bool is_gpio_exported(uint8_t gpio) { //Checks if the gpio in question is exported
  73.     DIR *dir;
  74.     struct dirent *ent;
  75.     char *gpio_file;
  76.  
  77.     gpio_file = (char *)malloc(sizeof(char) * 7);
  78.  
  79.     strcpy(gpio_file, "gpio");
  80.     strcat(gpio_file, int_to_string(gpio));
  81.  
  82.     if( (dir = opendir(GPIODIR)) != NULL) {
  83.         while( (ent = readdir(dir)) != NULL)
  84.             if(!strcmp(ent->d_name, gpio_file))
  85.                 return(true);
  86.        
  87.         closedir(dir);
  88.     }
  89.  
  90.     else {
  91.         perror("");
  92.         return(false);
  93.     }
  94.  
  95.     return(false);
  96. }
  97.  
  98.  
  99. uint8_t gpio_export(uint8_t gpio) { // Exports gpio pin, does it by writing to 'export' file in directory '/sys/class/gpio/export'
  100.     FILE *export;
  101.  
  102.     if(is_gpio_exported(gpio)) {
  103.         fprintf(stderr, "gpio %d: already exported", gpio);
  104.         return(GPIO_ALREADY_EXPORTED_ERROR);
  105.     }
  106.  
  107.     export = fopen(EXPORTFILE, "w");
  108.     if(!export) {
  109.         fputs("Error opening export file: '"EXPORTFILE"'", stderr);
  110.         return(FILE_ERROR);
  111.     }
  112.  
  113.     fprintf(export, "%d", gpio);
  114.  
  115.     fclose(export);
  116.  
  117.     return(0);
  118. }
  119.  
  120. uint8_t gpio_unexport(uint8_t gpio) { // Unexports gpio pin, does it by writing to 'unexport' file
  121.     FILE *unexport;
  122.  
  123.     if(!is_gpio_exported(gpio))
  124.         return(GPIO_NOT_EXPORTED_ERROR);
  125.  
  126.     unexport = fopen(UNEXPORTFILE, "w");
  127.     if(!unexport) {
  128.         fputs("Error opening file: '"UNEXPORTFILE"'", stderr);
  129.         return(FILE_ERROR);
  130.     }
  131.  
  132.     fprintf(unexport, "%d", gpio);
  133.  
  134.     fclose(unexport);
  135.  
  136.     return(0);
  137. }
  138. uint8_t gpio_change_direction(uint8_t gpio, char *direction) {
  139.     FILE *fdirection;
  140.  
  141.     char *direction_filename;
  142.  
  143.     direction_filename = (char *)malloc(sizeof(char) * (strlen(GPIODIR) + GPIO_FILENAME_CHAR_SIZE + strlen("/direction")));
  144.    
  145.     strcpy(direction_filename, GPIODIR);
  146.     strcat(direction_filename, "gpio");
  147.     strcat(direction_filename, int_to_string(gpio));
  148.     strcat(direction_filename, "/direction");
  149.  
  150.     fdirection = fopen(direction_filename, "w");
  151.     puts("Hello");
  152.     printf("fdirection: %p %d %s\n", fdirection, fdirection, direction_filename);
  153.  
  154.     if(fdirection == NULL) {
  155.         puts("Helerror timelo!");
  156.         return(FILE_ERROR);
  157.     }
  158.  
  159.     fputs(direction, fdirection);
  160.  
  161.     fclose(fdirection);
  162.     return(0);
  163. }
  164.  
  165. uint8_t gpio_read_direction(uint8_t gpio, char *d) {
  166.     FILE *direction;
  167.     char *direction_filename;
  168.  
  169.     if(!is_gpio_exported(gpio)) {
  170.         fprintf(stderr, "gpio %d not exported\n", gpio);
  171.         return(GPIO_NOT_EXPORTED_ERROR);
  172.     }
  173.  
  174.     direction_filename = (char *)malloc(sizeof(char) * (strlen(GPIODIR) + GPIO_FILENAME_CHAR_SIZE + strlen("direction")));
  175.  
  176.     strcpy(direction_filename, GPIODIR);
  177.     strcat(direction_filename, "gpio");
  178.     strcat(direction_filename, int_to_string(gpio));
  179.     strcat(direction_filename, "/direction");
  180.  
  181.     direction = fopen(direction_filename, "r");
  182.     if(!direction) {
  183.         fprintf(stderr, "Error opening file: '%s'\n", direction_filename);
  184.         return(FILE_ERROR);
  185.     }
  186.  
  187.     fscanf(direction, "%s", d);
  188.  
  189.     fclose(direction);
  190.     return(0);
  191. }
  192.  
  193. uint8_t gpio_write(uint8_t gpio, bool v) {
  194.     FILE *value;
  195.     char *value_filename, *direction;
  196.  
  197.     if(!is_gpio_exported(gpio)) {
  198.         fprintf(stderr, "gpio %d: not exported\n", gpio);
  199.         return(GPIO_NOT_EXPORTED_ERROR);
  200.     }
  201.  
  202.     direction = (char *)malloc(sizeof(char) * 3);
  203.     gpio_read_direction(gpio, direction);
  204.    
  205.     printf("direction: %s\n", direction);
  206.     if(strcmp(direction, GPIO_OUT)) {
  207.         fprintf(stderr, "gpio %d: wrong direction for write function\n", gpio);
  208.         return(GPIO_WRONG_DIRECTION_ERROR);
  209.     }
  210.  
  211.     value_filename = (char *)malloc(sizeof(char) * (strlen(GPIODIR) + GPIO_FILENAME_CHAR_SIZE + strlen("value")));
  212.  
  213.     strcpy(value_filename, GPIODIR);
  214.     strcat(value_filename, "gpio");
  215.     strcat(value_filename, int_to_string(gpio));
  216.     strcat(value_filename, "/value");
  217.  
  218.     value = fopen(value_filename, "w");
  219.     if(!value) {
  220.         fprintf(stderr, "Error opening file: '%s'\n", value_filename);
  221.         return(FILE_ERROR);
  222.     }
  223.  
  224.     fprintf(value, "%d", v);
  225.  
  226.     fclose(value);
  227.     return(0);
  228. }
  229.  
  230. uint8_t gpio_read(uint8_t gpio, uint8_t *v) {
  231.     FILE *value;
  232.     char *value_filename, *direction;
  233.  
  234.     if(!is_gpio_exported(gpio)) {
  235.         fprintf(stderr, "gpio %d: not exported\n", gpio);
  236.         return(GPIO_NOT_EXPORTED_ERROR);
  237.     }
  238.  
  239.     direction = (char *)malloc(sizeof(char) * 3);
  240.     gpio_read_direction(gpio, direction);
  241.     if(strcmp(direction, GPIO_IN)) {
  242.         fprintf(stderr, "gpio %d: wrong direction for read function\n", gpio);
  243.         return(GPIO_WRONG_DIRECTION_ERROR);
  244.     }
  245.  
  246.     value_filename = (char *)malloc(sizeof(char) * (strlen(GPIODIR) + GPIO_FILENAME_CHAR_SIZE + strlen("value")));
  247.  
  248.     strcpy(value_filename, GPIODIR);
  249.     strcat(value_filename, "gpio");
  250.     strcat(value_filename, int_to_string(gpio));
  251.     strcat(value_filename, "/value");
  252.  
  253.     value = fopen(value_filename, "r");
  254.     if(!value) {
  255.         fprintf(stderr, "Error opening file: '%s'\n", value_filename);
  256.         return(FILE_ERROR);
  257.     }
  258.  
  259.     fscanf(value, "%d", (int *)v);
  260.  
  261.     fclose(value);
  262.     return(0);
  263. }
  264.  
  265. int main(int argv, char *argc[]) {
  266.     int i;
  267.     char *d;
  268.  
  269.     d = (char *)malloc(sizeof(char) * 3);
  270.  
  271.     gpio_export(24);
  272.     gpio_read_direction(24, d);
  273.     printf("direction: %s\n", d);
  274.  
  275.     gpio_change_direction(24, GPIO_OUT);
  276.    
  277.     gpio_read_direction(24, d);
  278.     printf("direction: %s\n", d);
  279.  
  280.     gpio_unexport(24); //Works if this is removed and then the program is ran again
  281.  
  282.     return(0);
  283. }
Add Comment
Please, Sign In to add comment