281 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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;
 | |
| }
 | |
| 
 |