Files
kunlun/sp/applet/phy/cpu1_fix.c

315 lines
10 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "os_types.h"
#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "phy_rxtd_reg.h"
#include "mac_sys_reg.h"
#include "phy_dfe_reg.h"
#include "cpu1_fix.h"
#include "phy_bb.h"
#include "iot_system.h"
#include "iot_config.h"
#include "phy_chn.h"
/* AGC FSM */
typedef enum{
RSSI_L = 0,
RSSI_H = 1,
PACKET = 2,
LOCK = 3,
}AGC_STATE;
/* RX TD FSM */
typedef enum{
RX_TD_IDLE = 0,
RX_TD_WAIT_AGC = 1,
RX_TD_WAIT_SELF_CORR = 2,
RX_TD_AGC_LOCK = 3,
}RX_TD_FSM;
extern cpu_state g_cpu1_state;
/* 0.040us units for each tick */
void delay_td_point(uint32_t point)
{
uint64_t time_span = 0;
uint32_t start_time = 0, end_time = 0;
uint64_t dly_us = point/3;/* us=point/75*25 */
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
do{
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
time_span = end_time - start_time;
if (time_span < 0) { // wrap around
time_span = (0x100000000LL) - start_time + end_time;
}
}while(time_span < dly_us);
}
void set_next_gain(uint8_t exp_gain_entry)
{
uint32_t tmp = 0;
int8_t exp_gain_int = 0;
exp_gain_int = (int8_t)exp_gain_entry - 24;
/* force the exp_gain */
tmp = PHY_RXTD_READ_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR);
REG_FIELD_SET(SW_MAX_GAIN, tmp, exp_gain_int );
REG_FIELD_SET(SW_FIX_GAIN_EN, tmp, 1 );
PHY_RXTD_WRITE_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR, tmp);
/* force rx_abort to reset phy */
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_RX_ABORT_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_ABORT, tmp, 1);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
REG_FIELD_SET(CFG_PHY_RX_ABORT_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_ABORT, tmp, 0);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
/* delay 5us to let gain work */
delay_td_point(400);
}
uint8_t phy_rxtd_rssi_get()
{
uint32_t tmp = PHY_RXTD_READ_REG(CFG_BB_PACKET_INF_0_ADDR);
return REG_FIELD_GET(FREE_RSSI, tmp);
}
uint8_t cpu1_get_nf_by_phase()
{
uint8_t nf_phase;
if (g_phy_cpu_share_ctxt.cal_3phase_nf_init) {
uint32_t tmp = RGF_MAC_READ_REG(CFG_RD_MACPHY_INTF_0_ADDR);
uint8_t cur_phase = REG_FIELD_GET(PHY_RX_PHASE_SEL, tmp);
nf_phase = g_phy_cpu_share_ctxt.nf_phase[cur_phase];
} else {
nf_phase = g_phy_cpu_share_ctxt.nf_192p;
}
return nf_phase;
}
void cpu1_fix()
{
uint32_t tmp = 0;
uint8_t cur_adc_pwr = 0, adc_pwr_th1, adc_pwr_th2;
uint8_t cur_gain_entry = 0;
uint8_t exp_gain_entry = 0;
uint8_t cur_rssi = 120;
uint8_t td_fsm = 0; //0:idle, 1:AGC, 2:CORR, 3:PACKET
uint8_t rssi_high_cnt = 0;
uint8_t rssi_low_cnt = 0;
uint8_t current_nf = 0;
volatile bool_t shift_en = false;
volatile bool_t shift_flag = false;
uint32_t tmp_spare2 = 0;
#if PHY_CHIP_CERT_EN == 0
uint8_t no_shift_cnt =0 ;
uint8_t shift1_cnt =0 ;
uint16_t lock_cnt =0 ;
bool_t shift1_en = 0;
#endif
#if PHY_CPU1_DBG_EN
volatile uint32_t *shift_cnt = \
(uint32_t *)(PHY_RXTD_BASEADDR + CFG_BB_RXTD_SPARE3_ADDR);
volatile uint32_t *dbg_sts = \
(uint32_t *)(PHY_RXTD_BASEADDR + CFG_BB_RXTD_SPARE1_ADDR);
#endif
while(1)
{
tmp_spare2 = PHY_RXTD_READ_REG(CFG_BB_RXTD_SPARE2_ADDR);
/* check magic number */
if (tmp_spare2 != 0x5A5A5A5A) {
continue;
}
if (g_phy_cpu_share_ctxt.high_perf_en) {
delay_td_point(150);
} else {
delay_td_point(1500);
}
/* get td fsm value */
tmp = PHY_RXTD_READ_REG(CFG_RX_TD_FSM_DBG_BUS_ADDR);
td_fsm = (uint8_t)(tmp & 0xf);
if (g_phy_cpu_share_ctxt.high_perf_en) {
if(td_fsm == RX_TD_WAIT_SELF_CORR) { //if not find packet
/* get current nf (updated per 1s) */
current_nf = cpu1_get_nf_by_phase();
/*target power is 110*/
if (g_phy_cpu_share_ctxt.spur_exist) {
exp_gain_entry = 114 + 24 - current_nf;
} else {
exp_gain_entry = 110 + 24 - current_nf;
}
if (exp_gain_entry > 84) {
exp_gain_entry = 84;
}
#if PHY_CPU1_DBG_EN
*shift_cnt = (*shift_cnt & 0xFFFFFF00) + \
(uint32_t)exp_gain_entry + 0x100;
#endif
/*
* Maybe changed by reg write but nf always the same.
* need read the current reg value.
*/
tmp = PHY_RXTD_READ_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR);
cur_gain_entry = REG_FIELD_GET(SW_MAX_GAIN, tmp) + 24;
/*adjust gain*/
if (cur_gain_entry != exp_gain_entry) {
set_next_gain(exp_gain_entry);
#if PHY_CHIP_CERT_EN == 0
no_shift_cnt = 0;
shift1_cnt = 0;
shift1_en = 0;
lock_cnt = 0;
#endif
}
#if PHY_CHIP_CERT_EN == 0
/*if no big spur, do shift*/
if (!g_phy_cpu_share_ctxt.spur_exist) {
/*push the cur_adc_pwr in*/
cur_adc_pwr = phy_rxtd_rssi_get();
/* if adc power > 100, can not shift */
adc_pwr_th1 = 100;
adc_pwr_th2 = 92;
/* decide shift */
if (cur_adc_pwr > adc_pwr_th1) {
no_shift_cnt = (no_shift_cnt == 8) ? 8 : no_shift_cnt + 1;
//shift1_cnt = 0 ;
} else if(cur_adc_pwr > adc_pwr_th2) {
shift1_cnt = (shift1_cnt == 8) ? 8 : shift1_cnt + 1;
no_shift_cnt = 0;
} else {
no_shift_cnt = 0;
shift1_cnt = 0;
}
if (shift1_en == 1 && no_shift_cnt == 8) {
lock_cnt = 0;
}
if (lock_cnt == 0) {
if (no_shift_cnt == 8) {
phy_gain_shift_set(0,0,0,0);
lock_cnt++;
shift1_en = 0;
} else if (shift1_cnt == 8) {
phy_gain_shift_set(0,0,
g_phy_cpu_share_ctxt.shift_low > 0,
g_phy_cpu_share_ctxt.shift_low);
lock_cnt++;
shift1_en = 1;
} else if (no_shift_cnt == 0 && shift1_cnt == 0) {
phy_gain_shift_set(0,0,
g_phy_cpu_share_ctxt.shift_high > 0,
g_phy_cpu_share_ctxt.shift_high);
shift1_en = 0;
}
} else if (lock_cnt >= 1000) { //>2ms for preamble dectection
lock_cnt = 0;
} else {
lock_cnt++ ;
}
} else {
phy_gain_shift_set(0,0,0,0);
}
#else
phy_gain_shift_set(0,0,0,0);
#endif
}
#if PHY_CHIP_CERT_EN == 0
else {
no_shift_cnt = 0;
shift1_cnt = 0 ;
lock_cnt = 0;
shift1_en = 0;
}
#endif
}
/* if not high_perf_en*/
/* check if not idle */
else if (td_fsm != 0) {
/* get current gain and adc power */
tmp = PHY_RXTD_READ_REG(CFG_BB_PACKET_INF_0_ADDR);
cur_adc_pwr = REG_FIELD_GET(FREE_RSSI, tmp);
cur_gain_entry = REG_FIELD_GET(GAIN_TABLE_ENTRY, tmp);
if (td_fsm == RX_TD_WAIT_SELF_CORR && cur_adc_pwr != 0) {
cur_rssi = PHY_RSSI_FROM_RMI_GAIN(cur_adc_pwr, cur_gain_entry);
/* high/low rssi dection */
if (cur_rssi <= (current_nf + PHY_SPIKE_RSSI_NF_THD)) {
rssi_high_cnt = 0;
if (rssi_low_cnt < PHY_SPIKE_RSSI_LOW_CNT) {
rssi_low_cnt++;
}
} else if (rssi_high_cnt < PHY_SPIKE_RSSI_HIGH_CNT) {
rssi_high_cnt++;
if (rssi_low_cnt > 0) {
rssi_low_cnt--;
}
} else if (rssi_low_cnt > 0) {
rssi_low_cnt--;
}
#if PHY_CPU1_DBG_EN
/* rssi low cnt*/
*dbg_sts = rssi_low_cnt | \
(cur_rssi << 8) | \
(g_phy_cpu_share_ctxt.nf_192p << 16) | \
(g_phy_cpu_share_ctxt.nf_384p << 24);
*shift_cnt = g_phy_cpu_share_ctxt.nf_768p | \
(g_phy_cpu_share_ctxt.nf_1536p << 8) | \
(g_phy_cpu_share_ctxt.nf_3072p << 16) | \
(g_phy_cpu_share_ctxt.nf_6144p << 24);
#endif
/* spike find */
if (rssi_high_cnt == PHY_SPIKE_RSSI_HIGH_CNT || \
cur_adc_pwr > PHY_PWR_SHIFT_FULL_LVL) {
shift_en = false;
} else if (rssi_low_cnt > 0) {
/* rssi low */
shift_en = true;
}
/* check if shift */
if (shift_en && !shift_flag) {
phy_gain_shift_set(0,0,1,2);
shift_flag = true;
} else if (!shift_en && shift_flag) {
phy_gain_shift_set(0,0,0,0);
shift_flag = false;
}
}
}
g_cpu1_state.count++;
}
}