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

281 lines
8.3 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"
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);
/* 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_PWR_JUMP);
/* check force mode and so on */
if (ada_dump_dump_mode == ADC_DUMP_MODE_FORCE) {
*b_size = 56*K - 1;
*s_size = 56*K - 1;
} else if (ada_dump_dump_mode == ADC_DUMP_MODE_AUTO) {
*b_size = 32*K;
*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 = 56*K - 1;
*s_size = 36*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_PWR_JUMP:
*b_size = 56*K - 1;
*s_size = 32;
break;
default:
*b_size = 56*K - 1;
*s_size = 56*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 is defective, the length use the maximum,
* and the address use the fixed value.
*/
size = 0xFFFFFFFF;
*addr = ADC_DUMP_RAM_ADDR;
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 tmp = 0;
uint32_t cnt = 0;
uint32_t raw_offset = 0;
/* enable adc */
phy_adc_en_cfg(true);
/* ram mode form ada, the memory used must start from 0xFD0000.
* if using ram1 (0xFD0000--0xFDFFFF, 16k word), enable bit1.
* if using ram2 (0xFE0000--0xFEFFFF, 16k word), enable bit2.
* if using ram3 (0xFF0000--0xFFFFFF, 16k word), enable bit3.
*/
if (b_size > (K << 5)) {
/* open the third ram if over than 32K word */
ahb_hram_adc_mode_enable((1 << 1) | (1 << 2) | (1 << 3));
} else if (b_size > (K << 4)) {
ahb_hram_adc_mode_enable((1 << 1) | (1 << 2));
} else {
ahb_hram_adc_mode_enable(1 << 1);
}
/* 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
/*
* 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);
mode = ADC_DUMP_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) {
/* adc trigger en */
phy_adc_trig_en_cfg(true);
}
while(1) {
/* sample done */
if (phy_adc_is_sample_done()) {
*trig_offset = phy_adc_trig_addr_get();
break;
} else {
/* timeout */
if (cnt++ > dly_cnt) {
return ERR_FAIL;
}
}
}
/* adc trigger disable */
if (mode == ADC_DUMP_MODE_FORCE) {
phy_adc_trig_en_cfg(false);
}
/* ram mode form cpu */
ahb_hram_adc_mode_disable((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3));
/* note:
* dump from 0xfd0000
* dump end with 16*3K word
* dump head from 0xfc8000 with 8K word
*/
if (*trig_offset >= 48*K) {
raw_offset = *trig_offset - 48*K;
raw_offset = raw_offset*2;
} else {
raw_offset = 8*K*2 + *trig_offset*2;
}
/* dump adc buffer */
iot_printf("trigger addr:%d, raw print addr:%d\n", *trig_offset, raw_offset);
}
return ERR_OK;
}