drv_uart.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (c) 2006-2025 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2025-05-28 ZhangJing Porting to ultrarisc dp1000
  9. */
  10. #include <rthw.h>
  11. #include <rtdevice.h>
  12. #include <rtthread.h>
  13. #include "board.h"
  14. #include "drv_uart.h"
  15. #include <stdio.h>
  16. #ifdef RT_USING_SMART
  17. #include <ioremap.h>
  18. #endif
  19. #include "sbi.h"
  20. struct device_uart
  21. {
  22. rt_ubase_t hw_base;
  23. rt_uint32_t irqno;
  24. };
  25. #ifdef BSP_USING_UART0
  26. void *uart0_base = (void *)UART0_BASE_ADDR;
  27. struct rt_serial_device serial0;
  28. struct device_uart uart0;
  29. #define UART0_CLK (UART0_REFERENCE_CLOCK)
  30. #define UART0_BAUDRATE (UART0_DEFAULT_BAUDRATE)
  31. #endif
  32. #define UART_REFERENCE_CLOCK (UART0_CLK)
  33. #define REG_SHIFT (1 << UART0_REG_SHIFT)
  34. #define write8_uart(base,idx, value) __raw_writeb(((rt_uint8_t)value), (void*)((size_t)base + (idx*REG_SHIFT)))
  35. #define read8_uart(base,idx) __raw_readb((void*)((size_t)base + (idx*REG_SHIFT)))
  36. static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  37. {
  38. struct device_uart *uart = (struct device_uart *)serial->parent.user_data;
  39. rt_uint32_t div = UART_REFERENCE_CLOCK / (cfg->baud_rate * 16);
  40. rt_uint32_t ier = read8_uart(uart->hw_base, UART_IER);
  41. write8_uart(uart->hw_base, UART_IER, 0x00);
  42. write8_uart(uart->hw_base, UART_LCR, UART_LCR_BAUD_LATCH);
  43. /* LSB */
  44. write8_uart(uart->hw_base, 0, div & 0xff);
  45. /* MSB */
  46. write8_uart(uart->hw_base, 1, (div >> 8) & 0xff);
  47. /* set word length to 8 bits, no parity */
  48. write8_uart(uart->hw_base, UART_LCR, UART_LCR_EIGHT_BITS);
  49. write8_uart(uart->hw_base, UART_FCR, UART_FCR_FIFO_ENABLE | UART_FCR_FIFO_CLEAR);
  50. write8_uart(uart->hw_base, UART_IER, ier);
  51. return (RT_EOK);
  52. }
  53. static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  54. {
  55. struct device_uart *uart = (struct device_uart *)serial->parent.user_data;
  56. switch (cmd)
  57. {
  58. case RT_DEVICE_CTRL_CLR_INT:
  59. if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
  60. {
  61. rt_uint8_t value = read8_uart(uart->hw_base, UART_IER);
  62. write8_uart(uart->hw_base, UART_IER, value & ~UART_IER_RX_ENABLE);
  63. }
  64. break;
  65. case RT_DEVICE_CTRL_SET_INT:
  66. if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
  67. {
  68. rt_uint8_t value = read8_uart(uart->hw_base, UART_IER);
  69. write8_uart(uart->hw_base, UART_IER, value | UART_IER_RX_ENABLE);
  70. }
  71. break;
  72. }
  73. return (RT_EOK);
  74. }
  75. static int _uart_putc(struct rt_serial_device *serial, char c)
  76. {
  77. struct device_uart *uart;
  78. uart = (struct device_uart *)serial->parent.user_data;
  79. /* wait for Transmit Holding Empty to be set in LSR. */
  80. while ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_TX_IDLE) == 0)
  81. ;
  82. write8_uart(uart->hw_base, UART_THR, c);
  83. return (1);
  84. }
  85. static int _uart_getc(struct rt_serial_device *serial)
  86. {
  87. struct device_uart *uart;
  88. volatile rt_uint32_t lsr;
  89. int ch = -1;
  90. uart = (struct device_uart *)serial->parent.user_data;
  91. lsr = read8_uart(uart->hw_base, UART_LSR);
  92. if (lsr & UART_LSR_RX_READY)
  93. {
  94. ch = read8_uart(uart->hw_base, UART_RHR);
  95. }
  96. return ch;
  97. }
  98. const struct rt_uart_ops _uart_ops =
  99. {
  100. _uart_configure,
  101. _uart_control,
  102. _uart_putc,
  103. _uart_getc,
  104. /* TODO: add DMA support */
  105. RT_NULL
  106. };
  107. static void rt_hw_uart_isr(int irqno, void *param)
  108. {
  109. rt_ubase_t level = rt_hw_interrupt_disable();
  110. struct rt_serial_device *serial = (struct rt_serial_device *)param;
  111. struct device_uart *uart = (struct device_uart *)serial->parent.user_data;
  112. if ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_RX_READY) != 0)
  113. {
  114. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  115. }
  116. rt_hw_interrupt_enable(level);
  117. return;
  118. }
  119. /*
  120. * UART Initiation
  121. */
  122. int rt_hw_uart_init(void)
  123. {
  124. struct rt_serial_device *serial;
  125. struct device_uart *uart;
  126. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  127. char ch;
  128. #ifdef BSP_USING_UART0
  129. /* register device */
  130. serial = &serial0;
  131. uart = &uart0;
  132. serial->ops = &_uart_ops;
  133. serial->config = config;
  134. serial->config.baud_rate = UART0_BAUDRATE;
  135. uart->hw_base = (rt_ubase_t)uart0_base;
  136. #ifdef RT_USING_SMART
  137. uart->hw_base = (rt_ubase_t)rt_ioremap((void *)uart0_base, 0x1000);
  138. #endif
  139. uart->irqno = UART0_IRQ_BASE;
  140. /* disable all uart irqs */
  141. write8_uart(uart->hw_base, UART_IER, 0);
  142. /* wait for Transmit Holding Empty to be set in LSR. */
  143. while ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_TX_IDLE) == 0)
  144. ;
  145. while ((read8_uart(uart->hw_base, UART_LSR) & UART_LSR_RX_READY) != 0)
  146. {
  147. ch = read8_uart(uart->hw_base, UART_RHR);
  148. }
  149. rt_hw_serial_register(serial,
  150. RT_CONSOLE_DEVICE_NAME,
  151. RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  152. uart);
  153. rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, RT_CONSOLE_DEVICE_NAME);
  154. rt_hw_interrupt_umask(uart->irqno);
  155. #endif
  156. }