
#include <stdio.h>
#include <stdint.h>
#include "fcntl.h"
#include "gpio_api.h"
#include "./../stm32f429xx.h"
#include "./../../driver/GPIO/gpio.h"

static int assert_gpio(gpio_data_t *gpin_data)
{
	//check  gpio port
	if((gpin_data->port != GPIOA)&&(gpin_data->port != GPIOB)\
		&&(gpin_data->port != GPIOC)&&(gpin_data->port != GPIOD)\
		&&(gpin_data->port != GPIOE)&&(gpin_data->port != GPIOF)\
		&&(gpin_data->port != GPIOG)&&(gpin_data->port != GPIOH)\
		&&(gpin_data->port != GPIOI)&&(gpin_data->port != GPIOJ)\
		&&(gpin_data->port != GPIOK))
	{
		printf("Error: %s %d Invalid GPIO port!\n",__FILE__,__LINE__);
		return -1;
	}

	//check gpio pin
	if((gpin_data->pin != GPIO_PIN_0)&&(gpin_data->pin != GPIO_PIN_1)\
		&&(gpin_data->pin != GPIO_PIN_2)&&(gpin_data->pin != GPIO_PIN_3)\
		&&(gpin_data->pin != GPIO_PIN_4)&&(gpin_data->pin != GPIO_PIN_5)\
		&&(gpin_data->pin != GPIO_PIN_6)&&(gpin_data->pin != GPIO_PIN_7)\
		&&(gpin_data->pin != GPIO_PIN_8)&&(gpin_data->pin != GPIO_PIN_9)\
		&&(gpin_data->pin != GPIO_PIN_10)&&(gpin_data->pin != GPIO_PIN_11)\
		&&(gpin_data->pin != GPIO_PIN_12)&&(gpin_data->pin != GPIO_PIN_13)\
		&&(gpin_data->pin != GPIO_PIN_14)&&(gpin_data->pin != GPIO_PIN_15))
	{
		printf("Error: %s %d Invalid GPIO pin!\n",__FILE__,__LINE__);
		return -1;
	}

	return 0;
}

int set_gpio_input(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,SET_GPIO_INPUT,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio input fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int set_gpio_push_pull_output(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,SET_GPIO_PUSH_PULL_OUTPUT,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio push pull output fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int set_gpio_open_drain_output(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}
	ret = ioctl(fd,SET_GPIO_OPEN_DRAIN_OUTPUT,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio open drain output fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int set_gpio_pull_up(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,SET_GPIO_PULL_UP,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio pull up fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int set_gpio_pull_down(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,SET_GPIO_PULL_DOWN,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio pull down fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int set_gpio_no_pull(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,SET_GPIO_NO_PULL,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio no pull fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int set_gpio_speed(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	if((gpin_data->data != GPIO_LOW_SPEED)&&(gpin_data->data != GPIO_MEDIUM_SPEED)\
		&&(gpin_data->data != GPIO_FAST_SPEED)&&(gpin_data->data != GPIO_HIGH_SPEED))
	{
		printf("Error: %s %d Invalid gpio speed %#x",__FILE__,__LINE__,gpin_data->data);
	}
	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,SET_GPIO_SPEED,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio speed fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int set_gpio_value(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,SET_GPIO_VALUE,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio value fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}

int get_gpio_value(gpio_data_t *gpin_data)
{
	int fd;
	int ret = 0;
	if(assert_gpio(gpin_data) != 0)
		return -1;

	fd = open("/dev/gpio",O_RDWR);
	if(fd == -1)
	{
		printf("Error: %s %d Open GPIO fail!\n",__FILE__,__LINE__);
		return -1;
	}

	ret = ioctl(fd,GET_GPIO_VALUE,gpin_data);
	if(ret != 0)
	{
		printf("Error: %s %d Set gpio speed fail!\n,__FILE__,__LINE__");
		ret = -1;
	}
	close(fd);
	return ret;
}
