660 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			660 lines
		
	
	
		
			20 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 "iot_config.h"
 | |
| #include "os_types.h"
 | |
| #include "hw_reg_api.h"
 | |
| #include "phy_tmap.h"
 | |
| #include "phy_bb.h"
 | |
| #include "iot_errno_api.h"
 | |
| #include "phy_reg.h"
 | |
| #include "phy_tx_reg.h"
 | |
| #include "phy_rx_fd_reg.h"
 | |
| #include "phy_rxtd_reg.h"
 | |
| #include "hw_tonemask.h"
 | |
| #include "hw_tonemap.h"
 | |
| #include "iot_io.h"
 | |
| #include "phy_mix.h"
 | |
| #include "hw_phy_api.h"
 | |
| 
 | |
| void phy_fft_4096p_init(bool_t en)
 | |
| {
 | |
|     /* init */
 | |
|     uint32_t tmp = 0;
 | |
| 
 | |
|     if(en == true) {
 | |
|         /* 4096 point */
 | |
|         tmp = PHY_READ_REG(CFG_BB_SAMPLING_RATE_ADDR);
 | |
|         REG_FIELD_SET(SW_SAMPLING_RATE_SEL, tmp, 1);
 | |
|         PHY_WRITE_REG(CFG_BB_SAMPLING_RATE_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR);
 | |
|         REG_FIELD_SET(SW_PLD_FFT_HALF_NUM, tmp, 2048);
 | |
|         REG_FIELD_SET(SW_FC_FFT_HALF_NUM, tmp, 2048);
 | |
|         PHY_WRITE_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_3_ADDR);
 | |
|         REG_FIELD_SET(SW_IS_191_INSERT_PREAM, tmp, 255);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_3_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_1_ADDR);
 | |
|         REG_FIELD_SET(SW_IS_1535_INSERT_PREAM, tmp, 2047);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_1_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_D_ADDR);
 | |
|         REG_FIELD_SET(SW_SG_IFFT_POINT_NUM_HALF, tmp, 2048);
 | |
|         REG_FIELD_SET(SW_SG_IFFT_POINT_NUM, tmp, 4096);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_D_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_E_ADDR);
 | |
|         REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM_HALF, tmp, 256);
 | |
|         REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM, tmp, 512);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_E_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_C_ADDR);
 | |
|         REG_FIELD_SET(SW_RI_POINT_NUM, tmp, 496);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_C_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR);
 | |
|         REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_567, tmp, 756);
 | |
|         REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_417, tmp, 556);
 | |
|         PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR);
 | |
|         REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_3534, tmp, 4712);
 | |
|         PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR);
 | |
|         REG_FIELD_SET(SW_GP_PLD_GI_STD, tmp, 556);
 | |
|         PHY_WRITE_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TR_GP_PLD_GI_ADDR);
 | |
|         REG_FIELD_SET(SW_GP_PLD_GI_HS, tmp, 556);
 | |
|         REG_FIELD_SET(SW_GP_PLD_GI_MIN, tmp, 756);
 | |
|         PHY_WRITE_REG(CFG_BB_TR_GP_PLD_GI_ADDR, tmp);
 | |
| 
 | |
|         phy_rxfd_rate0_det(0, 2047);
 | |
|         phy_rxfd_rate1_det(0, 2047);
 | |
|     } else {
 | |
|         /* 4096 point */
 | |
|         tmp = PHY_READ_REG(CFG_BB_SAMPLING_RATE_ADDR);
 | |
|         REG_FIELD_SET(SW_SAMPLING_RATE_SEL, tmp, 0);
 | |
|         PHY_WRITE_REG(CFG_BB_SAMPLING_RATE_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR);
 | |
|         REG_FIELD_SET(SW_PLD_FFT_HALF_NUM, tmp, 1536);
 | |
|         REG_FIELD_SET(SW_FC_FFT_HALF_NUM, tmp, 1536);
 | |
|         PHY_WRITE_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_3_ADDR);
 | |
