uart.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /*************************************************************************
  2. > File Name: uart.c
  3. > Created Time: Fri 23 Oct 2020 11:02:21 AM CST
  4. ************************************************************************/
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <unistd.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <termios.h>
  12. #include <limits.h>
  13. #include <errno.h>
  14. #include <stdio.h>
  15. #include <stdint.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <unistd.h>
  19. #include "bsp.h"
  20. #include "rt.h"
  21. #include "uart_user.h"
  22. #define UART_MAX_FD 256 //noted by sunxi: 因为传进来的UART_CHANNEL[i]不一定是连续的。
  23. //static int am335x_uarts_fd[CFG_UART_NUM_MAX];
  24. static int am335x_uarts_fd[UART_MAX_FD] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  25. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  26. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  27. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  28. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  29. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  30. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  31. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  32. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  33. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  34. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  35. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  36. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  37. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  38. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  39. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,};
  40. static void am335x_uarts_init(int channel)
  41. {
  42. am335x_uarts_fd[channel] = -1;
  43. }
  44. static int set_port(int fd, int nSpeed, int nBits, char nEvent, int nStop)
  45. {
  46. struct termios newtio, oldtio;
  47. memset(&oldtio, 0, sizeof(oldtio));
  48. /* save the old serial port configuration */
  49. if(tcgetattr(fd, &oldtio) != 0) {
  50. perror("set_port/tcgetattr");
  51. return -1;
  52. }
  53. memset(&newtio, 0, sizeof(newtio));
  54. /* ignore modem control lines and enable receiver */
  55. newtio.c_cflag |= CLOCAL | CREAD;
  56. newtio.c_cflag &= ~CSIZE;
  57. /* set character size */
  58. switch (nBits) {
  59. case 8:
  60. newtio.c_cflag |= CS8;
  61. break;
  62. case 7:
  63. newtio.c_cflag |= CS7;
  64. break;
  65. case 6:
  66. newtio.c_cflag |= CS6;
  67. break;
  68. case 5:
  69. newtio.c_cflag |= CS5;
  70. break;
  71. default:
  72. newtio.c_cflag |= CS8;
  73. break;
  74. }
  75. /* set the parity */
  76. switch (nEvent) {
  77. default:
  78. case 'N':
  79. case 'n':
  80. {
  81. newtio.c_cflag &= ~PARENB; //清除校验位
  82. newtio.c_iflag &= ~(ICRNL|INPCK|IXON|IXOFF); //关闭奇偶校验 关闭软件流控
  83. break;
  84. }
  85. case 'o':
  86. case 'O':
  87. {
  88. newtio.c_cflag |= (PARODD | PARENB); //使用奇校验不是用偶校验
  89. newtio.c_iflag |= INPCK;
  90. break;
  91. }
  92. case 'e':
  93. case 'E':
  94. {
  95. newtio.c_cflag |= PARENB;
  96. newtio.c_cflag &= ~PARODD; //使用偶校验
  97. newtio.c_iflag |= INPCK;
  98. break;
  99. }
  100. case 's':
  101. case 'S':
  102. {
  103. newtio.c_cflag &= ~PARENB;
  104. newtio.c_cflag &= ~CSTOPB;
  105. break;
  106. }
  107. }
  108. /* set the stop bits */
  109. switch (nStop) {
  110. case 1:
  111. newtio.c_cflag &= ~CSTOPB;
  112. break;
  113. case 2:
  114. newtio.c_cflag |= CSTOPB;
  115. break;
  116. default:
  117. newtio.c_cflag &= ~CSTOPB;
  118. break;
  119. }
  120. /* set output and input baud rate */
  121. switch (nSpeed) {
  122. case 0:
  123. cfsetospeed(&newtio, B0);
  124. cfsetispeed(&newtio, B0);
  125. break;
  126. case 50:
  127. cfsetospeed(&newtio, B50);
  128. cfsetispeed(&newtio, B50);
  129. break;
  130. case 75:
  131. cfsetospeed(&newtio, B75);
  132. cfsetispeed(&newtio, B75);
  133. break;
  134. case 110:
  135. cfsetospeed(&newtio, B110);
  136. cfsetispeed(&newtio, B110);
  137. break;
  138. case 134:
  139. cfsetospeed(&newtio, B134);
  140. cfsetispeed(&newtio, B134);
  141. break;
  142. case 150:
  143. cfsetospeed(&newtio, B150);
  144. cfsetispeed(&newtio, B150);
  145. break;
  146. case 200:
  147. cfsetospeed(&newtio, B200);
  148. cfsetispeed(&newtio, B200);
  149. break;
  150. case 300:
  151. cfsetospeed(&newtio, B300);
  152. cfsetispeed(&newtio, B300);
  153. break;
  154. case 600:
  155. cfsetospeed(&newtio, B600);
  156. cfsetispeed(&newtio, B600);
  157. break;
  158. case 1200:
  159. cfsetospeed(&newtio, B1200);
  160. cfsetispeed(&newtio, B1200);
  161. break;
  162. case 1800:
  163. cfsetospeed(&newtio, B1800);
  164. cfsetispeed(&newtio, B1800);
  165. break;
  166. case 2400:
  167. cfsetospeed(&newtio, B2400);
  168. cfsetispeed(&newtio, B2400);
  169. break;
  170. case 4800:
  171. cfsetospeed(&newtio, B4800);
  172. cfsetispeed(&newtio, B4800);
  173. break;
  174. case 9600:
  175. cfsetospeed(&newtio, B9600);
  176. cfsetispeed(&newtio, B9600);
  177. break;
  178. case 19200:
  179. cfsetospeed(&newtio, B19200);
  180. cfsetispeed(&newtio, B19200);
  181. break;
  182. case 38400:
  183. cfsetospeed(&newtio, B38400);
  184. cfsetispeed(&newtio, B38400);
  185. break;
  186. case 57600:
  187. cfsetospeed(&newtio, B57600);
  188. cfsetispeed(&newtio, B57600);
  189. break;
  190. case 115200:
  191. cfsetospeed(&newtio, B115200);
  192. cfsetispeed(&newtio, B115200);
  193. break;
  194. case 230400:
  195. cfsetospeed(&newtio, B230400);
  196. cfsetispeed(&newtio, B230400);
  197. break;
  198. default:
  199. cfsetospeed(&newtio, B115200);
  200. cfsetispeed(&newtio, B115200);
  201. break;
  202. }
  203. /* set timeout in deciseconds for non-canonical read */
  204. newtio.c_cc[VTIME] = 0;
  205. /* set minimum number of characters for non-canonical read */
  206. newtio.c_cc[VMIN] = 0;
  207. /* flushes data received but not read */
  208. tcflush(fd, TCIFLUSH);
  209. /* set the parameters associated with the terminal from
  210. the termios structure and the change occurs immediately */
  211. if((tcsetattr(fd, TCSANOW, &newtio))!=0)
  212. {
  213. perror("set_port/tcsetattr");
  214. return -1;
  215. }
  216. return 0;
  217. }
  218. int uart_open(int channel, uint32_t baudRate, int setting)
  219. {
  220. /*
  221. * Initialize UART for serial communications
  222. */
  223. char tty_name[16] = {0x00};
  224. int ret;
  225. char parity;
  226. if(channel > (UART_MAX_FD - 1) || channel < 0)
  227. {
  228. return -1;
  229. }
  230. if (am335x_uarts_fd[channel] < 0)
  231. {
  232. am335x_uarts_init(channel);
  233. memset(tty_name,0,sizeof(tty_name));
  234. sprintf(tty_name, "/dev/ttyAS%d", channel); //sprintf(tty_name, "/dev/ttyO%d", channel); by ygl 2025.6.13
  235. am335x_uarts_fd[channel] = open(tty_name, O_RDWR, 0);
  236. if(am335x_uarts_fd[channel] < 0)
  237. {
  238. printf("inside open %s failed!\n", tty_name);
  239. return am335x_uarts_fd[channel];
  240. }
  241. }
  242. switch(setting)
  243. {
  244. case PARITY_EVEN://偶校验
  245. parity = 'E';
  246. break;
  247. case PARITY_ODD://奇校验
  248. parity = 'O';
  249. break;
  250. case PARITY_NONE://无校验
  251. default:
  252. parity = 'N';
  253. break;
  254. }
  255. ret = set_port(am335x_uarts_fd[channel], baudRate, 8, parity, 1);
  256. if(ret < 0)
  257. {
  258. close(am335x_uarts_fd[channel]);
  259. perror("set_port failed");
  260. return -2;
  261. }
  262. return 0;
  263. }
  264. void uart_close(int channel)
  265. {
  266. if(channel > (UART_MAX_FD - 1))
  267. {
  268. return;
  269. }
  270. if(am335x_uarts_fd[channel] >= 0)
  271. {
  272. close(am335x_uarts_fd[channel]);
  273. am335x_uarts_fd[channel] = -1;
  274. }
  275. }
  276. int uart_write(int channel, const char *data, int count)
  277. {
  278. int ret;
  279. if((channel > (UART_MAX_FD - 1)) || (data == NULL))
  280. return -1;
  281. if(am335x_uarts_fd[channel] < 0)
  282. return -2;
  283. ret = write(am335x_uarts_fd[channel], data, count);
  284. return ret;
  285. }
  286. void uart_puts (int channel, char *ch)
  287. {
  288. int write_len;
  289. if(ch == NULL)
  290. return;
  291. write_len = strlen(ch);
  292. uart_write(channel, (const char *)ch, write_len);
  293. }
  294. int uart_read(int channel, char *data, int count)
  295. {
  296. int ret;
  297. if((channel > (UART_MAX_FD - 1)) || (data == NULL))
  298. return -1;
  299. if(am335x_uarts_fd[channel] < 0)
  300. return -2;
  301. ret = read(am335x_uarts_fd[channel], data, count);
  302. return ret;
  303. }
  304. //noted by sunxi: 这个是read的select.
  305. int uart_select(int channel)
  306. {
  307. int ret;
  308. struct timeval tv;
  309. fd_set rset;
  310. tv.tv_sec = 0;
  311. tv.tv_usec = 10000;
  312. if(channel > (UART_MAX_FD - 1))
  313. return -1;
  314. if(am335x_uarts_fd[channel] < 0)
  315. return -2;
  316. FD_ZERO(&rset);
  317. FD_SET(am335x_uarts_fd[channel], &rset);
  318. ret = select(am335x_uarts_fd[channel]+1, &rset, NULL, NULL, &tv);
  319. return ret;
  320. }
  321. /********************************************************************/
  322. /*
  323. * Wait for a character to be received on the specified UART
  324. *
  325. * Return Values:
  326. * the received character
  327. */
  328. char uart_getchar (int channel)
  329. {
  330. return 0;
  331. }
  332. int uart_getchar2 (int channel,char *ch)
  333. {
  334. int ret = uart_read(channel, ch, 1);
  335. return ret;
  336. }
  337. /********************************************************************/
  338. /*
  339. * Wait for space in the UART Tx FIFO and then send a character
  340. */
  341. void uart_putchar (int channel, char ch)
  342. {
  343. }
  344. void uart_putchar2 (int channel, char ch)
  345. {
  346. uart_write(channel, (const char *)&ch, 1);
  347. }
  348. int uart_init(void)
  349. {
  350. int i, ret;
  351. for(i = 0; i < CFG_UART_NUM_MAX; i++)
  352. {
  353. if((UART_CHANNEL[i]==g_con_uart_index) || (UART_CHANNEL[i]==CFG_UART_HMI))
  354. {
  355. continue;
  356. }
  357. ret = uart_open(i,115200,PARITY_NONE);
  358. if (ret < 0)
  359. {
  360. #ifdef UART_DEBUG
  361. printf("%s: outside uart %d open failed!\n", __FUNCTION__, i);
  362. #endif
  363. }
  364. else
  365. {
  366. #ifdef UART_DEBUG
  367. printf("%s: outside uart %d open success!\n", __FUNCTION__, i);
  368. #endif
  369. }
  370. }
  371. return 0;
  372. }
  373. void uart_exit(void)
  374. {
  375. int i;
  376. printf("uart_exit\n");//sunxi for test
  377. for(i = 0; i < CFG_UART_NUM_MAX; i++)
  378. {
  379. if((UART_CHANNEL[i]==g_con_uart_index) || (UART_CHANNEL[i]==CFG_UART_HMI))
  380. {
  381. continue;
  382. }
  383. uart_close(i);
  384. }
  385. }
  386. int uart_test(void)
  387. {
  388. char tmp[] = "hello sunxi!";
  389. // u8 c;
  390. int ret;
  391. static unsigned char buf[256];
  392. static int ret_cnt =0;
  393. int i;
  394. uart_open(1,9600,PARITY_EVEN);
  395. uart_write(1, (const char *)&tmp, strlen(tmp));
  396. for(i = 0; i < 500; i++)
  397. {
  398. ret = uart_select(1);
  399. //有数据可读
  400. if(ret > 0)
  401. {
  402. printf("\nch_%d have select.",1);
  403. //读取数据
  404. memset(buf,0,sizeof(buf));
  405. ret = uart_read(1, buf, sizeof(buf));
  406. if(ret != -1)
  407. {
  408. //测试代码
  409. printf("\nch_%d RECV num=%d:",1,ret);
  410. for(i = 0; i < ret; i++)
  411. {
  412. printf("%02x ", (unsigned char)buf[i]);
  413. }
  414. printf("\n");
  415. if(++ret_cnt >= 3)
  416. {
  417. ret_cnt = 0;
  418. uart_write(1, buf, ret);
  419. }
  420. }
  421. }
  422. }
  423. return 0;
  424. }