| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745 |
- /******************************************************************************
- 版权所有:
- 文件名称: 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
- M1 开入 --> GPIOI_11 --> gpio267
- M3 采样 --> GPIOI_10 --> gpio266
- M4 开出 --> GPIOA_02 --> gpio2
- 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
- #define GPIO_LOW 0
- #define GPIO_INPUT 0
- #define GPIO_OUTPUT 1
- #define NEW_GOIO_VERSION 1
- /*------------------------------ 全局变量 -------------------------------------
- */
- typedef enum
- {
- SYS_GPIO = 0,
- RTDM_GPIO = 1,
- } GPIO_TYPE;
- unsigned short kc_kout0_stu;
- extern uint32_t g_yx_buf[2]; // 预留64个遥信
- /*------------------------------ 函数声明 -------------------------------------
- */
- extern unsigned int change_di_ch(unsigned int di);
- #if (0 == NEW_GOIO_VERSION)
- int gpio_val_fd[DO_NUM];
- int gpio_dev_type[DO_NUM] = {
- SYS_GPIO,
- }; // 0:系统GPIO, 1:RTDM GPIO
- /* 开出gpio */
- const int gpio_val[DO_NUM] = {115, 98, 105, 114, 112, 103, 104, 102, 99, 113};
- #else
- struct t_goio_cfg
- {
- int l_pin_num; // 引脚号
- int l_pin_fd; // 句柄
- int l_pin_type; // 类型 0:系统GPIO, 1:RTDM GPIO
- int l_pin_dir; // 方向 GPIO_INPUT 0 输入, GPIO_OUTPUT 1 输出
- };
- static struct t_goio_cfg mst_gpio_cfg[GPIO_NUM_TOTAL] =
- {
- {115, -1, -1, GPIO_OUTPUT},
- {98, -1, -1, GPIO_OUTPUT},
- {105, -1, -1, GPIO_OUTPUT},
- {114, -1, -1, GPIO_OUTPUT},
- {112, -1, -1, GPIO_OUTPUT},
- {103, -1, -1, GPIO_OUTPUT},
- {104, -1, -1, GPIO_OUTPUT},
- {102, -1, -1, GPIO_OUTPUT},
- {99, -1, -1, GPIO_OUTPUT},
- {113, -1, -1, GPIO_INPUT},
- {267, -1, -1, GPIO_INPUT},
- {266, -1, -1, GPIO_INPUT},
- {2, -1, -1, GPIO_INPUT},
- };
- #endif
- // static int gpio_watchdog_val = 0;
- static int gpio_run_led_val = 0;
- /*------------------------------ 外部函数 -------------------------------------
- */
- 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_get_value(int gpio)
- {
- char path[64];
- int fd = -1;
- int value = 0;
- snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", gpio);
- fd = open(path, O_RDONLY);
- if (fd < 0)
- {
- perror("Failed to open value");
- return -1;
- }
- if (read(fd, value, 1) < 0)
- {
- perror("Failed to get value");
- close(fd);
- return -1;
- }
- return fd;
- }
- int sysfs_gpio_init(int gpio, int direction)
- {
- int ret;
- ret = sysfs_gpio_export(gpio);
- if (ret < 0)
- {
- dp_err_n_c("sysfs_gpio_export error ret = %d!", ret);
- return -1;
- }
- ret = sysfs_gpio_set_direction(gpio, direction);
- if (ret < 0)
- {
- dp_err_n_c("sysfs_gpio_set_direction error");
- }
- if (GPIO_INPUT == direction)
- {
- return sysfs_gpio_get_value(gpio);
- }
- else
- {
- return sysfs_gpio_set_value(gpio, GPIO_LOW); // 初始化IO为低电平
- }
- }
- int is_rtdm_device(int fd)
- {
- #if (0 == NEW_GOIO_VERSION)
- if (gpio_dev_type[fd] > SYS_GPIO)
- return 1;
- else if (gpio_dev_type[fd] == SYS_GPIO)
- return 0;
- else
- return -1;
- #else
- if (mst_gpio_cfg[fd].l_pin_type > SYS_GPIO)
- return 1;
- else if (mst_gpio_cfg[fd].l_pin_type == SYS_GPIO)
- return 0;
- else
- return -1;
- #endif
- }
- int rt_write(int fd, char *buf, int len)
- {
- int value;
- if (len <= 0 || buf == NULL)
- {
- return -1;
- }
- if (is_rtdm_device(fd) == 1)
- {
- value = atoi(buf);
- if (value != 0 && value != 1)
- {
- dp_err_n_c("value :%d ERR, Please enter '0' or '1'", value);
- return -1;
- }
- return write(fd, &value, sizeof(value));
- }
- else
- {
- return write(fd, buf, len);
- }
- }
- int rt_read(int _l_fd, int *_l_state, int len)
- {
- int ret = 0, l_val = -1;
- if (is_rtdm_device(_l_fd) == 1)
- {
- ret = read(_l_fd, &l_val, sizeof(l_val));
- if (ret < 0 || ret != sizeof(l_val))
- {
- dp_err_n_c("Failed to read from RTDM device, ret=%d", ret);
- return -1;
- }
- *_l_state = l_val;
- }
- else
- {
- ret = read(_l_fd, &l_val, len);
- dp_err_n_c("ret=%d", ret);
- if (ret < 0)
- {
- dp_err_n_c("Failed to read from regular device");
- return -1;
- }
- *_l_state = l_val;
- }
- return ret;
- }
- int rtdm_gpio_init(int gpio, int direction)
- {
- char path[64];
- int fd = -1, ret;
- int value = 1;
- snprintf(path, sizeof(path), "/dev/rtdm/3604000.pinctrl/gpio%d", gpio);
- if (GPIO_INPUT == direction)
- {
- fd = open(path, O_RDWR | O_NONBLOCK);
- }
- else
- {
- fd = open(path, O_RDWR);
- }
- if (fd < 0)
- {
- dp_err_n_c("gpio [%d] open error", gpio);
- perror("open");
- return -1;
- }
- if (GPIO_INPUT == direction)
- {
- ret = ioctl(fd, GPIO_RTIOC_DIR_IN, &value);
- }
- else
- {
- ret = ioctl(fd, GPIO_RTIOC_DIR_OUT, &value);
- }
- if (ret < 0)
- {
- dp_err_n_c("gpio [%d] ioctl error", gpio);
- perror("gpio ioctl err");
- close(fd);
- return -1;
- }
- return fd;
- }
- int gpio_init(void)
- {
- int i;
- #if (0 == NEW_GOIO_VERSION)
- 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);
- dp_info_n_c("gpio_val_fd[%02d] = %d", i, gpio_val_fd[i]);
- if (gpio_val_fd[i] < 0)
- {
- dp_err_n_c("gpio_val_fd[%d] error", 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
- }
- }
- msleep(10); // 延时10ms
- kc_kout0_stu = 0;
- for (i = DO_OUT1; i < DO_NUM; i++)
- {
- rt_write(gpio_val_fd[i], "1", 2);
- }
- return 0;
- #else
-
- for (i = 0; i < GPIO_NUM_TOTAL; i++)
- {
- mst_gpio_cfg[i].l_pin_fd = rtdm_gpio_init(mst_gpio_cfg[i].l_pin_num, mst_gpio_cfg[i].l_pin_dir);
- if (mst_gpio_cfg[i].l_pin_fd < 0)
- {
- mst_gpio_cfg[i].l_pin_fd = sysfs_gpio_init(mst_gpio_cfg[i].l_pin_num, mst_gpio_cfg[i].l_pin_dir);
- if (mst_gpio_cfg[i].l_pin_fd < 0)
- {
- dp_err_n_c("mst_gpio_cfg[%d].l_pin_fd error", i);
- mst_gpio_cfg[i].l_pin_fd = -1;
- mst_gpio_cfg[i].l_pin_type = -1;
- return -1;
- }
- }
- else
- {
- mst_gpio_cfg[i].l_pin_type = mst_gpio_cfg[i].l_pin_fd; // 保存RTDM设备类型句柄,这里有风险,fd句柄可能为0
- }
- }
- msleep(10); // 延时10ms
- kc_kout0_stu = 0;
- for (i = 0; i < (DO_NUM - 1); i++)
- {
- rt_write(mst_gpio_cfg[i].l_pin_fd, "1", 2);
- }
- return 0;
- #endif
- }
- int gpio_exit(void)
- {
- int i;
- for (i = 0; i < DO_NUM; i++)
- {
- #if (0 == NEW_GOIO_VERSION)
- if (gpio_val_fd[i] >= 0)
- {
- close(gpio_val_fd[i]);
- gpio_val_fd[i] = -1;
- }
- sysfs_gpio_unexport(gpio_val[i]);
- #else
- if (mst_gpio_cfg[i].l_pin_fd >= 0)
- {
- close(mst_gpio_cfg[i].l_pin_fd);
- mst_gpio_cfg[i].l_pin_fd = -1;
- }
- sysfs_gpio_unexport(mst_gpio_cfg[i].l_pin_num);
- #endif
- }
- return 0;
- }
- /******************************************************************************
- 函数名称: 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
- ret = (unsigned short)((di >> index) & 0x0001);
- #else
- ret = (unsigned short)((di >> 23) & 0x0001);
- #endif
- return ret;
- }
- /**
- * @brief 读取gpio的状态
- * @author lch (lch_work@foxmail.com)
- * @version 1.0
- * @date 20260311
- * @param[in/out] {uint8_t} _uc_idx 下标
- * @return * int
- * @retval none
- *
- * @warning none
- * @note none
- */
- int gpioio_get_gpio_status(uint8_t _uc_idx)
- {
- int ret, l_io_state = 0;
- if (_uc_idx < DO_IN_PRESET || _uc_idx > GPIO_INT_M4)
- return -1;
- ret = rt_read(mst_gpio_cfg[_uc_idx].l_pin_fd, &l_io_state, sizeof(l_io_state));
- if (ret < 0)
- {
- dp_err_n_c("l_io_state: %d\r\n", l_io_state);
- return -2;
- }
- return l_io_state;
- }
- /******************************************************************************
- 函数名称: gpio_kout_do
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2014-11-28
- 函数说明: 开出
- 参数说明: on: 1开出, 0回收
- kout: 那一路
- 返回值: 无
- 修改记录:
- */
- int gpio_kout_do(int on, unsigned int kout)
- {
- int l_ret = -1;
- if (kout > DO_OUT_PRESET)
- return;
- #if (0 == NEW_GOIO_VERSION)
- if (on)
- {
- l_ret = rt_write(gpio_val_fd[kout + DO_OUT0], "0", 2);
- // dp_info_n_c("kout = %d, on = %d, l_ret = %d", kout, on, l_ret);
- }
- else
- {
- l_ret = rt_write(gpio_val_fd[kout + DO_OUT0], "1", 2);
- // dp_info_n_c("kout = %d, on = %d, l_ret = %d", kout, on, l_ret);
- }
- #else
- if (on)
- {
- l_ret = rt_write(mst_gpio_cfg[kout + DO_OUT0].l_pin_fd, "0", 2);
- // dp_info_n_c("kout = %d, on = %d, l_ret = %d", kout, on, l_ret);
- }
- else
- {
- l_ret = rt_write(mst_gpio_cfg[kout + DO_OUT0].l_pin_fd, "1", 2);
- // dp_info_n_c("kout = %d, on = %d, l_ret = %d", kout, on, l_ret);
- }
- #endif
- return l_ret;
- }
- /******************************************************************************
- 函数名称: 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;
- }
- 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);
- }
- /*------------------------------ 内部函数 -------------------------------------
- */
- /*------------------------------ 测试函数 -------------------------------------
- */
- #if (0)
- int test_read_pin(void)
- {
- int ret, l_io_state = 0;
- dp_info_n_c("test_read_pin!");
- ret = rt_read(mst_gpio_cfg[GPIO_INT_M1].l_pin_fd, &l_io_state, sizeof(l_io_state));
- dp_info_n_c("ret: %d", ret);
- if (ret > 0)
- {
- dp_info_n_c("l_io_state: %d\r\n", l_io_state);
- }
- else
- {
- dp_err_n_c("l_io_state: %d\r\n", l_io_state);
- }
- ret = rt_read(mst_gpio_cfg[GPIO_INT_M3].l_pin_fd, &l_io_state, sizeof(l_io_state));
- dp_info_n_c("ret: %d", ret);
- if (ret > 0)
- {
- dp_info_n_c("l_io_state: %d\r\n", l_io_state);
- }
- else
- {
- dp_err_n_c("l_io_state: %d\r\n", l_io_state);
- }
- ret = rt_read(mst_gpio_cfg[GPIO_INT_M4].l_pin_fd, &l_io_state, sizeof(l_io_state));
- dp_info_n_c("ret: %d", ret);
- if (ret > 0)
- {
- dp_info_n_c("l_io_state: %d\r\n", l_io_state);
- }
- else
- {
- dp_err_n_c("l_io_state: %d\r\n", l_io_state);
- }
- }
- #endif
|