389 lines
9.0 KiB
C
Raw Normal View History

2025-10-10 16:07:00 +08:00
#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