680 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			680 lines
		
	
	
		
			20 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 "hw_phy_init.h"
 | ||
|  | #include "hw_tonemask.h"
 | ||
|  | #include "phy_ana.h"
 | ||
|  | #include "plc_fr.h"
 | ||
|  | #if HW_PLATFORM > HW_PLATFORM_SIMU
 | ||
|  | #include "dbg_io.h"
 | ||
|  | #endif
 | ||
|  | #include "plc_utils.h"
 | ||
|  | #include "phy_bb.h"
 | ||
|  | #include "hw_desc.h"
 | ||
|  | #include "hw_gain_table.h"
 | ||
|  | #include "mac_sys_reg.h"
 | ||
|  | #include "hw_reg_api.h"
 | ||
|  | #include "phy_reg.h"
 | ||
|  | #include "iot_io_api.h"
 | ||
|  | #include "plc_protocol.h"
 | ||
|  | #include "gpio_mtx.h"
 | ||
|  | #include "phy_cal.h"
 | ||
|  | #include "phy_dfe_reg.h"
 | ||
|  | #include "iot_errno_api.h"
 | ||
|  | #include "iot_share_task.h"
 | ||
|  | #include "hw_phy_api.h"
 | ||
|  | #include "phy_isr.h"
 | ||
|  | #include "phy_nf.h"
 | ||
|  | #include "phy_pm.h"
 | ||
|  | #include "phy_status.h"
 | ||
|  | #include "phy_overstress.h"
 | ||
|  | #include "phy_cfg.h"
 | ||
|  | #include "phy_mix.h"
 | ||
|  | #include "phy_txrx_pwr.h"
 | ||
|  | #include "iot_config.h"
 | ||
|  | #include "phy_phase.h"
 | ||
|  | #include "clk.h"
 | ||
|  | #include "phy_chn.h"
 | ||
|  | #include "phy_data_ckb.h"
 | ||
|  | #include "iot_cli.h"
 | ||
|  | #include "iot_system.h"
 | ||
|  | #include "phy_geode_gpio.h"
 | ||
|  | #include "phy_temperature.h"
 | ||
|  | #include "iot_clock.h"
 | ||
|  | #include "os_utils.h"
 | ||
|  | #include "iot_gpio_api.h"
 | ||
|  | #include "iot_board_api.h"
 | ||
|  | 
 | ||