|         REG_FIELD_SET(SW_IS_191_INSERT_PREAM, tmp, 191);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_3_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_1_ADDR);
 | |
|         REG_FIELD_SET(SW_IS_1535_INSERT_PREAM, tmp, 1535);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_1_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_D_ADDR);
 | |
|         REG_FIELD_SET(SW_SG_IFFT_POINT_NUM_HALF, tmp, 1536);
 | |
|         REG_FIELD_SET(SW_SG_IFFT_POINT_NUM, tmp, 3072);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_D_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_E_ADDR);
 | |
|         REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM_HALF, tmp, 192);
 | |
|         REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM, tmp, 384);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_E_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_C_ADDR);
 | |
|         REG_FIELD_SET(SW_RI_POINT_NUM, tmp, 372);
 | |
|         PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_C_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR);
 | |
|         REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_567, tmp, 567);
 | |
|         REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_417, tmp, 417);
 | |
|         PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR);
 | |
|         REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_3534, tmp, 3534);
 | |
|         PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR);
 | |
|         REG_FIELD_SET(SW_GP_PLD_GI_STD, tmp, 417);
 | |
|         PHY_WRITE_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR, tmp);
 | |
| 
 | |
|         tmp = PHY_READ_REG(CFG_BB_TR_GP_PLD_GI_ADDR);
 | |
|         REG_FIELD_SET(SW_GP_PLD_GI_HS, tmp, 417);
 | |
|         REG_FIELD_SET(SW_GP_PLD_GI_MIN, tmp, 567);
 | |
|         PHY_WRITE_REG(CFG_BB_TR_GP_PLD_GI_ADDR, tmp);
 | |
| 
 | |
|         /* config det tone */
 | |
|         phy_update_tone_det_range();
 | |
| 
 | |
|     }
 | |
| }
 | |
| 
 | |
| #if SUPPORT_GREEN_PHY
 | |
| 
 | |
| uint32_t phy_tmap_cal( \
 | |
|     uint32_t *sound_data_ptr, \
 | |
|     uint32_t *tone_map_ptr, \
 | |
|     uint32_t start_tone, \
 | |
|     uint32_t end_tone, \
 | |
|     uint8_t cal_lvl)
 | |
