
#include <errno.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <getopt.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <net/if.h> 
#include <sys/socket.h> 
#include <linux/can.h> 
#include <linux/can/raw.h>

#include <linux/input.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#include <linux/input.h>

/**
 * @name: user_led_set_none_mode
 * @description: 将LED设置为无触发模式，此种模式下通过调用 user_led_turn_on_off 来配置亮和灭
 * @param led_name:LED的名称，如work work1
 * @return 0 - 成功 小于0 - 失败 
 */
int user_led_set_none_mode(char *led_name);

/**
 * @name: user_led_turn_on_off
 * @description: 配置LED为亮或者灭，只能在无触发模式下使用
 * @param led_name:LED的名称，如work work1
 * @param level:1 - 亮 0 -灭
 * @return 0 - 成功 小于0 - 失败 
 */
int user_led_turn_on_off(char *led_name, unsigned char level);

/**
 * @name: user_led_set_timer_mode
 * @description: 配置LED为定时器翻转模式
 * @param led_name:LED的名称，如work work1
 * @return 0 - 成功 小于0 - 失败 
 */
int user_led_set_timer_mode(char *led_name);

/**
 * @name: user_led_set_timer_on_off
 * @description: LED为定时器翻转模式时设置亮和灭的时间
 * @param led_name:LED的名称，如work work1
 * @param on_time:亮的时间，单位ms
 * @param on_time:灭的时间，单位ms
 * @return 0 - 成功 小于0 - 失败 
 */
int user_led_set_timer_on_off(char *led_name, int on_time, int off_time);

/**
 * @name: user_uart_open
 * @description: 打开串口
 * @param uart_num: 串口号，板上引出的串口包括3 4 8 9
 * @return 大于等于0 - 成功，返回值为文件描述符 小于0 - 失败 
 */
int user_uart_open(int uart_num);

/**
 * @name: user_uart_set_property
 * @description: 设置波特率 位数 停止位 校验位
 * @param fd: 文件描述符，user_uart_open返回值
 * @param speed: 波特率，目前支持 921600, 460800, 230400, 115200, 57600, 38400,  19200,  9600,  4800,  2400,  1200,  300
 * @param databits: 长度，目前支持7 8位数据位
 * @param stopbits: 停止位，目前支持1 2位停止位
 * @param parity: 校验，n不校验，o奇校验，e偶校验
 * 
 * @return 等于0 - 成功 小于0 - 失败 
 */
int user_uart_set_property(int fd, int speed, int databits, int stopbits, int parity);

/**
 * @name: user_uart_read
 * @description: 从串口缓冲读取数据
 * @param fd: 文件描述符，user_uart_open返回值
 * @param buf: 读入数据的指针
 * @param buf_len: buf指向区域的长度
 * 
 * @return 大于0 - 成功 小于0 - 失败 等于0 - 没有读到任何数据
 */
int user_uart_read(int fd, char *buf, unsigned int buf_len);

/**
 * @name: user_uart_write
 * @description: 向串口缓冲写入数据
 * @param fd: 文件描述符，user_uart_open返回值
 * @param buf: 读入数据的指针
 * @param buf_len: buf指向区域的长度
 * 
 * @return 大于0 - 成功 小于0 - 失败 等于0 - 没有数据被写入
 */
int user_uart_write(int fd, const char *buf, unsigned int buf_len);

/**
 * @name: user_uart_close
 * @description: 关闭串口
 * @param fd: 文件描述符，user_uart_open返回值
 * @return 始终等于0，无意义
 */
int user_uart_close(int fd);

/**
 * @name: user_i2c_open
 * @description: 打开i2c设备
 * @param i2c_num: i2c号，板上引出的i2c包括 1 5
 * @return 大于等于0 - 成功，返回值为文件描述符 小于0 - 失败 
 */
int user_i2c_open(int i2c_num);

