hard_rc_subs.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "board.h"
  2. #include "hard_rc_sbus.h"
  3. #include "stdbool.h"
  4. #include "hpm_uart_drv.h"
  5. #include "test.h"
  6. // 与串口3一致
  7. // 如果使用发送和接收都是串口2 那就不需要在sbus_out里面再次进行串口初始化
  8. /*hpm6750没有串口空闲中断 不能使用UART iRQ+DMA 这里采用的是FIFO+超时中断*/
  9. #define SBUS_UART2_RX HPM_UART2
  10. #define SBUS_UART2_CLK_NAME clock_uart2
  11. #define SBUS_UART2_IRQ IRQn_UART2
  12. #define SBUS_UART2_BAUD 115200
  13. #define SBUS_UART2_IRQ_RANK 2
  14. /* 接收缓冲区 */
  15. ATTR_PLACE_AT_NONCACHEABLE uint8_t uart2_dma_rx_buf[UART2_RX_LENDTH_MAX];
  16. /* 全局变量 */
  17. static volatile uint16_t sbus_rx_index = 0;
  18. static volatile bool sbus_frame_ready = false;
  19. static volatile uint16_t sbus_frame_length = 0;
  20. static volatile uint32_t rx_interrupt_count = 0;
  21. /* 外部函数声明 */
  22. extern void recv_rcsbus_data_hookfunction(unsigned int len, uint8_t *data);
  23. /**
  24. * @brief UART中断服务函数
  25. */
  26. SDK_DECLARE_EXT_ISR_M(SBUS_UART2_IRQ, uart2_sbus_isr)
  27. void uart2_sbus_isr(void)
  28. {
  29. uint8_t irq_id = uart_get_irq_id(SBUS_UART2_RX);
  30. uint8_t count = 0;
  31. /* 处理FIFO阈值中断 - 批量读取数据 */
  32. if (irq_id == uart_intr_id_rx_data_avail) {
  33. rx_interrupt_count++;
  34. /* 从FIFO中读取数据 */
  35. while (uart_check_status(SBUS_UART2_RX, uart_stat_data_ready)) {
  36. count++;
  37. uart2_dma_rx_buf[sbus_rx_index++] = uart_read_byte(SBUS_UART2_RX);
  38. /* 防止缓冲区溢出 */
  39. if (sbus_rx_index >= UART2_RX_LENDTH_MAX) {
  40. sbus_rx_index = 0; /* 环形缓冲,溢出后从头开始 */
  41. }
  42. /*in order to ensure rx fifo there are remaining bytes*/
  43. if (count > 12) {
  44. break;
  45. }
  46. }
  47. }
  48. /* 处理FIFO超时中断 - 一帧数据接收完成 */
  49. if (irq_id == uart_intr_id_rx_timeout) {
  50. rx_interrupt_count++;
  51. /* 读取FIFO中剩余的所有数据 */
  52. while (uart_check_status(SBUS_UART2_RX, uart_stat_data_ready)) {
  53. uart2_dma_rx_buf[sbus_rx_index++] = uart_read_byte(SBUS_UART2_RX);
  54. // 回调解析数据
  55. }
  56. recv_rcsbus_data_hookfunction(sbus_rx_index, uart2_dma_rx_buf);
  57. // recv_rcsbus_data_hookfunction(sbus_rx_index, sbus_rx_buf);
  58. /* 标记一帧SBUS数据接收完成 */
  59. sbus_frame_ready = true;
  60. sbus_frame_length = sbus_rx_index; /* 记录当前帧长度 */
  61. sbus_rx_index = 0;
  62. }
  63. }
  64. static void rc_uart2_pin_config(void) // 如果使用的是同一个串口的rx 和tx 就初始化1次
  65. {
  66. HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_UART2_RXD;
  67. HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_UART2_TXD;
  68. }
  69. /**
  70. * @brief SBUS初始化
  71. */
  72. void rc_sbus_init(uint32_t baud)
  73. {
  74. uart_config_t config = {0};
  75. hpm_stat_t stat;
  76. /* 初始化UART */
  77. rc_uart2_pin_config();
  78. clock_set_source_divider(SBUS_UART2_CLK_NAME, clk_src_osc24m, 1);
  79. clock_add_to_group(SBUS_UART2_CLK_NAME, 0);
  80. uint32_t freq = clock_get_frequency(SBUS_UART2_CLK_NAME);
  81. printf("uart2 clk fre %d\r\n", freq);
  82. /* UART默认配置 */
  83. uart_default_config(SBUS_UART2_RX, &config);
  84. /* SBUS参数配置 */
  85. config.baudrate = baud; /* 100000bps */
  86. config.word_length = word_length_8_bits; /* 9位数据(8位+偶校验) */
  87. config.num_of_stop_bits = stop_bits_2; /* 2停止位 */
  88. config.parity = parity_even; /* 偶校验 */
  89. config.fifo_enable = true; /* 使能FIFO */
  90. config.src_freq_in_hz = clock_get_frequency(SBUS_UART2_CLK_NAME);
  91. /* 设置FIFO阈值 - 设为接近一帧的长度 要小于实际期望接收的字节数 25 */
  92. config.rx_fifo_level = uart_rx_fifo_trg_gt_three_quarters; /* 约24字节 */
  93. stat = uart_init(SBUS_UART2_RX, &config);
  94. if (stat != status_success) {
  95. printf("SBUS UART2 RX init failed\n");
  96. while (1);
  97. }
  98. /* 使能UART中断(FIFO阈值+超时) */
  99. uart_enable_irq(SBUS_UART2_RX, uart_intr_rx_data_avail_or_timeout);
  100. /* 使能中断控制器 */
  101. intc_m_enable_irq_with_priority(SBUS_UART2_IRQ, SBUS_UART2_IRQ_RANK);
  102. /* 初始化变量 */
  103. sbus_rx_index = 0;
  104. sbus_frame_ready = false;
  105. rx_interrupt_count = 0;
  106. printf("SBUS initialized with FIFO + timeout interrupt\n");
  107. }
  108. /* uart2 rx_irq demo 2026/03/15 pass*/
  109. #ifdef UART2_RX_TEST
  110. void uart2_sbus_test(void)
  111. {
  112. // char c = 0;
  113. rc_sbus_init(SBUS_UART2_BAUD);
  114. while(1)
  115. {
  116. // c++;
  117. board_delay_ms(500);
  118. if(sbus_frame_ready)
  119. {
  120. sbus_frame_ready = false;
  121. while(sbus_frame_length--)
  122. {
  123. printf(" %c ",uart2_dma_rx_buf[sbus_frame_length]);
  124. }
  125. }
  126. // UART3_Put_Char(c); // pass
  127. }
  128. }
  129. #endif