/*********************************************************************************
|
* Copyright: (C) 2019 LingYun IoT System Studio
|
* All rights reserved.
|
*
|
* Filename: at91_sysGpio.c
|
* Description: This file si GPIO API operatore on /sys/class/gpio/xxx
|
*
|
* Version: 1.0.0(2019年08月26日)
|
* Author: Guo Wenxue <guowenxue@gmail.com>
|
* ChangeLog: 1, Release initial version on "2019年08月26日 22时28分19秒"
|
*
|
********************************************************************************/
|
|
#include <stdio.h>
|
#include <unistd.h>
|
#include <sys/types.h>
|
#include <sys/stat.h>
|
#include <fcntl.h>
|
#include <string.h>
|
#include <errno.h>
|
|
#include "at91_sysGpio.h"
|
|
|
/* export $port in /sys/class/gpio/export */
|
int gpio_export(const char *port)
|
{
|
char fpath[SYSFILE_LEN];
|
FILE *fp;
|
int pin;
|
|
if(!port)
|
{
|
gpio_print("invalid input arguments\n");
|
return -1;
|
}
|
|
snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
|
|
/* GPIO port already export */
|
if( !access(fpath, F_OK) )
|
{
|
gpio_print("%s already export\n", port);
|
return 0;
|
}
|
|
if( !(fp=fopen(SYSGPIO_EXPORT_PATH, "w")) )
|
{
|
gpio_print("open '%s' failure: %s\n", SYSGPIO_EXPORT_PATH, strerror(errno));
|
return -2;
|
}
|
|
pin = at91_port2pin(port);
|
fprintf(fp, "%d", pin);
|
|
fclose(fp);
|
|
return 0;
|
}
|
|
|
/* unexport $port in /sys/class/gpio/unexport */
|
int gpio_unexport(const char *port)
|
{
|
char fpath[SYSFILE_LEN];
|
FILE *fp;
|
int pin;
|
|
if(!port)
|
{
|
gpio_print("invalid input arguments\n");
|
return -1;
|
}
|
|
snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
|
|
/* GPIO port not export */
|
if( access(fpath, F_OK) )
|
{
|
gpio_print("%s not export\n", port);
|
return 0;
|
}
|
|
if( !(fp=fopen(SYSGPIO_UNEXPORT_PATH, "w")) )
|
{
|
gpio_print("open '%s' failure: %s\n", SYSGPIO_EXPORT_PATH, strerror(errno));
|
return -2;
|
}
|
|
pin = at91_port2pin(port);
|
fprintf(fp, "%d", pin);
|
|
fclose(fp);
|
|
return 0;
|
}
|
|
|
/* configure $port direction as $mode */
|
int gpio_config(const char *port, const char *mode)
|
{
|
char fpath[SYSFILE_LEN];
|
FILE *fp;
|
int size;
|
|
if(!port)
|
{
|
gpio_print("invalid input arguments\n");
|
return 0;
|
}
|
|
snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
|
|
if( access(fpath, F_OK) ) /* GPIO port not export */
|
{
|
if( gpio_export(port) < 0 )
|
return -1;
|
}
|
|
size = SYSFILE_LEN-strlen(fpath);
|
strncat(fpath, "/direction", size);
|
if( !(fp=fopen(fpath, "w")) )
|
{
|
gpio_print("open '%s' failure: %s\n", fpath, strerror(errno));
|
return -1;
|
}
|
|
fputs(mode, fp);
|
|
fclose(fp);
|
|
return 0;
|
}
|
|
|
|
/* write $value into GPIO $port */
|
int gpio_write(const char *port, const char *value)
|
{
|
char fpath[SYSFILE_LEN];
|
FILE *fp;
|
int size;
|
|
if(!port)
|
{
|
gpio_print("invalid input arguments\n");
|
return 0;
|
}
|
|
snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
|
|
if( access(fpath, F_OK) ) /* GPIO port not export */
|
{
|
if( gpio_export(port) < 0 )
|
return -1;
|
}
|
|
size = SYSFILE_LEN-strlen(fpath);
|
strncat(fpath, "/value", size);
|
if( !(fp=fopen(fpath, "w")) )
|
{
|
gpio_print("open '%s' failure: %s\n", fpath, strerror(errno));
|
return -1;
|
}
|
|
fputs(value, fp);
|
|
fclose(fp);
|
|
return 0;
|
}
|
|
|
/* read gpio value from $port */
|
int gpio_read(const char *port)
|
{
|
char fpath[SYSFILE_LEN];
|
FILE *fp;
|
int size;
|
char v_str[32];
|
|
if(!port)
|
{
|
gpio_print("invalid input arguments\n");
|
return 0;
|
}
|
|
snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
|
|
if( access(fpath, F_OK) ) /* GPIO port not export */
|
{
|
return -1;
|
}
|
|
size = SYSFILE_LEN-strlen(fpath);
|
strncat(fpath, "/value", size);
|
if( !(fp=fopen(fpath, "r")) )
|
{
|
gpio_print("open '%s' failure: %s\n", fpath, strerror(errno));
|
return -1;
|
}
|
|
memset(v_str, 0, sizeof(v_str));
|
fgets(v_str, sizeof(v_str), fp);
|
|
fclose(fp);
|
|
return atoi(v_str);
|
}
|