/******************************************************************************
版权所有：	
文件名称：	gpio.c
文件版本：	01.01
创建作者:	zhaoyang
创建日期：	2023-12-14
功能说明：	gpio驱动程序。
其它说明：
修改记录：

[new]-->applay
B_DO_ADJ	--> GPIOD_17	-->  gpio113
B_DO_0		--> GPIOD_03	-->  gpio99
B_DO_1		--> GPIOD_19	-->  gpio115
B_DO_2		--> GPIOD_02	-->  gpio98
B_DO_3		--> GPIOD_09	-->  gpio105
B_DO_4		--> GPIOD_18	-->  gpio114
B_DO_5		--> GPIOD_16	-->  gpio112
B_DO_6		--> GPIOD_07	-->  gpio103
B_DO_7		--> GPIOD_08	-->  gpio104
B_DO_8		--> GPIOD_06	-->  gpio102

T536 start ↓↓↓↓↓↓
RUN_LED			-->  PB7  	-->  gpio39
ERR_LED			-->  PF4	-->  gpio164
ESAM_PWR		-->  PL7	-->  gpio159
LINE_LOSS_SET	-->  PM5	-->  gpio389
T536 end   ↑↑↑↑↑↑
*/

/*------------------------------- 头文件 --------------------------------------
*/
#include "bspconfig.h"
#include "gpio.h"
#include "head.h"

#include <rtdm/gpio.h>
/*------------------------------- 宏定义 --------------------------------------
*/
#if CFG_BSP_DEBUG

#define _GPIO_DEBUG

#endif

/*------------------------------ 全局变量 -------------------------------------
*/
typedef enum {
    SYS_GPIO = 0,
	RTDM_GPIO = 1,
} GPIO_TYPE;

unsigned short kc_pwm0_stu;
unsigned short kc_pwm1_stu;

unsigned short kc_kout0_stu;
unsigned short kc_kout1_stu;

extern uint32_t g_yx_buf[2]; //预留64个遥信

/*------------------------------ 函数声明 -------------------------------------
*/
extern unsigned int change_di_ch(unsigned int di);

int gpio_val_fd[DO_NUM];
int gpio_dev_type[DO_NUM] = {SYS_GPIO,};	//0:系统GPIO, 1:RTDM GPIO
const int gpio_val[DO_NUM] = {98, 99, 115, 98, 105, 114, 112, 103, 104, 102};

int gpio_val_fd_other[GPIO_NUM_OTHER];
int gpio_dev_type_other[GPIO_NUM_OTHER] = {SYS_GPIO,};	
const int gpio_val_other[GPIO_NUM_OTHER] ={39,164,359,389};

// static int gpio_watchdog_val = 0;
static int gpio_run_led_val = 0;

/*------------------------------ 外部函数 -------------------------------------
*/
#if 1
int sysfs_gpio_unexport(int gpio) 
{
    char path[64];
    int fd;
    
    snprintf(path, sizeof(path), "/sys/class/gpio/unexport");
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        perror("Failed to open unexport");
        return -1;
    }
    
    char buf[16];
	snprintf(buf, sizeof(buf), "%d", gpio);
	if (write(fd, buf, strlen(buf)) < 0) { 
		perror("Failed to set GPIO");
        close(fd);
        return -1;
    }
	close(fd);
	return 0;
}

int sysfs_gpio_export(int gpio) {
    char path[64];
    int fd;
    
	// 检查是否已导出
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d", gpio);
    if (access(path, F_OK) == 0) {
        sysfs_gpio_unexport(gpio);	//	bugfix: 避免重复导出
		msleep(50);				//短暂等待让内核处理
    }

    snprintf(path, sizeof(path), "/sys/class/gpio/export");
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        perror("Failed to open export");
        return -1;
    }
    
    char buf[16];
    snprintf(buf, sizeof(buf), "%d", gpio);
    if (write(fd, buf, strlen(buf)) < 0) {
        perror("Failed to export GPIO");
        close(fd);
        return -2;
    }
    
    close(fd);
    return 0;
}

int sysfs_gpio_set_direction(int gpio, int is_output) {
    char path[64];
    int fd;
    
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", gpio);
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        perror("Failed to open direction");
        return -1;
    }
    
    if (write(fd, is_output ? "out" : "in", is_output ? 3 : 2) < 0) {
        perror("Failed to set direction");
        close(fd);
        return -1;
    }
    
    close(fd);
    return 0;
}

