
#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/spi/spidev.h>

/**
 * @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);

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);

/**
 * @name: user_adc_get_value
 * @description: 获取adc值
 * @param adc_num: adc通道号
 * @param value: 读取的原始值
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_adc_get_value(int adc_num, unsigned int *value);


/**
 * @name: user_spi_open
 * @description: 打开 spidev 设备
 * @param i2c_num: spi号
 * @param spi_cs: spi片选号
 * @return 大于等于0 - 成功，返回值为文件描述符 小于0 - 失败 
 */
int user_spi_open(int spi_num,int spi_cs);

/**
 * @name: user_spi_write_read
 * @description: 从spi设备读写数据spi通讯是全双工的只读可以配置write_buf内容为0 只写可以丢弃read_buf内容
 * @param fd: 文件描述符，user_spi_open返回值
 * @param write_buf: spi写数据指针
 * @param read_buf: spi读数据指针
 * @param addr_len: 寄存器地址长度
 * @param len: 读写数据长度
 * 
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_spi_write_read(int fd, unsigned char* write_buf,unsigned char* read_buf,unsigned int len);

/**
 * @name: user_spi_close
 * @description: 关闭spi
 * @param fd: 文件描述符，user_spi_close 返回值
 * @return 始终等于0，无意义
 */
int user_spi_close(int fd);

/**
 * @name: user_pwm_enable
 * @description: 设置pwm属性并开启pwm
 * @param pwmchip_num: pwmchip序号
 * @param pwmchannel_num: pwm通道号
 * @param period: 周期
 * @param duty_cycle: 高电平持续时间
 * @param polarity: 0 - 极性不反转 其它 - 极性反转
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_pwm_enable(int pwmchip_num, int pwmchannel_num, int period, int duty_cycle, unsigned char polarity);

/**
 * @name: user_pwm_disable
 * @description: 关闭pwm
 * @param pwmchip_num: pwmchip序号
 * @param pwmchannel_num: pwm通道号
 * @return 等于0 - 成功 小于0 - 失败
 */
int user_pwm_disable(int pwmchip_num, int pwmchannel_num);