|  | /* load band table by default */ | ||
|  | void phy_tone_band_init(uint32_t mac_typ) | ||
|  | { | ||
|  |     /* multi band from default tbl */ | ||
|  |     phy_rate_band_set(0, HW_FULL_BAND, | ||
|  |         all_mask_band_table_r0_full.fc_sym_num, | ||
|  |         all_mask_band_table_r0_full.start_tone, | ||
|  |         all_mask_band_table_r0_full.end_tone); | ||
|  |     phy_rate_band_set(0, HW_LOW_BAND, | ||
|  |         all_mask_band_table_r0_low.fc_sym_num, | ||
|  |         all_mask_band_table_r0_low.start_tone, | ||
|  |         all_mask_band_table_r0_low.end_tone); | ||
|  |     phy_rate_band_set(0, HW_HIGH_BAND, | ||
|  |         all_mask_band_table_r0_high.fc_sym_num, | ||
|  |         all_mask_band_table_r0_high.start_tone, | ||
|  |         all_mask_band_table_r0_high.end_tone); | ||
|  |     phy_rate_band_set(1, HW_FULL_BAND, | ||
|  |         all_mask_band_table_r1_full.fc_sym_num, | ||
|  |         all_mask_band_table_r1_full.start_tone, | ||
|  |         all_mask_band_table_r1_full.end_tone); | ||
|  |     phy_rate_band_set(1, HW_LOW_BAND, | ||
|  |         all_mask_band_table_r1_low.fc_sym_num, | ||
|  |         all_mask_band_table_r1_low.start_tone, | ||
|  |         all_mask_band_table_r1_low.end_tone); | ||
|  |     phy_rate_band_set(1, HW_HIGH_BAND, | ||
|  |         all_mask_band_table_r1_high.fc_sym_num, | ||
|  |         all_mask_band_table_r1_high.start_tone, | ||
|  |         all_mask_band_table_r1_high.end_tone); | ||
|  | 
 | ||
|  |     phy_vld_tone_num_set(0, HW_FULL_BAND, | ||
|  |         all_mask_band_table_r0_full.valid_tone_number); | ||
|  |     phy_vld_tone_num_set(0, HW_LOW_BAND, | ||
|  |         all_mask_band_table_r0_low.valid_tone_number); | ||
|  |     phy_vld_tone_num_set(0, HW_HIGH_BAND, | ||
|  |         all_mask_band_table_r0_high.valid_tone_number); | ||
|  |     phy_vld_tone_num_set(1, HW_FULL_BAND, | ||
|  |         all_mask_band_table_r1_full.valid_tone_number); | ||
|  |     phy_vld_tone_num_set(1, HW_LOW_BAND, | ||
|  |         all_mask_band_table_r1_low.valid_tone_number); | ||
|  |     phy_vld_tone_num_set(1, HW_HIGH_BAND, | ||
|  |         all_mask_band_table_r1_high.valid_tone_number); | ||
|  | 
 | ||
|  |     if(mac_typ == PLC_PROTO_TYPE_SG) | ||
|  |     { | ||
|  |         /* short band for mix mode*/ | ||
|  |         phy_short_band_set(1, 80, 743); | ||
|  |         phy_short_vld_tone_num_set(664); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | /* config start/end/valid tone and fc num */ | ||
|  | void phy_band_init(uint32_t mac_typ, uint32_t band_id) | ||
|  | { | ||
|  |     phy_tone_band_init(mac_typ); | ||
|  |     (void)band_id; | ||
|  | } | ||
|  | 
 | ||
|  | /* keep sync the old version, maybe delete later */ | ||
|  | void phy_band_tbl_load(plc_band_table_t *table) | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU
 | ||
|  |     if (!table) { | ||
|  |         return; | ||
|  |     } | ||
|  |     /* write the band table into reg */ | ||
|  |     RGF_MAC_WRITE_REG(CFG_BAND_PTR_ADDR, (uint32_t)table); | ||
|  | #else
 | ||
|  |     (void)table; | ||
|  | #endif
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_start_end_tone_get( | ||
|  |     uint32_t mac_proto, | ||
|  |     uint32_t range_id, | ||
|  |     uint32_t band_id, | ||
|  |     plc_tone_mask_id mask_id, | ||
|  |     uint16_t *band_start_tone, | ||
|  |     uint16_t *band_end_tone, | ||
|  |     uint8_t *fc_sym) | ||
|  | { | ||
|  |     uint32_t ret = ERR_OK; | ||
|  |     uint16_t valid_tone_num = 0; | ||
|  | 
 | ||
|  |     /* get band info */ | ||
|  |     ret = phy_band_info_get_by_id( | ||
|  |         mac_proto, | ||
|  |         range_id, | ||
|  |         band_id, | ||
|  |         &valid_tone_num, | ||
|  |         fc_sym, | ||
|  |         band_start_tone, | ||
|  |         band_end_tone); | ||
|  | 
 | ||
|  |     /* check tone mask id */ | ||
|  |     if (range_id == IOT_SUPPORT_PROTO_GP_BAND) { | ||
|  |         /* check mask id for each band id */ | ||
|  |         if (mask_id != TONE_MASK_ID_GP && mask_id != TONE_MASK_ID_NULL) { | ||
|  |             ret = ERR_FAIL; | ||
|  |         } | ||
|  |     } else if (range_id == IOT_SUPPORT_PROTO_SG_NSG_BAND) { | ||
|  |         if (band_id == IOT_SUPPORT_TONE_80_490) { | ||
|  |             /* check mask id for each band id */ | ||
|  |             if (mask_id != TONE_MASK_ID_SG0 && mask_id != TONE_MASK_ID_NULL) { | ||
|  |                 ret = ERR_FAIL; | ||
|  |             } | ||
|  |         } else if (band_id == IOT_SUPPORT_TONE_100_230) { | ||
|  |             /* check mask id for each band id */ | ||
|  |             if (mask_id != TONE_MASK_ID_SG1 && mask_id != TONE_MASK_ID_NULL) { | ||
|  |                 ret = ERR_FAIL; | ||
|  |             } | ||
|  |         } else if (band_id == IOT_SUPPORT_TONE_32_120) { | ||
|  |             /* check mask id for each band id */ | ||
|  |             if (mask_id != TONE_MASK_ID_SG2 && mask_id != TONE_MASK_ID_NULL) { | ||
|  |                 ret = ERR_FAIL; | ||
|  |             } | ||
|  |         } else if (band_id == IOT_SUPPORT_TONE_72_120) { | ||
|  |             /* check mask id for each band id */ | ||
|  |             if (mask_id != TONE_MASK_ID_SG3 && mask_id != TONE_MASK_ID_NULL) { | ||
|  |                 ret = ERR_FAIL; | ||
|  |             } | ||
|  |         } else if (band_id == IOT_SUPPORT_TONE_200_1000) { | ||
|  |             /* check mask id for each band id */ | ||
|  |             if (mask_id != TONE_MASK_ID_CUS && mask_id != TONE_MASK_ID_NULL) { | ||
|  |                 ret = ERR_FAIL; | ||
|  |             } | ||
|  |         } | ||
|  |     } else { | ||
|  |         /* check mask id for each band id */ | ||
|  |         if (mask_id != TONE_MASK_ID_SG0 && mask_id != TONE_MASK_ID_SG1 && | ||
|  |             mask_id != TONE_MASK_ID_NULL) { | ||
|  |             ret = ERR_FAIL; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* check valid */ | ||
|  |     if(ret != ERR_OK) { | ||
|  |         *band_start_tone = 0; | ||
|  |         *band_end_tone = 0; | ||
|  |         iot_printf("%s: tome mask id not exit, use default!\n", __FUNCTION__); | ||
|  |     } | ||
|  | 
 | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_band_tbl_init(const plc_tonemask_table *tone_msk_ptr, | ||
|  |     uint32_t band_start_tone, uint32_t band_end_tone, uint32_t fc_sym) | ||
|  | { | ||
|  |     if (band_start_tone == 0 || band_end_tone == 0) { | ||
|  |         /* full band */ | ||
|  |         init_band_table(&all_mask_band_table_r0_full, HW_FULL_BAND, | ||
|  |             tone_msk_ptr, all_mask_band_table_r0_full.fc_sym_num, | ||
|  |             all_mask_band_table_r0_full.start_tone, | ||
|  |             all_mask_band_table_r0_full.end_tone); | ||
|  |         /* low band */ | ||
|  |         init_band_table(&all_mask_band_table_r0_low, HW_LOW_BAND, tone_msk_ptr, | ||
|  |             all_mask_band_table_r0_low.fc_sym_num, | ||
|  |             all_mask_band_table_r0_low.start_tone, | ||
|  |             all_mask_band_table_r0_low.end_tone); | ||
|  |         /* high band */ | ||
|  |         init_band_table(&all_mask_band_table_r0_high, HW_HIGH_BAND, | ||
|  |             tone_msk_ptr, all_mask_band_table_r0_high.fc_sym_num, | ||
|  |             all_mask_band_table_r0_high.start_tone, | ||
|  |             all_mask_band_table_r0_high.end_tone); | ||
|  |         /* full band */ | ||
|  |         init_band_table(&all_mask_band_table_r1_full, HW_FULL_BAND, | ||
|  |             tone_msk_ptr, all_mask_band_table_r1_full.fc_sym_num, | ||
|  |             all_mask_band_table_r1_full.start_tone, | ||
|  |             all_mask_band_table_r1_full.end_tone); | ||
|  |         /* low band */ | ||
|  |         init_band_table(&all_mask_band_table_r1_low, HW_LOW_BAND, tone_msk_ptr, | ||
|  |             all_mask_band_table_r1_low.fc_sym_num, | ||
|  |             all_mask_band_table_r1_low.start_tone, | ||
|  |             all_mask_band_table_r1_low.end_tone); | ||
|  |         /* high band */ | ||
|  |         init_band_table(&all_mask_band_table_r1_high, HW_HIGH_BAND, | ||
|  |             tone_msk_ptr, all_mask_band_table_r1_high.fc_sym_num, | ||
|  |             all_mask_band_table_r1_high.start_tone, | ||
|  |             all_mask_band_table_r1_high.end_tone); | ||
|  |     } else { | ||
|  |         /* full band */ | ||
|  |         init_band_table(&all_mask_band_table_r0_full, HW_FULL_BAND, | ||
|  |             tone_msk_ptr, fc_sym, band_start_tone, band_end_tone); | ||
|  |         /* low band */ | ||
|  |         init_band_table(&all_mask_band_table_r0_low, HW_LOW_BAND, tone_msk_ptr, | ||
|  |             fc_sym, band_start_tone, band_end_tone); | ||
|  |         /* high band */ | ||
|  |         init_band_table(&all_mask_band_table_r0_high, HW_HIGH_BAND, | ||
|  |             tone_msk_ptr, fc_sym, band_start_tone, band_end_tone); | ||
|  |         /* full band */ | ||
|  |         init_band_table(&all_mask_band_table_r1_full, HW_FULL_BAND, | ||
|  |             tone_msk_ptr, fc_sym, band_start_tone, band_end_tone); | ||
|  |         /* low band */ | ||
|  |         init_band_table(&all_mask_band_table_r1_low, HW_LOW_BAND, tone_msk_ptr, | ||
|  |             fc_sym, band_start_tone, band_end_tone); | ||
|  |         /* high band */ | ||
|  |         init_band_table(&all_mask_band_table_r1_high, HW_HIGH_BAND, | ||
|  |             tone_msk_ptr, fc_sym, band_start_tone, band_end_tone); | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* load range table to band table */ | ||
|  | void phy_multi_band_tbl_update(uint32_t range_id, uint32_t band_id) | ||
|  | { | ||
|  |     const plc_phy_band_table_t *band_tab; | ||
|  |     /* SR config */ | ||
|  |     if (range_id == IOT_SUPPORT_PROTO_SG_NSG_BAND) { | ||
|  |         phy_get_plc_nsg_band_tab_info(&band_tab); | ||
|  | #if SUPPORT_SOUTHERN_POWER_GRID
 | ||
|  |         if (IOT_SUPPORT_TONE_MULTI_BAND021 == band_id) { | ||
|  |             all_mask_band_table_r0_full = band_tab[2].band_info; | ||
|  |             all_mask_band_table_r0_low = band_tab[2].band_info; | ||
|  |             all_mask_band_table_r0_high = band_tab[1].band_info; | ||
|  |         } else { | ||
|  |             /* must specail multiband */ | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  | #elif SUPPORT_SMART_GRID
 | ||
|  |         if (IOT_SUPPORT_TONE_MULTI_BAND021 == band_id) { | ||
|  |             all_mask_band_table_r0_full = band_tab[0].band_info; | ||
|  |             all_mask_band_table_r0_low = band_tab[2].band_info; | ||
|  |             all_mask_band_table_r0_high = band_tab[1].band_info; | ||
|  |         } else { | ||
|  |             /* must specail multiband */ | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  | #endif
 | ||
|  |     } else if (range_id == IOT_SUPPORT_PROTO_GP_BAND) { | ||
|  |         phy_get_plc_gp_band_tab_info(&band_tab); | ||
|  |         // TODO: maybe use SUPPORT_GREEN_PHY manage the code
 | ||
|  |         all_mask_band_table_r0_full = band_tab[0].band_info; | ||
|  |         all_mask_band_table_r0_low = band_tab[1].band_info; | ||
|  |         /* gp only has 2 bands used, to prevent array index out of bounds */ | ||
|  |         all_mask_band_table_r0_high = band_tab[1].band_info; | ||
|  | 
 | ||
|  |     } else { | ||
|  |         (void)band_id; | ||
|  |         IOT_ASSERT(0); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void phy_band_info_update(uint32_t mac_proto, | ||
|  |     uint32_t range_id, | ||
|  |     uint32_t band_id, | ||
|  |     plc_tone_mask_id mask_id) | ||
|  | { | ||
|  |     uint16_t band_start_tone = 0; | ||
|  |     uint16_t band_end_tone = 0; | ||
|  |     uint8_t fc_sym = 0; | ||
|  |     const plc_tonemask_table *tone_msk_ptr = NULL; | ||
|  | 
 | ||
|  |     /* update glb config */ | ||
|  |     phy_proto_type_set(mac_proto); | ||
|  |     phy_band_id_set(band_id); | ||
|  |     phy_mask_id_set(mask_id); | ||
|  | 
 | ||
|  |     /* get tone */ | ||
|  |     if(band_id >= IOT_SUPPORT_TONE_MULTI_BAND021) { | ||
|  |         /* update all band */ | ||
|  |         phy_multi_band_tbl_update(range_id, band_id); | ||
|  |     } else { | ||
|  |         phy_start_end_tone_get( | ||
|  |             mac_proto, | ||
|  |             range_id, | ||
|  |             band_id, | ||
|  |             mask_id, | ||
|  |             &band_start_tone, | ||
|  |             &band_end_tone, | ||
|  |             &fc_sym); | ||
|  |     } | ||
|  | 
 | ||
|  |     /* mask id */ | ||
|  |     tone_msk_ptr = phy_tone_mask_ptr_get(mask_id); | ||
|  | 
 | ||
|  |     /* phy band init */ | ||
|  |     phy_band_tbl_init(tone_msk_ptr, band_start_tone, band_end_tone, fc_sym); | ||
|  | 
 | ||
|  |     /* band reg init */ | ||
|  |     phy_band_init(mac_proto, band_id); | ||
|  | 
 | ||
|  |     /* new sg support */ | ||
|  |     if (mac_proto == PLC_PROTO_TYPE_SG) { | ||
|  |         /* TODO Note:
 | ||
|  |             standard smart grid must < 512 and set flag en | ||
|  |             iot can use any band and donnot care flag or not | ||
|  |         */ | ||
|  |         if (all_mask_band_table_r0_full.end_tone > 512) { | ||
|  |             phy_new_sg_en(false); | ||
|  |         } else { | ||
|  |             phy_new_sg_en(true); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  | #if PLC_MAC_RX_DEBUG_LOG
 | ||
|  |     /* print the band table inited */ | ||
|  |     print_band_table(&all_mask_band_table_r0_full); | ||
|  |     print_band_table(&all_mask_band_table_r0_low); | ||
|  |     print_band_table(&all_mask_band_table_r0_high); | ||
|  |     print_band_table(&all_mask_band_table_r1_full); | ||
|  |     print_band_table(&all_mask_band_table_r1_low); | ||
|  |     print_band_table(&all_mask_band_table_r1_high); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if PLC_MEM_ALLOC_STAT
 | ||
|  |     iot_printf("band table = %d bytes, tone mask table = %d bytes\n", | ||
|  |         sizeof(all_mask_band_table_r0_full), sizeof(all_mask_tone_mask_table)); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* becareful the seq of these table load */ | ||
|  |     phy_band_tbl_load(&all_mask_band_table_r0_full); | ||
|  |     phy_tone_mask_amp_phase_tab_load(&all_mask_amp_phase_table, mask_id, | ||
|  |         mac_proto); | ||
|  |     phy_gain_tab_load(all_mask_gain_table); | ||
|  | 
 | ||
|  |     /* update tobe config */ | ||
|  |     phy_proto_type_to_set(mac_proto); | ||
|  |     phy_band_id_to_set(band_id); | ||
|  |     phy_mask_id_to_set(mask_id); | ||
|  | 
 | ||
|  |     /* update tone detect range */ | ||
|  |     phy_update_tone_det_range(); | ||
|  | 
 | ||
|  |     /* band rate tbl range init */ | ||
|  |     phy_ra_tbl_band_range_init(); | ||
|  | 
 | ||
|  |     /* band filter select cfg */ | ||
|  | #if (PLC_SUPPORT_BAND_FILTER_SELECT && IOT_DTEST_ONLY_SUPPORT == 0)
 | ||
|  |     if (mac_proto == PLC_PROTO_TYPE_SG || mac_proto == PLC_PROTO_TYPE_SPG) { | ||
|  |         phy_init_band_filter_gpio(); | ||
|  |         phy_cfg_band_filter_gpio((uint8_t)band_id); | ||
|  |     } | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | /* phy initialize */ | ||
|  | void phy_init(uint32_t mac_proto, uint32_t band_id, plc_tone_mask_id mask_id, | ||
|  |     bool_t bbai_en) | ||
|  | { | ||
|  |     uint32_t range_id = IOT_PLC_PHY_BAND_RANGE_DFT; | ||
|  | 
 | ||
|  |     /* check env */ | ||
|  |     phy_env_pre_check(mac_proto, band_id, mask_id); | ||
|  | 
 | ||
|  |     /* delay for boot-hang  */ | ||
|  |     os_delay(CHIP_HANG_DELAY); | ||
|  | 
 | ||
|  |     /* reset phy */ | ||
|  |     phy_reset(PHY_RST_REASON_COLD); | ||
|  | 
 | ||
|  |     /* enable phy reg clk */ | ||
|  |     phy_eb(true); | ||
|  | 
 | ||
|  |     /* update phy band */ | ||
|  |     phy_band_info_update(mac_proto, range_id, band_id, mask_id); | ||
|  | 
 | ||
|  |     /* load pib cfg*/ | ||
|  | #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | ||
|  |     phy_load_pib_cfg(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if HW_PLATFORM == HW_PLATFORM_FPGA
 | ||
|  |     /* ana init */ | ||
|  |     phy_ana_init(band_id); | ||
|  | 
 | ||
|  | #elif HW_PLATFORM == HW_PLATFORM_SILICON
 | ||
|  |     /* calibration form pib */ | ||
|  |     phy_load_cal_cfg(); | ||
|  | 
 | ||
|  |     /* CPU switch to 25M */ | ||
|  |     clk_core_freq_slip_25m_set(); | ||
|  | 
 | ||
|  |     /* analog initial */ | ||
|  |     phy_ana_init(band_id); | ||
|  |     /* gpio mapping */ | ||
|  |     geode_gpio_init(); | ||
|  | #if IOT_DTEST_ONLY_SUPPORT == 0
 | ||
|  |     /* phy low power start */ | ||
|  |     phy_pm_start(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* CPU switch to 150M */ | ||
|  |     clk_core_freq_slip_150m_set(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* map plc protocol phase to hw phase */ | ||
|  |     phy_set_phase_overwrite(true, | ||
|  |         HW_DESC_PHASE_ALL, | ||
|  |         HW_DESC_PHASE_A, | ||
|  |         HW_DESC_PHASE_B, | ||
|  |         HW_DESC_PHASE_C); | ||
|  | 
 | ||
|  |     /* config software version to register */ | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_DFE_SPARE2_ADDR,PHY_SW_VER); | ||
|  | 
 | ||
|  |     /* init phy register */ | ||
|  |     phy_param_init(PHY_PROTO_TYPE_GET()); | ||
|  | 
 | ||
|  |     /* delay for boot-hang  */ | ||
|  |     os_delay(CHIP_HANG_DELAY); | ||
|  | 
 | ||
|  | #if IOT_DTEST_ONLY_SUPPORT == 0
 | ||
|  |     if (phy_get_fw_mode() != MP_MODE) { | ||
|  |         /* WAR:bugid 244, enable phy isr for sack tx */ | ||
|  |         if (PHY_PROTO_TYPE_GET() != PLC_PROTO_TYPE_GP) { | ||
|  |             phy_isr_init(); | ||
|  |             phy_isr_start(); | ||
|  | 
 | ||
|  |             phy_isr_start_cpu1(); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* update fl for mac */ | ||
|  |     phy_symppb_flppb_init(mac_proto); | ||
|  | 
 | ||
|  |     /* sts cnt log */ | ||
|  |     register_regular_log(phy_get_status_printf); | ||
|  | 
 | ||
|  |     /* delay for boot-hang  */ | ||
|  |     os_delay(CHIP_HANG_DELAY); | ||
|  | 
 | ||
|  |     /* channel pre-estimate */ | ||
|  |     /*high_perf_en is 0 when first power on*/ | ||
|  |     if (bbai_en == true) { | ||
|  |         g_phy_cpu_share_ctxt.high_perf_en = 0; | ||
|  |         phy_chn_est_pre_detect(); | ||
|  |     } | ||
|  | 
 | ||
|  | #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | ||
|  |     /* init timer */ | ||
|  |     phy_nf_timer_start(); | ||
|  | #endif
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | ||
|  |     if (range_id == IOT_SUPPORT_PROTO_SG_NSG_BAND) { | ||
|  |         /* support diff featue base on platform */ | ||
|  |         phy_spcl_feat_init(); | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /*record phy init cnt*/ | ||
|  |     phy_set_init_cnt(); | ||
|  | 
 | ||
|  |     /* init multiband special optimization */ | ||
|  |     if (band_id == IOT_SUPPORT_TONE_MULTI_BAND021) { | ||
|  |         phy_multi_band_opt_ena(band_id); | ||
|  |     } | ||
|  |     /* war for bug
 | ||
|  |      * sometime cco start, failure to receive package. | ||
|  |      * add phy_reset to work around. | ||
|  |      */ | ||
|  |     phy_reset(PHY_RST_REASON_WARM); | ||
|  | 
 | ||
|  |     /* init phy temperature */ | ||
|  |     phy_temperature_adc_init(); | ||
|  | 
 | ||
|  | #if PHY_HW_SPIKE_OPTIMIZATION
 | ||
|  |     if (IOT_SUPPORT_TONE_32_120 == band_id) { | ||
|  |         phy_rxfd_pkt_det_thd_set(8, 16); | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* delay for boot-hang  */ | ||
|  |     os_delay(CHIP_HANG_DELAY); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | /* phy re-init */ | ||
|  | void phy_reinit(uint32_t mac_proto, uint32_t band_id, plc_tone_mask_id mask_id, | ||
|  |     bool_t bbai_en) | ||
|  | { | ||
|  |     uint32_t range_id = IOT_PLC_PHY_BAND_RANGE_DFT; | ||
|  | 
 | ||
|  |     /* check env */ | ||
|  |     phy_env_pre_check(mac_proto, band_id, mask_id); | ||
|  | 
 | ||
|  |     /* TODO: check if need disable clock */ | ||
|  |     /* reset phy */ | ||
|  |     phy_reset(PHY_RST_REASON_WARM); | ||
|  | 
 | ||
|  |     /* update phy band */ | ||
|  |     phy_band_info_update(mac_proto, range_id, band_id, mask_id); | ||
|  | 
 | ||
|  |     /* load pib cfg*/ | ||
|  | #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | ||
|  |     phy_load_pib_cfg(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if HW_PLATFORM == HW_PLATFORM_SILICON
 | ||
|  |     /* calibration from pib */ | ||
|  |     phy_load_cal_cfg(); | ||
|  | 
 | ||
|  |     phy_ana_init(band_id); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* init phy register */ | ||
|  |     phy_param_init(mac_proto); | ||
|  | 
 | ||
|  | #if IOT_DTEST_ONLY_SUPPORT == 0
 | ||
|  |     phy_symppb_flppb_init(mac_proto); | ||
|  | 
 | ||
|  |     if (bbai_en == true) { | ||
|  |         /* channel pre-estimate */ | ||
|  |         phy_chn_est_pre_detect(); | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | ||
|  |     if (range_id == IOT_SUPPORT_PROTO_SG_NSG_BAND) { | ||
|  |         /* support diff featue base on platform */ | ||
|  |         phy_spcl_feat_init(); | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /*record phy reinit cnt*/ | ||
|  |     phy_set_reinit_cnt(); | ||
|  | 
 | ||
|  | #if PHY_HW_SPIKE_OPTIMIZATION
 | ||
|  |     if (IOT_SUPPORT_TONE_32_120 == band_id) { | ||
|  |         phy_rxfd_pkt_det_thd_set(8, 16); | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void phy_new_cfg_apply() | ||
|  | { | ||
|  |     /* apply new phy mode */ | ||
|  |     phy_reinit(g_phy_ctxt.indep.chn.phy_proto_tobe, | ||
|  |         g_phy_ctxt.indep.chn.band_id_tobe, | ||
|  |         g_phy_ctxt.indep.chn.mask_id_tobe, | ||
|  |         true); | ||
|  | 
 | ||
|  |     /* clr fc ok find flag */ | ||
|  | #if IOT_DTEST_ONLY_SUPPORT == 0
 | ||
|  |     g_phy_cpu_share_ctxt.pm_status.fc_ok_found = 0; | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void phy_trx_phase_switch_gpio_init() | ||
|  | { | ||
|  |     uint8_t txrx_switch_a = iot_board_get_gpio(GPIO_TXRX_SWITCH_A); | ||
|  |     uint8_t txrx_switch_b = iot_board_get_gpio(GPIO_TXRX_SWITCH_B); | ||
|  |     uint8_t txrx_switch_c = iot_board_get_gpio(GPIO_TXRX_SWITCH_C); | ||
|  |     if (txrx_switch_a == GPIO_NO_VALID || txrx_switch_b == GPIO_NO_VALID || | ||
|  |         txrx_switch_c == GPIO_NO_VALID) { | ||
|  |         g_phy_cpu_share_ctxt.trx_phase_switch_en = 0; | ||
|  |         iot_printf("%s not_support trx switch gpio phase config\n", | ||
|  |             __FUNCTION__); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     g_phy_cpu_share_ctxt.trx_phase_switch_en = 1; | ||
|  |     g_phy_cpu_share_ctxt.trx_switch_phase = PLC_PHASE_A; | ||
|  | 
 | ||
|  |     /* default enable phase a */ | ||
|  |     iot_gpio_open_as_output(txrx_switch_a); | ||
|  |     iot_gpio_value_set(txrx_switch_a, 1); | ||
|  | 
 | ||
|  |     iot_gpio_open_as_output(txrx_switch_b); | ||
|  |     iot_gpio_value_set(txrx_switch_b, 0); | ||
|  | 
 | ||
|  |     iot_gpio_open_as_output(txrx_switch_c); | ||
|  |     iot_gpio_value_set(txrx_switch_c, 0); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_set_trx_switch_gpio_phase(uint8_t phase) | ||
|  | { | ||
|  |     if (!g_phy_cpu_share_ctxt.trx_phase_switch_en) { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (phase > PLC_PHASE_CNT) { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     g_phy_cpu_share_ctxt.trx_switch_phase = phase; | ||
|  | 
 | ||
|  |     uint8_t txrx_switch_a = iot_board_get_gpio(GPIO_TXRX_SWITCH_A); | ||
|  |     uint8_t txrx_switch_b = iot_board_get_gpio(GPIO_TXRX_SWITCH_B); | ||
|  |     uint8_t txrx_switch_c = iot_board_get_gpio(GPIO_TXRX_SWITCH_C); | ||
|  | 
 | ||
|  |     if (PLC_PHASE_A == phase) { | ||
|  |         /* phase A */ | ||
|  |         iot_gpio_value_set(txrx_switch_a, 1); | ||
|  |         iot_gpio_value_set(txrx_switch_b, 0); | ||
|  |         iot_gpio_value_set(txrx_switch_c, 0); | ||
|  |     } else if (PLC_PHASE_B == phase) { | ||
|  |         /* phase B */ | ||
|  |         iot_gpio_value_set(txrx_switch_a, 0); | ||
|  |         iot_gpio_value_set(txrx_switch_b, 1); | ||
|  |         iot_gpio_value_set(txrx_switch_c, 0); | ||
|  |     } else if (PLC_PHASE_C == phase) { | ||
|  |         /* phase C */ | ||
|  |         iot_gpio_value_set(txrx_switch_a, 0); | ||
|  |         iot_gpio_value_set(txrx_switch_b, 0); | ||
|  |         iot_gpio_value_set(txrx_switch_c, 1); | ||
|  |     } else { | ||
|  |         /* phase ALL */ | ||
|  |         iot_gpio_value_set(txrx_switch_a, 1); | ||
|  |         iot_gpio_value_set(txrx_switch_b, 1); | ||
|  |         iot_gpio_value_set(txrx_switch_c, 1); | ||
|  |     } | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint8_t phy_get_trx_switch_gpio_phase() | ||
|  | { | ||
|  |     if (!g_phy_cpu_share_ctxt.trx_phase_switch_en) { | ||
|  |         return PLC_PHASE_A; | ||
|  |     } | ||
|  | 
 | ||
|  |     return (uint8_t)g_phy_cpu_share_ctxt.trx_switch_phase; | ||
|  | } | ||
|  | 
 |