int sysfs_gpio_set_edge_detect(int gpio, int edge)
{
	char path[64];
	int fd;
	
	snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", gpio);
	fd = open(path, O_WRONLY);
	if (fd < 0) { 
		perror("Failed to open edge");
		close(fd);
		return -1;
    }

	if (write(fd, edge, strlen(edge)) < 0) { 
		perror("Failed to set edge");
		close(fd);
		return -1;
    }

	close(fd);
	return 0;
}
int sysfs_gpio_set_value(int gpio, int value) {
    char path[64];
    int fd = -1;
    
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", gpio);
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        perror("Failed to open value");
        return -1;
    }
    
    if (write(fd, value ? "1" : "0", 1) < 0) {
        perror("Failed to set value");
        close(fd);
        return -1;
    }
    
    return fd;
}

int sysfs_gpio_init(int gpio, int direction)
{
	#define GPIO_LOW 0
	int ret;
	ret = sysfs_gpio_export(gpio);
	if(ret < 0)
	{
		dp_err_n_c("sysfs_gpio_export error ret = %d!\n", ret);
		return -1;
	}
	ret = sysfs_gpio_set_direction(gpio, direction);
	if(ret < 0)
	{
		dp_err_n_c("sysfs_gpio_set_direction error\n");
	}

	return sysfs_gpio_set_value(gpio, GPIO_LOW);	// 初始化IO为低电平
}

int is_rtdm_device(int fd) {
    
	if(gpio_dev_type[fd] > SYS_GPIO)
		return 1;
	else
	if(gpio_dev_type[fd] == SYS_GPIO)
    	return 0;
	else
		return -1;
}
int rt_write(int fd, char *buf, int len) {
    int value;
    
    if(len <= 0 || buf == NULL) {
        return -1;
    }
    
    if (is_rtdm_device(fd) == 1) {
        // Xenomai RTDM设备：需要转换为二进制值
        value = atoi(buf);
        if(value != 0 && value != 1) {
            dp_err_n_c("value :%d ERR, Please enter '0' or '1'\n", value);
            return -1;
        }
        return write(fd, &value, sizeof(value));
    } 
	else 
	{
        // 常规系统设备：直接传递字符串
        return write(fd, buf, len);
    }
}
int rtdm_gpio_init(int gpio, int direction)
{
	#define GPIO_LOW 0
	char path[64];
    int fd = -1, ret;
    int value = 1;
    snprintf(path, sizeof(path), "/dev/rtdm/3604000.pinctrl/gpio%d", gpio);
    fd = open(path, O_RDWR);
	if (fd < 0) {
        perror("open");
        return -1;
    }

	ret = ioctl(fd, GPIO_RTIOC_DIR_OUT, &value);
	if (ret < 0) {
        perror("ioctl DIR_OUT");
        close(fd);
        return -1;
    }

	rt_write(gpio_val_fd[DO_OUT0], "0", 2);	// 初始化IO为低电平
	return fd;
}

