This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

pair cause bas not have notify of central

i use sdk14.2  52832  as  central ,  have bas  service and  myself  service  it   have pair  process , there  are  one change question.  When I first burned the program, the bas service cccd was enabled and the power was read, but 0% of the read power and the power did not receive a notify after the power was changed, everything was normal after another connection or reset, I guess it is possible It was caused by the first pairing, but the specific question was not known. This was the only strange problem after the first burning process.

Parents
  • Hi,

    I'm not sure if I understand your problem. Can you upload your project?

  • 
    /** @brief Clear bonding information from persistent storage
     */
    static void delete_bonds(void)
    {
        ret_code_t err_code;
    
        NRF_LOG_INFO("Erase bonds!");
    
        err_code = pm_peers_delete();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**
     * @brief 处理手机发送过来的unpair数据.
     */
    static void mt_pai_del_handler(uint8_t * cmd, uint8_t len)
    {
        /* 数据判断 ............*/
        if (len == 1 && cmd[0] == 1) {
            delete_bonds();
        }
    }
    
    
    
    static void ble_nus_c_evt_handler(ble_nus_c_t *p_ble_nus_c, 
                                    ble_nus_c_evt_t const *p_ble_nus_evt)
    {
        ret_code_t err_code;
    
        switch (p_ble_nus_evt->evt_type) {
            case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
                NRF_LOG_INFO("[%04d] nus discovery complete.", __LINE__);
                APP_ERROR_CHECK(ble_nus_c_handles_assign(p_ble_nus_c, 
                                                        p_ble_nus_evt->conn_handle, 
                                                        &p_ble_nus_evt->handles));
    
                // Initiate bonding.
                if (m_pair_bound_flag) {
                     err_code = pm_conn_secure(p_ble_nus_evt->conn_handle, false);
                    if (err_code != NRF_ERROR_INVALID_STATE) {
                        APP_ERROR_CHECK(err_code);
                    }
                }
               
                APP_ERROR_CHECK(ble_nus_c_rgb_notif_enable(&m_ble_nus_c));
                APP_ERROR_CHECK(ble_nus_c_pai_notif_enable(&m_ble_nus_c));
                APP_ERROR_CHECK(ble_nus_c_ota_notif_enable(&m_ble_nus_c));
    
                mt_mac_address_get();
                mt_mac_peripheral_send(m_ble_nus_c.handles.nus_mac_tx_handle, m_uicr_mac);
    
                break;
    
            case BLE_NUS_C_EVT_NUS_RGB_TX_EVT:
    
    
                break;
            /* Unpair Request */
            case BLE_NUS_C_EVT_NUS_PAI_TX_EVT:
            
                break;
    
            case BLE_NUS_C_EVT_NUS_OTA_TX_EVT:
    
             
                break;
    
            case BLE_NUS_C_EVT_NUS_RGB_READ_RSP_EVT:
     
                break;
    
            case BLE_NUS_C_EVT_NUS_MAC_WRITE_RSP_EVT:
    
                break;
    
            case BLE_NUS_C_EVT_NUS_QIC_WRITE_RSP_EVT:
    
                break;
                
            case BLE_NUS_C_EVT_DISCONNECTED:
     
                break;
        }
    }
    
    /**
     * @brief 配对绑定成功后处理.
     */
    static void mt_after_bonding_handler()
    {
        /*RGB:配对完成 .*/
        NRF_LOG_RAW_INFO("mt_after_bonding_handler\r\n");
        mt_rgb_flash_fun(RGB_STATE3, RGB_NULL);
        APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
        APP_ERROR_CHECK(app_timer_stop(rgb_flash_3_min_id));
        APP_ERROR_CHECK(app_timer_start(bat_check_timer_id, APP_TIMER_TICKS(10000) , NULL));
        APP_ERROR_CHECK(ble_bas_c_bl_read(&m_bas_c));
    }
    
    
    /**
     * @brief Function for handling Peer Manager events.
     *
     * @param[in] p_evt  Peer Manager event.
     */
    static void pm_evt_handler(pm_evt_t const * p_evt)
    {
        ret_code_t err_code;
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_BONDED_PEER_CONNECTED:
            {
                
                NRF_LOG_INFO("Connected to a previously bonded device.");
            } break;
    
            case PM_EVT_CONN_SEC_SUCCEEDED:
            {
                /* 配对或者绑定成功. */
                /* 调用 pm_conn_secure 导致首次配对绑定时此事件发生一次, 后续连接配对会一直是发生两次,目前尚不清楚原因,
                   通过跑nordic hrs主端例程发现是同样的现象, 而且每次连接只需要调用下列函数一次即可,多次可能发生意外 add by stronges. */
                if (m_connect_flag) {
                     mt_after_bonding_handler();
                     m_connect_flag = false;
                }
    
                NRF_LOG_INFO("Connection secured234234234: role: %d, conn_handle: 0x%x, procedure: %d.",
                             ble_conn_state_role(p_evt->conn_handle),
                             p_evt->conn_handle,
                             p_evt->params.conn_sec_succeeded.procedure);
               
            } break;
    
            case PM_EVT_CONN_SEC_FAILED:
            {
                NRF_LOG_INFO("PM_EVT_CONN_SEC_FAILED\r\n");
                NRF_LOG_INFO("Connection failed: procedure: %d, error: 0x%x, error_src: 0x%x.",
                             p_evt->params.conn_sec_failed.procedure,
                             p_evt->params.conn_sec_failed.error,
                             p_evt->params.conn_sec_failed.error_src);
                APP_ERROR_CHECK(sd_ble_gap_disconnect(p_evt->conn_handle,
                                                    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
                // mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                // m_scanlist_enable = true;
                // xx_scan_start(FILTER_ENABLE);
    
                /* Often, when securing fails, it shouldn't be restarted, for security reasons.
                 * Other times, it can be restarted directly.
                 * Sometimes it can be restarted, but only after changing some Security Parameters.
                 * Sometimes, it cannot be restarted until the link is disconnected and reconnected.
                 * Sometimes it is impossible, to secure the link, or the peer device does not support it.
                 * How to handle this error is highly application dependent. */
    
            } break;
    
            case PM_EVT_CONN_SEC_CONFIG_REQ:
            {
                /* Reject pairing request from an already bonded peer .*/
                pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
                pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
            } break;
    
            case PM_EVT_STORAGE_FULL:
            {
                /* Run garbage collection on the flash. */
                err_code = fds_gc();
                if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
                {
                    // Retry.
                }
                else
                {
                    APP_ERROR_CHECK(err_code);
                }
            } break;
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
            {
               /* Bonds are deleted. Start scanning. */
               xx_scanning_start(true);
            } break;
    
            case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED\r\n");
                /* The local database has likely changed, send service changed indications. */
                pm_local_database_has_changed();
            } break;
    
            case PM_EVT_PEER_DATA_UPDATE_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_PEER_DATA_UPDATE_FAILED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error);
            } break;
    
            case PM_EVT_PEER_DELETE_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_PEER_DELETE_FAILED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
            } break;
    
            case PM_EVT_PEERS_DELETE_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_PEERS_DELETE_FAILED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
            } break;
    
            case PM_EVT_ERROR_UNEXPECTED:
            {
                NRF_LOG_DEBUG("PM_EVT_ERROR_UNEXPECTED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
            } break;
    
            case PM_EVT_CONN_SEC_START:
            {
                APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
                NRF_LOG_INFO("BOND STARTXXXXXXXXXXXXXXXXX, procedure: %d.",
                             p_evt->params.conn_sec_start.procedure);
            }
            case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
            case PM_EVT_PEER_DELETE_SUCCEEDED:
            case PM_EVT_LOCAL_DB_CACHE_APPLIED:
                break;
            case PM_EVT_SERVICE_CHANGED_IND_SENT:
                NRF_LOG_DEBUG("PM_EVT_SERVICE_CHANGED_IND_SENT\r\n");
            break;
            case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
                NRF_LOG_DEBUG("PM_EVT_SERVICE_CHANGED_IND_SENT\r\n");
            default:
                break;
        }
    }
    
    
    /**
     * @brief Battery level Collector Handler.
     */
    static void bas_c_evt_handler(ble_bas_c_t * p_bas_c, ble_bas_c_evt_t * p_bas_c_evt)
    {
        ret_code_t err_code;
        static uint16_t batt = 0;
    
        switch (p_bas_c_evt->evt_type)
        {
            case BLE_BAS_C_EVT_DISCOVERY_COMPLETE:
            {
                NRF_LOG_INFO("[%04d] bas discovery complete.", __LINE__);
                err_code = ble_bas_c_handles_assign(p_bas_c,
                                                    p_bas_c_evt->conn_handle,
                                                    &p_bas_c_evt->params.bas_db);
                APP_ERROR_CHECK(err_code);
    
                // Initiate bonding.
                if (m_pair_bound_flag) {
                    err_code = pm_conn_secure(p_bas_c_evt->conn_handle, false);
                    if (err_code != NRF_ERROR_INVALID_STATE) {
                        APP_ERROR_CHECK(err_code);
                    }
                }
    
                APP_ERROR_CHECK(app_timer_start(rgb_flash_timer2, THREE_INTERVAL, NULL));
                /* APP_ERROR_CHECK(ble_bas_c_bl_notif_enable(&m_bas_c));*/
                APP_ERROR_CHECK(app_timer_start(bat_check_timer_id, APP_TIMER_TICKS(10000) , NULL));
                APP_ERROR_CHECK(ble_bas_c_bl_read(&m_bas_c));
               
                
                
            } break;
    
            case BLE_BAS_C_EVT_BATT_NOTIFICATION:
                m_battery_states_t = p_bas_c_evt->params.battery_level;
                NRF_LOG_INFO("Battery notify  %d%%.", m_battery_states_t);
                break;
    
            case BLE_BAS_C_EVT_BATT_READ_RESP:
                if (p_bas_c_evt->params.battery_level != batt) {
                    batt = p_bas_c_evt->params.battery_level;
                    m_temp_array.type = PHONE_CMD_BATTERY;
                    ble_nus_chars_received_uart_print(&batt, 1);
                }
                NRF_LOG_INFO("Battery read as %d%%.", p_bas_c_evt->params.battery_level);
                break;
    
            default:
                break;
        }
    }
    
    
    /**
     * @brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
    {
        ret_code_t err_code;
        ble_gap_evt_t const *p_gap_evt = &p_ble_evt->evt.gap_evt;
    
        switch (p_ble_evt->header.evt_id) {
            case BLE_GAP_EVT_ADV_REPORT: 
                scan_data_resolve_handler(p_ble_evt, NULL);
                break;
    
            case BLE_GAP_EVT_CONNECTED:
            {
                m_std_cmd_states = CMD_NONE;
                m_scan_states    = BLE_SCAN_CONN;
                uart_rec_process_clr();
    
                NRF_LOG_INFO("[%04d] Connected already", __LINE__);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                m_pending_db_disc_conn = p_ble_evt->evt.gap_evt.conn_handle;
                m_retry_db_disc = false;
                m_connect_flag = true;
    
                err_code = ble_db_discovery_start(&m_db_disc, m_pending_db_disc_conn);
                if (err_code == NRF_ERROR_BUSY) {
                    NRF_LOG_INFO("ble_db_discovery_start() returned busy, will retry later.\r\n");
                    m_retry_db_disc = true;
                } else if (err_code == NRF_ERROR_INVALID_STATE){
                   
                } else {
                    APP_ERROR_CHECK(err_code);
                }
    
                break;
            }
    
            case BLE_GAP_EVT_DISCONNECTED:
            {
                NRF_LOG_INFO("[%4d]line !!!Disconnected, reason 0x%x.\r\n", __LINE__,
                             p_ble_evt->evt.gap_evt.params.disconnected.reason);
                m_std_cmd_states = CMD_NONE;
                m_scan_states    = BLE_SCAN_STOP;
    
                /*RGB:断开连接 .*/
                mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                uart_rec_process_clr();
                APP_ERROR_CHECK(app_timer_stop(bat_check_timer_id));
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                mt_dev_pair_scan_connect();
                break;
            }
    
            case BLE_GAP_EVT_TIMEOUT:
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) {
    
                    if (m_scanlist_enable == false) {
                        m_scanlist_enable = mt_scan_data_in_order();
                    }else {
                        m_scanlist_enable = false;
                    }
    
                    if(m_scan_pair_count++ < 36) {  /* 36个循环36 * 5 = 180s */
                        xx_scan_start(FILTER_ENABLE);
                    } else {
                        /*RGB:配对超时 .*/
                        m_scan_pair_count = 0;
                        NRF_LOG_INFO("[%04d] pair timeout.", __LINE__);
                        
                        APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
                        mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                    }
    
                } else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) {
                    NRF_LOG_INFO("[%04d] Connection Request timed out.", __LINE__);
    
                    /*RGB:连接超时 .*/
                    mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                    m_scanlist_enable = true;
                    xx_scan_start(FILTER_ENABLE);
                }
                break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                /* Accepting parameters requested by peer. */
                APP_ERROR_CHECK(sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                            &p_gap_evt->params.conn_param_update_request.conn_params));
                break;
    
    #ifndef S140
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
                NRF_LOG_DEBUG("[%04d] PHY update request.", __LINE__);
                ble_gap_phys_t const phys = {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                APP_ERROR_CHECK(sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, 
                                                    &phys));
            } break;
    #endif
    
            case BLE_GATTC_EVT_TIMEOUT:
                /* Disconnect on GATT Client timeout event. */
                NRF_LOG_DEBUG("[%04d] GATT Client Timeout.", __LINE__);
                APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                /* Disconnect on GATT Server timeout event. */
                NRF_LOG_DEBUG("[%04d] GATT Server Timeout.", __LINE__);
                APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
                break;
    
            case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
                break;
    
            default:
                break;
        }
    }
    
    
    /**@brief SoftDevice SoC event handler.
     *
     * @param[in]   evt_id      SoC event.
     * @param[in]   p_context   Context.
     */
    static void soc_evt_handler(uint32_t evt_id, void * p_context)
    {
        switch (evt_id)
        {
            case NRF_EVT_FLASH_OPERATION_SUCCESS:
                /* fall through */
            case NRF_EVT_FLASH_OPERATION_ERROR:
    
                if (m_memory_progress) {
                    m_memory_progress = false;
                    NRF_LOG_INFO("[%04d] memory error.", __LINE__);
                    mt_dev_pair_scan_connect();
                }
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    /** 
     * @brief Function for handling events from the GATT library. 
     */
    void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt)
    {
        if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED) {
            NRF_LOG_INFO("[%04d] ATT MTU exchange completed.", __LINE__);
    
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - 
                                    OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("[%04d] Ble NUS max data length set to 0x%X(%d)", __LINE__, m_ble_nus_max_data_len, m_ble_nus_max_data_len);
        }
    
         if (m_retry_db_disc) {
            NRF_LOG_DEBUG("Retrying DB discovery.\r\n");
    
            m_retry_db_disc = false;
    
            // Discover peer's services.
            ret_code_t err_code;
            err_code = ble_db_discovery_start(&m_db_disc, m_pending_db_disc_conn);
    
            if (err_code == NRF_ERROR_BUSY) {
                NRF_LOG_DEBUG("ble_db_discovery_start() returned busy, will retry later.\r\n");
                m_retry_db_disc = true;
            } else {
                APP_ERROR_CHECK(err_code);
            } 
        }
    }
    
    
    /**
     * @brief Function for button handler
     */
    static void button_event_handler(xx_button_app_evt_t * evt_code)
    {
        NRF_LOG_RAW_INFO("button_event_handler");
        if (evt_code->btn_evt == XX_BTN_LONG_PUSH_EVT) {
            switch (evt_code->pin_no) {
                case TEST_BUTTON :
                    m_pair_bound_flag = true;
                    break;
                default :
                    break;
            }
        }
    }
    
    
    /**
     * @brief 看门狗中断
     */
    static void wdt_event_handler(void) {
        /* @todo */
    }
    
    
    /**
     * @brief 定时喂狗
     */
    static void wdt_timeout_handler(void * p_context) 
    {
        nrf_drv_wdt_feed();
        nrf_delay_us(150);
    }
    
    
    /**
     * @brief 定时检测电池电量
     */
    static void battery_check_timeout_handler(void * p_context) 
    {
        APP_ERROR_CHECK(ble_bas_c_bl_read(&m_bas_c));
    }
    
    
    /**
     * @brief 配对定时闪
     */
    static void rgb_flash_timeout_handler1(void * p_context) {
        mt_rgb_flash_fun(RGB_STATE2, RGB_STATE1);
    }
    
    
    /**
     * @brief 预留当连接三秒没有手机APP数据后亮指定灯
     */
    static void rgb_flash_timeout_handler2(void * p_context) {
        if(nrf_gpio_pin_read(XXXX1_PIN_NUMBER) == 1 && is_device_connect() == true) {
            mt_rgb_flash_fun(RGB_STATE9, RGB_NULL);
        } 
    
        else 
        if (nrf_gpio_pin_read(XXXX1_PIN_NUMBER) == 0 && is_device_connect() == true) {
            mt_rgb_flash_fun(RGB_STATE10, RGB_NULL);
        }
    }
    
    /**
     * @brief 180s关闭配对闪烁灯.
     */
    static void rgb_close_rgb_pair_handler(void * p_context) {
       /*RGB:180s没有配对成功, 关灯 .*/
        m_scan_pair_count = 0;
        NRF_LOG_INFO("[%04d] 180s close flash rgb.", __LINE__);
                        
        APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
        mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
    }
    
    /**
     * @brief Battery level collector initialization.
     */
    static void bas_c_init(void)
    {
        ble_bas_c_init_t bas_c_init_obj;
    
        bas_c_init_obj.evt_handler = bas_c_evt_handler;
    
        ret_code_t err_code = ble_bas_c_init(&m_bas_c, &bas_c_init_obj);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /** 
     * @brief Function for initializing the NUS Client. 
     */
    static void nus_c_init(void)
    {
        ble_nus_c_init_t init;
    
        init.evt_handler = ble_nus_c_evt_handler;
        APP_ERROR_CHECK(ble_nus_c_init(&m_ble_nus_c, &init));
    }
    
    
    /** 
     * @brief Function for initializing the GATT library. 
     */
    void gatt_init(void)
    {
        APP_ERROR_CHECK(nrf_ble_gatt_init(&m_gatt, gatt_evt_handler));
    
        APP_ERROR_CHECK(nrf_ble_gatt_att_mtu_central_set(&m_gatt, BLE_GATT_ATT_MTU_DEFAULT));
    }
    
    
    /**
     * @brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        APP_ERROR_CHECK(nrf_sdh_enable_request());
    
        /** Configure the BLE stack using the default settings.
         *  Fetch the start address of the application RAM. 
         */
        uint32_t ram_start = 0;
        APP_ERROR_CHECK(nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start));
    
        /* Enable BLE stack. */
        APP_ERROR_CHECK(nrf_sdh_ble_enable(&ram_start));
    
        /* Register a handler for BLE events. */
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
        NRF_SDH_SOC_OBSERVER(m_soc_observer, APP_SOC_OBSERVER_PRIO, soc_evt_handler, NULL);
    }
    
    
    /** 
     * @brief Function for initializing the Database Discovery Module. 
     */
    static void db_discovery_init(void)
    {
        APP_ERROR_CHECK(ble_db_discovery_init(db_disc_handler));
    }
    
    
    /**
     * @brief Function for gpiote:1.预留的输入引脚 2.预留引脚2
     */
    static void gpio_init(void)
    {
        nrf_gpio_cfg_input(TEST_IC_OUT_1,NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(TEST_IC_OUT_2,NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(TEST_BUTTON,NRF_GPIO_PIN_PULLUP);
        
        /* 预留颜色选择引脚. */
        nrf_gpio_cfg_input(XXXX1_PIN_NUMBER,NRF_GPIO_PIN_PULLUP);
    
        mt_WS2812B_rgb_init();
       
    }
    
    
    /**
     * @brief 相关硬件初始化
     */
    static void mt_dev_pair_scan_connect(void) {
        m_cmd_collection.scan_inte_win_level     = DEFAULT_L_SCAN_INTERVAL;   
        m_cmd_collection.min_max_cinterval_level = DEFAULT_L_CONN_INTERVAL;
    
        if (nrf_fstorage_is_busy(NULL)) {
            NRF_LOG_INFO("nrf fstorage is busy.");
            m_memory_progress = true;
            return;
        }
    
        if(mt_peer_pair_init(m_cmd_collection) == true) {
            xx_scan_start(FILTER_ENABLE);
            if (m_pair_bound_flag) {
                mt_rgb_flash_fun(RGB_STATE2, RGB_STATE2);
                APP_ERROR_CHECK(app_timer_start(rgb_flash_3_min_id, APP_TIMER_TICKS(180000), NULL));
                APP_ERROR_CHECK(app_timer_start(rgb_flash_timer1, APP_TIMER_TICKS(2000), NULL));
            }
        }
    }
    
    
    /**
     * @brief Application timer start.
     */
    static void application_timers_start(void)
    {
        APP_ERROR_CHECK(app_timer_create(&wdt_timer_id, APP_TIMER_MODE_REPEATED, 
                        wdt_timeout_handler));
        APP_ERROR_CHECK(app_timer_start(wdt_timer_id, ONE_SECOND_INTERVAL, NULL));
    
        /* 定时检测电量 */
        APP_ERROR_CHECK(app_timer_create(&bat_check_timer_id, APP_TIMER_MODE_REPEATED, 
                        battery_check_timeout_handler));
    
        /* 配对定时闪 */
        APP_ERROR_CHECK(app_timer_create(&rgb_flash_timer1, APP_TIMER_MODE_REPEATED, 
                        rgb_flash_timeout_handler1));
    
        /* 连接上后3秒,预留高低电平脚,对应RGB颜色灯*/
        APP_ERROR_CHECK(app_timer_create(&rgb_flash_timer2, APP_TIMER_MODE_SINGLE_SHOT, 
                        rgb_flash_timeout_handler2));
        
        /* 180s没有配对成功,关灯.*/
        APP_ERROR_CHECK(app_timer_create(&rgb_flash_3_min_id, APP_TIMER_MODE_SINGLE_SHOT, 
                        rgb_close_rgb_pair_handler));
    }
    
    
    /**
     * @brief 相关硬件初始化
     */
    static void hal_init(void)
    {
        rgb_ss_init();
        uart_init();
        APP_ERROR_CHECK(app_fifo_init(&m_uart_rec_fifo, m_rec_buf, sizeof(m_rec_buf)));
        uart_rec_process_clr();
        NRF_LOG_DEBUG("[%04d] UART init", __LINE__);
    }
    
    
    /**
     * @brief 主端应用与服务初始化
     */
    static void ble_central_init(void)
    {
        gpio_init();
        ble_stack_init();
        gatt_init();
        mt_peer_manager_init();
        APP_ERROR_CHECK(pm_register(pm_evt_handler));
        db_discovery_init();
        nus_c_init();
        bas_c_init();
        NRF_LOG_DEBUG("[%04d] ble service init", __LINE__);
    }
    
    
    /**
     * @brief 基本必需功能初始化
     */
    static void basic_init(void)
    {
        nrf_delay_ms(400);
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        APP_ERROR_CHECK(app_timer_init());
        APP_ERROR_CHECK(app_simple_timer_init());
    
        /* APP gpiote初始化注册. */
        APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS);
    
        /* SCHED初始化. */
        APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    
    
        APP_ERROR_CHECK(nrf_pwr_mgmt_init());
    
        /* 看门狗初始化. */
        nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
        APP_ERROR_CHECK(nrf_drv_wdt_init(&config, wdt_event_handler));
        APP_ERROR_CHECK(nrf_drv_wdt_channel_alloc(&m_channel_id));
    
        NRF_LOG_DEBUG("[%04d] basic init", __LINE__);
    }
    
    
    /**
     * @brief Enter main function.0
     */
    int main(void)
    {
        basic_init();
        ble_central_init();
        hal_init();
    
        nrf_drv_wdt_enable();  
        application_timers_start();
        NRF_LOG_INFO("[%04d] ble uart central started", __LINE__);
        mt_dev_pair_scan_connect();
    
        while (true){
            app_sched_execute();
            sched_monitor();
            if (NRF_LOG_PROCESS() == false) {
                nrf_pwr_mgmt_run();
            }
        }
    }
    

Reply
  • 
    /** @brief Clear bonding information from persistent storage
     */
    static void delete_bonds(void)
    {
        ret_code_t err_code;
    
        NRF_LOG_INFO("Erase bonds!");
    
        err_code = pm_peers_delete();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**
     * @brief 处理手机发送过来的unpair数据.
     */
    static void mt_pai_del_handler(uint8_t * cmd, uint8_t len)
    {
        /* 数据判断 ............*/
        if (len == 1 && cmd[0] == 1) {
            delete_bonds();
        }
    }
    
    
    
    static void ble_nus_c_evt_handler(ble_nus_c_t *p_ble_nus_c, 
                                    ble_nus_c_evt_t const *p_ble_nus_evt)
    {
        ret_code_t err_code;
    
        switch (p_ble_nus_evt->evt_type) {
            case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
                NRF_LOG_INFO("[%04d] nus discovery complete.", __LINE__);
                APP_ERROR_CHECK(ble_nus_c_handles_assign(p_ble_nus_c, 
                                                        p_ble_nus_evt->conn_handle, 
                                                        &p_ble_nus_evt->handles));
    
                // Initiate bonding.
                if (m_pair_bound_flag) {
                     err_code = pm_conn_secure(p_ble_nus_evt->conn_handle, false);
                    if (err_code != NRF_ERROR_INVALID_STATE) {
                        APP_ERROR_CHECK(err_code);
                    }
                }
               
                APP_ERROR_CHECK(ble_nus_c_rgb_notif_enable(&m_ble_nus_c));
                APP_ERROR_CHECK(ble_nus_c_pai_notif_enable(&m_ble_nus_c));
                APP_ERROR_CHECK(ble_nus_c_ota_notif_enable(&m_ble_nus_c));
    
                mt_mac_address_get();
                mt_mac_peripheral_send(m_ble_nus_c.handles.nus_mac_tx_handle, m_uicr_mac);
    
                break;
    
            case BLE_NUS_C_EVT_NUS_RGB_TX_EVT:
    
    
                break;
            /* Unpair Request */
            case BLE_NUS_C_EVT_NUS_PAI_TX_EVT:
            
                break;
    
            case BLE_NUS_C_EVT_NUS_OTA_TX_EVT:
    
             
                break;
    
            case BLE_NUS_C_EVT_NUS_RGB_READ_RSP_EVT:
     
                break;
    
            case BLE_NUS_C_EVT_NUS_MAC_WRITE_RSP_EVT:
    
                break;
    
            case BLE_NUS_C_EVT_NUS_QIC_WRITE_RSP_EVT:
    
                break;
                
            case BLE_NUS_C_EVT_DISCONNECTED:
     
                break;
        }
    }
    
    /**
     * @brief 配对绑定成功后处理.
     */
    static void mt_after_bonding_handler()
    {
        /*RGB:配对完成 .*/
        NRF_LOG_RAW_INFO("mt_after_bonding_handler\r\n");
        mt_rgb_flash_fun(RGB_STATE3, RGB_NULL);
        APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
        APP_ERROR_CHECK(app_timer_stop(rgb_flash_3_min_id));
        APP_ERROR_CHECK(app_timer_start(bat_check_timer_id, APP_TIMER_TICKS(10000) , NULL));
        APP_ERROR_CHECK(ble_bas_c_bl_read(&m_bas_c));
    }
    
    
    /**
     * @brief Function for handling Peer Manager events.
     *
     * @param[in] p_evt  Peer Manager event.
     */
    static void pm_evt_handler(pm_evt_t const * p_evt)
    {
        ret_code_t err_code;
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_BONDED_PEER_CONNECTED:
            {
                
                NRF_LOG_INFO("Connected to a previously bonded device.");
            } break;
    
            case PM_EVT_CONN_SEC_SUCCEEDED:
            {
                /* 配对或者绑定成功. */
                /* 调用 pm_conn_secure 导致首次配对绑定时此事件发生一次, 后续连接配对会一直是发生两次,目前尚不清楚原因,
                   通过跑nordic hrs主端例程发现是同样的现象, 而且每次连接只需要调用下列函数一次即可,多次可能发生意外 add by stronges. */
                if (m_connect_flag) {
                     mt_after_bonding_handler();
                     m_connect_flag = false;
                }
    
                NRF_LOG_INFO("Connection secured234234234: role: %d, conn_handle: 0x%x, procedure: %d.",
                             ble_conn_state_role(p_evt->conn_handle),
                             p_evt->conn_handle,
                             p_evt->params.conn_sec_succeeded.procedure);
               
            } break;
    
            case PM_EVT_CONN_SEC_FAILED:
            {
                NRF_LOG_INFO("PM_EVT_CONN_SEC_FAILED\r\n");
                NRF_LOG_INFO("Connection failed: procedure: %d, error: 0x%x, error_src: 0x%x.",
                             p_evt->params.conn_sec_failed.procedure,
                             p_evt->params.conn_sec_failed.error,
                             p_evt->params.conn_sec_failed.error_src);
                APP_ERROR_CHECK(sd_ble_gap_disconnect(p_evt->conn_handle,
                                                    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
                // mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                // m_scanlist_enable = true;
                // xx_scan_start(FILTER_ENABLE);
    
                /* Often, when securing fails, it shouldn't be restarted, for security reasons.
                 * Other times, it can be restarted directly.
                 * Sometimes it can be restarted, but only after changing some Security Parameters.
                 * Sometimes, it cannot be restarted until the link is disconnected and reconnected.
                 * Sometimes it is impossible, to secure the link, or the peer device does not support it.
                 * How to handle this error is highly application dependent. */
    
            } break;
    
            case PM_EVT_CONN_SEC_CONFIG_REQ:
            {
                /* Reject pairing request from an already bonded peer .*/
                pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
                pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
            } break;
    
            case PM_EVT_STORAGE_FULL:
            {
                /* Run garbage collection on the flash. */
                err_code = fds_gc();
                if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
                {
                    // Retry.
                }
                else
                {
                    APP_ERROR_CHECK(err_code);
                }
            } break;
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
            {
               /* Bonds are deleted. Start scanning. */
               xx_scanning_start(true);
            } break;
    
            case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED\r\n");
                /* The local database has likely changed, send service changed indications. */
                pm_local_database_has_changed();
            } break;
    
            case PM_EVT_PEER_DATA_UPDATE_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_PEER_DATA_UPDATE_FAILED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error);
            } break;
    
            case PM_EVT_PEER_DELETE_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_PEER_DELETE_FAILED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
            } break;
    
            case PM_EVT_PEERS_DELETE_FAILED:
            {
                NRF_LOG_DEBUG("PM_EVT_PEERS_DELETE_FAILED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
            } break;
    
            case PM_EVT_ERROR_UNEXPECTED:
            {
                NRF_LOG_DEBUG("PM_EVT_ERROR_UNEXPECTED\r\n");
                /* Assert. */
                APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
            } break;
    
            case PM_EVT_CONN_SEC_START:
            {
                APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
                NRF_LOG_INFO("BOND STARTXXXXXXXXXXXXXXXXX, procedure: %d.",
                             p_evt->params.conn_sec_start.procedure);
            }
            case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
            case PM_EVT_PEER_DELETE_SUCCEEDED:
            case PM_EVT_LOCAL_DB_CACHE_APPLIED:
                break;
            case PM_EVT_SERVICE_CHANGED_IND_SENT:
                NRF_LOG_DEBUG("PM_EVT_SERVICE_CHANGED_IND_SENT\r\n");
            break;
            case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
                NRF_LOG_DEBUG("PM_EVT_SERVICE_CHANGED_IND_SENT\r\n");
            default:
                break;
        }
    }
    
    
    /**
     * @brief Battery level Collector Handler.
     */
    static void bas_c_evt_handler(ble_bas_c_t * p_bas_c, ble_bas_c_evt_t * p_bas_c_evt)
    {
        ret_code_t err_code;
        static uint16_t batt = 0;
    
        switch (p_bas_c_evt->evt_type)
        {
            case BLE_BAS_C_EVT_DISCOVERY_COMPLETE:
            {
                NRF_LOG_INFO("[%04d] bas discovery complete.", __LINE__);
                err_code = ble_bas_c_handles_assign(p_bas_c,
                                                    p_bas_c_evt->conn_handle,
                                                    &p_bas_c_evt->params.bas_db);
                APP_ERROR_CHECK(err_code);
    
                // Initiate bonding.
                if (m_pair_bound_flag) {
                    err_code = pm_conn_secure(p_bas_c_evt->conn_handle, false);
                    if (err_code != NRF_ERROR_INVALID_STATE) {
                        APP_ERROR_CHECK(err_code);
                    }
                }
    
                APP_ERROR_CHECK(app_timer_start(rgb_flash_timer2, THREE_INTERVAL, NULL));
                /* APP_ERROR_CHECK(ble_bas_c_bl_notif_enable(&m_bas_c));*/
                APP_ERROR_CHECK(app_timer_start(bat_check_timer_id, APP_TIMER_TICKS(10000) , NULL));
                APP_ERROR_CHECK(ble_bas_c_bl_read(&m_bas_c));
               
                
                
            } break;
    
            case BLE_BAS_C_EVT_BATT_NOTIFICATION:
                m_battery_states_t = p_bas_c_evt->params.battery_level;
                NRF_LOG_INFO("Battery notify  %d%%.", m_battery_states_t);
                break;
    
            case BLE_BAS_C_EVT_BATT_READ_RESP:
                if (p_bas_c_evt->params.battery_level != batt) {
                    batt = p_bas_c_evt->params.battery_level;
                    m_temp_array.type = PHONE_CMD_BATTERY;
                    ble_nus_chars_received_uart_print(&batt, 1);
                }
                NRF_LOG_INFO("Battery read as %d%%.", p_bas_c_evt->params.battery_level);
                break;
    
            default:
                break;
        }
    }
    
    
    /**
     * @brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
    {
        ret_code_t err_code;
        ble_gap_evt_t const *p_gap_evt = &p_ble_evt->evt.gap_evt;
    
        switch (p_ble_evt->header.evt_id) {
            case BLE_GAP_EVT_ADV_REPORT: 
                scan_data_resolve_handler(p_ble_evt, NULL);
                break;
    
            case BLE_GAP_EVT_CONNECTED:
            {
                m_std_cmd_states = CMD_NONE;
                m_scan_states    = BLE_SCAN_CONN;
                uart_rec_process_clr();
    
                NRF_LOG_INFO("[%04d] Connected already", __LINE__);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                m_pending_db_disc_conn = p_ble_evt->evt.gap_evt.conn_handle;
                m_retry_db_disc = false;
                m_connect_flag = true;
    
                err_code = ble_db_discovery_start(&m_db_disc, m_pending_db_disc_conn);
                if (err_code == NRF_ERROR_BUSY) {
                    NRF_LOG_INFO("ble_db_discovery_start() returned busy, will retry later.\r\n");
                    m_retry_db_disc = true;
                } else if (err_code == NRF_ERROR_INVALID_STATE){
                   
                } else {
                    APP_ERROR_CHECK(err_code);
                }
    
                break;
            }
    
            case BLE_GAP_EVT_DISCONNECTED:
            {
                NRF_LOG_INFO("[%4d]line !!!Disconnected, reason 0x%x.\r\n", __LINE__,
                             p_ble_evt->evt.gap_evt.params.disconnected.reason);
                m_std_cmd_states = CMD_NONE;
                m_scan_states    = BLE_SCAN_STOP;
    
                /*RGB:断开连接 .*/
                mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                uart_rec_process_clr();
                APP_ERROR_CHECK(app_timer_stop(bat_check_timer_id));
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                mt_dev_pair_scan_connect();
                break;
            }
    
            case BLE_GAP_EVT_TIMEOUT:
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) {
    
                    if (m_scanlist_enable == false) {
                        m_scanlist_enable = mt_scan_data_in_order();
                    }else {
                        m_scanlist_enable = false;
                    }
    
                    if(m_scan_pair_count++ < 36) {  /* 36个循环36 * 5 = 180s */
                        xx_scan_start(FILTER_ENABLE);
                    } else {
                        /*RGB:配对超时 .*/
                        m_scan_pair_count = 0;
                        NRF_LOG_INFO("[%04d] pair timeout.", __LINE__);
                        
                        APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
                        mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                    }
    
                } else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) {
                    NRF_LOG_INFO("[%04d] Connection Request timed out.", __LINE__);
    
                    /*RGB:连接超时 .*/
                    mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
                    m_scanlist_enable = true;
                    xx_scan_start(FILTER_ENABLE);
                }
                break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                /* Accepting parameters requested by peer. */
                APP_ERROR_CHECK(sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                            &p_gap_evt->params.conn_param_update_request.conn_params));
                break;
    
    #ifndef S140
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
                NRF_LOG_DEBUG("[%04d] PHY update request.", __LINE__);
                ble_gap_phys_t const phys = {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                APP_ERROR_CHECK(sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, 
                                                    &phys));
            } break;
    #endif
    
            case BLE_GATTC_EVT_TIMEOUT:
                /* Disconnect on GATT Client timeout event. */
                NRF_LOG_DEBUG("[%04d] GATT Client Timeout.", __LINE__);
                APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                /* Disconnect on GATT Server timeout event. */
                NRF_LOG_DEBUG("[%04d] GATT Server Timeout.", __LINE__);
                APP_ERROR_CHECK(sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
                break;
    
            case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
                break;
    
            default:
                break;
        }
    }
    
    
    /**@brief SoftDevice SoC event handler.
     *
     * @param[in]   evt_id      SoC event.
     * @param[in]   p_context   Context.
     */
    static void soc_evt_handler(uint32_t evt_id, void * p_context)
    {
        switch (evt_id)
        {
            case NRF_EVT_FLASH_OPERATION_SUCCESS:
                /* fall through */
            case NRF_EVT_FLASH_OPERATION_ERROR:
    
                if (m_memory_progress) {
                    m_memory_progress = false;
                    NRF_LOG_INFO("[%04d] memory error.", __LINE__);
                    mt_dev_pair_scan_connect();
                }
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    /** 
     * @brief Function for handling events from the GATT library. 
     */
    void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt)
    {
        if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED) {
            NRF_LOG_INFO("[%04d] ATT MTU exchange completed.", __LINE__);
    
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - 
                                    OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("[%04d] Ble NUS max data length set to 0x%X(%d)", __LINE__, m_ble_nus_max_data_len, m_ble_nus_max_data_len);
        }
    
         if (m_retry_db_disc) {
            NRF_LOG_DEBUG("Retrying DB discovery.\r\n");
    
            m_retry_db_disc = false;
    
            // Discover peer's services.
            ret_code_t err_code;
            err_code = ble_db_discovery_start(&m_db_disc, m_pending_db_disc_conn);
    
            if (err_code == NRF_ERROR_BUSY) {
                NRF_LOG_DEBUG("ble_db_discovery_start() returned busy, will retry later.\r\n");
                m_retry_db_disc = true;
            } else {
                APP_ERROR_CHECK(err_code);
            } 
        }
    }
    
    
    /**
     * @brief Function for button handler
     */
    static void button_event_handler(xx_button_app_evt_t * evt_code)
    {
        NRF_LOG_RAW_INFO("button_event_handler");
        if (evt_code->btn_evt == XX_BTN_LONG_PUSH_EVT) {
            switch (evt_code->pin_no) {
                case TEST_BUTTON :
                    m_pair_bound_flag = true;
                    break;
                default :
                    break;
            }
        }
    }
    
    
    /**
     * @brief 看门狗中断
     */
    static void wdt_event_handler(void) {
        /* @todo */
    }
    
    
    /**
     * @brief 定时喂狗
     */
    static void wdt_timeout_handler(void * p_context) 
    {
        nrf_drv_wdt_feed();
        nrf_delay_us(150);
    }
    
    
    /**
     * @brief 定时检测电池电量
     */
    static void battery_check_timeout_handler(void * p_context) 
    {
        APP_ERROR_CHECK(ble_bas_c_bl_read(&m_bas_c));
    }
    
    
    /**
     * @brief 配对定时闪
     */
    static void rgb_flash_timeout_handler1(void * p_context) {
        mt_rgb_flash_fun(RGB_STATE2, RGB_STATE1);
    }
    
    
    /**
     * @brief 预留当连接三秒没有手机APP数据后亮指定灯
     */
    static void rgb_flash_timeout_handler2(void * p_context) {
        if(nrf_gpio_pin_read(XXXX1_PIN_NUMBER) == 1 && is_device_connect() == true) {
            mt_rgb_flash_fun(RGB_STATE9, RGB_NULL);
        } 
    
        else 
        if (nrf_gpio_pin_read(XXXX1_PIN_NUMBER) == 0 && is_device_connect() == true) {
            mt_rgb_flash_fun(RGB_STATE10, RGB_NULL);
        }
    }
    
    /**
     * @brief 180s关闭配对闪烁灯.
     */
    static void rgb_close_rgb_pair_handler(void * p_context) {
       /*RGB:180s没有配对成功, 关灯 .*/
        m_scan_pair_count = 0;
        NRF_LOG_INFO("[%04d] 180s close flash rgb.", __LINE__);
                        
        APP_ERROR_CHECK(app_timer_stop(rgb_flash_timer1));
        mt_rgb_flash_fun(RGB_NULL, RGB_NULL);
    }
    
    /**
     * @brief Battery level collector initialization.
     */
    static void bas_c_init(void)
    {
        ble_bas_c_init_t bas_c_init_obj;
    
        bas_c_init_obj.evt_handler = bas_c_evt_handler;
    
        ret_code_t err_code = ble_bas_c_init(&m_bas_c, &bas_c_init_obj);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /** 
     * @brief Function for initializing the NUS Client. 
     */
    static void nus_c_init(void)
    {
        ble_nus_c_init_t init;
    
        init.evt_handler = ble_nus_c_evt_handler;
        APP_ERROR_CHECK(ble_nus_c_init(&m_ble_nus_c, &init));
    }
    
    
    /** 
     * @brief Function for initializing the GATT library. 
     */
    void gatt_init(void)
    {
        APP_ERROR_CHECK(nrf_ble_gatt_init(&m_gatt, gatt_evt_handler));
    
        APP_ERROR_CHECK(nrf_ble_gatt_att_mtu_central_set(&m_gatt, BLE_GATT_ATT_MTU_DEFAULT));
    }
    
    
    /**
     * @brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        APP_ERROR_CHECK(nrf_sdh_enable_request());
    
        /** Configure the BLE stack using the default settings.
         *  Fetch the start address of the application RAM. 
         */
        uint32_t ram_start = 0;
        APP_ERROR_CHECK(nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start));
    
        /* Enable BLE stack. */
        APP_ERROR_CHECK(nrf_sdh_ble_enable(&ram_start));
    
        /* Register a handler for BLE events. */
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
        NRF_SDH_SOC_OBSERVER(m_soc_observer, APP_SOC_OBSERVER_PRIO, soc_evt_handler, NULL);
    }
    
    
    /** 
     * @brief Function for initializing the Database Discovery Module. 
     */
    static void db_discovery_init(void)
    {
        APP_ERROR_CHECK(ble_db_discovery_init(db_disc_handler));
    }
    
    
    /**
     * @brief Function for gpiote:1.预留的输入引脚 2.预留引脚2
     */
    static void gpio_init(void)
    {
        nrf_gpio_cfg_input(TEST_IC_OUT_1,NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(TEST_IC_OUT_2,NRF_GPIO_PIN_PULLUP);
        nrf_gpio_cfg_input(TEST_BUTTON,NRF_GPIO_PIN_PULLUP);
        
        /* 预留颜色选择引脚. */
        nrf_gpio_cfg_input(XXXX1_PIN_NUMBER,NRF_GPIO_PIN_PULLUP);
    
        mt_WS2812B_rgb_init();
       
    }
    
    
    /**
     * @brief 相关硬件初始化
     */
    static void mt_dev_pair_scan_connect(void) {
        m_cmd_collection.scan_inte_win_level     = DEFAULT_L_SCAN_INTERVAL;   
        m_cmd_collection.min_max_cinterval_level = DEFAULT_L_CONN_INTERVAL;
    
        if (nrf_fstorage_is_busy(NULL)) {
            NRF_LOG_INFO("nrf fstorage is busy.");
            m_memory_progress = true;
            return;
        }
    
        if(mt_peer_pair_init(m_cmd_collection) == true) {
            xx_scan_start(FILTER_ENABLE);
            if (m_pair_bound_flag) {
                mt_rgb_flash_fun(RGB_STATE2, RGB_STATE2);
                APP_ERROR_CHECK(app_timer_start(rgb_flash_3_min_id, APP_TIMER_TICKS(180000), NULL));
                APP_ERROR_CHECK(app_timer_start(rgb_flash_timer1, APP_TIMER_TICKS(2000), NULL));
            }
        }
    }
    
    
    /**
     * @brief Application timer start.
     */
    static void application_timers_start(void)
    {
        APP_ERROR_CHECK(app_timer_create(&wdt_timer_id, APP_TIMER_MODE_REPEATED, 
                        wdt_timeout_handler));
        APP_ERROR_CHECK(app_timer_start(wdt_timer_id, ONE_SECOND_INTERVAL, NULL));
    
        /* 定时检测电量 */
        APP_ERROR_CHECK(app_timer_create(&bat_check_timer_id, APP_TIMER_MODE_REPEATED, 
                        battery_check_timeout_handler));
    
        /* 配对定时闪 */
        APP_ERROR_CHECK(app_timer_create(&rgb_flash_timer1, APP_TIMER_MODE_REPEATED, 
                        rgb_flash_timeout_handler1));
    
        /* 连接上后3秒,预留高低电平脚,对应RGB颜色灯*/
        APP_ERROR_CHECK(app_timer_create(&rgb_flash_timer2, APP_TIMER_MODE_SINGLE_SHOT, 
                        rgb_flash_timeout_handler2));
        
        /* 180s没有配对成功,关灯.*/
        APP_ERROR_CHECK(app_timer_create(&rgb_flash_3_min_id, APP_TIMER_MODE_SINGLE_SHOT, 
                        rgb_close_rgb_pair_handler));
    }
    
    
    /**
     * @brief 相关硬件初始化
     */
    static void hal_init(void)
    {
        rgb_ss_init();
        uart_init();
        APP_ERROR_CHECK(app_fifo_init(&m_uart_rec_fifo, m_rec_buf, sizeof(m_rec_buf)));
        uart_rec_process_clr();
        NRF_LOG_DEBUG("[%04d] UART init", __LINE__);
    }
    
    
    /**
     * @brief 主端应用与服务初始化
     */
    static void ble_central_init(void)
    {
        gpio_init();
        ble_stack_init();
        gatt_init();
        mt_peer_manager_init();
        APP_ERROR_CHECK(pm_register(pm_evt_handler));
        db_discovery_init();
        nus_c_init();
        bas_c_init();
        NRF_LOG_DEBUG("[%04d] ble service init", __LINE__);
    }
    
    
    /**
     * @brief 基本必需功能初始化
     */
    static void basic_init(void)
    {
        nrf_delay_ms(400);
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        APP_ERROR_CHECK(app_timer_init());
        APP_ERROR_CHECK(app_simple_timer_init());
    
        /* APP gpiote初始化注册. */
        APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS);
    
        /* SCHED初始化. */
        APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    
    
        APP_ERROR_CHECK(nrf_pwr_mgmt_init());
    
        /* 看门狗初始化. */
        nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
        APP_ERROR_CHECK(nrf_drv_wdt_init(&config, wdt_event_handler));
        APP_ERROR_CHECK(nrf_drv_wdt_channel_alloc(&m_channel_id));
    
        NRF_LOG_DEBUG("[%04d] basic init", __LINE__);
    }
    
    
    /**
     * @brief Enter main function.0
     */
    int main(void)
    {
        basic_init();
        ble_central_init();
        hal_init();
    
        nrf_drv_wdt_enable();  
        application_timers_start();
        NRF_LOG_INFO("[%04d] ble uart central started", __LINE__);
        mt_dev_pair_scan_connect();
    
        while (true){
            app_sched_execute();
            sched_monitor();
            if (NRF_LOG_PROCESS() == false) {
                nrf_pwr_mgmt_run();
            }
        }
    }
    

Children
Related