drv_uart.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-05-20 bigmagic first version
  9. */
  10. #include <rthw.h>
  11. #include <rtdevice.h>
  12. #include "board.h"
  13. #include "drv_uart.h"
  14. #include <stdio.h>
  15. #include "sbi.h"
  16. #include "interrupt.h"
  17. struct device_uart
  18. {
  19. rt_ubase_t hw_base;
  20. rt_uint32_t irqno;
  21. };
  22. static rt_err_t rt_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
  23. static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg);
  24. static int drv_uart_putc(struct rt_serial_device *serial, char c);
  25. static int drv_uart_getc(struct rt_serial_device *serial);
  26. void virt_uart_init(void)
  27. {
  28. //http://byterunner.com/16550.html
  29. uart_write_reg(IER, 0x00);
  30. uint8_t lcr = uart_read_reg(LCR);
  31. uart_write_reg(LCR, lcr | (1 << 7));
  32. uart_write_reg(DLL, 0x03);
  33. uart_write_reg(DLM, 0x00);
  34. lcr = 0;
  35. uart_write_reg(LCR, lcr | (3 << 0));
  36. /*
  37. * enable receive interrupts.
  38. */
  39. uint8_t ier = uart_read_reg(IER);
  40. uart_write_reg(IER, ier | (1 << 0));
  41. }
  42. /*
  43. * UART interface
  44. */
  45. static rt_err_t rt_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  46. {
  47. struct device_uart *uart;
  48. RT_ASSERT(serial != RT_NULL);
  49. serial->config = *cfg;
  50. return (RT_EOK);
  51. }
  52. static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  53. {
  54. struct device_uart *uart;
  55. uart = serial->parent.user_data;
  56. rt_uint32_t channel = 1;
  57. RT_ASSERT(uart != RT_NULL);
  58. RT_ASSERT(channel != 3);
  59. switch (cmd)
  60. {
  61. case RT_DEVICE_CTRL_CLR_INT:
  62. break;
  63. case RT_DEVICE_CTRL_SET_INT:
  64. break;
  65. }
  66. return (RT_EOK);
  67. }
  68. static int drv_uart_putc(struct rt_serial_device *serial, char c)
  69. {
  70. while ((uart_read_reg(LSR) & LSR_TX_IDLE) == 0);
  71. return uart_write_reg(THR, c);
  72. }
  73. static int drv_uart_getc(struct rt_serial_device *serial)
  74. {
  75. if (uart_read_reg(LSR) & LSR_RX_READY){
  76. return uart_read_reg(RHR);
  77. } else {
  78. return -1;
  79. }
  80. //return sbi_console_getchar();
  81. }
  82. static void rt_hw_uart_isr(int irqno, void *param)
  83. {
  84. struct rt_serial_device *serial = (struct rt_serial_device*)param;
  85. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  86. }
  87. struct rt_serial_device serial1;
  88. struct device_uart uart1;
  89. const struct rt_uart_ops _uart_ops =
  90. {
  91. rt_uart_configure,
  92. uart_control,
  93. drv_uart_putc,
  94. drv_uart_getc,
  95. RT_NULL
  96. };
  97. /*
  98. * UART Initiation
  99. */
  100. int rt_hw_uart_init(void)
  101. {
  102. struct rt_serial_device *serial;
  103. struct device_uart *uart;
  104. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  105. {
  106. serial = &serial1;
  107. uart = &uart1;
  108. serial->ops = &_uart_ops;
  109. serial->config = config;
  110. serial->config.baud_rate = UART_DEFAULT_BAUDRATE;
  111. uart->hw_base = UART_BASE;
  112. uart->irqno = UART0_IRQ;
  113. virt_uart_init();
  114. rt_hw_serial_register(serial,
  115. "uart",
  116. RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  117. uart);
  118. rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, "uart");
  119. rt_hw_interrupt_umask(uart->irqno);
  120. }
  121. return 0;
  122. }