uart.c 8.1 KB

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