serial.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * COPYRIGHT (C) 2018, Real-Thread Information Technology Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. * Change Logs:
  6. * Date Author Notes
  7. * 2013-03-30 Bernard the first verion
  8. */
  9. #include <rthw.h>
  10. #include <registers/regsuart.h>
  11. #include <imx_uart.h>
  12. #include <rtdevice.h>
  13. #include "serial.h"
  14. struct hw_uart_device
  15. {
  16. uint32_t instance;
  17. int irqno;
  18. };
  19. static void rt_hw_uart_isr(int irqno, void *param)
  20. {
  21. struct rt_serial_device *serial = (struct rt_serial_device *)param;
  22. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  23. }
  24. static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  25. {
  26. struct hw_uart_device *uart;
  27. uint32_t baudrate;
  28. uint8_t parity, stopbits, datasize, flowcontrol;
  29. RT_ASSERT(serial != RT_NULL);
  30. uart = (struct hw_uart_device *)serial->parent.user_data;
  31. baudrate = cfg->baud_rate;
  32. switch (cfg->data_bits)
  33. {
  34. case DATA_BITS_8:
  35. datasize = EIGHTBITS;
  36. break;
  37. case DATA_BITS_7:
  38. datasize = SEVENBITS;
  39. break;
  40. }
  41. if (cfg->stop_bits == STOP_BITS_1) stopbits = STOPBITS_ONE;
  42. else if (cfg->stop_bits == STOP_BITS_2) stopbits = STOPBITS_TWO;
  43. parity = PARITY_NONE;
  44. flowcontrol = FLOWCTRL_OFF;
  45. /* Initialize UART */
  46. uart_init(uart->instance, baudrate, parity, stopbits, datasize, flowcontrol);
  47. rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, "uart");
  48. rt_hw_interrupt_mask(uart->irqno);
  49. /* Set the IRQ mode for the Rx FIFO */
  50. uart_set_FIFO_mode(uart->instance, RX_FIFO, 1, IRQ_MODE);
  51. return RT_EOK;
  52. }
  53. static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  54. {
  55. struct hw_uart_device *uart;
  56. RT_ASSERT(serial != RT_NULL);
  57. uart = (struct hw_uart_device *)serial->parent.user_data;
  58. switch (cmd)
  59. {
  60. case RT_DEVICE_CTRL_CLR_INT:
  61. /* disable rx irq */
  62. rt_hw_interrupt_mask(uart->irqno);
  63. break;
  64. case RT_DEVICE_CTRL_SET_INT:
  65. /* enable rx irq */
  66. rt_hw_interrupt_umask(uart->irqno);
  67. break;
  68. }
  69. return RT_EOK;
  70. }
  71. static int uart_putc(struct rt_serial_device *serial, char c)
  72. {
  73. struct hw_uart_device *uart;
  74. RT_ASSERT(serial != RT_NULL);
  75. uart = (struct hw_uart_device *)serial->parent.user_data;
  76. uart_putchar(uart->instance, (uint8_t*)&c);
  77. return 1;
  78. }
  79. static int uart_getc(struct rt_serial_device *serial)
  80. {
  81. int ch;
  82. struct hw_uart_device *uart;
  83. RT_ASSERT(serial != RT_NULL);
  84. uart = (struct hw_uart_device *)serial->parent.user_data;
  85. ch = uart_getchar(uart->instance);
  86. if (ch == NONE_CHAR) ch = -1;
  87. return ch;
  88. }
  89. static const struct rt_uart_ops _uart_ops =
  90. {
  91. uart_configure,
  92. uart_control,
  93. uart_putc,
  94. uart_getc,
  95. };
  96. #ifdef RT_USING_UART0
  97. /* UART device driver structure */
  98. static struct hw_uart_device _uart0_device =
  99. {
  100. HW_UART0,
  101. IMX_INT_UART0
  102. };
  103. static struct rt_serial_device _serial0;
  104. #endif
  105. #ifdef RT_USING_UART1
  106. /* UART1 device driver structure */
  107. static struct hw_uart_device _uart1_device =
  108. {
  109. HW_UART1,
  110. IMX_INT_UART1
  111. };
  112. static struct rt_serial_device _serial1;
  113. #endif
  114. int rt_hw_uart_init(void)
  115. {
  116. struct hw_uart_device *uart;
  117. struct serial_configure config;
  118. config.baud_rate = BAUD_RATE_115200;
  119. config.bit_order = BIT_ORDER_LSB;
  120. config.data_bits = DATA_BITS_8;
  121. config.parity = PARITY_NONE;
  122. config.stop_bits = STOP_BITS_1;
  123. config.invert = NRZ_NORMAL;
  124. config.bufsz = RT_SERIAL_RB_BUFSZ;
  125. #ifdef RT_USING_UART0
  126. uart = &_uart0_device;
  127. _serial0.ops = &_uart_ops;
  128. _serial0.config = config;
  129. /* register UART1 device */
  130. rt_hw_serial_register(&_serial0, "uart0",
  131. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  132. uart);
  133. #endif
  134. #ifdef RT_USING_UART1
  135. uart = &_uart1_device;
  136. _serial1.ops = &_uart_ops;
  137. _serial1.config = config;
  138. /* register UART1 device */
  139. rt_hw_serial_register(&_serial1, "uart1",
  140. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart);
  141. #endif
  142. return 0;
  143. }
  144. INIT_BOARD_EXPORT(rt_hw_uart_init);