- binary_tx_handler를 dr_binary_tx_safe로 전체 교체 (APP_ERROR_CHECK 제거) - data_tx_handler APP_ERROR_CHECK → DBG_PRINTF 교체 - memset/memcpy 하드코딩 크기를 define 상수로 교체 (버퍼 오버런 수정) - SERIAL_NO_LENGTH, HW_NO_LENGTH, PASSKEY_LENGTH를 main.h로 통합 - 미사용 HW 드라이버/EEPROM 코드 삭제, TWI를 i2c_manager.c로 통합 - EEPROM → FDS 전환, 코드 리뷰 현황 문서 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
317 lines
9.0 KiB
C
317 lines
9.0 KiB
C
/*******************************************************************************
|
|
* @file battery_saadc.c
|
|
* @author CandyPops Co.
|
|
* @version V1.0.0
|
|
* @date 2022-09-05
|
|
* @brief
|
|
******************************************************************************/
|
|
|
|
#include "sdk_common.h"
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include "nrf.h"
|
|
#include "boards.h"
|
|
#include "app_error.h"
|
|
#include "nrf_drv_saadc.h"
|
|
#include "nrf_drv_timer.h"
|
|
#include "ble_nus.h"
|
|
#include "nrf_log.h"
|
|
#include "main.h"
|
|
#include "app_timer.h"
|
|
//#include "fstorage.h"
|
|
#include "battery_saadc.h"
|
|
#include "main_timer.h"
|
|
#include <cmd_parse.h>
|
|
#include "debug_print.h"
|
|
#define BATTERY_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
|
|
#define BATTERY_PRE_SCALING_COMPENSATION 6 /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
|
|
#define BATTERY_ADC_RES_10BITS 1023 /**< Maximum digital value for 10-bit ADC conversion. */
|
|
//#define PRESSURE_RESULT_IN_MILLI_VOLTS(adc) ((adc * 3600) / 1023)
|
|
|
|
#define PRESSURE_OFFSET_DEFAULT 0 // ?? offset. ?? ? ??? ?? ??.
|
|
#define MV_PER_ADC_STEP 805 // ? 0.805mV per 1 LSB (nRF 12bit + scaling)
|
|
/**@brief Macro to convert the result of ADC conversion in millivolts.
|
|
*
|
|
* @param[in] ADC_VALUE ADC result.
|
|
*
|
|
* @retval Result converted to millivolts.
|
|
*/
|
|
#define BATTERY_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
|
|
((((ADC_VALUE) * BATTERY_REF_VOLTAGE_IN_MILLIVOLTS) / BATTERY_ADC_RES_10BITS) * BATTERY_PRE_SCALING_COMPENSATION)
|
|
|
|
static nrf_saadc_value_t adc_bufs[2];
|
|
static int16_t pressure_adc_buf[2]; //cj add 25/11/19
|
|
static uint16_t convert_adc_to_mV(int16_t raw_adc); //cj add 25/11/19
|
|
|
|
APP_TIMER_DEF(m_battery_loop_timer_id);
|
|
#define BATTERY_LOOP_INTERVAL 5000
|
|
|
|
bool low_battery_check = false;
|
|
extern bool info4; //cmd_parse
|
|
|
|
// cj add edit 25/11/24
|
|
volatile uint16_t info_p1;
|
|
volatile uint16_t info_p2;
|
|
|
|
|
|
extern char ble_tx_buffer[BLE_NUS_MAX_DATA_LEN];
|
|
extern bool go_device_power_off;
|
|
extern volatile bool processing;
|
|
|
|
extern which_cmd_t cmd_type_t;
|
|
|
|
extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
|
|
volatile uint16_t info_batt; //48_c
|
|
extern bool go_temp; //
|
|
extern bool go_batt; //cmd_parse
|
|
|
|
extern bool motion_raw_data_enabled ;
|
|
extern bool ble_got_new_data;
|
|
extern bool motion_data_once ;
|
|
/**@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.
|
|
*/
|
|
static uint16_t convert_adc_to_mV(int16_t raw_adc)
|
|
{
|
|
if (raw_adc < 0)
|
|
raw_adc = 0;
|
|
|
|
int32_t mv = (int32_t)raw_adc * MV_PER_ADC_STEP; // ?: 805 uV
|
|
mv /= 1000;
|
|
|
|
// ===== (3) 0~3500mV ??? ???? ?? ?? =====
|
|
if (mv < 0)
|
|
mv = 0;
|
|
|
|
if (mv > 3500)
|
|
mv = 3500;
|
|
|
|
|
|
return (uint16_t)mv;
|
|
}
|
|
void pressure_all_event_handler(nrf_drv_saadc_evt_t const * p_event)
|
|
{
|
|
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
|
|
{
|
|
int16_t p1_adc = p_event->data.done.p_buffer[0]; // AIN7
|
|
int16_t p2_adc = p_event->data.done.p_buffer[1]; // AIN4
|
|
|
|
|
|
uint16_t p1_mV = convert_adc_to_mV(p1_adc);
|
|
uint16_t p2_mV = convert_adc_to_mV(p2_adc);
|
|
|
|
// PD Full mode(info4=true)When info_p1/info_p2 to Update
|
|
if(info4 == true)
|
|
{
|
|
info_p1 = p1_mV;
|
|
info_p2 = p2_mV;
|
|
}
|
|
// Re-buffer
|
|
APP_ERROR_CHECK(nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 2));
|
|
|
|
// uninit
|
|
nrf_drv_saadc_uninit();
|
|
nrf_drv_saadc_channel_uninit(0);
|
|
nrf_drv_saadc_channel_uninit(1);
|
|
|
|
// UART send
|
|
|
|
if(cmd_type_t == CMD_UART)
|
|
{
|
|
DBG_PRINTF("P1:%d P2:%d\r\n", p1_mV, p2_mV);
|
|
}
|
|
else if(cmd_type_t == CMD_BLE && info4 == false)
|
|
{
|
|
DBG_PRINTF("P1:%d P2:%d\r\n", p1_mV, p2_mV);
|
|
// uint16_t len = sprintf((char*)ble_bin_buffer,
|
|
// "rpn:%04x,%04x", p1_mV, p2_mV);
|
|
uint16_t result_data[2];
|
|
result_data[0] = p1_mV;
|
|
result_data[1] = p2_mV;
|
|
format_data(ble_bin_buffer, "rpn:", result_data,2);
|
|
dr_binary_tx_safe(ble_bin_buffer,4);
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
|
|
{
|
|
|
|
static uint8_t low_battery_cnt = 0;
|
|
|
|
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
|
|
{
|
|
nrf_saadc_value_t register_val = 0;
|
|
uint16_t batt_lvl_in_milli_volt_0 = 0;
|
|
uint16_t batt_lvl_in_milli_volt_1 = 0;
|
|
uint32_t err_code = 0;
|
|
|
|
register_val = 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);
|
|
|
|
nrf_drv_saadc_uninit();
|
|
nrf_drv_saadc_channel_uninit(0);
|
|
|
|
batt_lvl_in_milli_volt_0 = BATTERY_RESULT_IN_MILLI_VOLTS(register_val);
|
|
batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0) *1.42;
|
|
if(low_battery_check == true) {
|
|
|
|
low_battery_check = false;
|
|
|
|
if(batt_lvl_in_milli_volt_1 <= LOW_BATTERY_VOLTAGE) {
|
|
if(low_battery_cnt >= 10) {
|
|
low_battery_cnt = 0;
|
|
/*go to power off and fds save */
|
|
DBG_PRINTF("Save FDS parameters and then Power OFF\r\n");
|
|
go_device_power_off = true;
|
|
main_timer_start();
|
|
}else{
|
|
low_battery_cnt++;
|
|
DBG_PRINTF("WARNING!!! low_battery cnt = %d, Batt = %d(mV)\r\n", low_battery_cnt, batt_lvl_in_milli_volt_1);
|
|
}
|
|
}
|
|
|
|
}
|
|
else if (info4 == true){
|
|
|
|
info_batt = batt_lvl_in_milli_volt_1;
|
|
DBG_PRINTF("INFOTn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
if(cmd_type_t == CMD_UART) {
|
|
DBG_PRINTF("Tn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
|
|
} else if(cmd_type_t == CMD_BLE) {
|
|
|
|
single_format_data(ble_bin_buffer, "rsn:", batt_lvl_in_milli_volt_1);
|
|
|
|
dr_binary_tx_safe(ble_bin_buffer,3);
|
|
//data_tx_handler(ble_tx_buffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (info4 == true){
|
|
go_batt =false;
|
|
go_temp = true;
|
|
main_timer_start();
|
|
}
|
|
}
|
|
|
|
|
|
/**@brief Function for configuring ADC to do battery level conversion.
|
|
*/
|
|
static void battery_configure(void)
|
|
{
|
|
ret_code_t err_code = nrf_drv_saadc_init(NULL, battery_event_handler);
|
|
APP_ERROR_CHECK(err_code);
|
|
|
|
nrf_saadc_channel_config_t config =
|
|
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);
|
|
err_code = nrf_drv_saadc_channel_init(0, &config);
|
|
APP_ERROR_CHECK(err_code);
|
|
|
|
err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[0], 1);
|
|
APP_ERROR_CHECK(err_code);
|
|
|
|
err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[1], 1);
|
|
APP_ERROR_CHECK(err_code);
|
|
}
|
|
void pressure_all_configure(void)
|
|
{
|
|
ret_code_t err_code;
|
|
|
|
err_code = nrf_drv_saadc_init(NULL, pressure_all_event_handler);
|
|
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
|
|
DBG_PRINTF("SAADC init err=%d\r\n", err_code);
|
|
return;
|
|
}
|
|
|
|
nrf_saadc_channel_config_t ch0_cfg =
|
|
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
|
|
nrf_saadc_channel_config_t ch1_cfg =
|
|
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
|
|
|
|
err_code = nrf_drv_saadc_channel_init(0, &ch0_cfg);
|
|
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
|
|
DBG_PRINTF("SAADC ch0 init err=%d\r\n", err_code);
|
|
return;
|
|
}
|
|
|
|
err_code = nrf_drv_saadc_channel_init(1, &ch1_cfg);
|
|
if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
|
|
DBG_PRINTF("SAADC ch1 init err=%d\r\n", err_code);
|
|
return;
|
|
}
|
|
|
|
err_code = nrf_drv_saadc_buffer_convert(pressure_adc_buf, 2);
|
|
if (err_code != NRF_SUCCESS) {
|
|
DBG_PRINTF("SAADC buf conv err=%d\r\n", err_code);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void battery_level_meas(void)
|
|
{
|
|
ret_code_t err_code;
|
|
|
|
battery_configure();
|
|
err_code = nrf_drv_saadc_sample();
|
|
APP_ERROR_CHECK(err_code);
|
|
|
|
|
|
}
|
|
void pressure_all_level_meas(void) //add cj add 25/11/19
|
|
{
|
|
ret_code_t err_code;
|
|
|
|
pressure_all_configure(); // 2
|
|
|
|
err_code = nrf_drv_saadc_sample();
|
|
APP_ERROR_CHECK(err_code);
|
|
}
|
|
|
|
void battery_loop(void * p_context) /* For 1sec */
|
|
{
|
|
UNUSED_PARAMETER(p_context);
|
|
if(processing==true)
|
|
{
|
|
processing = false ; // add 20241218
|
|
//low_battery_check = true;
|
|
return;}
|
|
else{
|
|
low_battery_check = true;
|
|
battery_level_meas();
|
|
}
|
|
}
|
|
|
|
void battery_timer_start(void)
|
|
{
|
|
APP_ERROR_CHECK(app_timer_start(m_battery_loop_timer_id, APP_TIMER_TICKS(BATTERY_LOOP_INTERVAL), NULL));
|
|
}
|
|
|
|
void battery_timer_stop(void)
|
|
{
|
|
APP_ERROR_CHECK(app_timer_stop(m_battery_loop_timer_id));
|
|
}
|
|
|
|
void battery_timer_init(void)
|
|
{
|
|
APP_ERROR_CHECK(app_timer_create(&m_battery_loop_timer_id, APP_TIMER_MODE_REPEATED, battery_loop));
|
|
}
|
|
|
|
|