uart.c 9.8 KB

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