int gpio_init(void)
{
	#define GPIO_OUTPUT 1
    int i;

#ifdef NW_AREA_MAIN_2021
    for (i = 0; i < DO_NUM; i ++)
    {
		gpio_val_fd[i] = rtdm_gpio_init(gpio_val[i], GPIO_OUTPUT);
		if(gpio_val_fd[i] < 0)
		{
			gpio_val_fd[i] = sysfs_gpio_init(gpio_val[i], GPIO_OUTPUT);
			if(gpio_val_fd[i] < 0)
			{
				dp_err_n_c("gpio_val_fd[%d] error\n", i);
				gpio_val_fd[i] = -1;
				gpio_dev_type[i] = -1;
				return -1;
			}
		}
		else {
			gpio_dev_type[i] = gpio_val_fd[i];	// 保存RTDM设备类型句柄,这里有风险，fd句柄可能为0
		}
    }
#endif
     for (i = 0; i < GPIO_NUM_OTHER; i ++)
    {
		gpio_val_fd_other[i] = -1;	//rtdm_gpio_init(gpio_val_other[i], GPIO_OUTPUT);
		if(gpio_val_fd_other[i] < 0)
		{
			gpio_val_fd_other[i] = sysfs_gpio_init(gpio_val_other[i], GPIO_OUTPUT);
			if(gpio_val_fd_other[i] < 0)
			{
				dp_err_n_c("gpio_val_fd_other[%d] error\n", i);
				gpio_val_fd_other[i] = -1;
				gpio_dev_type_other[i] = -1;
				return -1;
			}
		}
		else {
			gpio_dev_type_other[i] = gpio_val_fd_other[i];	// 保存RTDM设备类型句柄,这里有风险，fd句柄可能为0
		}
    }

	msleep(10);// 延时10ms

	kc_pwm0_stu = 0;
	kc_pwm1_stu = 0;
    kc_kout0_stu=0;
    kc_kout1_stu=0;

    //其他与底层GPIO相关的配置再此处添加 比如 LED WATCHDOG                 
    write(gpio_val_fd_other[RUN_LED], "0", 2);
    gpio_run_led_val = 0;

	//上电默认切换到外部232串口
	//后续根据投退判断是否需要切换到线损的维护口
	write(gpio_val_fd_other[LINE_LOSS_SET], "0", 2);	

	//开启esam供电
	write(gpio_val_fd_other[ESAM_PWR], "0", 2);
#ifdef NW_AREA_MAIN_2021
    for (i = 0; i < DO_NUM; i ++)
    {
		write(gpio_val_fd[i], "1", 2);
    }
#endif
    return 0;
}

int gpio_exit(void)
{
	int i;
#ifdef NW_AREA_MAIN_2021
    for (i = 0; i < DO_NUM; i ++)
    {
    	if(gpio_val_fd[i] >= 0)
    	{
    		close(gpio_val_fd[i]);
    		gpio_val_fd[i] = -1;
    	}
		sysfs_gpio_unexport(gpio_val[i]);
    }
#endif
    for (i = 0; i < GPIO_NUM_OTHER; i ++)
    {
    	if(gpio_val_fd_other[i] >= 0)
    	{
    		close(gpio_val_fd_other[i]);
    		gpio_val_fd_other[i] = -1;
    	}
		sysfs_gpio_unexport(gpio_val_other[i]);
    }

    return 0;
}

