1、用户copy这份代码,调用dtm_start()即可进入DTM模式; 2、在SDK的HCI代码基础上,略做整理,POOL的变量由静态变量(512字节)修改为临时变量,这样可以节省RAM的占用,只在调用时产生 3、代码部分初始化函数的调用已经在应用代码的main执行了,本代码将其注释掉了,用户可根据实际情况调整。 4、BLE的DTM模式通讯接口,蓝牙规范中有2个接口协议的定义,分别是hci和2 wire,但都是串口的接口,部分蓝牙综测仪可能是只支持2 wire模式,则可以通过打开宏CONFIG_DTM_USE_2WIRE_MODE开启2 wire模式。 /********************************************************************* * INCLUDES */ #include "om_driver.h" #include "evt.h" #include "pm.h" #include "nvds.h" // Controller header #include "obc.h" /********************************************************************* * MACROS */ //#define CONFIG_DTM_USE_2WIRE_MODE #define DTM_UART OM_UART1 #define PAD_DTM_UART_TXD 5 #define PAD_DTM_UART_RXD 6 /********************************************************************* * CONSTANTS */ #define EVT_TYPE_HCI_H4 ((evt_type_t)(EVT_TYPE_USR_FIRST+0)) #if defined(CONFIG_DTM_USE_2WIRE_MODE) #define HCI_UART_BAUDRATE 19200 #else #define HCI_UART_BAUDRATE 115200 #endif #define HCI_H4_RX_POOL_SIZE 512 /********************************************************************* * LOCAL VARIABLES */ static om_fifo_t *p_rx_fifo; static uint8_t *p_rx_pool; static const uart_config_t hci_uart_cfg = { .baudrate = HCI_UART_BAUDRATE, .flow_control = UART_FLOW_CONTROL_NONE, .data_bit = UART_DATA_BIT_8, .stop_bit = UART_STOP_BIT_1, .parity = UART_PARITY_NONE, .half_duplex_en = 0, .lin_enable = 0, }; /********************************************************************* * LOCAL FUNCTIONS */ static void dtm_pm_sleep_notify_handler(pm_sleep_state_t sleep_state, pm_status_t power_status) { switch(sleep_state) { case PM_SLEEP_ENTRY: break; case PM_SLEEP_LEAVE_TOP_HALF: break; case PM_SLEEP_LEAVE_BOTTOM_HALF: break; default: break; } } static void hci_h4_transmit_handler(const uint8_t *pdata, uint32_t length) { drv_uart_write(DTM_UART, pdata, length, DRV_MAX_DELAY); } static void hci_h4_uart_rx_handler(void *om_uart, drv_event_t event, void *rx_buf, void *rx_cnt) { if (event & DRV_EVENT_COMMON_READ_COMPLETED) { om_fifo_in(p_rx_fifo, rx_buf, (uint32_t)rx_cnt); evt_set(EVT_TYPE_HCI_H4); } } static void hci_h4_uart_rx_evt_handler(void) { uint8_t buffer[64]; uint32_t length; evt_clear(EVT_TYPE_HCI_H4); while (1) { length = om_fifo_out(p_rx_fifo, buffer, sizeof(buffer)); if (length == 0) break; #ifdef CONFIG_DTM_USE_2WIRE_MODE obc_2wire_read_handler(buffer, length); #else obc_hci_h4_receive_handler(buffer, length); #endif } } static void ble_controller_init(void) { obc_init(); om_fifo_init(p_rx_fifo, p_rx_pool, HCI_H4_RX_POOL_SIZE); evt_callback_set(EVT_TYPE_HCI_H4, hci_h4_uart_rx_evt_handler); obc_hci_h4_transmit_callback_set(hci_h4_transmit_handler); #ifdef CONFIG_DTM_USE_2WIRE_MODE obc_2wire_init(hci_h4_transmit_handler); #endif } static void dtm_hardware_init(void) { pin_config_t pin_config[] ={ {PAD_DTM_UART_TXD, {PINMUX_PAD5_UART1_TRX_CFG}, PMU_PIN_MODE_PP, PMU_PIN_DRIVER_CURRENT_NORMAL}, {PAD_DTM_UART_RXD, {PINMUX_PAD6_UART1_RX_CFG}, PMU_PIN_MODE_PU, PMU_PIN_DRIVER_CURRENT_NORMAL}, }; gpio_config_t gpio_config[] = { {OM_GPIO0, PAD_DTM_UART_TXD, GPIO_DIR_OUTPUT, GPIO_LEVEL_HIGH, GPIO_TRIG_NONE}, {OM_GPIO0, PAD_DTM_UART_RXD, GPIO_DIR_INPUT, GPIO_LEVEL_HIGH, GPIO_TRIG_NONE}, }; drv_pin_init(pin_config, sizeof(pin_config) / sizeof(pin_config[0])); drv_gpio_init(gpio_config, sizeof(gpio_config) / sizeof(gpio_config[0])); drv_uart_init(DTM_UART, &hci_uart_cfg); drv_uart_register_isr_callback(DTM_UART, hci_h4_uart_rx_handler); drv_uart_read_int(DTM_UART, NULL, 0); } /********************************************************************* * PUBLIC FUNCTIONS */ /** * @brief v start DTM function **/ void dtm_start(void) { #if 0 // do comment the codes below, if those have been called in the main(). drv_wdt_init(0); onchip_flash_init(); nvds_init(0); pm_init(); #endif drv_pmu_pof_enable(false, PMU_POF_VOLTAGE_2P5V, PMU_POF_INT_NEG_EDGE); pm_sleep_notify_user_callback_register(dtm_pm_sleep_notify_handler); pm_sleep_enable(false); drv_rf_init(); evt_init(); om_fifo_t hci_h4_rx_fifo; uint8_t hci_h4_rx_pool[HCI_H4_RX_POOL_SIZE]; p_rx_fifo=&hci_h4_rx_fifo; p_rx_pool=&hci_h4_rx_pool[0]; dtm_hardware_init(); ble_controller_init(); while(1) { evt_schedule(); OM_CRITICAL_BEGIN(); if(evt_get_all() == 0) { pm_power_manage(); } OM_CRITICAL_END(); } } |