1052 lines
32 KiB
C
1052 lines
32 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 "hw_reg_api.h"
|
||
|
#include "plc_fr.h"
|
||
|
#include "phy_cal.h"
|
||
|
#include "phy_bb.h"
|
||
|
#include "phy_phase.h"
|
||
|
#include "granite_reg.h"
|
||
|
#include "phy_rxtd_reg.h"
|
||
|
#include "phy_txrx_pwr.h"
|
||
|
#include "phy_rx_fd_reg.h"
|
||
|
#include "phy_dfe_reg.h"
|
||
|
#include "mac_sys_reg.h"
|
||
|
#include "iot_io.h"
|
||
|
#include "hw_tonemask.h"
|
||
|
#include "iot_config.h"
|
||
|
#include "iot_pib.h"
|
||
|
#include "iot_errno.h"
|
||
|
#include "rx_pb_reorder.h"
|
||
|
#include "ahb.h"
|
||
|
#include "iot_cal_data.h"
|
||
|
#include "phy_ana.h"
|
||
|
#include "ahb.h"
|
||
|
#include "hw_phy_api.h"
|
||
|
#include "iot_oem.h"
|
||
|
#include "clk.h"
|
||
|
#include "iot_clock.h"
|
||
|
#include "iot_system.h"
|
||
|
|
||
|
int16_t int16_abs(int16_t x)
|
||
|
{
|
||
|
if(x<0) x=0-x;
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
/* Note: wmask is useful for rx0 and top reg only */
|
||
|
#if PHY_CAL_PIB_SUPPORT == 1
|
||
|
uint32_t tx_dc_calibration(int16_t *tx_dc, iot_pib_w_halphy_real_cfg_t *pib_ptr)
|
||
|
#else
|
||
|
uint32_t tx_dc_calibration(uint16_t *tx_dc)
|
||
|
#endif
|
||
|
{
|
||
|
uint8_t reg_id = 0;
|
||
|
uint8_t rodata = 0;
|
||
|
uint32_t rdata = 0;
|
||
|
volatile uint16_t dac_golden = 512;
|
||
|
volatile uint16_t dac_ovr = 0;
|
||
|
volatile uint16_t dac_step = 0;
|
||
|
int16_t dc_offset = 0;
|
||
|
|
||
|
/* force phy in idle state */
|
||
|
phy_txrx_ovr_set(true,0);
|
||
|
/* auto gain */
|
||
|
phy_agc_gain_lvl_set(0,60,-24,0);
|
||
|
|
||
|
/* en analog tx */
|
||
|
phy_ana_tx_set(true, true);
|
||
|
phy_ana_rx_set(false, false);
|
||
|
|
||
|
/* en tx compen */
|
||
|
reg_id = CFG_ANA_TX_REG_ADDR;
|
||
|
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
|
REG_FIELD_SET(TX_COMPEN,rdata,1);
|
||
|
phy_ana_i2c_write(reg_id,rdata,~0);
|
||
|
|
||
|
/* reset the dc correction register */
|
||
|
phy_dfe_dc_comp_set(0,0);
|
||
|
phy_dfe_dc_comp_set(1,0);
|
||
|
phy_dfe_dc_comp_set(2,0);
|
||
|
phy_dfe_dc_comp_set(3,0);
|
||
|
|
||
|
/* dc offset */
|
||
|
for(uint32_t i = 0; i < 4; i++)
|
||
|
{
|
||
|
reg_id = CFG_ANA_TX_REG_ADDR;
|
||
|
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
|
REG_FIELD_SET(TX_GPGA,rdata,i);
|
||
|
phy_ana_i2c_write(reg_id,rdata,~0);
|
||
|
/*
|
||
|
if(phy_dfe_dc_comp_get(i)>>9)
|
||
|
{
|
||
|
dac_golden = PHY_DAC_STEP + phy_dfe_dc_comp_get(i) - 1024;
|
||
|
}
|
||
|
else{
|
||
|
dac_golden = PHY_DAC_STEP + phy_dfe_dc_comp_get(i);
|
||
|
}
|
||
|
*/
|
||
|
dac_golden = 512;
|
||
|
dac_step = dac_golden;
|
||
|
dac_ovr = dac_step;
|
||
|
do{
|
||
|
phy_dac_data_ovr_set(true,dac_ovr);
|
||
|
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
|
rodata = (rodata >> 7) & 0x1;
|
||
|
dac_step = dac_step >> 1;
|
||
|
if(rodata == 1){
|
||
|
dac_ovr += dac_step;
|
||
|
}
|
||
|
else{
|
||
|
dac_ovr -= dac_step;
|
||
|
}
|
||
|
}while(dac_step > 0);
|
||
|
|
||
|
dc_offset = dac_ovr-512;
|
||
|
|
||
|
if(tx_dc != NULL)
|
||
|
{
|
||
|
*tx_dc = dc_offset;
|
||
|
tx_dc++;
|
||
|
#if PHY_CAL_PIB_SUPPORT == 1
|
||
|
/*todo: update pib */
|
||
|
pib_ptr->tx_dc[i] = dc_offset;
|
||
|
#endif
|
||
|
}
|
||
|
else{
|
||
|
IOT_ASSERT(0);
|
||
|
}
|
||
|
|
||
|
if(int16_abs(dc_offset)>TX_DC_THR){
|
||
|
iot_printf("tx dc calibration: i=%d, dac_cal=%d, ###fail###\r\n", \
|
||
|
i, dc_offset);
|
||
|
/* set tx dc compen */
|
||
|
phy_dfe_dc_comp_set(i, 0);
|
||
|
}
|
||
|
else{
|
||
|
iot_printf("tx dc calibration: i=%d, dac_cal=%d, ###success###\r\n", \
|
||
|
i, dc_offset);
|
||
|
/* set tx dc compen */
|
||
|
phy_dfe_dc_comp_set(i, dc_offset);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* disable tx compen */
|
||
|
reg_id = CFG_ANA_TX_REG_ADDR;
|
||
|
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
|
REG_FIELD_SET(TX_COMPEN,rdata,0);
|
||
|
phy_ana_i2c_write(reg_id,rdata,~0);
|
||
|
|
||
|
/* disable analog tx */
|
||
|
phy_ana_tx_set(false, false);
|
||
|
|
||
|
/* clear ovr */
|
||
|
phy_dac_data_ovr_set(0,0);
|
||
|
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
/* Note: wmask is useful for rx0 and top reg only */
|
||
|
#if PHY_CAL_PIB_SUPPORT == 1
|
||
|
uint32_t rx_dc_calibration(uint32_t *rx_dc, \
|
||
|
iot_pib_w_halphy_real_cfg_t *pib_ptr)
|
||
|
#else
|
||
|
uint32_t rx_dc_calibration(uint16_t *rx_dc)
|
||
|
#endif
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
uint32_t tmp = 0;
|
||
|
volatile uint8_t flag = 0;
|
||
|
uint16_t i = 0 ,j = 0;
|
||
|
int16_t dc_offset = 0;
|
||
|
int16_t dc_offset_after_pgf = 0;
|
||
|
uint8_t reg_id = 0;
|
||
|
int8_t gain = 0;
|
||
|
uint32_t wdata = 0;
|
||
|
uint32_t wmask = 0;
|
||
|
volatile uint16_t dc_val = 0;
|
||
|
volatile uint16_t dc_pgf = 0;
|
||
|
volatile uint16_t dc_pga = 0;
|
||
|
volatile uint16_t dc_step = 0;
|
||
|
uint8_t bq_qvalue = 0;
|
||
|
uint8_t pgf = 0, bq = 0, pga = 0;
|
||
|
uint8_t lna = 0, byphpf = 0, enord2 = 0;
|
||
|
uint32_t start_time = 0, end_time = 0;
|
||
|
uint64_t time_span = 0;
|
||
|
|
||
|
phy_add_dc_cal_cnt();
|
||
|
|
||
|
/* disable packet detect timeout */
|
||
|
phy_pkt_time_out_disable(true);
|
||
|
|
||
|
/* CPU switch to 25M */
|
||
|
clk_core_freq_slip_25m_set();
|
||
|
|
||
|
/* disable reset by full */
|
||
|
phy_agc_sat_adj_set(1, 1);
|
||
|
|
||
|
/* disable rx0 overwrite by hw */
|
||
|
PHY_DFE_WRITE_REG(CFG_BB_ANA_RX_ON_CFG_MASK_ADDR, 0x0);
|
||
|
|
||
|
/* turn off adc */
|
||
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
||
|
(0 << TOP_EN_ADC_OFFSET), \
|
||
|
TOP_EN_ADC_MASK);
|
||
|
|
||
|
/* force phy in rx state */
|
||
|
phy_txrx_ovr_set(true,1);
|
||
|
|
||
|
/* diable analog loopen */
|
||
|
phy_ana_i2c_write(CFG_ANA_RX_REG_0_ADDR, \
|
||
|
0 << RX_PGFLOOPEN_OFFSET, \
|
||
|
RX_PGFLOOPEN_MASK);
|
||
|
|
||
|
if(!iot_chip_check_lic()) {
|
||
|
phy_phase_ovr_set(PHY_PHASE_OVR_ALL,true,PHY_TXRX_OVR_IDLE);
|
||
|
}
|
||
|
|
||
|
/* turn off dac/tx/enlic/rx */
|
||
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
||
|
(1 << TOP_EN_RX_OFFSET), \
|
||
|
TOP_EN_DAC_MASK | \
|
||
|
TOP_ENLIC_MASK | \
|
||
|
TOP_EN_TX_MASK | \
|
||
|
TOP_EN_RX_MASK);
|
||
|
|
||
|
/* turn on adc after delay */
|
||
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
||
|
(1 << TOP_EN_ADC_OFFSET), \
|
||
|
TOP_EN_ADC_MASK);
|
||
|
|
||
|
/* CPU switch to 150M */
|
||
|
clk_core_freq_slip_150m_set();
|
||
|
|
||
|
/* check raw_dc start*/
|
||
|
/* granite gain=0, pwdpgfoffset=1, pwdpgaoffset=1, hpfenord2=1 */
|
||
|
wdata = 1 << RX_GPGF_OFFSET | \
|
||
|
1 << RX_GBQ_OFFSET | \
|
||
|
0 << RX_GPGA_OFFSET | \
|
||
|
PHY_RX_PGF_OFFSET_DFT << RX_PGFOFFSET_OFFSET | \
|
||
|
PHY_RX_PGA_OFFSET_DFT << RX_PGAOFFSET_OFFSET | \
|
||
|
1 << RX_HPFENORD2_OFFSET | \
|
||
|
0 << RX_BYPHPF_OFFSET | \
|
||
|
1 << RX_PWDPGFOFFSET_OFFSET | \
|
||
|
1 << RX_PWDPGAOFFSET_OFFSET ;
|
||
|
|
||
|
wmask = RX_GPGF_MASK | \
|
||
|
RX_GBQ_MASK | \
|
||
|
RX_GPGA_MASK | \
|
||
|
RX_PGFOFFSET_MASK | \
|
||
|
RX_PGAOFFSET_MASK | \
|
||
|
RX_HPFENORD2_MASK | \
|
||
|
RX_BYPHPF_MASK | \
|
||
|
RX_PWDPGAOFFSET_MASK | \
|
||
|
RX_PWDPGFOFFSET_MASK ;
|
||
|
|
||
|
phy_ana_i2c_write(CFG_ANA_RX_REG_0_ADDR,wdata,wmask);
|
||
|
|
||
|
/* delay 3us */
|
||
|
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 < 3*TICKS_US);
|
||
|
|
||
|
/* get dc est */
|
||
|
dc_offset = 0;
|
||
|
for(j = 0; j< PHY_DC_EST_RETRY_NUM; j++)
|
||
|
{
|
||
|
tmp = PHY_RXTD_READ_REG(CFG_BB_PACKET_INF_2_ADDR);
|
||
|
flag = REG_FIELD_GET(DC_EST_FREE,tmp) >> 9;
|
||
|
if(flag) {
|
||
|
dc_offset += REG_FIELD_GET(DC_EST_FREE,tmp) - 1024;
|
||
|
} else {
|
||
|
dc_offset += REG_FIELD_GET(DC_EST_FREE,tmp);
|
||
|
}
|
||
|
}
|
||
|
dc_offset = dc_offset/PHY_DC_EST_RETRY_NUM;
|
||
|
#if IOT_DTEST_ONLY_SUPPORT == 1
|
||
|
iot_printf("raw_dc with 0db gain and pwd correction dac is %d\r\n", \
|
||
|
dc_offset);
|
||
|
#endif
|
||
|
if(int16_abs(dc_offset)>RX_DC_RAW_THR) {
|
||
|
iot_printf("raw_dc=%d is too large! ###fail###\r\n",dc_offset);
|
||
|
ret = ERR_FAIL;
|
||
|
}
|
||
|
|
||
|
/*write back RX0 register*/
|
||
|
wdata = 1 << RX_GPGF_OFFSET | \
|
||
|
1 << RX_GBQ_OFFSET | \
|
||
|
0 << RX_GPGA_OFFSET | \
|
||
|
PHY_RX_PGF_OFFSET_DFT << RX_PGFOFFSET_OFFSET | \
|
||
|
PHY_RX_PGA_OFFSET_DFT << RX_PGAOFFSET_OFFSET | \
|
||
|
1 << RX_HPFENORD2_OFFSET | \
|
||
|
0 << RX_BYPHPF_OFFSET | \
|
||
|
0 << RX_PWDPGFOFFSET_OFFSET | \
|
||
|
0 << RX_PWDPGAOFFSET_OFFSET ;
|
||
|
|
||
|
wmask = RX_GPGF_MASK | \
|
||
|
RX_GBQ_MASK | \
|
||
|
RX_GPGA_MASK | \
|
||
|
RX_PGFOFFSET_MASK | \
|
||
|
RX_PGAOFFSET_MASK | \
|
||
|
RX_HPFENORD2_MASK | \
|
||
|
RX_BYPHPF_MASK | \
|
||
|
RX_PWDPGAOFFSET_MASK | \
|
||
|
RX_PWDPGFOFFSET_MASK ;
|
||
|
|
||
|
phy_ana_i2c_write(CFG_ANA_RX_REG_0_ADDR,wdata,wmask);
|
||
|
/* check raw_dc end*/
|
||
|
|
||
|
/* scan normal and narrow gain table */
|
||
|
for(i = 0; i < PHY_GAIN_STEP_MAX * 2; i++)
|
||
|
{
|
||
|
/* get current gain info */
|
||
|
if(i < PHY_GAIN_STEP_MAX) {
|
||
|
gain = i - 24;
|
||
|
} else {
|
||
|
gain = i - PHY_GAIN_STEP_MAX - 24;
|
||
|
}
|
||
|
dc_pga = 0;
|
||
|
dc_pgf = 0;
|
||
|
/* fix gain accss from analog */
|
||
|
phy_pgf_bq_pga_gain_get(i, \
|
||
|
&pgf, \
|
||
|
&bq, \
|
||
|
&pga, \
|
||
|
&lna, \
|
||
|
&byphpf, \
|
||
|
&enord2, \
|
||
|
&bq_qvalue);
|
||
|
reg_id = CFG_ANA_RX_REG_0_ADDR;
|
||
|
wdata = (pgf << RX_GPGF_OFFSET) | \
|
||
|
(bq << RX_GBQ_OFFSET) | \
|
||
|
(pga << RX_GPGA_OFFSET) | \
|
||
|
(byphpf << RX_BYPHPF_OFFSET) | \
|
||
|
(enord2 << RX_HPFENORD2_OFFSET);
|
||
|
wmask = RX_GPGF_MASK | \
|
||
|
RX_GBQ_MASK | \
|
||
|
RX_GPGA_MASK | \
|
||
|
RX_BYPHPF_MASK | \
|
||
|
RX_HPFENORD2_MASK;
|
||
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
||
|
|
||
|
#if PHY_LNA_DC_CALI_EN == 1
|
||
|
/* enable geode */
|
||
|
if(byphpf) {
|
||
|
reg_id = CFG_ANA_TOP_REG_ADDR;
|
||
|
wdata = lna << TOP_GLNA_OFFSET ;
|
||
|
wmask = TOP_GLNA_MASK ;
|
||
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* step1: pgf cal */
|
||
|
phy_pgf_pga_dc_cal_get(i, &dc_pgf, &dc_pga);
|
||
|
#if PHY_DBG_EN == 1
|
||
|
iot_printf("***** gain=%d calibration start *******\r\n",gain);
|
||
|
#endif
|
||
|
dc_val = PHY_RX_PGF_OFFSET_DFT;
|
||
|
dc_step = PHY_RX_PGF_OFFSET_DFT;
|
||
|
do{
|
||
|
reg_id = CFG_ANA_RX_REG_0_ADDR;
|
||
|
wdata = (dc_val << RX_PGFOFFSET_OFFSET) | \
|
||
|
(PHY_RX_PGA_OFFSET_DFT << RX_PGAOFFSET_OFFSET);
|
||
|
wmask = RX_PGFOFFSET_MASK | RX_PGAOFFSET_MASK;
|
||
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
||
|
|
||
|
/* delay 3us */
|
||
|
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 < 3*TICKS_US);
|
||
|
|
||
|
/* get dc est */
|
||
|
dc_offset = 0;
|
||
|
for(j = 0; j< PHY_DC_EST_RETRY_NUM; j++)
|
||
|
{
|
||
|
tmp = PHY_RXTD_READ_REG(CFG_BB_PACKET_INF_2_ADDR);
|
||
|
flag = REG_FIELD_GET(DC_EST_FREE,tmp) >> 9;
|
||
|
if(flag) {
|
||
|
dc_offset += REG_FIELD_GET(DC_EST_FREE,tmp) - 1024;
|
||
|
} else {
|
||
|
dc_offset += REG_FIELD_GET(DC_EST_FREE,tmp);
|
||
|
}
|
||
|
}
|
||
|
dc_offset = dc_offset/PHY_DC_EST_RETRY_NUM;
|
||
|
#if PHY_DBG_EN == 1
|
||
|
iot_printf("rx pgf dc cali: pgfoffset=%d,dc=%d\r\n", \
|
||
|
dc_val, dc_offset);
|
||
|
#endif
|
||
|
/* PGF thd */
|
||
|
if(dc_offset < PHY_DC_PGF_GOLDEN && \
|
||
|
dc_offset > -PHY_DC_PGF_GOLDEN) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* check dc result */
|
||
|
if(dc_val > 48 || dc_val < 16) {
|
||
|
break;
|
||
|
}
|
||
|
/* cal step to cal dc */
|
||
|
dc_step = dc_step >> 1;
|
||
|
if(dc_offset > 0) {
|
||
|
dc_val -= dc_step;
|
||
|
} else {
|
||
|
dc_val += dc_step;
|
||
|
}
|
||
|
}while(dc_step > 0);
|
||
|
dc_pgf = dc_val;
|
||
|
#if PHY_DBG_EN == 1
|
||
|
iot_printf("rx pgf cali done: gain=%d, pgfoffset=%d\r\n", \
|
||
|
gain, dc_pgf);
|
||
|
#endif
|
||
|
dc_offset_after_pgf = dc_offset;
|
||
|
|
||
|
/* step2: pga cal */
|
||
|
dc_val = PHY_RX_PGA_OFFSET_DFT;
|
||
|
dc_step = PHY_RX_PGA_OFFSET_DFT;
|
||
|
do{
|
||
|
reg_id = CFG_ANA_RX_REG_0_ADDR;
|
||
|
wdata = (dc_pgf << RX_PGFOFFSET_OFFSET) | \
|
||
|
(dc_val << RX_PGAOFFSET_OFFSET);
|
||
|
wmask = RX_PGFOFFSET_MASK | RX_PGAOFFSET_MASK;
|
||
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
||
|
|
||
|
/* delay 3us */
|
||
|
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 < 3*TICKS_US);
|
||
|
|
||
|
/* get dc est */
|
||
|
dc_offset = 0;
|
||
|
for(j = 0; j< PHY_DC_EST_RETRY_NUM; j++)
|
||
|
{
|
||
|
tmp = PHY_RXTD_READ_REG(CFG_BB_PACKET_INF_2_ADDR);
|
||
|
flag = REG_FIELD_GET(DC_EST_FREE,tmp)>>9;
|
||
|
if(flag) {
|
||
|
dc_offset += REG_FIELD_GET(DC_EST_FREE,tmp) - 1024;
|
||
|
} else {
|
||
|
dc_offset += REG_FIELD_GET(DC_EST_FREE,tmp);
|
||
|
}
|
||
|
}
|
||
|
dc_offset = dc_offset/PHY_DC_EST_RETRY_NUM;
|
||
|
#if PHY_DBG_EN == 1
|
||
|
iot_printf("rx pga dc cali: pgaoffset=%d, dc=%d\r\n", \
|
||
|
dc_val,dc_offset);
|
||
|
#endif
|
||
|
|
||
|
if(dc_offset < PHY_DC_PGA_GOLDEN && \
|
||
|
dc_offset > -PHY_DC_PGA_GOLDEN) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* cal step to cal dc */
|
||
|
dc_step = dc_step >> 1;
|
||
|
if(dc_offset > 0) {
|
||
|
dc_val -= dc_step;
|
||
|
} else {
|
||
|
dc_val += dc_step;
|
||
|
}
|
||
|
}while(dc_step > 0);
|
||
|
dc_pga = dc_val;
|
||
|
if(int16_abs(dc_offset)>int16_abs(dc_offset_after_pgf)) {
|
||
|
dc_offset = dc_offset_after_pgf;
|
||
|
dc_pga = PHY_RX_PGA_OFFSET_DFT;
|
||
|
}
|
||
|
if(int16_abs(dc_offset)>RX_DC_FINAL_THR) {
|
||
|
#if IOT_DTEST_ONLY_SUPPORT == 1
|
||
|
iot_printf("rx pga dc cali done: gain=%d,pgf=%d,bq=%d,pga=%d,", \
|
||
|
gain, pgf, bq, pga);
|
||
|
#endif
|
||
|
iot_printf("pgfoffset=%d,pgaoffset=%d, final_dc=%0d ###fail###\r\n", \
|
||
|
dc_pgf, dc_pga, dc_offset);
|
||
|
ret = ERR_FAIL;
|
||
|
} else {
|
||
|
#if IOT_DTEST_ONLY_SUPPORT == 1
|
||
|
iot_printf("rx pga dc cali done: gain=%d,pgf=%d,bq=%d,pga=%d,", \
|
||
|
gain, pgf, bq, pga);
|
||
|
#endif
|
||
|
iot_printf("pgfoffset=%d,pgaoffset=%d, final_dc=%0d ###success###\r\n", \
|
||
|
dc_pgf, dc_pga, dc_offset);
|
||
|
}
|
||
|
|
||
|
/* set pgf and pga dc offset to gain table */
|
||
|
phy_pgf_pga_dc_cal(i, dc_pgf, dc_pga);
|
||
|
|
||
|
if(rx_dc != NULL) {
|
||
|
*rx_dc = (dc_pgf & 0x3F) | \
|
||
|
((dc_pga & 0x1F) << 6);
|
||
|
rx_dc++;
|
||
|
|
||
|
#if PHY_CAL_PIB_SUPPORT == 1
|
||
|
//todo: support pib
|
||
|
pib_ptr->rx_dc[i] = dc_pgf | (dc_pga << 6);
|
||
|
#endif
|
||
|
} else {
|
||
|
IOT_ASSERT(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* CPU switch to 25M */
|
||
|
clk_core_freq_slip_25m_set();
|
||
|
|
||
|
/* disable force tx/rx to avoid mac hang */
|
||
|
phy_txrx_ovr_set(0,0);
|
||
|
|
||
|
/* CPU switch to 150M */
|
||
|
clk_core_freq_slip_150m_set();
|
||
|
|
||
|
/* K68 branch*/
|
||
|
if(!iot_chip_check_lic()) {
|
||
|
phy_phase_ovr_set(PHY_PHASE_OVR_ALL,false,PHY_TXRX_OVR_IDLE);
|
||
|
}
|
||
|
|
||
|
/* disable packet detect timeout */
|
||
|
phy_pkt_time_out_disable(false);
|
||
|
|
||
|
/* disable reset by full */
|
||
|
phy_agc_sat_adj_set(0, 0);
|
||
|
|
||
|
(void)gain;
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void phy_txrx_loop_back_begin(uint32_t phase, TXRX_LOOP_BACK_MODE_ID mode)
|
||
|
{
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
/* Must not ovr da data */
|
||
|
phy_dac_data_ovr_set(false,0);
|
||
|
|
||
|
/* CPU switch to 25M */
|
||
|
clk_core_freq_slip_25m_set();
|
||
|
|
||
|
/* disable analog tx and rx */
|
||
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
||
|
(0 << TOP_EN_DAC_OFFSET) | \
|
||
|
(0 << TOP_EN_ADC_OFFSET) | \
|
||
|
(0 << TOP_EN_TX_OFFSET) | \
|
||
|
(0 << TOP_EN_RX_OFFSET), \
|
||
|
TOP_EN_DAC_MASK | \
|
||
|
TOP_EN_ADC_MASK | \
|
||
|
TOP_EN_TX_MASK | \
|
||
|
TOP_EN_RX_MASK);
|
||
|
|
||
|
/* force inte rx state */
|
||
|
phy_txrx_ovr_set(1,1);
|
||
|
|
||
|
/* disable packet detect timeout */
|
||
|
phy_pkt_time_out_disable(true);
|
||
|
|
||
|
/* bypass dc blocker */
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR);
|
||
|
REG_FIELD_SET(SW_DC_BLK_BYPASS, tmp, 1);
|
||
|
PHY_DFE_WRITE_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR, tmp);
|
||
|
|
||
|
/* fix gain and disable agc */
|
||
|
phy_agc_gain_lvl_set(1,0,-24,0);
|
||
|
|
||
|
/* disable adj and sat reset */
|
||
|
phy_agc_sat_adj_set(1, 1);
|
||
|
|
||
|
/* disable auto-adjust gain */
|
||
|
phy_agc_gain_adj_dis(0);
|
||
|
|
||
|
/* turn on dac/tx/rx */
|
||
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
||
|
(1 << TOP_EN_DAC_OFFSET) | \
|
||
|
(1 << TOP_EN_TX_OFFSET) | \
|
||
|
(1 << TOP_EN_RX_OFFSET), \
|
||
|
TOP_EN_DAC_MASK | \
|
||
|
TOP_EN_TX_MASK | \
|
||
|
TOP_EN_RX_MASK);
|
||
|
|
||
|
/* turn on adc after delay */
|
||
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
||
|
(1 << TOP_EN_ADC_OFFSET), \
|
||
|
TOP_EN_ADC_MASK);
|
||
|
|
||
|
#if CHIP_BRINGUP_DEBUG == 1
|
||
|
phy_ana_i2c_write(CFG_ANA_TX_REG_ADDR,0x0,0xffffffff);
|
||
|
#endif
|
||
|
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
|
REG_FIELD_SET(SW_LOOPBACK_EN, tmp, 1);
|
||
|
PHY_DFE_WRITE_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR, tmp);
|
||
|
|
||
|
if(mode == TXRX_LOOP_BACK_GRANITE) {
|
||
|
/* enable analog loopen */
|
||
|
phy_ana_i2c_write(CFG_ANA_RX_REG_0_ADDR, \
|
||
|
(1 << RX_PGFLOOPEN_OFFSET) | \
|
||
|
(16 << RX_PGAOFFSET_OFFSET) | \
|
||
|
(32 << RX_PGFOFFSET_OFFSET) | \
|
||
|
(0 << RX_GPGA_OFFSET) | \
|
||
|
(1 << RX_GBQ_OFFSET) | \
|
||
|
(1 << RX_GPGF_OFFSET), \
|
||
|
RX_PGFLOOPEN_MASK | \
|
||
|
RX_PGAOFFSET_MASK | \
|
||
|
RX_PGFOFFSET_MASK | \
|
||
|
RX_GPGA_MASK | \
|
||
|
RX_GBQ_MASK | \
|
||
|
RX_GPGF_MASK);
|
||
|
} else if(mode == TXRX_LOOP_BACK_GEODE) {
|
||
|
/* disable analog loopen */
|
||
|
phy_ana_i2c_write(CFG_ANA_RX_REG_0_ADDR, \
|
||
|
0 << RX_PGFLOOPEN_OFFSET, \
|
||
|
RX_PGFLOOPEN_MASK);
|
||
|
|
||
|
/* k48 or k68 */
|
||
|
if(iot_chip_check_lic()) {
|
||
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR,TOP_ENLIC_MASK,TOP_ENLIC_MASK);
|
||
|
} else {
|
||
|
/* enable a/b/c and tx & rx*/
|
||
|
switch(phase)
|
||
|
{
|
||
|
case 0:
|
||
|
phy_phase_ovr_set(PHY_PHASE_OVR_A,1,3);
|
||
|
break;
|
||
|
case 1:
|
||
|
phy_phase_ovr_set(PHY_PHASE_OVR_B,1,3);
|
||
|
break;
|
||
|
case 2:
|
||
|
phy_phase_ovr_set(PHY_PHASE_OVR_C,1,3);
|
||
|
break;
|
||
|
case 3:
|
||
|
phy_phase_ovr_set(PHY_PHASE_OVR_ALL,1,3);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* CPU switch to 150M */
|
||
|
clk_core_freq_slip_150m_set();
|
||
|
|
||
|
/* tone */
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_TX_TONE_0_CFG_ADDR);
|
||
|
phy_dfe_tone_cfg(1,REG_FIELD_GET(SW_TONE_0_CFG_NUM,tmp), \
|
||
|
REG_FIELD_GET(SW_TONE_1_CFG_NUM,tmp));
|
||
|
/* loopback if < 6, will full */
|
||
|
#if IOT_DTEST_ONLY_SUPPORT == 1
|
||
|
phy_dfe_tone_att_cfg(0,3,3);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void phy_txrx_loop_back_end()
|
||
|
{
|
||
|
uint32_t tmp;
|
||
|
/* fallback:disable tone */
|
||
|
phy_dfe_tone_cfg(0,0,0);
|
||
|
|
||
|
/* en dc blocker */
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR);
|
||
|
REG_FIELD_SET(SW_DC_BLK_BYPASS, tmp, 0);
|
||
|
PHY_DFE_WRITE_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR, tmp);
|
||
|
|
||
|
phy_agc_sat_adj_set(0, 0);
|
||
|
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
|
REG_FIELD_SET(SW_LOOPBACK_EN, tmp, 0);
|
||
|
PHY_DFE_WRITE_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR, tmp);
|
||
|
|
||
|
/* disable packet detect timeout */
|
||
|
phy_pkt_time_out_disable(false);
|
||
|
|
||
|
/* config regression */
|
||
|
phy_ana_i2c_write(CFG_ANA_RX_REG_0_ADDR,0x0,RX_PGFLOOPEN_MASK);
|
||
|
phy_ana_tx_set(false, false);
|
||
|
|
||
|
}
|
||
|
|
||
|
uint32_t phy_csi_buf_amp_get(uint16_t tone_id)
|
||
|
{
|
||
|
uint32_t tmp = 0;
|
||
|
uint32_t fft_loop = 1;
|
||
|
uint32_t amp_val = 0;
|
||
|
int16_t csi_i = 0, csi_q = 0;
|
||
|
uint32_t *csi_buf = (uint32_t *)BB_CSI_BASEADDR;
|
||
|
|
||
|
/* reset phy */
|
||
|
phy_reset(PHY_RST_REASON_WARM);
|
||
|
|
||
|
/* config det tone */
|
||
|
phy_rxfd_rate0_det(0, 1535);
|
||
|
phy_rxfd_rate1_det(0, 1535);
|
||
|
|
||
|
/* enable ana loopback */
|
||
|
phy_txrx_loop_back_begin(0,TXRX_LOOP_BACK_GRANITE);
|
||
|
|
||
|
/* trig fft */
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
|
REG_FIELD_SET(SW_LOOP_FFT_CYCLE, tmp, fft_loop);
|
||
|
REG_FIELD_SET(SW_LOOP_FFT_START, tmp, 1);
|
||
|
PHY_DFE_WRITE_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR, tmp);
|
||
|
|
||
|
/* wait fft done */
|
||
|
do{
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
|
}while(!REG_FIELD_GET(LOOP_FFT_DONE, tmp));
|
||
|
|
||
|
/* enable sw csi buf access */
|
||
|
enable_sw_access_csi_buf(1);
|
||
|
|
||
|
/* cal csi for appointed tone */
|
||
|
csi_i = (int16_t)(*(csi_buf + tone_id) & 0xFFFF);
|
||
|
csi_q = (int16_t)(*(csi_buf + tone_id) >> 16);
|
||
|
amp_val = csi_i*csi_i + csi_q*csi_q;
|
||
|
/* enable sw csi buf access */
|
||
|
enable_sw_access_csi_buf(0);
|
||
|
|
||
|
/* recover to the state set in ana loopback */
|
||
|
phy_txrx_loop_back_end();
|
||
|
|
||
|
/* update the precise det range */
|
||
|
phy_update_tone_det_range();
|
||
|
|
||
|
return amp_val;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* rx bandwidth filter:
|
||
|
* rx_freq LPF(typ) Min Max
|
||
|
* 5.6M 63/5.790M 59 63
|
||
|
* 12M 23/12.129M 18 30
|
||
|
* fix big attenuation:
|
||
|
* 8M 36 29 45
|
||
|
* 15M 19 14 24
|
||
|
* 20M 14 11 18
|
||
|
* X/Y = 10^(3/10) = 1.995
|
||
|
*/
|
||
|
uint16_t phy_rx_bw_filter(RX_BW_LIST_ID freq_id)
|
||
|
{
|
||
|
uint8_t reg_id = 0;
|
||
|
uint32_t wdata = 0;
|
||
|
uint32_t wmask = 0;
|
||
|
uint32_t amp_val = 0;
|
||
|
uint16_t tone_id = 0;
|
||
|
uint16_t cap_id = 0;
|
||
|
uint16_t start_cap = 0, end_cap = 0;
|
||
|
uint32_t golden_data = 0;
|
||
|
uint8_t is_thd_find = false;
|
||
|
|
||
|
/* 1st get 3M amp */
|
||
|
tone_id = 41;
|
||
|
phy_dfe_tone_cfg(1,tone_id,0);
|
||
|
phy_dfe_tone_att_cfg(0,3,3);
|
||
|
golden_data = phy_csi_buf_amp_get(tone_id*3);
|
||
|
|
||
|
/* tx tone is trible than cfg */
|
||
|
switch(freq_id)
|
||
|
{
|
||
|
case RX_BW_LIST_BAND0_20M:
|
||
|
start_cap = 11;
|
||
|
end_cap = 18;
|
||
|
tone_id = PHY_SG_BAND0_TONE_20M/3;
|
||
|
break;
|
||
|
case RX_BW_LIST_BAND0_15M:
|
||
|
start_cap = 14;
|
||
|
end_cap = 24;
|
||
|
tone_id = PHY_SG_BAND0_TONE_15M/3;
|
||
|
break;
|
||
|
case RX_BW_LIST_BAND0_12M:
|
||
|
start_cap = 18;
|
||
|
end_cap = 30;
|
||
|
tone_id = PHY_SG_BAND0_TONE_12M/3;
|
||
|
break;
|
||
|
case RX_BW_LIST_BAND0_8M:
|
||
|
start_cap = 29;
|
||
|
end_cap = 45;
|
||
|
tone_id = PHY_SG_BAND0_TONE_8M/3;
|
||
|
break;
|
||
|
case RX_BW_LIST_BAND1_5P6M:
|
||
|
start_cap = 59;
|
||
|
end_cap = 63;
|
||
|
tone_id = PHY_SG_BAND1_TONE_5P6M/3;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* find the 3dB point */
|
||
|
for(cap_id = start_cap; cap_id <= end_cap; cap_id++)
|
||
|
{
|
||
|
/* update rx_selc*/
|
||
|
reg_id = CFG_ANA_RX_REG_0_ADDR;
|
||
|
wdata = cap_id << RX_SELC_OFFSET;
|
||
|
wmask = RX_SELC_MASK;
|
||
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
||
|
|
||
|
/* get the amp from the fixed tone */
|
||
|
phy_dfe_tone_cfg(1,tone_id,0);
|
||
|
phy_dfe_tone_att_cfg(0,3,3);
|
||
|
amp_val = phy_csi_buf_amp_get(tone_id*3);
|
||
|
#if CHIP_BRINGUP_DEBUG == 1
|
||
|
iot_printf("csi_buf_amp_val=%d\r\n", amp_val);
|
||
|
#endif
|
||
|
if(golden_data > (amp_val << 1)){
|
||
|
is_thd_find = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(is_thd_find){
|
||
|
/* update the cap value*/
|
||
|
iot_printf("bw filter cal:band=%d,cap value=%d\r\n",freq_id,cap_id);
|
||
|
}
|
||
|
else if(end_cap == 63){
|
||
|
iot_printf("bw filter cal:band=%d,cap value bigger than 63\r\n",freq_id);
|
||
|
return 63;
|
||
|
}
|
||
|
else{
|
||
|
iot_printf("bw filter cal:band=%d fail \r\n",freq_id);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return cap_id;
|
||
|
}
|
||
|
|
||
|
/* read ppm, dc cali and update to hw */
|
||
|
void phy_load_cal_cfg(void)
|
||
|
{
|
||
|
uint8_t reg_id = 0;
|
||
|
uint8_t rodata = 0;
|
||
|
uint32_t wdata = 0;
|
||
|
uint32_t wmask = 0;
|
||
|
uint16_t tx_dc[4] = {0};
|
||
|
uint16_t *rx_dc = NULL;
|
||
|
|
||
|
/* alloc rx dc mem */
|
||
|
rx_dc = (uint16_t *)os_mem_malloc( \
|
||
|
PLC_PHY_COMMON_MID, \
|
||
|
PHY_GAIN_STEP_MAX << 2);
|
||
|
if(rx_dc == NULL) {
|
||
|
iot_printf("%s: malloc rx dc fail!\n", __FUNCTION__);
|
||
|
IOT_ASSERT(0);
|
||
|
}
|
||
|
|
||
|
/* bias current:50uA */
|
||
|
reg_id = CFG_ANA_BIAS_REG_2_ADDR;
|
||
|
phy_ana_i2c_read(reg_id, &wdata, &rodata);
|
||
|
wdata |= 1 << 31;
|
||
|
wmask = ~0;
|
||
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
||
|
|
||
|
#if IOT_DTEST_ONLY_SUPPORT == 0
|
||
|
uint32_t i = 0;
|
||
|
uint32_t ret = ERR_FAIL;
|
||
|
uint8_t *section;
|
||
|
uint8_t pib_type = 0;
|
||
|
uint16_t dc_pgf = 0;
|
||
|
uint16_t dc_pga = 0;
|
||
|
iot_pib_w_halphy_real_cfg_t *phy_cfg;
|
||
|
|
||
|
iot_cal_data_cfg_t *cal_cfg;
|
||
|
/* init perf ppm */
|
||
|
g_phy_ctxt.dep.phy_ppm_pref = PHY_PPM_PREF_DFT;
|
||
|
g_phy_ctxt.dep.phy_ppm_init = PHY_PPM_PREF_DFT;
|
||
|
|
||
|
/* read crystal ppm from oem */
|
||
|
ret = iot_cal_data_get_cfg(&cal_cfg);
|
||
|
if (ret == ERR_OK || ret == ERR_NOSUPP) {
|
||
|
iot_printf("[PHY %d]oem load successfully!\n", ret);
|
||
|
|
||
|
/* check mtd sts */
|
||
|
if (iot_cal_data_get_mtd_sts() != ERR_OK) {
|
||
|
iot_printf("[PHY]oem mtd status check fail!\n");
|
||
|
} else {
|
||
|
/* check mask if valid */
|
||
|
if (iot_cal_data_check_mask(cal_cfg, IOT_PHY_CFG_MASK_PPM)) {
|
||
|
/* disable td and fd comp self */
|
||
|
phy_freq_shift_self_comp(false, false);
|
||
|
|
||
|
/* g_phy_ctxt.phy_ppm_pref = target crystal ppm
|
||
|
* cal_cfg->halphy_cfg.ppm = - local crystal ppm
|
||
|
* ppm of phy_ppm_cal_set(to self):
|
||
|
* + : faster - : more slowly
|
||
|
*/
|
||
|
|
||
|
/* apply ppm to phy register */
|
||
|
g_phy_ctxt.dep.phy_ppm_init =
|
||
|
g_phy_ctxt.dep.phy_ppm_pref +
|
||
|
cal_cfg->halphy_cfg.ppm;
|
||
|
uint32_t ver = cal_cfg->halphy_cfg.pt_fw_ver;
|
||
|
iot_printf("phy oem ver:0x%x\n", ver);
|
||
|
if (ver && 0xFFFFFFFF != ver) {
|
||
|
g_phy_ctxt.dep.phy_cal_ppm_in_oem =
|
||
|
g_phy_ctxt.dep.phy_ppm_init;
|
||
|
} else {
|
||
|
g_phy_ctxt.dep.phy_cal_ppm_in_oem = FORCE_INI_PPM;
|
||
|
}
|
||
|
g_phy_ctxt.dep.phy_ppm_init =
|
||
|
phy_ppm_cal_hw_val(PHY_CAL_UNIT_1_1,
|
||
|
g_phy_ctxt.dep.phy_cal_ppm_in_oem,
|
||
|
IOT_SUPPORT_RATE_SR);
|
||
|
//TODO: maybe phy_ppm_init save to g_phy_cpu_share_ctxt only
|
||
|
g_phy_cpu_share_ctxt.phy_ppm_init =
|
||
|
g_phy_ctxt.dep.phy_ppm_init;
|
||
|
#if PLC_SUPPORT_CCO_ROLE == 0
|
||
|
/* only sta apply this info
|
||
|
* cco just read and save in
|
||
|
* phy_cal_ppm_in_oem
|
||
|
*/
|
||
|
phy_ppm_set(g_phy_ctxt.dep.phy_ppm_init, BB_PPM_TXRX);
|
||
|
#endif
|
||
|
|
||
|
iot_printf("[PHY]config ppm:%d "
|
||
|
"(pref ppm:%d, oem ppm:%d ) to phy_reg.\n",
|
||
|
g_phy_ctxt.dep.phy_ppm_init,
|
||
|
g_phy_ctxt.dep.phy_ppm_pref,
|
||
|
cal_cfg->halphy_cfg.ppm);
|
||
|
} else {
|
||
|
iot_printf("[PHY]oem magic num check fail!\n");
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
iot_printf("[PHY]oem load failed, err code: %d.\n", ret);
|
||
|
}
|
||
|
|
||
|
/* get dc cal from pib */
|
||
|
ret = iot_pib_get_section(IOT_PIB_HALPHY_ID, §ion, &pib_type,
|
||
|
IOT_PIB_APP_GET_WRITE_SECTION);
|
||
|
if (ret == ERR_OK) {
|
||
|
phy_cfg = (iot_pib_w_halphy_real_cfg_t *)section;
|
||
|
|
||
|
/* check tx dc if valid */
|
||
|
if (phy_cfg->mask & (1 << IOT_PIB_PHY_MASK_TX_DC)) {
|
||
|
/* apply dc calibration */
|
||
|
for(i = 0; i < TOTAL_TX_DC_NUM; i++)
|
||
|
{
|
||
|
phy_dfe_dc_comp_set(i, phy_cfg->tx_dc[i]);
|
||
|
}
|
||
|
} else {
|
||
|
iot_printf("%s pib have no valid tx dc data.\n", __FUNCTION__);
|
||
|
#if PHY_CAL_PIB_SUPPORT == 1
|
||
|
/* commit pib write if need in the future */
|
||
|
tx_dc_calibration(tx_dc, phy_cfg);
|
||
|
#else
|
||
|
tx_dc_calibration(tx_dc);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/* check rx dc if valid */
|
||
|
if (phy_cfg->mask & (1 << IOT_PIB_PHY_MASK_RX_DC)) {
|
||
|
for(i = 0; i < TOTAL_GAIN_NUM; i++)
|
||
|
{
|
||
|
dc_pgf = phy_cfg->rx_dc[i] & 0x3F;
|
||
|
dc_pga = (phy_cfg->rx_dc[i] & 0xFC0) >> 6;
|
||
|
phy_pgf_pga_dc_cal(i, dc_pgf, dc_pga);
|
||
|
}
|
||
|
} else {
|
||
|
iot_printf("%s pib have no valid rx dc data.\n", __FUNCTION__);
|
||
|
#if PHY_CAL_PIB_SUPPORT == 1
|
||
|
/* commit pib write if need in the future */
|
||
|
rx_dc_calibration(rx_dc, phy_cfg);
|
||
|
#else
|
||
|
rx_dc_calibration(rx_dc);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/* check bandwidth filter calibration */
|
||
|
if (phy_cfg->mask & (1 << IOT_PIB_PHY_MASK_BW_FILTER)) {
|
||
|
/* update global variables for freshing */
|
||
|
g_phy_ctxt.dep.band_15m_cap_set = \
|
||
|
phy_cfg->cap_set[RX_BW_LIST_BAND0_15M];
|
||
|
g_phy_ctxt.dep.band_8m_cap_set = \
|
||
|
phy_cfg->cap_set[RX_BW_LIST_BAND0_8M];
|
||
|
g_phy_ctxt.dep.band_20m_cap_set = \
|
||
|
phy_cfg->cap_set[RX_BW_LIST_BAND0_20M];
|
||
|
} else {
|
||
|
iot_printf("%s pib have no valid bw filter data.\n", __FUNCTION__);
|
||
|
|
||
|
/* cali 15M/band0 and 8M/band1 */
|
||
|
phy_param_init(PHY_PROTO_TYPE_GET());
|
||
|
g_phy_ctxt.dep.band_20m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_20M);
|
||
|
g_phy_ctxt.dep.band_15m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_15M);
|
||
|
g_phy_ctxt.dep.band_8m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_8M);
|
||
|
}
|
||
|
} else {
|
||
|
iot_printf("%s cal load fail, calibrate again!\n", __FUNCTION__);
|
||
|
tx_dc_calibration(tx_dc);
|
||
|
rx_dc_calibration(rx_dc);
|
||
|
|
||
|
/* cali 15M/band0 and 8M/band1 */
|
||
|
phy_param_init(PHY_PROTO_TYPE_GET());
|
||
|
g_phy_ctxt.dep.band_20m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_20M);
|
||
|
g_phy_ctxt.dep.band_15m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_15M);
|
||
|
g_phy_ctxt.dep.band_8m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_8M);
|
||
|
}
|
||
|
|
||
|
/* commit pib write if need in the future */
|
||
|
#if PHY_CAL_PIB_SUPPORT == 1
|
||
|
uint8_t ref = 0;
|
||
|
uint16_t ticket = 0;
|
||
|
iot_pib_acquire_commit_ref(IOT_PIB_HALPHY_ID, &ref);
|
||
|
iot_pib_release_commit_ref(IOT_PIB_HALPHY_ID, &ref);
|
||
|
iot_pib_commit(IOT_PIB_HALPHY_ID, COMMIT_TYPE_WAIT_REFZERO,
|
||
|
&ticket);
|
||
|
#endif
|
||
|
|
||
|
#else
|
||
|
tx_dc_calibration(tx_dc);
|
||
|
rx_dc_calibration(rx_dc);
|
||
|
|
||
|
/* cali 15M/band0 and 8M/band1 */
|
||
|
phy_param_init(PHY_PROTO_TYPE_GET());
|
||
|
g_phy_ctxt.dep.band_20m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_20M);
|
||
|
g_phy_ctxt.dep.band_15m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_15M);
|
||
|
g_phy_ctxt.dep.band_8m_cap_set = \
|
||
|
phy_rx_bw_filter(RX_BW_LIST_BAND0_8M);
|
||
|
#endif
|
||
|
|
||
|
/* release malloc */
|
||
|
os_mem_free(rx_dc);
|
||
|
|
||
|
/* ana reset */
|
||
|
ahb_phy_ana_reset();
|
||
|
|
||
|
/* bias current:50uA after reset */
|
||
|
reg_id = CFG_ANA_BIAS_REG_2_ADDR;
|
||
|
phy_ana_i2c_read(reg_id, &wdata, &rodata);
|
||
|
wdata |= 1 << 31;
|
||
|
wmask = ~0;
|
||
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
||
|
|
||
|
/* load new dc cali table */
|
||
|
phy_gain_tab_load(all_mask_gain_table);
|
||
|
}
|
||
|
|