#else
/******************************************************************************
函数名称：	gpio_init
函数版本：	01.01
创建作者:	   sunxi
创建日期：	2008-06-26
函数说明：	gpio初始化。
参数说明：	无
返回值：  	成功返回0.
修改记录：
*/
int gpio_init(void)
{
    int i, j;
    int exportfd, directionfd;
    char num[10];
    char path[50] = "";

    //do
    exportfd = open("/sys/class/gpio/export", O_WRONLY);
    if (exportfd < 0)
    {
        dp_err_n_c("Cannot open GPIO to export it\n");
        return -1;
    }
#ifdef NW_AREA_MAIN_2021
    for (i = 0; i < DO_NUM; i ++)
    {
        sprintf(num, "%d", gpio_val[i]);
        write(exportfd, num, 4);
        gpio_val_fd[i] = -1;
    }
#endif
    for (i = 0; i < GPIO_NUM_OTHER; i ++)
    {
        sprintf(num, "%d", gpio_val_other[i]);
        write(exportfd, num, 4);
        gpio_val_fd_other[i] = -1;
    }
	
    close(exportfd);

#ifdef NW_AREA_MAIN_2021
    for (i = 0; i < DO_NUM; i ++)
    {
        sprintf(path, "/sys/class/gpio/gpio%d/value", gpio_val[i]);

        gpio_val_fd[i] = open(path, O_RDWR);
        if (gpio_val_fd[i] < 0)
        {
            dp_err_n_c("Cannot open GPIO%d value!\n", gpio_val[i]);
            for(j = 0; j < i; j ++)
            {
            	close(gpio_val_fd[j]);
            	gpio_val_fd[j] = -1;
            }
            return -4;
        }
    }

	// Update the direction of the GPIO to be an output
	for (i = 0; i < DO_NUM; i ++)
	{
		sprintf(path, "/sys/class/gpio/gpio%d/direction", gpio_val[i]);

		directionfd = open(path, O_RDWR);
		if (directionfd < 0)
		{
			dp_err_n_c("Cannot open GPIO%d direction!\n", gpio_val[i]);
			return -2;
		}
		write(directionfd, "out", 4);
		write(gpio_val_fd[i], "1", 2);
		close(directionfd);
	}
#endif
	msleep(10);// 延时10ms
	

    for (i = 0; i < GPIO_NUM_OTHER; i  ++)
    {
        sprintf(path, "/sys/class/gpio/gpio%d/value", gpio_val_other[i]);

        gpio_val_fd_other[i] = open(path, O_RDWR);
        if (gpio_val_fd_other[i] < 0)
        {
            dp_err_n_c("Cannot open GPIO%d value!\n", gpio_val_other[i]);
            for(j = 0; j < i; j ++)
            {
            	close(gpio_val_fd_other[j]);
            	gpio_val_fd_other[j] = -1;
            }
		#ifdef NW_AREA_MAIN_2021
            for(j = 0; j < DO_NUM; j ++)
            {
            	close(gpio_val_fd[j]);
            	gpio_val_fd[j] = -1;
            }
		#endif
            return -5;
        }
    }

	for (i = 0; i < GPIO_NUM_OTHER; i ++)
	{
		sprintf(path, "/sys/class/gpio/gpio%d/direction", gpio_val_other[i]);

		directionfd = open(path, O_RDWR);
		if (directionfd < 0)
		{
			dp_err_n_c("Cannot open GPIO%d direction!\n", gpio_val_other[i]);
			return -3;
		}
		write(directionfd, "out", 4);
		close(directionfd);
	}

	kc_pwm0_stu = 0;
	kc_pwm1_stu = 0;
    kc_kout0_stu=0;
    kc_kout1_stu=0;

    //其他与底层GPIO相关的配置再此处添加 比如 LED WATCHDOG                  jack.liu 202009010
    // write(gpio_val_fd_other[WATCHDOG], "0", 2);//TODO: 需根据实际硬件重新对应匹配
    // gpio_watchdog_val = 0;
    write(gpio_val_fd_other[RUN_LED], "0", 2);
    gpio_run_led_val = 0;

	//上电默认切换到外部232串口
	//后续根据投退判断是否需要切换到线损的维护口
	write(gpio_val_fd_other[LINE_LOSS_SET], "0", 2);
	
    //首次上电，开出合闸，会导致第六路也开出，需要初始化关闭
//    write(gpio_val_fd[DO_OUT1], "1", 2);

	//开启esam供电
	write(gpio_val_fd_other[ESAM_PWR], "0", 2);
#ifdef NW_AREA_MAIN_2021
    for (i = 0; i < DO_NUM; i ++)
    {
		write(gpio_val_fd[i], "1", 2);
    }
#endif
    return 0;
}

int gpio_exit(void)
{
	int i;
	int unexportfd;
    char num[10];

	unexportfd = open("/sys/class/gpio/unexport", O_WRONLY);
    if (unexportfd < 0)
    {
        dp_err_n_c("Cannot open GPIO to unexport it\n");
        return -1;
    }
#ifdef NW_AREA_MAIN_2021
    for (i = 0; i < DO_NUM; i ++)
    {
    	if(gpio_val_fd[i] >= 0)
    	{
    		close(gpio_val_fd[i]);
    		gpio_val_fd[i] = -1;
    	}
        sprintf(num, "%d", gpio_val[i]);
        write(unexportfd, num, 4);
    }
#endif
    for (i = 0; i < GPIO_NUM_OTHER; i ++)
    {
    	if(gpio_val_fd_other[i] >= 0)
    	{
    		close(gpio_val_fd_other[i]);
    		gpio_val_fd_other[i] = -1;
    	}
        sprintf(num, "%d", gpio_val_other[i]);
        write(unexportfd, num, 4);
    }

    close(unexportfd);

    return 0;
}
#endif
/******************************************************************************
函数名称：	gpio_get_kin
函数版本：	01.01
创建作者:	   sunxi
创建日期：	2008-09-16
函数说明：	得到开入的状态。
参数说明：	无
返回值：  	返回开入的状态，每个bit代表一个开入量。
修改记录：
*/
unsigned int gpio_get_kin(unsigned int addr)
{
	register unsigned int dw;
	unsigned int value[3];

	value[0]  = *(volatile unsigned int *)addr;
	value[1]  = *(volatile unsigned int *)addr;
	value[2]  = *(volatile unsigned int *)addr;

	dw = (value[0] & value[1]) | (value[0] & value[2]) | (value[1] & value[2]);

	return dw;
}


