uart.c 12 KB

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