/**@brief Function for handling the ADC interrupt. * * @details This function will fetch the conversion result from the ADC, convert the value into * percentage and send it to peer. */ void ADC_IRQHandler(void) { if (nrf_adc_conversion_finished()) { uint8_t adc_result; uint16_t batt_lvl_in_milli_volts; uint8_t percentage_batt_lvl; uint32_t err_code; nrf_adc_conversion_event_clean(); adc_result = nrf_adc_result_get(); batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS; percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts); err_code = ble_bas_battery_level_update(&m_bas, percentage_batt_lvl); if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_BUFFERS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } } }
/**@brief Function for handling the ADC interrupt. * * @details This function will fetch the conversion result from the ADC, convert the value into * percentage and send it to peer. */ void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event) { if (p_event->type == NRF_DRV_SAADC_EVT_DONE) { nrf_saadc_value_t adc_result; uint16_t batt_lvl_in_milli_volts; uint8_t percentage_batt_lvl; uint32_t err_code; adc_result = p_event->data.done.p_buffer[0]; err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer,1); APP_ERROR_CHECK(err_code); batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS; percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts); err_code = ble_bas_battery_level_update(&m_bas, percentage_batt_lvl); if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } } }
/**@brief Function for handling the ADC interrupt. * @details This function will fetch the conversion result from the ADC, convert the value into * percentage and send it to peer. */ void ADC_IRQHandler(void) { if (NRF_ADC->EVENTS_END != 0) { uint8_t adc_result; uint16_t batt_lvl_in_milli_volts; uint8_t percentage_batt_lvl; uint32_t err_code; NRF_ADC->EVENTS_END = 0; adc_result = NRF_ADC->RESULT; NRF_ADC->TASKS_STOP = 1; batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS; percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts); err_code = ble_bas_battery_level_update(&bas, percentage_batt_lvl); if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_BUFFERS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } } }
/**@brief Function for handling the ADC interrupt. * * @details This function will fetch the conversion result from the ADC, convert the value into * percentage and send it to peer. */ void ADC_IRQHandler(void) { uint32_t err_code; uint16_t adc_value; uint8_t percentage_batt_lvl; uint16_t batt_lvl_in_milli_volts; nrf_adc_conversion_event_clean(); nrf_adc_stop(); adc_value = nrf_adc_result_get(); batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_value); percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts); err_code = ble_bas_battery_level_update(&m_bas, percentage_batt_lvl); if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; battery_detect_start(); while(!battery_is_available()); battery_level = get_battery_value(); battery_detect_stop(); // xprintf("...battery_level = %d% \r\n", battery_level); // if(battery_level < 20) // system_low_battery(); err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_BUFFERS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
//============================================================================// void CP_BatteryServiceUpdate(uint8_t level) { uint32_t err_code; err_code = ble_bas_battery_level_update(&_bas, level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_BUFFERS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; battery_level = battery_level-counter; err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_BUFFERS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg); err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; battery_level = 79; err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) { APP_ERROR_HANDLER(err_code); debug_printf("Error updating battery level \r\n"); } }
/**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; //battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg); //printf("\n\rBegin conversion: ADC value = %d \r\n", (int)adc_sample); battery_level = (uint8_t)((float)adc_sample/9.04); //printf("\n\rConversion complete: batt level = %d \r\n", (int)battery_level); err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_BUFFERS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/** * @brief ADC interrupt handler. */ static void adc_event_handler(nrf_drv_adc_evt_t const * p_event) { uint32_t err_code; uint16_t adc_sum_value = 0; uint16_t adc_average_value; uint16_t adc_result_millivolts; uint8_t adc_result_percent; sd_clock_hfclk_release(); //Release the external crystal adc_event_counter++; NRF_LOG_INFO(" ADC event counter: %d\r\n", adc_event_counter); if (p_event->type == NRF_DRV_ADC_EVT_DONE) { uint32_t i; for (i = 0; i < p_event->data.done.size; i++) { NRF_LOG_INFO("Sample value %d: %d\r\n", i+1, p_event->data.done.p_buffer[i]); adc_sum_value += p_event->data.done.p_buffer[i]; //Sum all values in ADC buffer } adc_average_value = adc_sum_value / p_event->data.done.size; //Calculate average value from all samples in the ADC buffer NRF_LOG_INFO("Average ADC value: %d\r\n", adc_average_value); adc_result_millivolts = ADC_RESULT_IN_MILLI_VOLTS(adc_average_value); //Transform the average ADC value into millivolts value NRF_LOG_INFO("ADC result in millivolts: %d\r\n", adc_result_millivolts); adc_result_percent = battery_level_in_percent(adc_result_millivolts); //Transform the millivolts value into battery level percent. NRF_LOG_INFO("ADC result in percent: %d\r\n", adc_result_percent); //Send the battery level over BLE err_code = ble_bas_battery_level_update(&m_bas, adc_result_percent); //Send the battery level over BLE if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) { APP_ERROR_HANDLER(err_code); //Assert on error } } }
/**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; static uint8_t battery_level = 0; battery_level++; if (battery_level > 100) { battery_level = 0; } err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/**@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.\r\n"); } break; case PM_EVT_CONN_SEC_SUCCEEDED: { NRF_LOG_INFO("Connection secured. Role: %d. conn_handle: %d, Procedure: %d\r\n", 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: { /* 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: { advertising_start(); } break; case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED: { // The local database has likely changed, send service changed indications. pm_local_database_has_changed(); } break; case PM_EVT_PEER_DATA_UPDATE_FAILED: { // Assert. APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error); } break; case PM_EVT_PEER_DELETE_FAILED: { // Assert. APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error); } break; case PM_EVT_PEERS_DELETE_FAILED: { // Assert. APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error); } break; case PM_EVT_ERROR_UNEXPECTED: { // Assert. APP_ERROR_CHECK(p_evt->params.error_unexpected.error); } break; case PM_EVT_CONN_SEC_START: case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED: case PM_EVT_PEER_DELETE_SUCCEEDED: case PM_EVT_LOCAL_DB_CACHE_APPLIED: case PM_EVT_SERVICE_CHANGED_IND_SENT: case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED: default: break; } } /**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg); err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } }
/**@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_PRINTF_DEBUG("Connected to previously bonded device\r\n"); // Start Security Request timer. err_code = app_timer_start(m_sec_req_timer_id, SECURITY_REQUEST_DELAY, NULL); APP_ERROR_CHECK(err_code); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } }break;//PM_EVT_BONDED_PEER_CONNECTED case PM_EVT_CONN_SEC_START: break;//PM_EVT_CONN_SEC_START case PM_EVT_CONN_SEC_SUCCEEDED: { /*Check if the link is authenticated (meaning at least MITM)*/ pm_conn_sec_status_t conn_sec_status; err_code = pm_conn_sec_status_get(p_evt->conn_handle, &conn_sec_status); APP_ERROR_CHECK(err_code); if (!conn_sec_status.mitm_protected) { APP_LOG("Collector did not use MITM, disconnecting\r\n"); /*The peer did not use MITM, disconnect*/ err_code = pm_peer_id_get(m_conn_handle, &peer_to_be_deleted); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); // m_state = W_ADV_STATE_UNBONDED; } else { NRF_LOG_PRINTF_DEBUG("Link secured. Role: %d. conn_handle: %d, Procedure: %d\r\n", ble_conn_state_role(p_evt->conn_handle), p_evt->conn_handle, p_evt->params.conn_sec_succeeded.procedure); err_code = pm_peer_rank_highest(p_evt->peer_id); if (err_code != NRF_ERROR_BUSY) { APP_ERROR_CHECK(err_code); } // m_state = W_ADV_STATE_BONDED; } }break;//PM_EVT_CONN_SEC_SUCCEEDED case PM_EVT_CONN_SEC_FAILED: { /** In some cases, when securing fails, 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. */ APP_LOG("link secure failed! "); switch (p_evt->params.conn_sec_failed.error) { case PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING: NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING"); break;//PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING case PM_CONN_SEC_ERROR_MIC_FAILURE: NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_MIC_FAILURE"); break;//PM_CONN_SEC_ERROR_MIC_FAILURE case PM_CONN_SEC_ERROR_DISCONNECT : NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_DISCONNECT "); break;//PM_CONN_SEC_ERROR_DISCONNECT case PM_CONN_SEC_ERROR_SMP_TIMEOUT: NRF_LOG_DEBUG("error: PM_CONN_SEC_ERROR_SMP_TIMEOUT"); break;//PM_CONN_SEC_ERROR_SMP_TIMEOUT default: NRF_LOG_DEBUG("unknown error"); break; } APP_LOG("\r\nDisconnecting\r\n"); err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; }break;//PM_EVT_CONN_SEC_FAILED 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;//PM_EVT_CONN_SEC_CONFIG_REQ 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;//PM_EVT_STORAGE_FULL case PM_EVT_ERROR_UNEXPECTED: // Assert. APP_ERROR_CHECK(p_evt->params.error_unexpected.error); break;//PM_EVT_ERROR_UNEXPECTED case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED: break;//PM_EVT_PEER_DATA_UPDATE_SUCCEEDED case PM_EVT_PEER_DATA_UPDATE_FAILED: // Assert. APP_ERROR_CHECK_BOOL(false); break;//PM_EVT_PEER_DATA_UPDATE_FAILED case PM_EVT_PEER_DELETE_SUCCEEDED: break;//PM_EVT_PEER_DELETE_SUCCEEDED case PM_EVT_PEER_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error); break;//PM_EVT_PEER_DELETE_FAILED case PM_EVT_PEERS_DELETE_SUCCEEDED: NRF_LOG_PRINTF_DEBUG("%s: PM_EVT_PEERS_DELETE_SUCCEEDED\r\n", __func__); // m_erasing_bonds = false; // advertising_init(); // advertising_start(); break; case PM_EVT_PEERS_DELETE_FAILED: // Assert. APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error); break;//PM_EVT_PEERS_DELETE_FAILED case PM_EVT_LOCAL_DB_CACHE_APPLIED: break;//PM_EVT_LOCAL_DB_CACHE_APPLIED case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED: // The local database has likely changed, send service changed indications. pm_local_database_has_changed(); break;//PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED case PM_EVT_SERVICE_CHANGED_IND_SENT: break;//PM_EVT_SERVICE_CHANGED_IND_SENT case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED: break;//PM_EVT_SERVICE_CHANGED_IND_CONFIRMED default: // No implementation needed. break; } } /**@brief Function for handling Service errors. * * @details A pointer to this function will be passed to each service which may need to inform the * application about an error. * * @param[in] nrf_error Error code containing information about what went wrong. */ //static void service_error_handler(uint32_t nrf_error) //{ // APP_ERROR_HANDLER(nrf_error); //} /**@brief Function for performing battery measurement and updating the Battery Level characteristic * in Battery Service. */ static void battery_level_update(void) { uint32_t err_code; uint8_t battery_level; // battery_level = (uint8_t)sensorsim_measure(&m_battery_sim_state, &m_battery_sim_cfg); battery_level = 37; err_code = ble_bas_battery_level_update(&m_bas, battery_level); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE) && (err_code != BLE_ERROR_NO_TX_PACKETS) && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) ) { APP_ERROR_HANDLER(err_code); } // if (m_adv_state == W_ADV_STATE_IDLE) { // advertising_init(); // advertising_start(); // } }