496 lines
13 KiB
C
496 lines
13 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 "phy_rf_init.h"
|
|
#include "iot_config.h"
|
|
#include "iot_io_api.h"
|
|
#include "iot_board_api.h"
|
|
#include "iot_errno_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "iot_system.h"
|
|
#include "iot_cal_data.h"
|
|
#include "os_utils.h"
|
|
#include "hw_reg_api.h"
|
|
#include "phy_rf_chn.h"
|
|
#include "ahb.h"
|
|
#include "gpio_mtx.h"
|
|
#include "plc_const.h"
|
|
#include "phy_txrx_pwr.h"
|
|
#include "phy_bb.h"
|
|
#include "iot_efuse.h"
|
|
|
|
#if (HPLC_RF_DEV_SUPPORT && (HW_PLATFORM != HW_PLATFORM_SIMU))
|
|
|
|
#include "rfplc_reg_base.h"
|
|
#include "wphy_reg.h"
|
|
#include "mac_sys_reg.h"
|
|
#include "wphy_reg.h"
|
|
#include "mac_rf_isr.h"
|
|
#include "mac_rf_common_hw.h"
|
|
#include "phy_rf_chn.h"
|
|
#include "rf_hw_tonemap.h"
|
|
#include "gpio_mtx.h"
|
|
|
|
static uint32_t phy_rf_wait_bbcpu_ready()
|
|
{
|
|
#define WAIT_READY_TIMEOUT 37500000 // 1.5S * 1000 * 25
|
|
uint32_t start_ntb, cur_ntb, time_span;
|
|
|
|
/* wait bbcpu ready */
|
|
start_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
|
|
do {
|
|
cur_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
|
|
time_span = cur_ntb - start_ntb;
|
|
} while (!mac_rf_get_bbcpu_sts() && time_span < WAIT_READY_TIMEOUT);
|
|
|
|
if (!mac_rf_get_bbcpu_sts()) {
|
|
iot_printf("bbcpu init fail!\n");
|
|
IOT_ASSERT(0);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void phy_rf_load_cal_cfg(void)
|
|
{
|
|
uint32_t ret;
|
|
uint8_t i;
|
|
uint8_t bw_sel_en;
|
|
uint16_t special_tx_lvdos = 300;
|
|
uint16_t special_tx_scale = 0x80;
|
|
uint16_t bw_sel;
|
|
iot_cal_data_rf_ver_phy_txiqm_t *cal_iqm;
|
|
iot_cal_data_rf_phy_txf_t *cal_txf;
|
|
uint8_t tx_i_mag, tx_q_mag, tx_i_phase, tx_q_phase;
|
|
int8_t tx_i_dc, tx_q_dc;
|
|
|
|
ret = iot_cal_data_get_rf_phy_txiqm_cali(&cal_iqm);
|
|
mac_rf_set_tx_special_ldovs(special_tx_lvdos);
|
|
mac_rf_set_tx_special_scale(special_tx_scale);
|
|
if (ret == ERR_OK) {
|
|
mac_rf_set_tx_dc_cali((uint8_t)cal_iqm->tx_i_dc,
|
|
(uint8_t)cal_iqm->tx_q_dc);
|
|
mac_rf_set_tx_iqm_cali(cal_iqm->tx_i_mag, cal_iqm->tx_q_mag);
|
|
mac_rf_set_tx_iqp_cali(cal_iqm->tx_i_phase, cal_iqm->tx_q_phase);
|
|
if (phy_rf_check_rf_version(cal_iqm->rf_ver)) {
|
|
mac_rf_set_rf_ver(cal_iqm->rf_ver);
|
|
}
|
|
iot_printf("%s ok, src:flash, tx_i_dc:%d, tx_q_dc:%d, tx_i_mag:%lu, "
|
|
"tx_q_mag:%lu, tx_i_phase:%lu, tx_q_phase: %lu, rf_ver:%d\n",
|
|
__FUNCTION__, cal_iqm->tx_i_dc, cal_iqm->tx_q_dc, cal_iqm->tx_i_mag,
|
|
cal_iqm->tx_q_mag, cal_iqm->tx_i_phase, cal_iqm->tx_q_phase,
|
|
cal_iqm->rf_ver);
|
|
goto next_1;
|
|
}
|
|
ret = iot_efuse_get_rf_tx_iqm_dc_calib_info(&tx_i_mag, &tx_q_mag,
|
|
&tx_i_phase, &tx_q_phase, &tx_i_dc, &tx_q_dc);
|
|
if (ret == ERR_OK) {
|
|
mac_rf_set_tx_dc_cali((uint8_t)tx_i_dc, (uint8_t)tx_q_dc);
|
|
mac_rf_set_tx_iqm_cali(tx_i_mag, tx_q_mag);
|
|
mac_rf_set_tx_iqp_cali(tx_i_phase, tx_q_phase);
|
|
iot_printf("%s ok src:efuse, tx_i_dc:%d, tx_q_dc:%d, tx_i_mag:%lu, "
|
|
"tx_q_mag:%lu, tx_i_phase:%lu, tx_q_phase: %lu, rf_ver:%d\n",
|
|
__FUNCTION__, tx_i_dc, tx_q_dc, tx_i_mag, tx_q_mag,
|
|
tx_i_phase, tx_q_phase, RF_VER_3);
|
|
} else {
|
|
mac_rf_set_tx_dc_cali(0, 0);
|
|
mac_rf_set_tx_iqm_cali(0, 0);
|
|
mac_rf_set_tx_iqp_cali(0, 0);
|
|
iot_printf("%s tx iqm fail...\n", __FUNCTION__);
|
|
}
|
|
next_1:
|
|
ret = iot_cal_data_get_rf_phy_txf_cali(&cal_txf);
|
|
if (ret == ERR_OK) {
|
|
for (i = RF_OPTION_1; i <= RF_OPTION_MAX; i++) {
|
|
if (cal_txf->valid_mask & (1 << (i - 1))) {
|
|
bw_sel_en = 1;
|
|
bw_sel = cal_txf->bw_sel_value[i - 1];
|
|
} else {
|
|
bw_sel_en = 0;
|
|
bw_sel = 0;
|
|
}
|
|
mac_rf_set_tx_filter_cali(i, bw_sel_en, bw_sel);
|
|
iot_printf("%s ok, option %lu, en %lu, bw_sel %lu\n",
|
|
__FUNCTION__, i, bw_sel_en, bw_sel);
|
|
}
|
|
} else {
|
|
mac_rf_set_tx_filter_cali(RF_OPTION_1, 0, 0);
|
|
mac_rf_set_tx_filter_cali(RF_OPTION_2, 0, 0);
|
|
mac_rf_set_tx_filter_cali(RF_OPTION_3, 0, 0);
|
|
iot_printf("%s tx txf fail...\n", __FUNCTION__);
|
|
}
|
|
|
|
/* set user type */
|
|
mac_rf_set_user_type(iot_oem_get_user_type());
|
|
/* apply oem ppm to rf */
|
|
mac_rf_set_wphy_ppm(-phy_get_cal_ppm_in_pib() << PLC_NTB_PPM_SHIFT);
|
|
if (iot_oem_get_module_type() != MODULE_TYPE_CCO) {
|
|
mac_rf_set_sta_sel(1);
|
|
}
|
|
/* TODO:
|
|
* load rx iqm calibration data from efuse */
|
|
}
|
|
|
|
/* indicate if the first init rf phy or not */
|
|
static uint8_t phy_rf_first_init = 1;
|
|
/* record phy rf start ntb */
|
|
static uint32_t phy_rf_start_ntb;
|
|
|
|
void phy_rf_wait_init()
|
|
{
|
|
#define SET_OPTION_TIMEOUT 25000000 // 1S * 1000 * 25
|
|
uint32_t cur_ntb, time_span;
|
|
/* wait set option complete */
|
|
do {
|
|
cur_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
|
|
time_span = cur_ntb - phy_rf_start_ntb;
|
|
} while (mac_rf_get_option_sts() && time_span < SET_OPTION_TIMEOUT);
|
|
|
|
if (mac_rf_get_option_sts()) {
|
|
iot_printf("%s, set option fail\n", __FUNCTION__);
|
|
}
|
|
}
|
|
|
|
void phy_rf_in_check(void)
|
|
{
|
|
uint32_t chip_id;
|
|
chip_id = iot_efuse_get_chip_id();
|
|
switch (chip_id) {
|
|
case CHIP_ID_HZ3201_RF_V1A:
|
|
case CHIP_ID_HZ3211_RF_V1A:
|
|
{
|
|
mac_rf_set_rf_in(1);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
mac_rf_set_rf_in(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void phy_rf_init(uint32_t proto, uint32_t option, uint32_t channel,
|
|
uint32_t sync_init, uint32_t auto_rxdc, uint32_t auto_txdc)
|
|
{
|
|
IOT_ASSERT(option < PHY_RF_OPTION_MAX && proto <= PLC_PROTO_TYPE_RAWDATA);
|
|
|
|
uint32_t cert_flag = 0, cert_mode = 0, flag16com = 0, rf_ver = 0;
|
|
uint32_t rx_cali_flag = 0;
|
|
uint8_t rx_dc_i = 0, rx_dc_q = 0, tx_dc_i, tx_dc_q;
|
|
int8_t tx_power = RF_TX_PWR_INVALID;
|
|
uint8_t rf_in = 0;
|
|
/* if not the first time to init rf phy */
|
|
if (!phy_rf_first_init) {
|
|
/* restore cert config */
|
|
cert_flag = mac_rf_get_cert_flag();
|
|
cert_mode = mac_rf_get_cert_mode();
|
|
flag16com = mac_rf_get_cert_16qam_flag();
|
|
rf_in = mac_rf_is_rf_in();
|
|
if (mac_rf_get_target_tx_power(&tx_power)) {
|
|
/* if not init tx power, set default power */
|
|
phy_rf_get_power(NULL, NULL, &tx_power, NULL);
|
|
}
|
|
rf_ver = mac_rf_get_rf_ver();
|
|
/* restore rx dc configration */
|
|
rx_cali_flag = mac_rf_get_rx_dc_loopback_clibr_flag();
|
|
mac_rf_get_auto_rxdc_iq_value(&rx_dc_i, &rx_dc_q);
|
|
mac_rf_get_tx_dc_cali(&tx_dc_i, &tx_dc_q);
|
|
}
|
|
|
|
/* ahb init and reset */
|
|
ahb_rfmac_disable();
|
|
ahb_rfmac_reg_disable();
|
|
ahb_rfmac_enable();
|
|
ahb_rfmac_reg_enable();
|
|
ahb_rfmac_reset();
|
|
ahb_rfmac_reg_reset();
|
|
|
|
ahb_rfplc_phy_disable();
|
|
ahb_rfplc_phy_reg_disable();
|
|
ahb_rfplc_ana_disable();
|
|
ahb_rfplc_phy_enable();
|
|
ahb_rfplc_phy_reg_enable();
|
|
ahb_rfplc_ana_enable();
|
|
ahb_rfplc_phy_reset();
|
|
ahb_rfplc_phy_reg_reset();
|
|
ahb_rfplc_ana_reset();
|
|
|
|
/* enable wmac */
|
|
mac_rf_use_wmac_enable(HPLC_RF_WMAC_ENABLE);
|
|
|
|
#if (IOT_DTEST_ONLY_SUPPORT != 1)
|
|
/* get rf spi */
|
|
uint8_t clk = iot_board_get_gpio(GPIO_SPI_RF_CLK);
|
|
uint8_t cs = iot_board_get_gpio(GPIO_SPI_RF_CS);
|
|
uint8_t miso = iot_board_get_gpio(GPIO_SPI_RF_MISO);
|
|
uint8_t mosi = iot_board_get_gpio(GPIO_SPI_RF_MOSI);
|
|
#else
|
|
/* rf mac dtest */
|
|
#if HW_PLATFORM == HW_PLATFORM_FPGA
|
|
uint8_t clk = 9;
|
|
uint8_t cs = 12;
|
|
uint8_t miso = 11;
|
|
uint8_t mosi = 10;
|
|
#else
|
|
uint8_t clk = 12;
|
|
uint8_t cs = 9;
|
|
uint8_t miso = 10;
|
|
uint8_t mosi = 11;
|
|
for (uint32_t wphy_gpio = 42; wphy_gpio < 60; wphy_gpio++) {
|
|
gpio_pin_select(wphy_gpio, 1);
|
|
}
|
|
#endif
|
|
#endif
|
|
/* init rf spi gpio */
|
|
mac_rf_set_spi_gpio(clk, cs, mosi, miso);
|
|
/* load rf calibration config */
|
|
phy_rf_load_cal_cfg();
|
|
|
|
if (!phy_rf_first_init) {
|
|
mac_rf_set_rf_ver(rf_ver);
|
|
mac_rf_set_rf_in(rf_in);
|
|
} else {
|
|
phy_rf_in_check();
|
|
}
|
|
/* config band select */
|
|
mac_rf_set_band_sel(phy_rf_get_band_sel());
|
|
|
|
/* bbcpu start */
|
|
extern int bb_cpu_start();
|
|
bb_cpu_start();
|
|
|
|
if (!phy_rf_wait_bbcpu_ready()) {
|
|
return;
|
|
}
|
|
|
|
if (HPLC_RF_SUPPORT_AUTO_CALIBR_TX_DC) {
|
|
if (!auto_txdc && !phy_rf_first_init) {
|
|
mac_rf_set_tx_dc_loopback_clibr_en(0);
|
|
mac_rf_set_tx_dc_cali(tx_dc_i, tx_dc_q);
|
|
} else if (auto_txdc) {
|
|
mac_rf_set_tx_dc_loopback_clibr_en(1);
|
|
}
|
|
}
|
|
|
|
/* recover record value */
|
|
if (phy_rf_first_init) {
|
|
/* is first time to init rf */
|
|
phy_rf_set_init_power();
|
|
phy_rf_first_init = 0;
|
|
} else {
|
|
/* recover cert config */
|
|
mac_rf_set_cert_flag(cert_flag);
|
|
mac_rf_set_cert_mode(cert_mode);
|
|
mac_rf_set_cert_16qam_flag(flag16com);
|
|
mac_rf_set_target_tx_power(tx_power);
|
|
}
|
|
|
|
/* auto clibration enable or not */
|
|
mac_rf_set_rx_dc_loopback_clibr_en(HPLC_RF_SUPPORT_AUTO_CALIBR_RX_DC);
|
|
if (rx_cali_flag) {
|
|
if (auto_rxdc) {
|
|
mac_rf_set_rx_dc_loopback_clibr_flag(0);
|
|
} else {
|
|
mac_rf_set_rx_dc_loopback_clibr_flag(1);
|
|
mac_rf_set_auto_rxdc_iq_value(rx_dc_i, rx_dc_q);
|
|
}
|
|
} else if (!auto_rxdc) {
|
|
mac_rf_set_rx_dc_loopback_clibr_en(0);
|
|
}
|
|
|
|
/* fl init */
|
|
phy_rf_fl_init(option);
|
|
/* first set channel */
|
|
IOT_ASSERT(channel < phy_rf_get_channel_id_max(option));
|
|
/* set proto */
|
|
mac_rf_set_proto(proto);
|
|
/* set channel */
|
|
mac_rf_set_tobe_channel_id(channel);
|
|
/* set option */
|
|
mac_rf_set_option(option);
|
|
mac_rf_set_sw_irq_to_bbcpu(RF_MAC_SW_ISR_BB_INIT);
|
|
|
|
phy_rf_start_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
|
|
|
|
if (sync_init) {
|
|
phy_rf_wait_init();
|
|
}
|
|
}
|
|
|
|
void phy_rf_deinit(void)
|
|
{
|
|
/* bbcpu stop */
|
|
extern int bb_cpu_stop();
|
|
bb_cpu_stop();
|
|
|
|
/* ahb init and reset */
|
|
ahb_rfmac_disable();
|
|
ahb_rfmac_reg_disable();
|
|
|
|
ahb_rfplc_phy_disable();
|
|
ahb_rfplc_phy_reg_disable();
|
|
ahb_rfplc_ana_disable();
|
|
}
|
|
|
|
uint8_t phy_rf_is_run(void)
|
|
{
|
|
extern uint8_t bb_cpu_is_run();
|
|
return bb_cpu_is_run();
|
|
}
|
|
|
|
void phy_rf_set_channel(uint8_t channel)
|
|
{
|
|
#define SET_CHANNEL_TIMEOUT 25000000 // 1S * 1000 * 25
|
|
uint32_t start_ntb, cur_ntb, time_span;
|
|
uint32_t option = mac_rf_get_option();
|
|
uint32_t channel_max = phy_rf_get_channel_id_max(option);
|
|
IOT_ASSERT(channel < channel_max);
|
|
|
|
mac_rf_set_tobe_channel_id(channel);
|
|
mac_rf_set_sw_irq_to_bbcpu(RF_MAC_SW_ISR_SET_CHANNEL);
|
|
|
|
/* wait set channel complete */
|
|
start_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
|
|
do {
|
|
cur_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
|
|
time_span = cur_ntb - start_ntb;
|
|
} while (mac_rf_get_channel_sts() && time_span < SET_CHANNEL_TIMEOUT);
|
|
|
|
if (mac_rf_get_channel_sts()) {
|
|
iot_printf("%s, set channel fail\n", __FUNCTION__);
|
|
}
|
|
}
|
|
|
|
void phy_rf_reset()
|
|
{
|
|
// TODO: SOC supply register to hard reset phy.
|
|
return;
|
|
}
|
|
|
|
void phy_rf_new_cfg_apply()
|
|
{
|
|
/* rf phy init, plc cpu and bbcpu async init, rf rxdc enable */
|
|
phy_rf_init(phy_proto_type_get(), mac_rf_get_option(),
|
|
mac_rf_get_tobe_set_channel_id(), 1, 0, 0);
|
|
|
|
/* rf isr init */
|
|
mac_rf_isr_init(mac_rf_get_dsr_callback());
|
|
/* init rf pdev */
|
|
extern uint32_t mac_rf_pdev_init(pdevid_t pdev_id);
|
|
mac_rf_pdev_init(RF_PDEV_ID);
|
|
/* start isr */
|
|
mac_rf_isr_start();
|
|
}
|
|
|
|
void phy_record_dbg_cnt()
|
|
{
|
|
/* recover dbg cnt */
|
|
mac_rf_record_dbg_cnt();
|
|
}
|
|
|
|
void phy_recover_dbg_cnt()
|
|
{
|
|
/* recover dbg cnt */
|
|
mac_rf_recover_dbg_cnt();
|
|
}
|
|
|
|
void phy_rf_set_ps_idle(uint32_t ps_on)
|
|
{
|
|
mac_rf_set_bb_ps_idle(ps_on);
|
|
mac_rf_set_sw_irq_to_bbcpu(RF_MAC_SW_ISR_SET_PS_IDLE);
|
|
}
|
|
|
|
void phy_rf_set_init_power()
|
|
{
|
|
uint32_t power = RF_TX_PWR_INVALID;
|
|
int8_t def_pwr, full_pwr;
|
|
phy_rf_get_power(NULL, NULL, &def_pwr, &full_pwr);
|
|
|
|
if (!phy_get_pwr_ctl_en()) {
|
|
/* LP */
|
|
power = def_pwr;
|
|
} else {
|
|
/* FULL POWER */
|
|
power = full_pwr;
|
|
}
|
|
|
|
mac_rf_set_target_tx_power(power);
|
|
}
|
|
|
|
#else /* (HPLC_RF_DEV_SUPPORT && (HW_PLATFORM != HW_PLATFORM_SIMU)) */
|
|
|
|
void phy_rf_wait_init()
|
|
{
|
|
}
|
|
|
|
void phy_rf_init(uint32_t proto, uint32_t option, uint32_t channel,
|
|
uint32_t sync_init, uint32_t auto_rxdc, uint32_t auto_txdc)
|
|
{
|
|
(void)proto;
|
|
(void)option;
|
|
(void)channel;
|
|
(void)sync_init;
|
|
(void)auto_rxdc;
|
|
(void)auto_txdc;
|
|
}
|
|
|
|
void phy_rf_deinit()
|
|
{
|
|
}
|
|
|
|
void phy_rf_set_channel(uint8_t channel)
|
|
{
|
|
(void)channel;
|
|
}
|
|
|
|
void phy_rf_reset()
|
|
{
|
|
}
|
|
|
|
void phy_rf_new_cfg_apply()
|
|
{
|
|
}
|
|
|
|
void phy_recover_dbg_cnt()
|
|
{
|
|
}
|
|
|
|
void phy_record_dbg_cnt()
|
|
{
|
|
}
|
|
|
|
void phy_rf_load_cal_cfg(void)
|
|
{
|
|
|
|
}
|
|
|
|
void phy_rf_set_ps_idle(uint32_t ps_on)
|
|
{
|
|
(void)ps_on;
|
|
}
|
|
|
|
void phy_rf_set_init_power()
|
|
{
|
|
}
|
|
|
|
void phy_rf_in_check(void)
|
|
{
|
|
|
|
}
|
|
|
|
#endif /* (HPLC_RF_DEV_SUPPORT && (HW_PLATFORM != HW_PLATFORM_SIMU)) */
|