drv_uart.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-08-04 tangzz98 first version
  9. *
  10. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include "driver/uart.h"
  14. #include "hal/uart_hal.h"
  15. #include "sdkconfig.h"
  16. #ifdef RT_USING_SERIAL_V1
  17. #ifdef CONFIG_UART_ISR_IN_IRAM
  18. #define UART_ISR_ATTR IRAM_ATTR
  19. #else
  20. #define UART_ISR_ATTR
  21. #endif
  22. uart_hal_context_t hal[] = {
  23. {
  24. .dev = &UART0,
  25. },
  26. {
  27. .dev = &UART1,
  28. },
  29. };
  30. static struct rt_serial_device _serial;
  31. static void mcu_uart_rx_intr_handler(void *param)
  32. {
  33. uint32_t uart_intr_status;
  34. struct rt_serial_device *serial;
  35. uart_port_t port;
  36. rt_interrupt_enter();
  37. serial = (struct rt_serial_device *)param;
  38. port = (uart_port_t)serial->parent.user_data;
  39. uart_intr_status = uart_hal_get_intsts_mask(&hal[port]);
  40. if (uart_intr_status != 0)
  41. {
  42. if (uart_intr_status & UART_INTR_RXFIFO_FULL)
  43. {
  44. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  45. }
  46. uart_hal_clr_intsts_mask(&hal[port], uart_intr_status);
  47. }
  48. rt_interrupt_leave();
  49. }
  50. static rt_err_t mcu_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  51. {
  52. return RT_EOK;
  53. }
  54. static rt_err_t mcu_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  55. {
  56. return RT_EOK;
  57. }
  58. static int mcu_uart_putc(struct rt_serial_device *serial, char c)
  59. {
  60. uart_port_t port = (uart_port_t)serial->parent.user_data;
  61. uint32_t write_size = 0;
  62. do
  63. {
  64. uart_hal_write_txfifo(&hal[port], (const uint8_t *)&c, 1, &write_size);
  65. } while (write_size == 0);
  66. return 1;
  67. }
  68. static int mcu_uart_getc(struct rt_serial_device *serial)
  69. {
  70. uart_port_t port = (uart_port_t)serial->parent.user_data;
  71. uint8_t c;
  72. int len = uart_hal_get_rxfifo_len(&hal[port]);
  73. if (len == 0)
  74. {
  75. return -1;
  76. }
  77. else
  78. {
  79. len = 1;
  80. uart_hal_read_rxfifo(&hal[port], &c, &len);
  81. return (int)c;
  82. }
  83. }
  84. static const struct rt_uart_ops _uart_ops =
  85. {
  86. mcu_uart_configure,
  87. mcu_uart_control,
  88. mcu_uart_putc,
  89. mcu_uart_getc,
  90. RT_NULL,
  91. };
  92. int rt_hw_uart_init(void)
  93. {
  94. uart_intr_config_t uart_intr = {
  95. .intr_enable_mask = UART_INTR_RXFIFO_FULL,
  96. .rxfifo_full_thresh = 1,
  97. };
  98. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  99. uart_config_t uart_config = {
  100. .baud_rate = BAUD_RATE_115200,
  101. .data_bits = UART_DATA_8_BITS,
  102. .parity = UART_PARITY_DISABLE,
  103. .stop_bits = UART_STOP_BITS_1,
  104. .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
  105. .source_clk = UART_SCLK_APB,
  106. };
  107. int intr_alloc_flags = 0;
  108. #if CONFIG_UART_ISR_IN_IRAM
  109. intr_alloc_flags = ESP_INTR_FLAG_IRAM;
  110. #endif
  111. ESP_ERROR_CHECK(uart_param_config(RT_BSP_UART_PORT, &uart_config));
  112. ESP_ERROR_CHECK(uart_set_pin(RT_BSP_UART_PORT, RT_BSP_UART_TX_PIN, RT_BSP_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
  113. ESP_ERROR_CHECK(esp_intr_alloc(uart_periph_signal[RT_BSP_UART_PORT].irq, intr_alloc_flags, mcu_uart_rx_intr_handler, (void *)&_serial, NULL));
  114. ESP_ERROR_CHECK(uart_intr_config(RT_BSP_UART_PORT, &uart_intr));
  115. _serial.ops = &_uart_ops;
  116. _serial.config = config;
  117. return rt_hw_serial_register(&_serial, "uart", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, (void *)RT_BSP_UART_PORT);
  118. }
  119. INIT_BOARD_EXPORT(rt_hw_uart_init);
  120. #endif /* RT_USING_SERIAL_V1 */