gpio.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: gpio.c
  4. 文件版本: 01.01
  5. 创建作者: zhaoyang
  6. 创建日期: 2023-12-14
  7. 功能说明: gpio驱动程序。
  8. 其它说明:
  9. 修改记录:
  10. [old]-->drop
  11. gpio0: a0111000.gpio -> gpiochip480 -> GPIO0_0
  12. gpio1: a0112000.gpio -> gpiochip448 -> GPIO1_0
  13. gpio2: a0387000.gpio -> gpiochip416 -> GPIO2_0
  14. gpio3: a0388000.gpio -> gpiochip384 -> GPIO3_0
  15. gpio4: a0919000.gpio -> gpiochip352 -> GPIO4_0
  16. gpio5: a091a000.gpio -> gpiochip320 -> GPIO5_0
  17. gpio6: a091b000.gpio -> gpiochip288 -> GPIO6_0
  18. gpio7: a091c000.gpio -> gpiochip256 -> GPIO7_0
  19. PDO0_1 --> GPIO5_22 --> gpio342
  20. PDO1_1 --> GPIO5_23 --> gpio343
  21. PDO2_1 --> GPIO5_24 --> gpio344
  22. PDO3_1 --> GPIO5_25 --> gpio345
  23. KOUT0 --> GPIO4_29 --> gpio381
  24. KOUT1 --> GPIO4_30 --> gpio382
  25. KOUT2 --> GPIO4_31 --> gpio383
  26. KOUT3 --> GPIO5_0 --> gpio320
  27. KOUT4 --> GPIO5_1 --> gpio321
  28. KOUT5 --> GPIO5_2 --> gpio322
  29. KOUT6 --> GPIO5_3 --> gpio323
  30. KOUT7 --> GPIO5_4 --> gpio324
  31. KOUT8 --> GPIO5_5 --> gpio325
  32. KOUT9 --> GPIO5_6 --> gpio326
  33. // sunxi 20220530 KOUT10 --> GPIO5_7 --> gpio327
  34. // sunxi 20220530 KOUT_EN0 --> GPIO5_8 --> gpio328
  35. // sunxi 20220530 KOUT_EN1 --> GPIO5_9 --> gpio329
  36. KOUT10 --> GPIO2_21 --> gpio437
  37. KOUT_EN0 --> GPIO3_18 --> gpio402
  38. KOUT_EN1 --> GPIO3_19 --> gpio403
  39. RUN led --> GPIO3_17 --> gpio401
  40. ERR led --> GPIO3_20 --> gpio404
  41. // sunxi 20220609 esam_pwr --> GPIO0_10 --> gpio490
  42. esam_pwr --> GPIO2_21 --> gpio437
  43. WTD --> GPIO0_31 --> gpio511
  44. [new]-->applay
  45. gpio0: a0111000.gpio -> gpiochip0 -> GPIO0_0
  46. gpio1: a0112000.gpio -> gpiochip32 -> GPIO1_0
  47. gpio2: a0387000.gpio -> gpiochip64 -> GPIO2_0
  48. gpio3: a0388000.gpio -> gpiochip96 -> GPIO3_0
  49. gpio4: a0919000.gpio -> gpiochip128 -> GPIO4_0
  50. gpio5: a091a000.gpio -> gpiochip160 -> GPIO5_0
  51. gpio6: a091b000.gpio -> gpiochip192 -> GPIO6_0
  52. gpio7: a091c000.gpio -> gpiochip224 -> GPIO7_0
  53. PDO0_1 --> GPIO5_22 --> gpio182
  54. PDO1_1 --> GPIO5_23 --> gpio183
  55. PDO2_1 --> GPIO5_24 --> gpio184
  56. PDO3_1 --> GPIO5_25 --> gpio185
  57. KOUT0 --> GPIO4_29 --> gpio157
  58. KOUT1 --> GPIO4_30 --> gpio158
  59. KOUT2 --> GPIO4_31 --> gpio159
  60. KOUT3 --> GPIO5_0 --> gpio160
  61. KOUT4 --> GPIO5_1 --> gpio161
  62. KOUT5 --> GPIO5_2 --> gpio162
  63. KOUT6 --> GPIO5_3 --> gpio163
  64. KOUT7 --> GPIO5_4 --> gpio164
  65. KOUT8 --> GPIO5_5 --> gpio165
  66. KOUT9 --> GPIO5_6 --> gpio166
  67. // zhaoyang 20231214 KOUT10 --> GPIO5_7 --> gpio167
  68. // zhaoyang 20231214 KOUT_EN0 --> GPIO5_8 --> gpio168
  69. // zhaoyang 20231214 KOUT_EN1 --> GPIO5_9 --> gpio169
  70. KOUT10 --> GPIO2_21 --> gpio85
  71. KOUT_EN0 --> GPIO3_18 --> gpio114
  72. KOUT_EN1 --> GPIO3_19 --> gpio115
  73. RUN led --> GPIO3_17 --> gpio113
  74. ERR led --> GPIO3_20 --> gpio116
  75. // zhaoyang 20231214 esam_pwr --> GPIO0_10 --> gpio10
  76. esam_pwr --> GPIO2_21 --> gpio85
  77. WTD --> GPIO0_31 --> gpio31
  78. */
  79. /*------------------------------- 头文件 --------------------------------------
  80. */
  81. #include "bspconfig.h"
  82. #include "gpio.h"
  83. #include "head.h"
  84. /*------------------------------- 宏定义 --------------------------------------
  85. */
  86. #if CFG_BSP_DEBUG
  87. #define _GPIO_DEBUG
  88. #endif
  89. /*------------------------------ 全局变量 -------------------------------------
  90. */
  91. unsigned short kc_pwm0_stu;
  92. unsigned short kc_pwm1_stu;
  93. unsigned short kc_kout0_stu;
  94. unsigned short kc_kout1_stu;
  95. extern uint32_t g_yx_buf[2]; //预留64个遥信
  96. /*------------------------------ 函数声明 -------------------------------------
  97. */
  98. extern unsigned int change_di_ch(unsigned int di);
  99. int gpio_val_fd[DO_NUM];
  100. const int gpio_val[DO_NUM] = {96, 97, 98, 99, 100, 101, 102, 103, 104, 105};
  101. int gpio_val_fd_other[GPIO_NUM_OTHER];
  102. const int gpio_val_other[GPIO_NUM_OTHER] ={39,164,359,197};
  103. // static int gpio_watchdog_val = 0;
  104. static int gpio_run_led_val = 0;
  105. /*------------------------------ 外部函数 -------------------------------------
  106. */
  107. /******************************************************************************
  108. 函数名称: gpio_init
  109. 函数版本: 01.01
  110. 创建作者: sunxi
  111. 创建日期: 2008-06-26
  112. 函数说明: gpio初始化。
  113. 参数说明: 无
  114. 返回值: 成功返回0.
  115. 修改记录:
  116. */
  117. int gpio_init(void)
  118. {
  119. int i, j;
  120. int exportfd, directionfd;
  121. char num[10];
  122. char path[50] = "";
  123. //do
  124. exportfd = open("/sys/class/gpio/export", O_WRONLY);
  125. if (exportfd < 0)
  126. {
  127. printf("Cannot open GPIO to export it\n");
  128. return -1;
  129. }
  130. for (i = 0; i < DO_NUM; i ++)
  131. {
  132. sprintf(num, "%d", gpio_val[i]);
  133. write(exportfd, num, 4);
  134. gpio_val_fd[i] = -1;
  135. }
  136. for (i = 0; i < GPIO_NUM_OTHER; i ++)
  137. {
  138. sprintf(num, "%d", gpio_val_other[i]);
  139. write(exportfd, num, 4);
  140. gpio_val_fd_other[i] = -1;
  141. }
  142. close(exportfd);
  143. #if 0 // TODO:需根据实际硬件重新对应匹配
  144. for (i = 0; i < DO_NUM; i ++)
  145. {
  146. sprintf(path, "/sys/class/gpio/gpio%d/value", gpio_val[i]);
  147. gpio_val_fd[i] = open(path, O_RDWR);
  148. if (gpio_val_fd[i] < 0)
  149. {
  150. printf("Cannot open GPIO%d value!\n", gpio_val[i]);
  151. for(j = 0; j < i; j ++)
  152. {
  153. close(gpio_val_fd[j]);
  154. gpio_val_fd[j] = -1;
  155. }
  156. return -4;
  157. }
  158. }
  159. // Update the direction of the GPIO to be an output
  160. for (i = 0; i < DO_NUM; i ++)
  161. {
  162. sprintf(path, "/sys/class/gpio/gpio%d/direction", gpio_val[i]);
  163. directionfd = open(path, O_RDWR);
  164. if (directionfd < 0)
  165. {
  166. printf("Cannot open GPIO%d direction!\n", gpio_val[i]);
  167. return -2;
  168. }
  169. write(directionfd, "out", 4);
  170. write(gpio_val_fd[i], "1", 2);
  171. close(directionfd);
  172. }
  173. #endif
  174. msleep(10);// 延时10ms
  175. for (i = 0; i < GPIO_NUM_OTHER; i ++)
  176. {
  177. sprintf(path, "/sys/class/gpio/gpio%d/value", gpio_val_other[i]);
  178. gpio_val_fd_other[i] = open(path, O_RDWR);
  179. if (gpio_val_fd_other[i] < 0)
  180. {
  181. printf("Cannot open GPIO%d value!\n", gpio_val_other[i]);
  182. for(j = 0; j < i; j ++)
  183. {
  184. close(gpio_val_fd_other[j]);
  185. gpio_val_fd_other[j] = -1;
  186. }
  187. // for(j = 0; j < DO_NUM; j ++)
  188. // {
  189. // close(gpio_val_fd[j]);
  190. // gpio_val_fd[j] = -1;
  191. // }
  192. return -5;
  193. }
  194. }
  195. for (i = 0; i < GPIO_NUM_OTHER; i ++)
  196. {
  197. sprintf(path, "/sys/class/gpio/gpio%d/direction", gpio_val_other[i]);
  198. directionfd = open(path, O_RDWR);
  199. if (directionfd < 0)
  200. {
  201. printf("Cannot open GPIO%d direction!\n", gpio_val_other[i]);
  202. return -3;
  203. }
  204. write(directionfd, "out", 4);
  205. close(directionfd);
  206. }
  207. kc_pwm0_stu = 0;
  208. kc_pwm1_stu = 0;
  209. kc_kout0_stu=0;
  210. kc_kout1_stu=0;
  211. //其他与底层GPIO相关的配置再此处添加 比如 LED WATCHDOG jack.liu 202009010
  212. // write(gpio_val_fd_other[WATCHDOG], "0", 2);//TODO: 需根据实际硬件重新对应匹配
  213. // gpio_watchdog_val = 0;
  214. write(gpio_val_fd_other[RUN_LED], "0", 2);
  215. gpio_run_led_val = 0;
  216. //上电默认切换到外部232串口
  217. //后续根据投退判断是否需要切换到线损的维护口
  218. write(gpio_val_fd_other[LINE_LOSS_SET], "0", 2);
  219. //首次上电,开出合闸,会导致第六路也开出,需要初始化关闭
  220. // write(gpio_val_fd[DO_OUT1], "1", 2);
  221. #if 0 // TODO:需根据实际硬件重新对应匹配
  222. for (i = 0; i < DO_NUM; i ++)
  223. {
  224. write(gpio_val_fd[i], "1", 2);
  225. }
  226. #endif
  227. return 0;
  228. }
  229. int gpio_exit(void)
  230. {
  231. int i;
  232. int unexportfd;
  233. char num[10];
  234. unexportfd = open("/sys/class/gpio/unexport", O_WRONLY);
  235. if (unexportfd < 0)
  236. {
  237. printf("Cannot open GPIO to unexport it\n");
  238. return -1;
  239. }
  240. for (i = 0; i < DO_NUM; i ++)
  241. {
  242. if(gpio_val_fd[i] >= 0)
  243. {
  244. close(gpio_val_fd[i]);
  245. gpio_val_fd[i] = -1;
  246. }
  247. sprintf(num, "%d", gpio_val[i]);
  248. write(unexportfd, num, 4);
  249. }
  250. for (i = 0; i < GPIO_NUM_OTHER; i ++)
  251. {
  252. if(gpio_val_fd_other[i] >= 0)
  253. {
  254. close(gpio_val_fd_other[i]);
  255. gpio_val_fd_other[i] = -1;
  256. }
  257. sprintf(num, "%d", gpio_val_other[i]);
  258. write(unexportfd, num, 4);
  259. }
  260. close(unexportfd);
  261. return 0;
  262. }
  263. /******************************************************************************
  264. 函数名称: gpio_get_kin
  265. 函数版本: 01.01
  266. 创建作者: sunxi
  267. 创建日期: 2008-09-16
  268. 函数说明: 得到开入的状态。
  269. 参数说明: 无
  270. 返回值: 返回开入的状态,每个bit代表一个开入量。
  271. 修改记录:
  272. */
  273. unsigned int gpio_get_kin(unsigned int addr)
  274. {
  275. register unsigned int dw;
  276. unsigned int value[3];
  277. value[0] = *(volatile unsigned int *)addr;
  278. value[1] = *(volatile unsigned int *)addr;
  279. value[2] = *(volatile unsigned int *)addr;
  280. dw = (value[0] & value[1]) | (value[0] & value[2]) | (value[1] & value[2]);
  281. return dw;
  282. }
  283. /******************************************************************************
  284. 函数名称: gpio_get_di
  285. 函数版本: 01.01
  286. 创建作者:
  287. 创建日期: 2014-11-28
  288. 函数说明: 得到开入的状态
  289. 参数说明: 无
  290. 返回值: 返回开入的状态,每个bit代表一个开入量。
  291. 修改记录:
  292. */
  293. unsigned int gpio_get_di(void)
  294. {
  295. unsigned int dw = 0;
  296. dw = g_yx_buf[0];//这里保存的是共享内存的yx值,156us更新一次
  297. return change_di_ch(~dw);//取反---因为没有短接时,值为1. 所以要取反为0才行
  298. }
  299. /******************************************************************************
  300. 函数名称: gpio_di_fj
  301. 函数版本: 01.01
  302. 创建作者:
  303. 创建日期: 2014-11-28
  304. 函数说明: 读取开出返校遥信值,控制板遥信为YX17~YX18
  305. YX17:选择, YX18:执行
  306. 参数说明: 无
  307. 返回值: 返回遥信值
  308. 修改记录:
  309. */
  310. #ifdef DO_KOUT_CHECK
  311. unsigned short gpio_di_fj(unsigned char index)//(void)
  312. #else
  313. unsigned short gpio_di_fj(void)
  314. #endif
  315. {
  316. unsigned int di=0;
  317. unsigned short ret=0;
  318. di = gpio_get_di();
  319. #ifdef DO_KOUT_CHECK
  320. //V4-20;
  321. //ret = (unsigned short)((di >>19) & 0x0001);
  322. ret = (unsigned short)((di >>index) & 0x0001);
  323. #else
  324. ret = (unsigned short)((di >> 23) & 0x0001);//dtu
  325. #endif
  326. return ret;
  327. }
  328. static void gpio_kouten_do(int on, unsigned int kouten)
  329. {
  330. // if (kouten > KOUT_EN1)
  331. // return;
  332. // if(on)
  333. // {
  334. // write(gpio_val_fd_other[KOUT_EN0+kouten], "1", 2);
  335. // }
  336. // else
  337. // {
  338. // write(gpio_val_fd_other[KOUT_EN0+kouten], "0", 2);
  339. // }
  340. }
  341. /******************************************************************************
  342. 函数名称: gpio_kout_do
  343. 函数版本: 01.01
  344. 创建作者:
  345. 创建日期: 2014-11-28
  346. 函数说明: 开出
  347. 参数说明: on: 1开出, 0回收
  348. kout: 那一路
  349. 返回值: 无
  350. 修改记录:
  351. */
  352. void gpio_kout_do(int on, unsigned int kout)
  353. {
  354. //if (kout > (DO_NUM-DO_OUT0))
  355. // return;
  356. if(on)
  357. {
  358. if((kout==6) || (kout==7))
  359. {
  360. // gpio_kouten_do(1,KOUT_EN1);
  361. kc_kout1_stu |= (1 << kout);
  362. }
  363. else
  364. {
  365. // gpio_kouten_do(1,KOUT_EN0);
  366. kc_kout0_stu |= (1 << kout);
  367. }
  368. write(gpio_val_fd[kout+DO_OUT0], "0", 2);
  369. }
  370. else
  371. {
  372. write(gpio_val_fd[kout+DO_OUT0], "1", 2);
  373. if((kout==6) || (kout==7))
  374. {
  375. kc_kout1_stu &= ~(1 << kout);
  376. }
  377. else
  378. {
  379. kc_kout0_stu &= ~(1 << kout);
  380. }
  381. if ((kc_pwm1_stu== 0) &&(kc_kout1_stu == 0))
  382. {
  383. // gpio_kouten_do(0,KOUT_EN1);
  384. }
  385. if ((kc_kout0_stu == 0) && (kc_pwm0_stu==0))
  386. {
  387. // gpio_kouten_do(0,KOUT_EN0);
  388. }
  389. }
  390. }
  391. /******************************************************************************
  392. 函数名称: gpio_pwm_do
  393. 函数版本: 01.01
  394. 创建作者:
  395. 创建日期: 2014-11-28
  396. 函数说明: pwm开出,由于存在kc_pwm_stu,只允许在同一控制路径中开出(例如同一中断或同一线程).
  397. 参数说明: on: 1开出, 0回收
  398. 返回值: 无
  399. 修改记录:
  400. */
  401. void gpio_pwm_do(int on, unsigned int kout)
  402. {
  403. // if (kout >= DO_NUM)
  404. // return;
  405. if(on)
  406. {
  407. if((kout==0) || (kout==1))
  408. {
  409. // gpio_kouten_do(1,KOUT_EN1);
  410. kc_pwm1_stu |= (1 << kout);
  411. }
  412. else
  413. {
  414. // gpio_kouten_do(1,KOUT_EN0);
  415. kc_pwm0_stu |= (1 << kout);
  416. }
  417. write(gpio_val_fd[kout], "0", 2);
  418. }
  419. else
  420. {
  421. write(gpio_val_fd[kout], "1", 2);
  422. if((kout==0) || (kout==1))
  423. {
  424. kc_pwm1_stu &= ~(1 << kout);
  425. }
  426. else
  427. {
  428. kc_pwm0_stu &= ~(1 << kout);
  429. }
  430. if ((kc_pwm1_stu== 0) &&(kc_kout1_stu == 0))
  431. {
  432. // gpio_kouten_do(0,KOUT_EN1);
  433. }
  434. if ((kc_kout0_stu == 0) && (kc_pwm0_stu==0))
  435. {
  436. // gpio_kouten_do(0,KOUT_EN0);
  437. }
  438. }
  439. }
  440. /******************************************************************************
  441. 函数名称: gpio_get_wirelessin
  442. 函数版本: 01.01
  443. 创建作者: sunxi
  444. 创建日期: 2008-09-16
  445. 函数说明: 得到无线遥控的状态。
  446. 参数说明: 无
  447. 返回值: 返回开入的状态,每个bit代表一个开入量。
  448. 修改记录:
  449. */
  450. unsigned int gpio_get_wirelessin(void)
  451. {
  452. register unsigned int dw = 0;
  453. return dw;
  454. }
  455. unsigned int gpio_get_version(void)
  456. {
  457. register unsigned int dw = 0;
  458. return dw;
  459. }
  460. unsigned int gpio_get_addr(void)
  461. {
  462. register unsigned int dw = 0;
  463. return dw;
  464. }
  465. /******************************************************************************
  466. 函数名称: gpio_watchdog_reset
  467. 函数版本: 01.01
  468. 创建作者: sunxi
  469. 创建日期: 2008-09-16
  470. 函数说明: 复位看门狗。
  471. 参数说明: 无。
  472. 返回值: 无。
  473. 修改记录:
  474. */
  475. // void gpio_watchdog_reset(void)
  476. // {
  477. // if(gpio_watchdog_val)
  478. // {
  479. // gpio_watchdog_val = 0;
  480. // write(gpio_val_fd_other[WATCHDOG], "0", 2);
  481. // }
  482. // else
  483. // {
  484. // gpio_watchdog_val = 1;
  485. // write(gpio_val_fd_other[WATCHDOG], "1", 2);
  486. // }
  487. // return;
  488. // }
  489. void _led_run_err(void)
  490. {
  491. //运行指示灯,每隔0.5s改变状态一次
  492. if(!gpio_run_led_val)
  493. {
  494. gpio_run_led_val = 1;
  495. write(gpio_val_fd_other[RUN_LED], "0", 2);
  496. //错误指示灯,跟随RUN灯闪动
  497. if(rt_err_count())
  498. {
  499. write(gpio_val_fd_other[ERR_LED], "0", 2);
  500. }
  501. }
  502. else
  503. {
  504. gpio_run_led_val = 0;
  505. write(gpio_val_fd_other[RUN_LED], "1", 2);
  506. write(gpio_val_fd_other[ERR_LED], "1", 2);
  507. }
  508. }
  509. void esam_power_ctrl(int on)
  510. {
  511. if(on)
  512. write(gpio_val_fd_other[ESAM_PWR], "1", 2);
  513. else
  514. write(gpio_val_fd_other[ESAM_PWR], "0", 2);
  515. }
  516. /*------------------------------ 内部函数 -------------------------------------
  517. */
  518. /*------------------------------ 测试函数 -------------------------------------
  519. */
  520. #ifdef _GPIO_DEBUG
  521. #include "ustimer.h"
  522. #include "rt.h"
  523. int gpio_test(void)
  524. {
  525. int ret = 0;
  526. //unsigned int i;
  527. //gpio_kouten_do(1,KOUT_EN1);
  528. #if 1
  529. while(1)
  530. {
  531. sleep(5);
  532. gpio_kout_do(1,DO_OUT2-DO_OUT0);
  533. //gpio_kout_do(1,DO_OUT3-DO_OUT0);
  534. // gpio_pwm_do(1,DO_PWM1);
  535. sleep(5);
  536. gpio_kout_do(0,DO_OUT2-DO_OUT0);
  537. //gpio_kout_do(0,DO_OUT3-DO_OUT0);
  538. // gpio_pwm_do(0,DO_PWM1);
  539. /*
  540. for(i=DO_OUT0; i<DO_NUM; i++)
  541. {
  542. rt_printf("kout number = %d!\n\r", i);
  543. //msleep();
  544. sleep(1);
  545. gpio_kout_do(1,i-DO_OUT0);
  546. sleep(1);
  547. gpio_kout_do(0,i-DO_OUT0);
  548. }
  549. */
  550. }
  551. #endif
  552. return ret;
  553. }
  554. #endif