| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #include "board.h"
- #include "hard_rc_sbus.h"
- #include "stdbool.h"
- #include "hpm_uart_drv.h"
- #include "test.h"
- // 与串口3一致
- // 如果使用发送和接收都是串口2 那就不需要在sbus_out里面再次进行串口初始化
- /*hpm6750没有串口空闲中断 不能使用UART iRQ+DMA 这里采用的是FIFO+超时中断*/
- #define SBUS_UART2_RX HPM_UART2
- #define SBUS_UART2_CLK_NAME clock_uart2
- #define SBUS_UART2_IRQ IRQn_UART2
- #define SBUS_UART2_BAUD 115200
- #define SBUS_UART2_IRQ_RANK 2
- /* 接收缓冲区 */
- ATTR_PLACE_AT_NONCACHEABLE uint8_t uart2_dma_rx_buf[UART2_RX_LENDTH_MAX];
- /* 全局变量 */
- static volatile uint16_t sbus_rx_index = 0;
- static volatile bool sbus_frame_ready = false;
- static volatile uint16_t sbus_frame_length = 0;
- static volatile uint32_t rx_interrupt_count = 0;
- /* 外部函数声明 */
- extern void recv_rcsbus_data_hookfunction(unsigned int len, uint8_t *data);
- /**
- * @brief UART中断服务函数
- */
- SDK_DECLARE_EXT_ISR_M(SBUS_UART2_IRQ, uart2_sbus_isr)
- void uart2_sbus_isr(void)
- {
- uint8_t irq_id = uart_get_irq_id(SBUS_UART2_RX);
- uint8_t count = 0;
-
- /* 处理FIFO阈值中断 - 批量读取数据 */
- if (irq_id == uart_intr_id_rx_data_avail) {
- rx_interrupt_count++;
-
- /* 从FIFO中读取数据 */
- while (uart_check_status(SBUS_UART2_RX, uart_stat_data_ready)) {
- count++;
- uart2_dma_rx_buf[sbus_rx_index++] = uart_read_byte(SBUS_UART2_RX);
-
- /* 防止缓冲区溢出 */
- if (sbus_rx_index >= UART2_RX_LENDTH_MAX) {
- sbus_rx_index = 0; /* 环形缓冲,溢出后从头开始 */
- }
-
- /*in order to ensure rx fifo there are remaining bytes*/
- if (count > 12) {
- break;
- }
- }
- }
-
- /* 处理FIFO超时中断 - 一帧数据接收完成 */
- if (irq_id == uart_intr_id_rx_timeout) {
- rx_interrupt_count++;
-
- /* 读取FIFO中剩余的所有数据 */
- while (uart_check_status(SBUS_UART2_RX, uart_stat_data_ready)) {
- uart2_dma_rx_buf[sbus_rx_index++] = uart_read_byte(SBUS_UART2_RX);
- // 回调解析数据
- }
- recv_rcsbus_data_hookfunction(sbus_rx_index, uart2_dma_rx_buf);
- // recv_rcsbus_data_hookfunction(sbus_rx_index, sbus_rx_buf);
- /* 标记一帧SBUS数据接收完成 */
- sbus_frame_ready = true;
- sbus_frame_length = sbus_rx_index; /* 记录当前帧长度 */
- sbus_rx_index = 0;
- }
- }
- static void rc_uart2_pin_config(void) // 如果使用的是同一个串口的rx 和tx 就初始化1次
- {
- HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_UART2_RXD;
- HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_UART2_TXD;
- }
- /**
- * @brief SBUS初始化
- */
- void rc_sbus_init(uint32_t baud)
- {
- uart_config_t config = {0};
- hpm_stat_t stat;
-
- /* 初始化UART */
- rc_uart2_pin_config();
- clock_set_source_divider(SBUS_UART2_CLK_NAME, clk_src_osc24m, 1);
- clock_add_to_group(SBUS_UART2_CLK_NAME, 0);
- uint32_t freq = clock_get_frequency(SBUS_UART2_CLK_NAME);
- printf("uart2 clk fre %d\r\n", freq);
- /* UART默认配置 */
- uart_default_config(SBUS_UART2_RX, &config);
-
- /* SBUS参数配置 */
- config.baudrate = baud; /* 100000bps */
- config.word_length = word_length_8_bits; /* 9位数据(8位+偶校验) */
- config.num_of_stop_bits = stop_bits_2; /* 2停止位 */
- config.parity = parity_even; /* 偶校验 */
- config.fifo_enable = true; /* 使能FIFO */
- config.src_freq_in_hz = clock_get_frequency(SBUS_UART2_CLK_NAME);
-
- /* 设置FIFO阈值 - 设为接近一帧的长度 要小于实际期望接收的字节数 25 */
- config.rx_fifo_level = uart_rx_fifo_trg_gt_three_quarters; /* 约24字节 */
-
- stat = uart_init(SBUS_UART2_RX, &config);
- if (stat != status_success) {
- printf("SBUS UART2 RX init failed\n");
- while (1);
- }
-
- /* 使能UART中断(FIFO阈值+超时) */
- uart_enable_irq(SBUS_UART2_RX, uart_intr_rx_data_avail_or_timeout);
-
- /* 使能中断控制器 */
- intc_m_enable_irq_with_priority(SBUS_UART2_IRQ, SBUS_UART2_IRQ_RANK);
-
- /* 初始化变量 */
- sbus_rx_index = 0;
- sbus_frame_ready = false;
- rx_interrupt_count = 0;
-
- printf("SBUS initialized with FIFO + timeout interrupt\n");
- }
- /* uart2 rx_irq demo 2026/03/15 pass*/
- #ifdef UART2_RX_TEST
- void uart2_sbus_test(void)
- {
- // char c = 0;
- rc_sbus_init(SBUS_UART2_BAUD);
- while(1)
- {
- // c++;
- board_delay_ms(500);
- if(sbus_frame_ready)
- {
- sbus_frame_ready = false;
- while(sbus_frame_length--)
- {
- printf(" %c ",uart2_dma_rx_buf[sbus_frame_length]);
- }
- }
-
- // UART3_Put_Char(c); // pass
-
- }
- }
- #endif
|