Files
kunlun/plc/halphy/hw2/phy_ada_dump.c
2024-09-28 14:24:04 +08:00

279 lines
8.2 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 "hw_reg_api.h"
#include "chip_reg_base.h"
#include "ada_reg.h"
#include "iot_config.h"
#include "phy_bb.h"
#include "phy_reg.h"
#include "phy_rx_fd_reg.h"
#include "phy_ana.h"
#include "ahb.h"
#include "os_types.h"
#include "iot_errno_api.h"
#include "iot_io.h"
#include "hw_phy_api.h"
#include "phy_ada_dump.h"
#include "phy_agc.h"
#include "iot_clock.h"
void phy_ada_dump_adc_init( \
uint16_t tone_id, \
uint32_t b_size, \
uint32_t s_size)
{
DaRxPara_t rp = {0};
/* ADA power on */
phy_ada_enable(true);
/* ada_clk_ratio --- 2:1 */
phy_ada_clk_ratio_cfg(1);
/* tx ada cfg */
rp.buf_size = b_size;
rp.sample_size = s_size;
rp.mode = ADC_MODE_AUTO;
rp.thrd = PHY_DUMP_THD_DFT;
rp.clk_inv_en = true;
rp.dmsb_inv_en = false;
phy_ada_rx_cfg(&rp);
ahb_bb_adc_scale_set(0);
}
void phy_ada_dump_dac_init(uint16_t tone_id)
{
uint32_t tmp;
/* ADA power on */
phy_ada_enable(true);
/* dac clk inv */
tmp = ADA_READ_REG(CFG_ADC_CFG2_ADDR);
REG_FIELD_SET(DAC_CLK_INV,tmp,0x1);
ADA_WRITE_REG(CFG_ADC_CFG2_ADDR,tmp);
/* bb adc scale */
ahb_bb_adc_scale_set(3);
}
uint32_t phy_dump_size_cal(uint32_t *b_size, uint32_t *s_size)
{
uint32_t ada_dump_trig_mode = ADC_DUMP_TRIG_SUPPORT;
uint32_t ada_dump_dump_mode = ADC_DUMP_MODE_SUPPORT;
/* check dump mode */
IOT_ASSERT(ada_dump_dump_mode <= ADC_DUMP_MODE_PHY && \
ada_dump_trig_mode <= ADC_DUMP_TRIG_RX_ABORT);
/* check force mode and so on */
if (ada_dump_dump_mode == ADC_DUMP_MODE_FORCE) {
*b_size = 200*K - 1;
*s_size = 200*K - 1;
} else if (ada_dump_dump_mode == ADC_DUMP_MODE_AUTO) {
*b_size = 32*K - 1;
*s_size = 18*K;
} else {
/* TODO: cal dynamic */
switch (ada_dump_trig_mode)
{
case ADC_DUMP_TRIG_CCA:
case ADC_DUMP_TRIG_PKT_DECT:
case ADC_DUMP_TRIG_SYNC_OK:
case ADC_DUMP_TRIG_FC_DONE:
case ADC_DUMP_TRIG_FC_CRC_OK:
case ADC_DUMP_TRIG_FC_CRC_FAIL:
case ADC_DUMP_TRIG_FC_OK_REV_PB:
*b_size = 150*K - 1;
*s_size = 120*K;
break;
case ADC_DUMP_TRIG_PB_DONE:
case ADC_DUMP_TRIG_PB_CRC_OK:
case ADC_DUMP_TRIG_PB_CRC_FAIL:
case ADC_DUMP_TRIG_RX_ABORT:
*b_size = 150*K - 1;
*s_size = 1024;
break;
default:
*b_size = 150*K - 1;
*s_size = 150*K - 512;
break;
}
}
return ERR_OK;
}
uint32_t phy_ada_dump_addr_get(uint32_t *addr)
{
uint32_t size;
if (addr == NULL) {
size = 0;
goto out;
}
/* the address reservation use defective, the length use the maximum,
* and the address is the fixed value.
*/
size = 0xFFFFFFFF;
#if ADC_DUMP_FROM_DDR_EN
*addr = ADC_DUMP_DDR_ADDR;
#else
*addr = ADC_DUMP_RAM_ADDR;
#endif
out:
return size;
}
/* ADA adc data dump */
uint32_t phy_ada_dump_start(uint32_t b_size, \
uint32_t s_size, \
ADC_DUMP_MODE mode, \
uint32_t dly_cnt, \
uint32_t *trig_offset, \
uint32_t trig_id, \
uint32_t speed)
{
uint32_t ret = ERR_OK;
uint32_t tmp = 0;
uint32_t cnt = 0;
/* lose data with agc reset */
phy_gain_chg_rst_en_set(0x0);
/* pb crc fail gen */
#ifdef PHY_GEN_PB_CRC_FAIL_SUPPORT
tmp = PHY_RX_FD_READ_REG(CFG_BB_TURBO_CTRL_ADDR);
REG_FIELD_SET(SW_SCRAMBLE_MODE, tmp, 1);
PHY_RX_FD_WRITE_REG(CFG_BB_TURBO_CTRL_ADDR, tmp);
#endif
/* reduce robo inter num to avoid reseting rx path */
#if ADC_DUMP_TRIG_SUPPORT == ADC_DUMP_TRIG_PB_CRC_FAIL
phy_turbo_dec_inter_set(2);
#endif
/* ada dump start address */
ADA_WRITE_REG(CFG_PSRAM_BUF_PTR_ADDR, ADC_DUMP_DST_ADDR);
/* 1 select DDR and 0 select AI ram for dump */
tmp = ADA_READ_REG(CFG_ADC_CFG0_ADDR);
REG_FIELD_SET(ADA_DUMP_DDR_MODE, tmp, ADC_DUMP_FROM_DDR_EN);
ADA_WRITE_REG(CFG_ADC_CFG0_ADDR, tmp);
/*
* just for trig dump
* bit[3:2] 0: original speed;
* 1: 1/2 speed;
* 2: 1/4 speed;
* 3: 1/8 speed.
*/
tmp = ADA_READ_REG(CFG_ADC_DUMP_CTRL_ADDR);
if (mode == ADC_DUMP_MODE_AUTO) {
REG_FIELD_SET(SW_ADC_1BYTE_EN,tmp,true);
/* bypass adc_sample_ena_sw and adc_trig_pos_en */
tmp |= (1 << 6) | (1 << 5);
} else if(mode == ADC_DUMP_MODE_PHY) {
REG_FIELD_SET(SW_ADC_1BYTE_EN,tmp,false);
#if ADC_DUMP_TRIG_WITH_THRD == 1
REG_FIELD_SET(SW_ADC_TRIG_AUTO,tmp,true);
#else
REG_FIELD_SET(SW_ADC_TRIG_AUTO,tmp,false);
#endif
}
REG_FIELD_SET(SW_ADC_DUMP_SPEED, tmp, speed);
ADA_WRITE_REG(CFG_ADC_DUMP_CTRL_ADDR, tmp);
/* random dump the fixed length data */
if (b_size == s_size) {
phy_adc_mode_cfg(ADC_MODE_FORCE);
} else {
tmp = ADA_READ_REG(CFG_ADC_CFG2_ADDR);
if (mode == ADC_DUMP_MODE_AUTO) {
REG_FIELD_SET(ADC_TRIG_FROM_PHY,tmp,false);
REG_FIELD_SET(ADC_AUTO_MODE,tmp,false);
} else if(mode == ADC_DUMP_MODE_PHY) {
REG_FIELD_SET(ADC_TRIG_FROM_PHY,tmp,true);
}
REG_FIELD_SET(ADC_FORCE_MODE,tmp,false);
ADA_WRITE_REG(CFG_ADC_CFG2_ADDR, tmp);
}
/* trig option */
tmp = PHY_READ_REG(CFG_BB_ADA_DUMP_CFG_ADDR);
if (mode == ADC_DUMP_MODE_AUTO) {
REG_FIELD_SET(SW_BB_DUMP_DATA_SEL,tmp,ADC_DUMP_SEL_DATA_RAW);
} else if(mode == ADC_DUMP_MODE_PHY) {
REG_FIELD_SET(SW_BB_DUMP_DATA_SEL,tmp,ADC_DUMP_DATA_SEL);
REG_FIELD_SET(SW_BB_DUMP_TRIG_SEL,tmp,trig_id);
}
PHY_WRITE_REG(CFG_BB_ADA_DUMP_CFG_ADDR,tmp);
if (1) {
/* clear sample done */
while(phy_adc_is_sample_done()) {
tmp = ADA_READ_REG(CFG_ADC_DUMP_CTRL_ADDR);
tmp |= (1 << 7);
ADA_WRITE_REG(CFG_ADC_DUMP_CTRL_ADDR, tmp);
tmp = ADA_READ_REG(CFG_ADC_DUMP_CTRL_ADDR);
tmp &= ~(1 << 7);
ADA_WRITE_REG(CFG_ADC_DUMP_CTRL_ADDR, tmp);
}
if (mode == ADC_DUMP_MODE_AUTO) {
tmp = ADA_READ_REG(CFG_ADC_CFG2_ADDR);
REG_FIELD_SET(ADC_AUTO_MODE,tmp,true);
ADA_WRITE_REG(CFG_ADC_CFG2_ADDR, tmp);
} else if(mode == ADC_DUMP_MODE_FORCE || \
mode == ADC_DUMP_MODE_PHY) {
/* enable adc to trig dump */
phy_adc_en_cfg(true);
/* adc trigger en */
phy_adc_trig_en_cfg(true);
}
while(1) {
/* sample done */
if (phy_adc_is_sample_done()) {
/* get trig address */
*trig_offset = phy_adc_trig_addr_get();
/* delau 10 us for ai ram done */
iot_delay_us(10);
/* select DDR forever */
if(ADC_DUMP_FROM_DDR_EN == 0) {
tmp = ADA_READ_REG(CFG_ADC_CFG0_ADDR);
REG_FIELD_SET(ADA_DUMP_DDR_MODE, tmp, 1);
ADA_WRITE_REG(CFG_ADC_CFG0_ADDR, tmp);
}
/* dump adc buffer */
iot_printf("trigger addr:%d\n", *trig_offset);
break;
} else {
/* timeout */
if (cnt++ > dly_cnt) {
ret = ERR_FAIL;
break;
}
}
}
}
return ret;
}