/******************************************************************************
函数名称：	gpio_get_di
函数版本：	01.01
创建作者：
创建日期：	2014-11-28
函数说明：	得到开入的状态
参数说明：	无
返回值：  	返回开入的状态，每个bit代表一个开入量。
修改记录：
*/

unsigned int gpio_get_di(void)
{
    unsigned int dw = 0;

	dw = g_yx_buf[0];//这里保存的是共享内存的yx值，156us更新一次

	return  change_di_ch(~dw);//取反---因为没有短接时，值为1. 所以要取反为0才行
}


/******************************************************************************
函数名称：	gpio_di_fj
函数版本：	01.01
创建作者：
创建日期：	2014-11-28
函数说明：	读取开出返校遥信值,控制板遥信为YX17~YX18
			YX17:选择, YX18:执行

参数说明：	 无
返回值：  返回遥信值
修改记录：
*/
#ifdef DO_KOUT_CHECK
unsigned short gpio_di_fj(unsigned char index)//(void)
#else
unsigned short gpio_di_fj(void)
#endif
{
	unsigned int di=0;
	unsigned short ret=0;

	di = gpio_get_di();
#ifdef DO_KOUT_CHECK
    //V4-20;
	//ret = (unsigned short)((di >>19) & 0x0001);
	ret = (unsigned short)((di >>index) & 0x0001);
#else
	ret = (unsigned short)((di >> 23) & 0x0001);//dtu
#endif
	return ret;
}

static void gpio_kouten_do(int on, unsigned int kouten)
{
    // if (kouten > KOUT_EN1)
    //     return;

    // if(on)
    // {
    //     write(gpio_val_fd_other[KOUT_EN0+kouten], "1", 2);
    // }
    // else
    // {
    //     write(gpio_val_fd_other[KOUT_EN0+kouten], "0", 2);
    // }

}


/******************************************************************************
函数名称：	gpio_kout_do
函数版本：	01.01
创建作者：
创建日期：	2014-11-28
函数说明：	开出

参数说明：	on: 1开出, 0回收
			kout: 那一路
返回值：  无
修改记录：
*/
void gpio_kout_do(int on, unsigned int kout)
{

    //if (kout > (DO_NUM-DO_OUT0))
    //    return;

	if(on)
	{

		if((kout==6) || (kout==7))
		{
			// gpio_kouten_do(1,KOUT_EN1);
			kc_kout1_stu |= (1 << kout);
		}
		else
		{
			// gpio_kouten_do(1,KOUT_EN0);
			kc_kout0_stu |= (1 << kout);
		}
		
		write(gpio_val_fd[kout+DO_OUT0], "0", 2);

	}
	else
	{

		write(gpio_val_fd[kout+DO_OUT0], "1", 2);

		if((kout==6) || (kout==7))
		{
			kc_kout1_stu &= ~(1 << kout);
			
		}
		else
		{
			kc_kout0_stu &= ~(1 << kout);
		}

		if ((kc_pwm1_stu== 0) &&(kc_kout1_stu == 0))
		{
			// gpio_kouten_do(0,KOUT_EN1);
		}
		
		if ((kc_kout0_stu == 0) && (kc_pwm0_stu==0))
		{
			// gpio_kouten_do(0,KOUT_EN0);
		}	

	}


}

/******************************************************************************
函数名称：	gpio_pwm_do
函数版本：	01.01
创建作者：
创建日期：	2014-11-28
函数说明：	pwm开出，由于存在kc_pwm_stu，只允许在同一控制路径中开出(例如同一中断或同一线程).

参数说明：		on: 1开出, 0回收
返回值：  无
修改记录：
*/
void gpio_pwm_do(int on, unsigned int kout)
{
   // if (kout >= DO_NUM)
   //     return;

	if(on)
	{
		
		if((kout==0) || (kout==1))
		{
			// gpio_kouten_do(1,KOUT_EN1);
			kc_pwm1_stu |= (1 << kout);
		}
		else
		{
			// gpio_kouten_do(1,KOUT_EN0);
			kc_pwm0_stu |= (1 << kout);
		}

		write(gpio_val_fd[kout], "0", 2);

	}
	else
	{
		write(gpio_val_fd[kout], "1", 2);

		if((kout==0) || (kout==1))
		{
			kc_pwm1_stu &= ~(1 << kout);
			
		}
		else
		{
			kc_pwm0_stu &= ~(1 << kout);
		}

		if ((kc_pwm1_stu== 0) &&(kc_kout1_stu == 0))
		{
			// gpio_kouten_do(0,KOUT_EN1);

		}
		
		if ((kc_kout0_stu == 0) && (kc_pwm0_stu==0))
		{
			// gpio_kouten_do(0,KOUT_EN0);
		}	

	}

}