/**
 * @name: user_i2c_read
 * @description: 从i2c设备读取数据
 * @param fd: 文件描述符，user_i2c_open返回值
 * @param slave_addr: i2c设备地址
 * @param reg_addr: 寄存器地址的指针
 * @param addr_len: 寄存器地址长度
 * @param buf: 读入数据的指针
 * @param len: 读入数据的长度
 * 
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_i2c_read(int fd, unsigned short slave_addr, unsigned char *reg_addr, unsigned char addr_len, unsigned char *buf, unsigned short len);

/**
 * @name: user_i2c_read
 * @description: 从i2c设备读取数据
 * @param fd: 文件描述符，user_i2c_open返回值
 * @param slave_addr: i2c设备地址
 * @param reg_addr: 寄存器地址的指针
 * @param addr_len: 寄存器地址长度
 * @param buf: 写入数据的指针
 * @param len: 写入数据的长度
 * 
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_i2c_write(int fd, unsigned short slave_addr, unsigned char *reg_addr, unsigned char addr_len, unsigned char *buf, unsigned short len);

/**
 * @name: user_i2c_close
 * @description: 关闭i2c
 * @param fd: 文件描述符，user_i2c_open 返回值
 * @return 始终等于0，无意义
 */
int user_i2c_close(int fd);

/**
 * @name: user_can_init
 * @description: 初始化CAN
 * @param can_name: can网卡设备名 如can0
 * @param can_baud: 波特率 如250000
 * @param canfd_baud: canfd波特率 如3000000
 * @return 大于等于0 - 成功 小于0 - 失败 
 */
int user_can_init(char *can_name, int can_baud, int canfd_baud);

/**
 * @name: user_can_deinit
 * @description: 反初始化CAN
 * @param can_name: can网卡设备名 如can0
 * @return 大于等于0 - 成功 小于0 - 失败 
 */
int user_can_deinit(char *can_name);

/**
 * @name: user_can_send
 * @description: 发送一帧CAN数据
 * @param can_name: can网卡设备名 如can0
 * @param frame: Linux下的CAN结构体
 * @return 大于0 - 成功 小于0 - 失败 等于0 - 暂时无法发送，有可能缓冲区满
 */
int user_can_send(char *can_name, struct can_frame frame);

/**
 * @name: user_can_recv
 * @description: 接收一帧CAN数据
 * @param can_name: can网卡设备名 如can0
 * @param frame: Linux下的CAN结构体
 * @return 大于0 - 成功 小于0 - 失败 等于0 - 未收到数据，接收缓冲区空
 */
int user_can_recv(char *can_name, struct can_frame *frame);

/**
 * @name: user_ir_open
 * @description: 打开ir设备
 * @return 大于等于0 - 成功，返回值为文件描述符 小于0 - 失败 
 */
int user_ir_open(void);

/**
 * @name: user_ir_get
 * @description: 从ir设备读取数据
 * @param fd: 文件描述符，user_ir_open 返回值
 * @param code: 当前按键值
 * @param value: 当前事件类型，1 - 按下 0 - 弹起
 * 
 * @return 等于0 - 成功 小于0 - 失败，无数据或出错 
 */
int user_ir_get(int fd, int *code, int *value);

/**
 * @name: user_ir_close
 * @description: 关闭ir设备
 * @param fd: 文件描述符，user_ir_open 返回值
 * @return 始终等于0，无意义
 */
int user_ir_close(int fd);

typedef enum {
	PIN_DIRECTION_IN = 0,
	PIN_DIRECTION_OUT = 1
} Enum_PinDirection;

/**
 * @name: user_gpio_init
 * @description: 将某个pin配置为gpio
 * @param pin_num: 引脚号
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_gpio_init(int pin_num);

/**
 * @name: user_gpio_deinit
 * @description: 将某个pin释放
 * @param pin_num: 引脚号
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_gpio_deinit(int pin_num);

/**
 * @name: user_gpio_set_level
 * @description: 设置gpio电平
 * @param pin_num: 引脚号
 * @param level: 电平 0 - 低 1- 高
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_gpio_set_level(int pin_num, unsigned char level);

/**
 * @name: user_gpio_get_level
 * @description: 获取gpio电平
 * @param pin_num: 引脚号
 * @param level: 电平 0 - 低 1- 高
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_gpio_get_level(int pin_num, unsigned char *level);

/**
 * @name: user_gpio_set_direction
 * @description: 设置gpio方向
 * @param pin_num: 引脚号
 * @param direction: PIN_DIRECTION_IN - 输入 PIN_DIRECTION_OUT - 输出
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_gpio_set_direction(int pin_num, unsigned char direction);

/**
 * @name: user_gpio_get_direction
 * @description: 获取gpio方向
 * @param pin_num: 引脚号
 * @param direction: PIN_DIRECTION_IN - 输入 PIN_DIRECTION_OUT - 输出
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_gpio_get_direction(int pin_num, unsigned char *direction);
