uart.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <nds32_intrinsic.h>
  2. #define DEFAULT_BAUDRATE 115200 /* 8n1 */
  3. #define IN8(reg) (uint8_t)((*(volatile unsigned long *)(reg)) & 0x000000FF)
  4. #define READ_CLR(reg) (*(volatile unsigned long *)(reg))
  5. int drv_uart_set_baudrate(int baudrate)
  6. {
  7. unsigned long baud_div; /* baud rate divisor */
  8. unsigned long temp_word;
  9. baud_div = (MB_UCLK / (16 * baudrate));
  10. /* Save LCR temporary */
  11. temp_word = IN8(STUARTC_BASE + UARTC_LCR_OFFSET);
  12. /* Setup dlab bit for baud rate setting */
  13. OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, (temp_word | UARTC_LCR_DLAB));
  14. /* Apply baud rate */
  15. OUT8(STUARTC_BASE + UARTC_DLM_OFFSET, (unsigned char)(baud_div >> 8));
  16. OUT8(STUARTC_BASE + UARTC_DLL_OFFSET, (unsigned char)baud_div);
  17. OUT8(STUARTC_BASE + UARTC_PSR_OFFSET, (unsigned char)1);
  18. /* Restore LCR */
  19. OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, temp_word);
  20. return 0;
  21. }
  22. int drv_uart_is_kbd_hit(void)
  23. {
  24. return IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_RDR;
  25. }
  26. int drv_uart_get_char(void)
  27. {
  28. while (!(IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_RDR))
  29. ;
  30. return IN8(STUARTC_BASE + UARTC_RBR_OFFSET);
  31. }
  32. void drv_uart_put_char(int ch)
  33. {
  34. while (!(IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_THRE))
  35. ;
  36. OUT8(STUARTC_BASE + UARTC_THR_OFFSET, ch);
  37. }
  38. int drv_uart_init(void)
  39. {
  40. /* Clear everything */
  41. OUT8(STUARTC_BASE + UARTC_IER_OFFSET, 0x0);
  42. OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, 0x0);
  43. /* Setup baud rate */
  44. drv_uart_set_baudrate(DEFAULT_BAUDRATE);
  45. /* Setup parity, data bits, and stop bits */
  46. OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, \
  47. (UARTC_LCR_PARITY_NONE | UARTC_LCR_BITS8 | UARTC_LCR_STOP1));
  48. return 0;
  49. }
  50. /**********************************************
  51. *
  52. * Archer Chang
  53. *
  54. * driver API with reg base
  55. *
  56. ***********************************************/
  57. int __drv_uart_set_baudrate(unsigned int regbase, int baudrate)
  58. {
  59. unsigned long baud_div; /* baud rate divisor */
  60. unsigned long temp_word;
  61. baud_div = (MB_UCLK / (16 * baudrate));
  62. /* Save LCR temporary */
  63. temp_word = IN8(regbase + UARTC_LCR_OFFSET);
  64. /* Setup dlab bit for baud rate setting */
  65. OUT8(regbase + UARTC_LCR_OFFSET, (temp_word | UARTC_LCR_DLAB));
  66. /* Apply baud rate */
  67. OUT8(regbase + UARTC_DLM_OFFSET, (unsigned char)(baud_div >> 8));
  68. OUT8(regbase + UARTC_DLL_OFFSET, (unsigned char)baud_div);
  69. OUT8(regbase + UARTC_PSR_OFFSET, (unsigned char)1);
  70. /* Restore LCR */
  71. OUT8(regbase + UARTC_LCR_OFFSET, temp_word);
  72. return 0;
  73. }
  74. int __drv_uart_is_kbd_hit(unsigned int regbase)
  75. {
  76. return IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_RDR;
  77. }
  78. int __drv_uart_get_char(unsigned int regbase)
  79. {
  80. while (!(IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_RDR))
  81. ;
  82. return IN8(regbase + UARTC_RBR_OFFSET);
  83. }
  84. void __drv_uart_put_char(unsigned int regbase, int ch)
  85. {
  86. while (!(IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_THRE))
  87. ;
  88. OUT8(regbase + UARTC_THR_OFFSET, ch);
  89. }
  90. int __drv_uart_put_char_nowait(unsigned int regbase, int ch)
  91. {
  92. OUT8(regbase + UARTC_THR_OFFSET, ch);
  93. return 1;
  94. }
  95. int __drv_uart_init(unsigned int regbase, int baudrate)
  96. {
  97. /* Clear everything */
  98. OUT8(regbase + UARTC_IER_OFFSET, 0x0);
  99. OUT8(regbase + UARTC_LCR_OFFSET, 0x0);
  100. /* Setup baud rate */
  101. __drv_uart_set_baudrate(regbase, baudrate);
  102. /* Setup parity, data bits, and stop bits */
  103. OUT8(regbase + UARTC_LCR_OFFSET, \
  104. (UARTC_LCR_PARITY_NONE | UARTC_LCR_BITS8 | UARTC_LCR_STOP1));
  105. return 0;
  106. }