| {
 | |
|     uint32_t ret = ERR_OK;
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA && \
 | |
|     SUPPORT_GREEN_PHY == 1
 | |
|     uint32_t i = 0;
 | |
|     uint32_t tmp = 0;
 | |
|     volatile uint32_t map_begin_col_idx = 0;
 | |
|     volatile uint32_t map_begin_group_idx = 0;
 | |
|     volatile uint32_t map_end_col_idx = 0;
 | |
|     volatile uint32_t map_end_group_idx = 0;
 | |
| 
 | |
|     /* check valid */
 | |
|     IOT_ASSERT((start_tone < end_tone) && \
 | |
|         (end_tone < TOTAL_TONE_MASK_NUM) && \
 | |
|         (sound_data_ptr != NULL) && \
 | |
|         (tone_map_ptr != NULL));
 | |
| 
 | |
|     /* get start tone */
 | |
|     map_begin_col_idx = start_tone & 0x7;
 | |
|     map_begin_group_idx = start_tone >> 3;
 | |
| 
 | |
|     /* get end tone */
 | |
|     map_end_col_idx = end_tone & 0x7;
 | |
|     map_end_group_idx = end_tone >> 3;
 | |
| 
 | |
|     enable_sw_access_tmi_buf(true);
 | |
|     /* tone mask table */
 | |
|     for(i = map_begin_group_idx; i <= map_end_group_idx; i++)
 | |
|     {
 | |
|         tmp = 0;
 | |
|         /* Must word write */
 | |
|         if((map_begin_col_idx != 0) && \
 | |
|             (i == map_begin_group_idx)) {
 | |
|             while(map_begin_col_idx < 8)
 | |
|             {
 | |
|                 tmp |= ((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << \
 | |
|                     (map_begin_col_idx << 2);
 | |
|                 map_begin_col_idx++;
 | |
|             }
 | |
|         } else if((map_end_col_idx != 7) && \
 | |
|             (i == map_end_group_idx)){
 | |
|             map_end_col_idx = map_end_col_idx + 1;
 | |
|             while(map_end_col_idx > 0)
 | |
|             {
 | |
|                 tmp |= ((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << \
 | |
|                     ((map_end_col_idx - 1) << 2);
 | |
|                 map_end_col_idx--;
 | |
|             }
 | |
|         } else {
 | |
|             /* TODO: get data from sound data */
 | |
|             (void)sound_data_ptr;
 | |
|             tmp = (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 0) | \
 | |
|                 (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 4) | \
 | |
|                 (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 8) | \
 | |
|                 (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 12) |\
 | |
|                 (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 16) | \
 | |
|                 (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 20) | \
 | |
|                 (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 24) | \
 | |
|                 (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 28);
 | |
|         }
 | |
|         *(tone_map_ptr + map_begin_group_idx) = tmp;
 | |
|         tone_map_ptr++;
 | |
|     }
 | |
|     enable_sw_access_tmi_buf(false);
 | |
| 
 | |
|     (void)cal_lvl;
 | |
| #else
 | |
|     (void)sound_data_ptr;
 | |
|     (void)tone_map_ptr;
 | |
|     (void)start_tone;
 | |
|     (void)end_tone;
 | |
|     (void)cal_lvl;
 | |
| #endif
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| void phy_tmap_tx_rule_set(plc_tmap_rule_t *rule)
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA && \
 | |
|     SUPPORT_GREEN_PHY == 1
 | |
|     uint32_t tmp = 0;
 | |
|     uint32_t reg_base = 0;
 | |
|     uint32_t tmap_base = 0;
 | |
|     uint32_t tmap_idx = 0;
 | |
| 
 | |
|     /* valid en */
 | |
|     tmap_base = rule->rule_id >> 5;
 | |
|     tmap_idx = 31 - (rule->rule_id & 0x1F);
 | |
|     reg_base = CFG_BB_TMAP_TX_VLD_CTRL_0_ADDR + (tmap_base << 2);
 | |
|     tmp = PHY_READ_REG(reg_base);
 | |
|     if(rule->en) {
 | |
|         tmp |= 1 << tmap_idx;
 | |
|         PHY_WRITE_REG(reg_base, tmp);
 | |
|     } else {
 | |
|         tmp &= ~(1 << tmap_idx);
 | |
|         PHY_WRITE_REG(reg_base, tmp);
 | |
|     }
 | |
| 
 | |
|     /* tx dtei */
 | |
|     tmap_base = rule->rule_id >> 2;
 | |
|     tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
 | |
|     reg_base = CFG_BB_TMAP_TX_DTEI_CTRL_0_ADDR + (tmap_base << 2);
 | |
|     tmp = PHY_READ_REG(reg_base);
 | |
|     tmp |= rule->dtei << tmap_idx;
 | |
|     PHY_WRITE_REG(reg_base, tmp);
 | |
| 
 | |
|     /* tmi */
 | |
|     tmap_base = rule->rule_id >> 2;
 | |
|     tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
 | |
|     reg_base = CFG_BB_TMAP_TX_TMI_CTRL_0_ADDR + (tmap_base << 2);
 | |
|     tmp = PHY_READ_REG(reg_base);
 | |
|     tmp |= rule->tmi << tmap_idx;
 | |
|     PHY_WRITE_REG(reg_base, tmp);
 | |
| #else
 | |
|     (void)rule;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void phy_tmap_rx_rule_set(plc_tmap_rule_t *rule)
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA && \
 | |
|     SUPPORT_GREEN_PHY == 1
 | |
|     uint32_t tmp = 0;
 | |
|     uint32_t reg_base = 0;
 | |
|     uint32_t tmap_base = 0;
 | |
|     uint32_t tmap_idx = 0;
 | |
| 
 | |
|     /* valid en */
 | |
|     tmap_base = rule->rule_id >> 5;
 | |
|     tmap_idx = 31 - (rule->rule_id & 0x1F);
 | |
|     reg_base = CFG_BB_TMAP_RX_VLD_CTRL_0_ADDR + (tmap_base << 2);
 | |
|     tmp = PHY_READ_REG(reg_base);
 | |
|     if(rule->en) {
 | |
|         tmp |= 1 << tmap_idx;
 | |
|         PHY_WRITE_REG(reg_base, tmp);
 | |
|     } else {
 | |
|         tmp &= ~(1 << tmap_idx);
 | |
|         PHY_WRITE_REG(reg_base, tmp);
 | |
|     }
 | |
| 
 | |
|     /* rx stei */
 | |
|     tmap_base = rule->rule_id >> 2;
 | |
|     tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
 | |
|     reg_base = CFG_BB_TMAP_RX_STEI_CTRL_0_ADDR + (tmap_base << 2);
 | |
|     tmp = PHY_READ_REG(reg_base);
 | |
|     tmp |= rule->dtei << tmap_idx;
 | |
|     PHY_WRITE_REG(reg_base, tmp);
 | |
| 
 | |
|     /* tmi */
 | |
|     tmap_base = rule->rule_id >> 2;
 | |
|     tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
 | |
|     reg_base = CFG_BB_TMAP_RX_TMI_CTRL_0_ADDR + (tmap_base << 2);
 | |
|     tmp = PHY_READ_REG(reg_base);
 | |
|     tmp |= rule->tmi << tmap_idx;
 | |
|     PHY_WRITE_REG(reg_base, tmp);
 | |
| #else
 | |
|     (void)rule;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void phy_tmap_self_tmi_set(uint8_t tmi)
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA && \
 | |
|     SUPPORT_GREEN_PHY == 1
 | |
|     uint32_t tmp = 0;
 | |
| 
 | |
|     /* tx/rx stei */
 | |
|     tmp = PHY_READ_REG(CFG_BB_TMAP_SELF_TEI_CTRL_ADDR);
 | |
|     REG_FIELD_SET(SW_TMAP_TX_STEI, tmp, tmi);
 | |
|     REG_FIELD_SET( SW_TMAP_RX_DTEI, tmp, tmi);
 | |
|     PHY_WRITE_REG(CFG_BB_TMAP_SELF_TEI_CTRL_ADDR, tmp);
 | |
| #else
 | |
|     (void)tmi;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void phy_tmap_init()
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA && \
 | |
|     SUPPORT_GREEN_PHY == 1
 | |
|     uint32_t tmp = 0;
 | |
| 
 | |
|     tmp = PHY_RX_FD_READ_REG(CFG_BB_DECISION_FEEDBACK_ADDR);
 | |
|     REG_FIELD_SET(SW_DCFB_ALPHA, tmp, 4);
 | |
|     REG_FIELD_SET(SW_DCFB_EN, tmp, 0);
 | |
|     PHY_RX_FD_WRITE_REG(CFG_BB_DECISION_FEEDBACK_ADDR, tmp);
 | |
| 
 | |
|     phy_mix_flag_set(false);
 | |
| 
 | |
|     tmp = PHY_RX_FD_READ_REG(CFG_BB_RATE_OFFET_ADDR);
 | |
|     REG_FIELD_SET(SW_CSI_RATE1_OFFSET, tmp, 0);
 | |
|     PHY_RX_FD_WRITE_REG(CFG_BB_RATE_OFFET_ADDR, tmp);
 | |
| 
 | |
|     phy_rxfd_mc_en(true);
 | |
| 
 | |
|     tmp = PHY_RX_FD_READ_REG(CFG_BB_PKT_DET_ADDR);
 | |
|     REG_FIELD_SET(SW_SYMB_SYNC_OFFSET, tmp, 1);
 | |
|     PHY_RX_FD_WRITE_REG(CFG_BB_PKT_DET_ADDR, tmp);
 | |
| 
 | |
|     /* disable acc first negative preamble */
 | |
|     tmp = PHY_RX_FD_READ_REG(CFG_BB_FRAME_SYNC_ADDR);
 | |
|     REG_FIELD_SET(SW_SYNC_SYMB_ACC_EN, tmp, 0);
 | |
|     PHY_RX_FD_WRITE_REG(CFG_BB_FRAME_SYNC_ADDR,tmp);
 | |
| 
 | |
|     /* GI */
 | |
|     tmp = PHY_RXTD_READ_REG(CFG_BB_TUNE_FOR_GI_ADDR);
 | |
|     REG_FIELD_SET(SW_TUNE_FOR_PLD_GI2, tmp, 2);
 | |
|     REG_FIELD_SET(SW_TUNE_FOR_PLD_GI1, tmp, 2);
 | |
|     REG_FIELD_SET(SW_TUNE_FOR_PLD_GI0, tmp, 2);
 | |
|     REG_FIELD_SET(SW_TUNE_FOR_FC_GI1, tmp, 0);
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_TUNE_FOR_GI_ADDR, tmp);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /* tmap bits array
 | |
|     PHY_MODU_BPSK ~ PHY_MODU_4096QAM */
 | |
| uint8_t tmap_bits_arry[] = {1,2,4,3,6,8,10,12};
 | |
| 
 | |
| uint32_t phy_cal_tmap_symb_bits( \
 | |
|     uint32_t start_tone, \
 | |
|     uint32_t end_tone, \
 | |
|     uint32_t *tone_map_ptr, \
 | |
|     const plc_tonemask_table *tmt)
 | |
| {
 | |
|     uint32_t i = 0;
 | |
|     uint32_t modu = 0;
 | |
|     uint32_t bits_in_a_symb = 0;
 | |
|     uint32_t tmap_col_idx = 0, tmsk_col_idx = 0;
 | |
|     uint32_t tmap_group_idx = 0, tmsk_group_idx = 0;
 | |
| 
 | |
|     /* check valid */
 | |
|     IOT_ASSERT((start_tone < end_tone) && \
 | |
|         (end_tone < TOTAL_TONE_MASK_NUM) && \
 | |
|         (tone_map_ptr != NULL) && \
 | |
|         (tmt != NULL));
 | |
| 
 | |
|     for(i = start_tone; i <= end_tone; i++)
 | |
|     {
 | |
|         /* get tmap index */
 | |
|         tmap_col_idx = i & 0x7;
 | |
|         tmap_group_idx = i >> 3;
 | |
|         /* get tone mask index */
 | |
|         tmsk_col_idx = i & 0x1F;
 | |
|         tmsk_group_idx = i >> 5;
 | |
| 
 | |
|         /* (*(tone_map_ptr + group_idx) & (0x8 << (col_idx << 2)))  */
 | |
|         if (tmt->tone_mask_bitmap[tmsk_group_idx] & \
 | |
|             (1 << tmsk_col_idx)) {
 | |
|             /* cal modulation */
 | |
|             modu = (*(tone_map_ptr + tmap_group_idx) >> \
 | |
|                 (tmap_col_idx << 2)) & 0x7;
 | |
|             /* cal bits */
 | |
|             bits_in_a_symb += tmap_bits_arry[modu];
 | |
|         }
 | |
|         //iot_printf("i=%d, bits:%d\n", i, bits_in_a_symb);
 | |
|     }
 | |
|     return bits_in_a_symb;
 | |
| }
 | |
| 
 | |
| static const uint8_t sv_turbo_rate_x16[3] =
 | |
| {
 | |
|     32, 21, 18
 | |
| };
 | |
| 
 | |
| int hpav_cal_fl_tmap
 | |
| (
 | |
|     uint8_t mpdu_cnt,
 | |
|     uint8_t pb_num,
 | |
|     uint8_t turbo_rate,
 | |
|     uint8_t tmap_gi,
 | |
|     uint32_t bits_per_symb
 | |
| )
 | |
| {
 | |
|     int         cur_ifs;
 | |
|     uint16_t    pb_size;
 | |
|     int         pb_gi0;
 | |
|     int         pb_gi0_range;
 | |
|     int         align_para;
 | |
|     int         bits_num_total;
 | |
|     int         bits_rest;
 | |
|     int         bits_per_pb;
 | |
|     int         turbo_rate_x16;
 | |
|     int         max_symb_num;
 | |
|     int         max_pb_num;
 | |
|     int         symb_num_total;
 | |
|     float       fl_total;
 | |
|     int         fl_total_new;
 | |
|     int         tmap_gi_val;
 | |
| 
 | |
|     tmap_gi_val = (tmap_gi == PHY_GI_417) ? 417 :
 | |
|                   (tmap_gi == PHY_GI_567) ? 567 : 3534;
 | |
| 
 | |
|     cur_ifs = (mpdu_cnt == 0) ? HPAV_RIFS : HPAV_BIFS ;
 | |
|     pb_size = PB_SIZE_520;
 | |
| 
 | |
|     if (turbo_rate > 2) {
 | |
|         turbo_rate = 2;
 | |
|     }
 | |
|     turbo_rate_x16 = sv_turbo_rate_x16[turbo_rate];
 | |
| 
 | |
|     pb_gi0       = PB_GI0;
 | |
|     pb_gi0_range = 2;
 | |
|     align_para   = ALIGN_PARA;
 | |
| 
 | |
|     bits_per_pb = (pb_size * 8 * turbo_rate_x16)/16 ;
 | |
| 
 | |
|     /* (4095-140/1.28) = 3985.625 */
 | |
|     max_symb_num = (int)(((3985.625) * (float)(align_para) - \
 | |
|         (FFT_POINT + pb_gi0) * pb_gi0_range) / \
 | |
|         (FFT_POINT + tmap_gi_val) + pb_gi0_range - 1) ;
 | |
|     max_pb_num =  (int)(max_symb_num * bits_per_symb / bits_per_pb);
 | |
|     if (pb_num > max_pb_num) {
 | |
|         pb_num = max_pb_num;
 | |
|     }
 | |
| 
 | |
|     bits_num_total = pb_num * bits_per_pb ;
 | |
|     symb_num_total = bits_num_total / bits_per_symb ;
 | |
|     bits_rest = bits_num_total % bits_per_symb;
 | |
| 
 | |
|     if (bits_rest == 0) {
 | |
|         symb_num_total = symb_num_total - 1;
 | |
|         bits_rest = bits_per_symb;
 | |
|     }
 | |
| 
 | |
|     while (bits_rest > bits_per_pb)
 | |
|     {
 | |
|         pb_num = pb_num + 1;
 | |
| 
 | |
|         bits_num_total = bits_num_total + bits_per_pb ;
 | |
|         symb_num_total = bits_num_total / bits_per_symb ;
 | |
|         bits_rest = bits_num_total % bits_per_symb;
 | |
| 
 | |
|         if (bits_rest == 0) {
 | |
|             symb_num_total = symb_num_total - 1;
 | |
|             bits_rest = bits_per_symb;
 | |
|         }
 | |
|     }
 | |
|     symb_num_total = symb_num_total + 1;
 | |
| 
 | |
|     fl_total = (float)( (FFT_POINT + pb_gi0) * pb_gi0_range + \
 | |
|         (symb_num_total - pb_gi0_range) * (FFT_POINT + tmap_gi_val) \
 | |
|          ) / ((float)align_para) + (float)(cur_ifs) / 1.28;
 | |
| 
 | |
|     if (fl_total > 4095) {
 | |
|         /* error, it should not happen! */
 | |
|         IOT_ASSERT("Based on spec, GP fl_total cannot be over 4095!");
 | |
|     }
 | |
| 
 | |
|     if (fl_total - (int)fl_total > 0) {
 | |
|         fl_total_new = (int)fl_total + 1;
 | |
|     } else {
 | |
|         fl_total_new = (int)fl_total;
 | |
|     }
 | |
| 
 | |
|     return fl_total_new;
 | |
| }
 | |
| 
 | |
| extern tonemap_table_entry gp_tonemap_table[];
 | |
| 
 | |
| int hpav_cal_fl_robo(uint8_t tmi, uint8_t mpdu_cnt, uint8_t pb_num)
 | |
| {
 | |
|     int         cur_ifs;
 | |
|     uint16_t    pb_size;
 | |
|     uint8_t     copy_num;
 | |
|     uint8_t     modulation;
 | |
|     uint8_t     turbo_rate;
 | |
|     int         pb_gi0;
 | |
|     int         pb_gi1;
 | |
|     int         pb_gi0_range;
 | |
|     int         align_para;
 | |
|     int         bpc;
 | |
|     int         inter_num;
 | |
|     int         car_robo_cnt;
 | |
|     int         car_in_seg;
 | |
|     int         inter_bits_num;
 | |
|     int         bits_per_symb;
 | |
|     int         bits_in_seg;
 | |
|     int         bits_in_last_sym;
 | |
|     int         pad_bit_num;
 | |
|     int         bits_in_last_seg;
 | |
|     int         last_bits_seg;
 | |
|     int         bits_per_pb;
 | |
|     int         turbo_rate_x16;
 | |
|     int         symb_per_pb;
 | |
|     int         symb_num_total;
 | |
|     float       fl_total;
 | |
|     int         fl_total_new;
 | |
|     int         tx_vld_tone_num = phy_vld_tone_num_get(0, phy_band_id_get());
 | |
| 
 | |
|     if (tmi > 2) {
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     cur_ifs = (mpdu_cnt == 0) ? HPAV_RIFS : HPAV_BIFS ;
 | |
|     pb_size = gp_tonemap_table[tmi].pb_size;
 | |
|     copy_num = gp_tonemap_table[tmi].robo_cnt;
 | |
|     modulation = gp_tonemap_table[tmi].modulation;
 | |
|     turbo_rate = gp_tonemap_table[tmi].coding_rate_idx;
 | |
| 
 | |
|     if (turbo_rate > 2) {
 | |
|         turbo_rate = 2;
 | |
|     }
 | |
|     turbo_rate_x16 = sv_turbo_rate_x16[turbo_rate];
 | |
| 
 | |
|     pb_gi0       = PB_GI0;
 | |
|     pb_gi0_range = 2;
 | |
|     pb_gi1       = ((tmi == 1) || (tmi == 0)) ? GI_STD_ROBO : GI_MINI_ROBO;
 | |
|     align_para   = ALIGN_PARA;
 | |
| 
 | |
|     bpc = modulation;
 | |
|     inter_num = copy_num;
 | |
|     car_robo_cnt = (tx_vld_tone_num / inter_num) * inter_num;
 | |
|     car_in_seg   = car_robo_cnt / copy_num;
 | |
| 
 | |
|     inter_bits_num   = (pb_size * 8 * turbo_rate_x16) / 16;
 | |
|     bits_per_symb    = bpc * car_robo_cnt;
 | |
|     bits_in_seg      = bpc * car_in_seg;
 | |
|     bits_in_last_sym = inter_bits_num % bits_per_symb;
 | |
| 
 | |
|     if (bits_in_last_sym == 0) {
 | |
|         bits_in_last_sym = bits_per_symb;
 | |
|         bits_in_last_seg = bits_in_seg;
 | |
|     } else {
 | |
|         int tmp;
 | |
| 
 | |
|         tmp = (bits_in_last_sym - 1) / bits_in_seg;
 | |
|         bits_in_last_seg = bits_in_last_sym - bits_in_seg * tmp;
 | |
|     }
 | |
| 
 | |
|     pad_bit_num = bits_in_seg - bits_in_last_seg;
 | |
|     last_bits_seg = (bits_in_last_sym / bits_in_seg);
 | |
| 
 | |
|     if (bits_in_last_sym % bits_in_seg == 0) {
 | |
|         if (last_bits_seg) {
 | |
|             last_bits_seg--;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     bits_per_pb = \
 | |
|         ((pb_size * 8 * turbo_rate_x16) / 16 + pad_bit_num) * copy_num;
 | |
|     symb_per_pb = (bits_per_pb + bits_per_symb -1)/bits_per_symb;
 | |
|     symb_num_total = symb_per_pb * pb_num;
 | |
| 
 | |
|     fl_total = (float)( (FFT_POINT + pb_gi0) * pb_gi0_range +
 | |
|         (symb_num_total - pb_gi0_range) * (FFT_POINT + pb_gi1)
 | |
|         ) / ((float)align_para) + (float)(cur_ifs) / 1.28;
 | |
| 
 | |
|     if (fl_total > 4095) {
 | |
|         /* error, it should not happen! */
 | |
|         IOT_ASSERT("Based on spec, GP fl_total cannot be over 4095!");
 | |
|     }
 | |
| 
 | |
|     if (fl_total - (int)fl_total > 0) {
 | |
|         fl_total_new = (int)fl_total + 1;
 | |
|     } else {
 | |
|         fl_total_new = (int)fl_total;
 | |
|     }
 | |
| 
 | |
| #if PHY_DBG_EN
 | |
|     hpav_printf(ePRINT_LEVEL_INFO, \
 | |
|         "hpav_cal_fl_robo::tmi = %d\n", tmi);
 | |
|     hpav_printf(ePRINT_LEVEL_INFO, \
 | |
|         "hpav_cal_fl_robo::tx_vld_tone_num = %d\n", tx_vld_tone_num);
 | |
|     hpav_printf(ePRINT_LEVEL_INFO, \
 | |
|         "hpav_cal_fl_robo::fl_total_new = %d\n", fl_total_new);
 | |
| #endif
 | |
| 
 | |
|     return fl_total_new;
 | |
| }
 | |
| 
 | |
| uint32_t phy_symb_bits_get(uint32_t *tmap_addr)
 | |
| {
 | |
|     /* get symbol number bits */
 | |
|     uint16_t band_start_tone = 0;
 | |
|     uint16_t band_end_tone = 0;
 | |
|     uint16_t valid_tone_num = 0;
 | |
|     uint8_t fc_sym = 0;
 | |
|     const plc_tonemask_table *tone_msk_ptr = NULL;
 | |
|     uint32_t symb_bits = 0;
 | |
| 
 | |
|     /* get tone */
 | |
|     phy_band_info_get_by_id( \
 | |
|         PHY_PROTO_TYPE_GET(), \
 | |
|         IOT_PLC_PHY_BAND_RANGE_DFT, \
 | |
|         phy_band_id_get(), \
 | |
|         &valid_tone_num, \
 | |
|         &fc_sym, \
 | |
|         &band_start_tone, \
 | |
|         &band_end_tone);
 | |
| 
 | |
|     /* mask id */
 | |
|     tone_msk_ptr = phy_tone_mask_ptr_get(phy_mask_id_get());
 | |
| 
 | |
|     /* get symb bits */
 | |
|     symb_bits = phy_cal_tmap_symb_bits( \
 | |
|         band_start_tone, \
 | |
|         band_end_tone, \
 | |
|         tmap_addr, \
 | |
|         tone_msk_ptr);
 | |
|     //iot_printf("symb_bits :%d\n", symb_bits);
 | |
| 
 | |
|     return symb_bits;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 |