**
* @fn int gpio_is_exported(size_t gpio)
* @brief Test gpio is exported or not
* @param size_t gpio : The number of gpio
* @param
* @return Is exported:(0) ; Is not exported:(-1)
*/
int gpio_is_exported(size_t gpio)
{
int fd = 0;
char buf[64] = {0};
size_t len = 0;
int piobasenum;
piobasenum = gpio;
len = snprintf(buf, sizeof(buf), CFG_GPIO_DIR "/gpio%u/direction", piobasenum);
if(len < 0) {
return -1;
}
fd = open(buf, O_WRONLY);
if (fd >= 0) {
close(fd);
//OK, GPIO is exported
return 0;
}
return -1;
}
/**
* @fn int gpio_export(size_t gpio)
* @brief Export the gpio to operate.
* @param size_t gpio : The number of gpio
* @param
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_export(size_t gpio)
{
int fd = 0;
int i;
char buf[64] = {0};
size_t len = 0;
if( gpio_is_exported(gpio) == 0 ) {
return 0; //No need to re-export
}
fd = open(CFG_GPIO_DIR "/export", O_WRONLY);
if( fd < 0 ) {
return -1;
}
len = snprintf(buf, sizeof(buf), "%u", gpio);
if(len < 0) {
return -1;
}
write(fd, buf, len);
close(fd);
/* wait until file is actually available in user space */
for (i = 0; i < CFG_GPIO_SYS_FILE_EXPORTED_TIME_IN_100MS; i++) {
if( gpio_is_exported(gpio) == 0 ) {
return 0; //GPIO is present in user space
}
usleep(100 * 1000);
}
return -1;
}
/**
* @fn int gpio_unexport(size_t gpio)
* @brief Unexport the gpio .
* @param size_t gpio : The number of gpio
* @param
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_unexport(size_t gpio)
{
int fd = 0;
char buf[64] = {0};
size_t len = 0;
fd = open(CFG_GPIO_DIR "/unexport", O_WRONLY);
if( fd < 0 ) {
return -1;
}
len = snprintf(buf, sizeof(buf), "%u", gpio);
if( len < 0 ) {
return -1;
}
write(fd, buf, len);
close(fd);
return 0;
}
/**
* @fn int gpio_set_direction(size_t gpio, bool output)
* @brief Set direction of the gpio .
* @param size_t gpio : The number of gpio
* @param char output : 1 - output; 0 - input
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_set_direction(size_t gpio, char output)
{
int fd = 0;
char buf[64] = {0};
size_t len = 0;
int piobasenum;
piobasenum = gpio;
len = snprintf(buf, sizeof(buf), CFG_GPIO_DIR "/gpio%u/direction", piobasenum);
if( len < 0 ) {
return -1;
}
fd = open(buf, O_WRONLY);
if( fd < 0 ) {
return -1;
}
if(output) {
write(fd, "out", 3);
} else {
write(fd, "in", 2);
}
close(fd);
return 0;
}
/**
* @fn int gpio_open(size_t gpio, int mode)
* @brief open the gpio value file,prepare to operate.
* @param size_t gpio : The number of gpio
* @param int mode : O_NONBLOCK open or not
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_open(size_t gpio, int mode)
{
int fd = 0;
char buf[64] = {0};
size_t len = 0;
int piobasenum;
piobasenum = gpio;
len = snprintf(buf, sizeof(buf), CFG_GPIO_DIR "/gpio%u/value", piobasenum);
if( len < 0 ) {
return -1;
}
fd = open(buf, mode | O_NONBLOCK);
if( fd < 0 ) {
printf("gpio open fail \n");
return -1;
}
return fd;
}
/**
* @fn int gpio_close(int fd)
* @brief close the gpio value file.
* @param int fd : file handler of value
* @param
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_close(int fd)
{
return close(fd);
}
/**
* @fn int gpio_set_value(size_t gpio, int value)
* @brief Set the gpio value.
* @param size_t gpio : The number of gpio
* @param int value : value to set 1 - High; 0 - Low
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_set_value(size_t gpio, int value)
{
int fd;
int i;
char j;
fd = gpio_open(gpio, O_WRONLY);
if(fd == -1) {
printf("gpio open fail \n");
return -1;
}
if(!value) {
j = '0';
} else {
j = '1';
}
i = write(fd, &j, sizeof(char));
gpio_close(fd);
if ( i < 0 ) {
printf("gpio write fail \n");
return -1;
} else {
return 0;
}
}
/**
* @fn int gpio_get_value(size_t gpio, int value)
* @brief get the gpio value and return.
* @param size_t gpio : The number of gpio
* @param
* @return Sucess:(0/1) ; Fail:(-1)
*/
int gpio_get_value(size_t gpio)
{
int fd;
int i;
char value;
fd = gpio_open(gpio, O_RDONLY);
if(fd == -1) {
return -1;
}
i = read(fd, &value, sizeof(char));
gpio_close(fd);
if ( i < 0 ) {
return -1;
} else {
if (value == '1') {
i = 1;
} else {
i = 0;
}
}
return i;
}
/**
* @fn int gpio_register(size_t gpio, int mode)
* @brief registe the gpio according the mode.
* @param size_t gpio : The number of gpio
* @param int mode : input/output
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_register(size_t gpio, int mode)
{
int i;
i = gpio_export(gpio);
if (i) {
return -1; //export fail
}
switch (mode) {
case GPIO_MODE_INPUT:
i = gpio_set_direction(gpio, 0);
break;
case GPIO_MODE_OUTPUT:
i = gpio_set_direction(gpio, 1);
break;
default:
i = gpio_set_direction(gpio, 0);
}
return i; //-1: fail 0: success
}
/**
* @fn int gpio_unregister(size_t gpio)
* @brief unregiste the gpio .
* @param size_t gpio : The number of gpio
* @param
* @return Sucess:(0) ; Fail:(-1)
*/
int gpio_unregister(size_t gpio)
{
return gpio_unexport(gpio);
}
/**
* @fn int InitExIOState(void)
* @brief Initialize the GPIO state.
* @param
* @param
* @return Sucess:(==0) ; Fail:-1
*/
int InitExIOState(void)
{
int i;
int ret = 0;
int gpio_num;
for(i=0; i< (sizeof(DO_map)/2); i++) {
gpio_num = DO_map[i];
ret = gpio_register(gpio_num, GPIO_MODE_OUTPUT);
if(ret < 0) {
return -1;
}
}
for(i=0; i < (sizeof(DI_map)/2); i++) {
gpio_num = DI_map[i];
ret = gpio_register(gpio_num, GPIO_MODE_INPUT);
if(ret < 0) {
return -1;
}
}
return 0;
}
/**
* @fn int SetExIOOutState(int gpio, int state)
* @brief Set the GPIO output(level) and IO statement.
* @param int gpio : Port number of IO
* @param int state : Statement of IO(0:open/1:close)
* @return Sucess:(==0) ; Fail: else
*/
int SetExIOOutState(int gpio, int state)
{
int i;
i = gpio_set_value(gpio, state);
return i;
}
/**
* @fn int GetExIOInValue(int gpio,int *curval)
* @brief Read the statement of IO in input state.
* @param int gpio : Port number of IO
* @param int *curval : Current Statement of IO(0:Low/1:High)
* @return Sucess:(==0) ; Fail:(else)
*/
int GetExIOInValue(int gpio,int* curval)
{
int i;
i = gpio_get_value(gpio);
if(i<0) {
return i;
} else {
*curval = i;
return 0;
}
}