hard_rc_subs.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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 sbus_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. sbus_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. sbus_rx_buf[sbus_rx_index++] = uart_read_byte(SBUS_UART2_RX);
  54. // 回调解析数据
  55. }
  56. // recv_rcsbus_data_hookfunction(sbus_rx_index, sbus_rx_buf);
  57. /* 标记一帧SBUS数据接收完成 */
  58. sbus_frame_ready = true;
  59. sbus_frame_length = sbus_rx_index; /* 记录当前帧长度 */
  60. sbus_rx_index = 0;
  61. }
  62. }
  63. static void rc_uart2_pin_config(void) // 如果使用的是同一个串口的rx 和tx 就初始化1次
  64. {
  65. HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_UART2_RXD;
  66. HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_UART2_TXD;
  67. }
  68. /**
  69. * @brief SBUS初始化
  70. */
  71. void rc_sbus_init(uint32_t baud)
  72. {
  73. uart_config_t config = {0};
  74. hpm_stat_t stat;
  75. /* 初始化UART */
  76. rc_uart2_pin_config();
  77. clock_set_source_divider(SBUS_UART2_CLK_NAME, clk_src_osc24m, 1);
  78. clock_add_to_group(SBUS_UART2_CLK_NAME, 0);
  79. uint32_t freq = clock_get_frequency(SBUS_UART2_CLK_NAME);
  80. printf("uart2 clk fre %d\r\n", freq);
  81. /* UART默认配置 */
  82. uart_default_config(SBUS_UART2_RX, &config);
  83. /* SBUS参数配置 */
  84. config.baudrate = baud; /* 100000bps */
  85. config.word_length = word_length_8_bits; /* 9位数据(8位+偶校验) */
  86. config.num_of_stop_bits = stop_bits_2; /* 2停止位 */
  87. config.parity = parity_even; /* 偶校验 */
  88. config.fifo_enable = true; /* 使能FIFO */
  89. config.src_freq_in_hz = clock_get_frequency(SBUS_UART2_CLK_NAME);
  90. /* 设置FIFO阈值 - 设为接近一帧的长度 要小于实际期望接收的字节数 25 */
  91. config.rx_fifo_level = uart_rx_fifo_trg_gt_three_quarters; /* 约24字节 */
  92. stat = uart_init(SBUS_UART2_RX, &config);
  93. if (stat != status_success) {
  94. printf("SBUS UART2 RX init failed\n");
  95. while (1);
  96. }
  97. /* 使能UART中断(FIFO阈值+超时) */
  98. uart_enable_irq(SBUS_UART2_RX, uart_intr_rx_data_avail_or_timeout);
  99. /* 使能中断控制器 */
  100. intc_m_enable_irq_with_priority(SBUS_UART2_IRQ, SBUS_UART2_IRQ_RANK);
  101. /* 初始化变量 */
  102. sbus_rx_index = 0;
  103. sbus_frame_ready = false;
  104. rx_interrupt_count = 0;
  105. printf("SBUS initialized with FIFO + timeout interrupt\n");
  106. }
  107. /* uart2 rx_irq demo 2026/03/15 pass*/
  108. #ifdef UART2_RX_TEST
  109. void uart2_sbus_test(void)
  110. {
  111. // char c = 0;
  112. rc_sbus_init(SBUS_UART2_BAUD);
  113. while(1)
  114. {
  115. // c++;
  116. board_delay_ms(500);
  117. if(sbus_frame_ready)
  118. {
  119. sbus_frame_ready = false;
  120. while(sbus_frame_length--)
  121. {
  122. printf(" %c ",sbus_rx_buf[sbus_frame_length]);
  123. }
  124. }
  125. // UART3_Put_Char(c); // pass
  126. }
  127. }
  128. #endif