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