uart.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /**
  3. ******************************************************************************
  4. * @file uart.c
  5. * @author StarFive Technology
  6. * @version V1.0
  7. * @date 07/24/2020
  8. * @brief
  9. ******************************************************************************
  10. * @copy
  11. *
  12. * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  13. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  14. * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
  15. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  16. * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  17. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
  20. */
  21. #include <stdarg.h>
  22. #include <comdef.h>
  23. #include <uart.h>
  24. #include <sys.h>
  25. #include <ezGPIO_fullMux_ctrl_macro.h>
  26. #include <clkgen_ctrl_macro.h>
  27. #include <rstgen_ctrl_macro.h>
  28. #include <vic_module_reset_clkgen.h>
  29. #define UART_CLK (100000000UL)
  30. /* CLK 32M */
  31. #define UART_BUADRATE_32MCLK_9600 9600
  32. #define UART_BUADRATE_32MCLK_57600 57600
  33. #define UART_BUADRATE_32MCLK_115200 115200
  34. #define UART_BUADRATE_32MCLK_125000 125000
  35. #define UART_BUADRATE_32MCLK_222222 222222 ///230400
  36. #define UART_BUADRATE_32MCLK_333333 333333 ///380400
  37. #define UART_BUADRATE_32MCLK_400000 400000 ///460800
  38. #define UART_BUADRATE_32MCLK_500000 500000
  39. #define UART_BUADRATE_32MCLK_666666 666666 ///921600
  40. #define UART_BUADRATE_32MCLK_1M 1000000
  41. #define UART_BUADRATE_32MCLK_2M 2000000
  42. /* CLK 64M */
  43. #define UART_BUADRATE_64MCLK_38400 38400
  44. #define UART_BUADRATE_64MCLK_57600 57600
  45. #define UART_BUADRATE_64MCLK_115200 115200
  46. #define UART_BUADRATE_64MCLK_230400 230400
  47. #define UART_BUADRATE_64MCLK_380400 380400
  48. #define UART_BUADRATE_64MCLK_444444 444444 ///460800
  49. #define UART_BUADRATE_64MCLK_500000 500000
  50. #define UART_BUADRATE_64MCLK_571428 571428
  51. #define UART_BUADRATE_64MCLK_666666 666666 ///921600
  52. #define UART_BUADRATE_64MCLK_800000 800000 ///921600
  53. #define UART_BUADRATE_64MCLK_1M 1000000
  54. #define UART_BUADRATE_64MCLK_2M 2000000
  55. ////#define UART_BUADRATE_2_5M 2500000 ///
  56. ////#define UART_BUADRATE_3M 3000000 ///
  57. #define UART_BUADRATE_64MCLK_4M 4000000 ///shiboqi
  58. unsigned int uart_id=0;
  59. static const u64 uart_base[4] = {
  60. UART0_HS_BASE_ADDR,
  61. UART1_HS_BASE_ADDR,
  62. UART2_BASE_ADDR,
  63. UART3_BASE_ADDR,
  64. };
  65. static unsigned int serial_in(int offset)
  66. {
  67. offset <<= 2;
  68. return readl((volatile void *)(uart_base[uart_id] + offset));
  69. }
  70. static void serial_out(int offset, int value)
  71. {
  72. offset <<= 2;
  73. writel(value, (volatile void *)(uart_base[uart_id] + offset));
  74. }
  75. int __serial_tstc()
  76. {
  77. return ((serial_in(REG_LSR)) & (1 << 0));
  78. }
  79. int serial_tstc()
  80. {
  81. return __serial_tstc();
  82. }
  83. void uart_init(int id)
  84. {
  85. unsigned int divisor;
  86. unsigned char lcr_cache;
  87. #if 0 //repeat init
  88. switch(id)
  89. {
  90. case 0:
  91. vic_uart0_reset_clk_gpio_misc_enable;
  92. break;
  93. case 1:
  94. vic_uart1_reset_clk_gpio_misc_enable;
  95. break;
  96. case 2:
  97. vic_uart2_reset_clk_gpio_misc_enable
  98. break;
  99. case 3:
  100. _ENABLE_CLOCK_clk_uart3_apb_;
  101. _ENABLE_CLOCK_clk_uart3_core_;
  102. _ASSERT_RESET_rstgen_rstn_uart3_apb_;
  103. _ASSERT_RESET_rstgen_rstn_uart3_core_;
  104. _CLEAR_RESET_rstgen_rstn_uart3_core_;
  105. _CLEAR_RESET_rstgen_rstn_uart3_apb_;
  106. SET_GPIO_14_dout_uart3_pad_sout;
  107. SET_GPIO_14_doen_LOW;
  108. SET_GPIO_13_doen_HIGH;
  109. SET_GPIO_uart3_pad_sin(13);
  110. break;
  111. default:
  112. return;
  113. }
  114. #endif
  115. uart_id = id;
  116. divisor = (UART_CLK / UART_BUADRATE_32MCLK_115200) >> 4;
  117. lcr_cache = serial_in(REG_LCR);
  118. serial_out(REG_LCR, (LCR_DLAB | lcr_cache));
  119. serial_out(REG_BRDL,(unsigned char)(divisor & 0xff));
  120. serial_out(REG_BRDH,(unsigned char)((divisor >> 8) & 0xff));
  121. /* restore the DLAB to access the baud rate divisor registers */
  122. serial_out(REG_LCR, lcr_cache);
  123. /* 8 data bits, 1 stop bit, no parity, clear DLAB */
  124. serial_out(REG_LCR, (LCR_CS8 | LCR_1_STB | LCR_PDIS));
  125. serial_out(REG_MDC, 0); /*disable flow control*/
  126. /*
  127. * Program FIFO: enabled, mode 0 (set for compatibility with quark),
  128. * generate the interrupt at 8th byte
  129. * Clear TX and RX FIFO
  130. */
  131. serial_out(REG_FCR, (FCR_FIFO | FCR_MODE1 | /*FCR_FIFO_1*/FCR_FIFO_8 | FCR_RCVRCLR | FCR_XMITCLR));
  132. serial_out(REG_IER, 0);//dis the ser interrupt
  133. }
  134. int _putc(char c) {
  135. do
  136. {}while((serial_in(REG_LSR) & LSR_THRE) == 0);
  137. serial_out(REG_THR, c);
  138. return 0;
  139. }
  140. void rlSendString(char *s)
  141. {
  142. while (*s){
  143. _putc(*s++);
  144. }
  145. }
  146. int CtrlBreak( void )
  147. {
  148. int retflag;
  149. do{
  150. retflag = serial_getc();
  151. if( retflag == 0x03 ){
  152. break;
  153. }
  154. }while( retflag );
  155. return retflag;
  156. }
  157. int serial_getc()
  158. {
  159. /* Wait here until the the FIFO is not full */
  160. while (!(serial_in(REG_LSR) & (1 << 0))){};
  161. return serial_in(REG_RDR);
  162. }
  163. void serial_gets(char *pstr)
  164. {
  165. char c;
  166. char *pstrorg;
  167. pstrorg = (char *) pstr;
  168. while ((c = (char)serial_getc()) != '\r')
  169. {
  170. if (c == '\b'){
  171. if (pstrorg < pstr){
  172. rlSendString("\b \b");
  173. pstr--;
  174. }
  175. }else{
  176. *pstr++ = c;
  177. _putc(c);
  178. }
  179. }
  180. *pstr = '\0';
  181. rlSendString("\r\n");
  182. }
  183. void _puts(const char * s) {
  184. while (*s != '\0'){
  185. _putc(*s++);
  186. }
  187. }
  188. void print_ubyte_hex(unsigned char bval)
  189. {
  190. static const char digits[16] = "0123456789ABCDEF";
  191. char tmp[2];
  192. int dig=0;
  193. dig = ((bval&0xf0)>>4);
  194. tmp[0] = digits[dig];
  195. dig = (bval&0x0f);
  196. tmp[1] = digits[dig];
  197. _putc(tmp[0]);
  198. _putc(tmp[1]);
  199. }
  200. int serial_nowait_getc()
  201. {
  202. unsigned int status;
  203. status = serial_in(REG_LSR);
  204. if (!(status & (1 << 0))) {
  205. status = 0;//NO_POLL_CHAR;
  206. goto out;
  207. }
  208. status = serial_in(REG_RDR);
  209. out:
  210. return status;
  211. }
  212. #if 1
  213. int vnprintf(char* out, size_t n, const char* s, va_list vl)
  214. {
  215. bool format = false;
  216. bool longarg = false;
  217. size_t pos = 0;
  218. for( ; *s; s++)
  219. {
  220. if(format)
  221. {
  222. switch(*s)
  223. {
  224. case 'l':
  225. longarg = true;
  226. break;
  227. case 'p':
  228. longarg = true;
  229. if (++pos < n) out[pos-1] = '0';
  230. if (++pos < n) out[pos-1] = 'x';
  231. case 'x':
  232. {
  233. long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
  234. for(int i = 2*(longarg ? sizeof(long) : sizeof(int))-1; i >= 0; i--) {
  235. int d = (num >> (4*i)) & 0xF;
  236. if (++pos < n) out[pos-1] = (d < 10 ? '0'+d : 'a'+d-10);
  237. }
  238. longarg = false;
  239. format = false;
  240. break;
  241. }
  242. case 'd':
  243. {
  244. long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
  245. if (num < 0) {
  246. num = -num;
  247. if (++pos < n) out[pos-1] = '-';
  248. }
  249. long digits = 1;
  250. for (long nn = num; nn /= 10; digits++)
  251. ;
  252. for (int i = digits-1; i >= 0; i--) {
  253. if (pos + i + 1 < n) out[pos + i] = '0' + (num % 10);
  254. num /= 10;
  255. }
  256. pos += digits;
  257. longarg = false;
  258. format = false;
  259. break;
  260. }
  261. case 's':
  262. {
  263. const char* s2 = va_arg(vl, const char*);
  264. while (*s2) {
  265. if (++pos < n)
  266. out[pos-1] = *s2;
  267. s2++;
  268. }
  269. longarg = false;
  270. format = false;
  271. break;
  272. }
  273. case 'c':
  274. {
  275. if (++pos < n) out[pos-1] = (char)va_arg(vl,int);
  276. longarg = false;
  277. format = false;
  278. break;
  279. }
  280. default:
  281. break;
  282. }
  283. }
  284. else if(*s == '%')
  285. format = true;
  286. else
  287. if (++pos < n) out[pos-1] = *s;
  288. }
  289. if (pos < n)
  290. out[pos] = 0;
  291. else if (n)
  292. out[n-1] = 0;
  293. return pos;
  294. }
  295. static void vprintk(const char* s, va_list vl)
  296. {
  297. char out[256];
  298. int res = vnprintf(out, sizeof(out), s, vl);
  299. _puts(out);
  300. }
  301. void printk(const char* s, ...)
  302. {
  303. va_list vl;
  304. va_start(vl, s);
  305. vprintk(s, vl);
  306. va_end(vl);
  307. }
  308. #endif
  309. int _inbyte(unsigned short timeout) // msec timeout
  310. {
  311. unsigned int c;
  312. unsigned int delay = timeout*20;
  313. while (!(serial_in(REG_LSR) & LSR_RXRDY)) {
  314. udelay(50);
  315. if (timeout && (--delay == 0)) {
  316. return -1;
  317. }
  318. }
  319. c = serial_in(REG_RDR);
  320. return c;
  321. }
  322. void _outbyte(int c)
  323. {
  324. while(!(serial_in(REG_LSR) & LSR_TEMT))
  325. ;
  326. serial_out(REG_THR, c);
  327. }