315 lines
10 KiB
C
315 lines
10 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
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++;
|
||
|
}
|
||
|
}
|