uart.c 8.4 KB

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