389 lines
9.0 KiB
C
389 lines
9.0 KiB
C
#include <common/bk_include.h>
|
|
#include "bk_arm_arch.h"
|
|
#include "bk_misc.h"
|
|
#include <os/mem.h>
|
|
#include "bk_drv_model.h"
|
|
#include "bk_sys_ctrl.h"
|
|
#include "bk_saradc.h"
|
|
#include "bk_uart.h"
|
|
|
|
#include "sys_rtos.h"
|
|
#include <os/os.h>
|
|
#include <common/bk_kernel_err.h>
|
|
#include "bk_fake_clock.h"
|
|
|
|
#include "bk_phy.h"
|
|
#include "temp_detect_pub.h"
|
|
#include "temp_detect.h"
|
|
#include "volt_detect.h"
|
|
#include "bk_ps.h"
|
|
#include "bk_wifi_private.h"
|
|
#include <components/log.h>
|
|
#include <components/ate.h>
|
|
#if CONFIG_SDMADC_TEMP
|
|
#include <driver/sdmadc.h>
|
|
#else
|
|
#include <driver/adc.h>
|
|
#endif
|
|
#include "drv_model.h"
|
|
#include "sys_driver.h"
|
|
#if CONFIG_FLASH_ORIGIN_API
|
|
#include "flash.h"
|
|
#endif
|
|
#include <modules/pm.h>
|
|
|
|
typedef struct {
|
|
uint16_t last_detect_val;
|
|
uint16_t detect_interval;
|
|
uint16_t detect_threshold;
|
|
uint16_t inital_data;
|
|
uint32_t detect_cnt;
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
beken2_timer_t detect_oneshot_timer;
|
|
#else
|
|
beken_timer_t detect_timer;
|
|
#endif
|
|
} volt_detect_config_t;
|
|
|
|
volt_detect_config_t s_voltd;
|
|
static uint16_t *s_raw_voltage_data = NULL;
|
|
|
|
extern void rwnx_cal_do_volt_detect(UINT16 volt_adc);
|
|
|
|
static int _volt_detect_init_adc_buffer(void)
|
|
{
|
|
if (!s_raw_voltage_data) {
|
|
s_raw_voltage_data = (uint16_t *)os_zalloc(ADC_TEMP_BUFFER_SIZE *
|
|
sizeof(s_raw_voltage_data[0]));
|
|
|
|
if (!s_raw_voltage_data) {
|
|
TEMPD_LOGE("oom\r\n");
|
|
return BK_ERR_NO_MEM;
|
|
}
|
|
}
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
#if CONFIG_SDMADC_TEMP
|
|
static int _volt_detect_get_adc_data(sdmadc_chan_t adc_chan, uint16_t *adc_buf)
|
|
{
|
|
sdmadc_config_t config = {0};
|
|
int err = BK_OK;
|
|
|
|
err = bk_sdmadc_driver_init();
|
|
if (BK_OK != err)
|
|
goto _release_adc;
|
|
|
|
err = bk_sdmadc_init();
|
|
if (BK_OK != err)
|
|
goto _release_adc;
|
|
|
|
config.samp_mode = 0x0;
|
|
config.samp_numb = 0x0;
|
|
config.samp_chan = adc_chan;
|
|
config.comp_bpss = 0x1;
|
|
config.cic2_bpss = 0x1;
|
|
config.cic2_gain = 0x2d;
|
|
config.int_enable = 0x8;
|
|
config.cali_offset = 0x0;
|
|
config.cali_gains = 0x1000;
|
|
|
|
err = bk_sdmadc_set_cfg(&config);
|
|
if (BK_OK != err)
|
|
goto _release_adc;
|
|
|
|
err = bk_sdmadc_read_raw((int16_t *)adc_buf, ADC_TEMP_BUFFER_SIZE);
|
|
|
|
_release_adc:
|
|
bk_sdmadc_deinit();
|
|
bk_sdmadc_driver_deinit();
|
|
|
|
return err;
|
|
}
|
|
#else
|
|
static int _volt_detect_get_adc_data(adc_chan_t adc_chan, uint16_t *adc_buf)
|
|
{
|
|
adc_config_t config = {0};
|
|
int err = BK_OK;
|
|
|
|
BK_RETURN_ON_ERR(bk_adc_acquire());
|
|
|
|
err = bk_adc_init(adc_chan);
|
|
if (BK_OK != err)
|
|
goto _release_adc;
|
|
|
|
config.chan = adc_chan;
|
|
config.adc_mode = ADC_CONTINUOUS_MODE;
|
|
config.clk = TEMP_DETEC_ADC_CLK;
|
|
config.src_clk = ADC_SCLK_XTAL_26M;
|
|
config.saturate_mode = ADC_TEMP_SATURATE_MODE;
|
|
config.sample_rate = TEMP_DETEC_ADC_SAMPLE_RATE;
|
|
config.steady_ctrl= TEMP_DETEC_ADC_STEADY_CTRL;
|
|
config.adc_filter = 0;
|
|
|
|
err = bk_adc_set_config(&config);
|
|
if (BK_OK != err)
|
|
goto _release_adc;
|
|
|
|
err = bk_adc_enable_bypass_clalibration();
|
|
if (BK_OK != err)
|
|
goto _release_adc;
|
|
|
|
err = bk_adc_start();
|
|
if (BK_OK != err)
|
|
goto _release_adc;
|
|
|
|
err = bk_adc_read_raw(adc_buf, ADC_TEMP_BUFFER_SIZE,
|
|
ADC_READ_SEMAPHORE_WAIT_TIME);
|
|
if (BK_OK != err) {
|
|
err = BK_ERR_TEMPD_SAMPLE_NO_DATA;
|
|
goto _release_adc;
|
|
}
|
|
|
|
_release_adc:
|
|
bk_adc_stop();
|
|
bk_adc_deinit(adc_chan);
|
|
bk_adc_release();
|
|
return err;
|
|
}
|
|
#endif
|
|
|
|
static uint16_t _volt_detect_calculate_voltage(uint16_t *raw_voltage_data)
|
|
{
|
|
#if (CONFIG_SOC_BK7231N) || (CONFIG_SOC_BK7236A) || (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX) || (CONFIG_SOC_BK7236XX)
|
|
uint32_t sum = 0, index, count = 0;
|
|
|
|
for (index = 5; index < ADC_TEMP_BUFFER_SIZE; index++) {
|
|
/* 0 is invalid, but saradc may return 0 in power save mode */
|
|
if ((0 != raw_voltage_data[index]) && (2048 != raw_voltage_data[index])) {
|
|
#if CONFIG_SDMADC_TEMP
|
|
sum += (int16_t)raw_voltage_data[index] + CFG_SDMADC_OFFSET; //offset half of 2^16 to be positive
|
|
#else
|
|
sum += raw_voltage_data[index];
|
|
#endif
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (count == 0)
|
|
raw_voltage_data[0] = 0;
|
|
else {
|
|
sum = sum / count;
|
|
raw_voltage_data[0] = sum;
|
|
}
|
|
#elif (CONFIG_SOC_BK7256XX)
|
|
uint32_t sum = 0, sum1, sum2;
|
|
|
|
sum1 = raw_voltage_data[1] + raw_voltage_data[2];
|
|
sum2 = raw_voltage_data[3] + raw_voltage_data[4];
|
|
sum = sum1 / 2 + sum2 / 2;
|
|
sum = sum / 2;
|
|
raw_voltage_data[0] = sum;
|
|
|
|
#else
|
|
uint32_t sum = 0, sum1, sum2;
|
|
|
|
sum1 = raw_voltage_data[1] + raw_voltage_data[2];
|
|
sum2 = raw_voltage_data[3] + raw_voltage_data[4];
|
|
sum = sum1 / 2 + sum2 / 2;
|
|
sum = sum / 2;
|
|
raw_voltage_data[0] = sum;
|
|
#endif
|
|
|
|
return raw_voltage_data[0];
|
|
}
|
|
|
|
#if CONFIG_VOLT_DETECT
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
static void _volt_detect_oneshot_timer_handler(void *data1, void *data2)
|
|
{
|
|
int result;
|
|
|
|
result = temp_detect_send_msg(VOLT_TIMER_EXPIRED);
|
|
if (result != BK_OK) {
|
|
result = temp_detect_send_msg(VOLT_RESTART_TIMER);
|
|
if (result != BK_OK) {
|
|
volt_daemon_restart();
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
static void _volt_detect_timer_handler(void *data)
|
|
{
|
|
temp_detect_send_msg(VOLT_TIMER_EXPIRED);
|
|
}
|
|
#endif
|
|
|
|
static void _volt_detect_notify(uint16_t volt_adc)
|
|
{
|
|
rwnx_cal_do_volt_detect(volt_adc);
|
|
}
|
|
|
|
int volt_daemon_restart(void)
|
|
{
|
|
int err;
|
|
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
err = rtos_oneshot_reload_timer(&s_voltd.detect_oneshot_timer);
|
|
#else
|
|
err = rtos_reload_timer(&s_voltd.detect_timer);
|
|
#endif
|
|
TEMPD_LOGD("restart err=%d\n", err);
|
|
|
|
return err;
|
|
}
|
|
|
|
int volt_daemon_stop(void)
|
|
{
|
|
int err;
|
|
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
err = rtos_stop_oneshot_timer(&s_voltd.detect_oneshot_timer);
|
|
#else
|
|
err = rtos_stop_timer(&s_voltd.detect_timer);
|
|
#endif
|
|
|
|
TEMPD_LOGD("stop err=%d\n", err);
|
|
|
|
return err;
|
|
}
|
|
|
|
void volt_daemon_polling_handler(void)
|
|
{
|
|
uint16_t volt_adc = 0;
|
|
int result = BK_OK;
|
|
|
|
bk_pm_module_vote_sleep_ctrl(PM_SLEEP_MODULE_NAME_SARADC, 0,0);
|
|
s_voltd.detect_cnt++;
|
|
volt_daemon_stop();
|
|
|
|
result = _volt_detect_init_adc_buffer();
|
|
if (BK_OK == result) {
|
|
result = _volt_detect_get_adc_data(ADC_VOLT_SENSER_CHANNEL, s_raw_voltage_data);
|
|
}
|
|
if (BK_OK != result) {
|
|
TEMPD_LOGW("detect failed(%d), retry\n", result);
|
|
volt_daemon_restart();
|
|
bk_pm_module_vote_sleep_ctrl(PM_SLEEP_MODULE_NAME_SARADC, 1,0);
|
|
return; //TODO is that correct?
|
|
}
|
|
|
|
volt_adc = _volt_detect_calculate_voltage(s_raw_voltage_data);
|
|
TEMPD_LOGD("cnt=%d, interval=%d, last=%d, cur=%d, thr=%d\r\n",
|
|
s_voltd.detect_cnt, s_voltd.detect_interval, s_voltd.last_detect_val,
|
|
volt_adc, s_voltd.detect_threshold);
|
|
|
|
_volt_detect_notify(volt_adc);
|
|
|
|
volt_daemon_restart();
|
|
|
|
bk_pm_module_vote_sleep_ctrl(PM_SLEEP_MODULE_NAME_SARADC, 1,0);
|
|
}
|
|
|
|
void volt_daemon_init(void)
|
|
{
|
|
int err;
|
|
|
|
s_voltd.last_detect_val = 0;
|
|
s_voltd.inital_data = 0;
|
|
s_voltd.detect_threshold = 0;
|
|
if (ate_is_enabled()) {
|
|
s_voltd.detect_interval = ADC_TMEP_DETECT_INTERVAL_INIT;
|
|
} else {
|
|
s_voltd.detect_interval = ADC_TMEP_DETECT_INTERVAL;
|
|
}
|
|
s_voltd.detect_cnt = 0;
|
|
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
err = rtos_init_oneshot_timer(&s_voltd.detect_oneshot_timer,
|
|
s_voltd.detect_interval * 1000,
|
|
_volt_detect_oneshot_timer_handler,
|
|
(void *)0,
|
|
(void *)0);
|
|
BK_ASSERT(kNoErr == err);
|
|
err = rtos_start_oneshot_timer(&s_voltd.detect_oneshot_timer);
|
|
#else
|
|
err = rtos_init_timer(&s_voltd.detect_timer,
|
|
s_voltd.detect_interval * 1000,
|
|
_volt_detect_timer_handler,
|
|
(void *)0);
|
|
BK_ASSERT(kNoErr == err);
|
|
err = rtos_start_timer(&s_voltd.detect_timer);
|
|
#endif
|
|
BK_ASSERT(kNoErr == err);
|
|
}
|
|
|
|
void volt_daemon_deinit(void)
|
|
{
|
|
int err;
|
|
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
err = rtos_deinit_oneshot_timer(&s_voltd.detect_oneshot_timer);
|
|
#else
|
|
err = rtos_deinit_timer(&s_voltd.detect_timer);
|
|
#endif
|
|
BK_ASSERT(kNoErr == err);
|
|
}
|
|
|
|
int volt_detect_start(void)
|
|
{
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
if (s_voltd.detect_oneshot_timer.function &&
|
|
!rtos_is_oneshot_timer_running(&s_voltd.detect_oneshot_timer))
|
|
temp_detect_send_msg(VOLT_RESTART_TIMER);
|
|
#else
|
|
if (s_voltd.detect_timer.function &&
|
|
!rtos_is_timer_running(&s_voltd.detect_timer))
|
|
temp_detect_send_msg(VOLT_RESTART_TIMER);
|
|
#endif
|
|
return BK_OK;
|
|
}
|
|
|
|
int volt_detect_stop(void)
|
|
{
|
|
#if TEMP_DETECT_ONESHOT_TIMER
|
|
if (s_voltd.detect_oneshot_timer.function
|
|
&& rtos_is_oneshot_timer_running(&s_voltd.detect_oneshot_timer))
|
|
temp_detect_send_msg(VOLT_PAUSE_TIMER);
|
|
#else
|
|
if (s_voltd.detect_timer.function
|
|
&& rtos_is_timer_running(&s_voltd.detect_timer))
|
|
temp_detect_send_msg(VOLT_PAUSE_TIMER);
|
|
#endif
|
|
return BK_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if (CONFIG_SOC_BK7256XX) ||(CONFIG_SOC_BK7236A) || (CONFIG_SOC_BK7231N) || (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX) || (CONFIG_SOC_BK7286XX)
|
|
int volt_single_get_current_voltage(UINT32 *volt_value)
|
|
{
|
|
int result;
|
|
int retry_count = 3;
|
|
|
|
if (!volt_value)
|
|
return BK_ERR_NULL_PARAM;
|
|
|
|
BK_RETURN_ON_ERR(_volt_detect_init_adc_buffer());
|
|
|
|
*volt_value = 0;
|
|
|
|
for (; retry_count > 0; retry_count--) {
|
|
result = _volt_detect_get_adc_data(ADC_VOLT_SENSER_CHANNEL, s_raw_voltage_data);
|
|
if (BK_OK != result) {
|
|
TEMPD_LOGW("get volt_single failed(%d), retry\n", result);
|
|
continue;
|
|
}
|
|
|
|
*volt_value = _volt_detect_calculate_voltage(s_raw_voltage_data);
|
|
if ((ADC_TEMP_VAL_MIN < *volt_value)/* && (*volt_value < ADC_TEMP_VAL_MAX)*/) {
|
|
break;
|
|
}
|
|
result = BK_ERR_TRY_AGAIN;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
#endif
|