/******************************************************************************
函数名称：	gpio_get_wirelessin
函数版本：	01.01
创建作者:	   sunxi
创建日期：	2008-09-16
函数说明：	得到无线遥控的状态。
参数说明：	无
返回值：  	返回开入的状态，每个bit代表一个开入量。
修改记录：
*/
unsigned int gpio_get_wirelessin(void)
{
	register unsigned int dw = 0;

	return dw;
}

unsigned int gpio_get_version(void)
{
	register unsigned int dw = 0;

	return dw;
}


unsigned int gpio_get_addr(void)
{
	register unsigned int dw = 0;

	return dw;
}



/******************************************************************************
函数名称：	gpio_watchdog_reset
函数版本：	01.01
创建作者:	   sunxi
创建日期：	2008-09-16
函数说明：	复位看门狗。
参数说明：	无。
返回值：  	无。
修改记录：
*/
// void gpio_watchdog_reset(void)
// {

// 	if(gpio_watchdog_val)
// 	{
// 		gpio_watchdog_val = 0;
// 		write(gpio_val_fd_other[WATCHDOG], "0", 2);
// 	}
// 	else
// 	{
// 		gpio_watchdog_val = 1;
// 		write(gpio_val_fd_other[WATCHDOG], "1", 2);
// 	}

// 	return;
// }

void _led_run_err(void)
{
	// 上电就亮错误灯，有错误就继续亮没有就熄灭
	static uint8 err_led = 2;
	
	if(rt_err_count())
	{
		//错误指示灯常亮且运行熄灭
		if(!(err_led&0x01))
		{
			err_led |= 1;
			write(gpio_val_fd_other[ERR_LED], "0", 2);
			write(gpio_val_fd_other[RUN_LED], "1", 2);
		}
		return;
	}

	if(err_led)
	{
		err_led = 0;
		write(gpio_val_fd_other[ERR_LED], "1", 2);
	}

	//运行指示灯,每隔1s改变状态一次
	if(!gpio_run_led_val)
	{
		gpio_run_led_val = 1;
		write(gpio_val_fd_other[RUN_LED], "0", 2);
	}
	else
	{
		gpio_run_led_val = 0;
		write(gpio_val_fd_other[RUN_LED], "1", 2);
	}
}

void esam_power_ctrl(int on)
{
	if(on)
		write(gpio_val_fd_other[ESAM_PWR], "1", 2);
	else
		write(gpio_val_fd_other[ESAM_PWR], "0", 2);
}

/*------------------------------ 内部函数 -------------------------------------
*/


/*------------------------------ 测试函数 -------------------------------------
*/
#ifdef _GPIO_DEBUG
#include "ustimer.h"
#include "rt.h"

int gpio_test(void)
{
	int ret = 0;
	//unsigned int i;

	//gpio_kouten_do(1,KOUT_EN1);

#if 1
	while(1)
	{


			sleep(5);

			gpio_kout_do(1,DO_OUT2-DO_OUT0);
			//gpio_kout_do(1,DO_OUT3-DO_OUT0);
			// gpio_pwm_do(1,DO_PWM1);



			sleep(5);

			gpio_kout_do(0,DO_OUT2-DO_OUT0);
			//gpio_kout_do(0,DO_OUT3-DO_OUT0);
			// gpio_pwm_do(0,DO_PWM1);

/*
			
		for(i=DO_OUT0; i<DO_NUM; i++)
		{
			rt_printf("kout number = %d!\n\r", i);
			//msleep();
			sleep(1);
			gpio_kout_do(1,i-DO_OUT0);
			sleep(1);
			gpio_kout_do(0,i-DO_OUT0);


		}
*/
		
	}
#endif
	return ret;
}
#endif
