838 lines
26 KiB
C
838 lines
26 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 "os_types.h"
|
|
#include "os_mem.h"
|
|
|
|
|
|
#include "iot_io_api.h"
|
|
#include "iot_gpio_api.h"
|
|
#include "iot_cli.h"
|
|
#include "iot_cal_data.h"
|
|
#include "cli_rf_ic_tool_def.h"
|
|
#include "cli_rf_ic_tool.h"
|
|
#include "cli_plc_ic_tool.h"
|
|
#include "iot_ftm_msg.h"
|
|
#include "iot_ftm_internal.h"
|
|
#include "iot_cli_msg_id_definition.h"
|
|
#include "iot_config.h"
|
|
|
|
#if IOT_CLI_IC_TOOL_EN
|
|
|
|
#include "rf_phy_tx.h"
|
|
#include "rf_phy_rx.h"
|
|
#include "phy_rf_chn.h"
|
|
#include "bb_rf_cfg.h"
|
|
#include "rf_spi_api.h"
|
|
#include "iot_version_api.h"
|
|
#include "phy_ada_dump.h"
|
|
#include "phy_data.h"
|
|
#include "phy_bb.h"
|
|
#include "mac_rf_common_hw.h"
|
|
#include "bb_init.h"
|
|
#include "os_utils.h"
|
|
#include "mp_mode.h"
|
|
|
|
void cli_rf_option_chn_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
uint32_t freq;
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
cli_rf_option_chn *option_chn = (cli_rf_option_chn *)iot_pkt_data(buffer);
|
|
|
|
/* phy tx common init interface */
|
|
rf_phy_tx_init(PHY_RF_BAND_NSG, option_chn->option);
|
|
freq = phy_rf_get_channel_freq_by_id(option_chn->option, option_chn->chn);
|
|
iot_printf("option:%d freq:%d\n", option_chn->option, freq);
|
|
|
|
/* phy rx common init interface */
|
|
rf_phy_rx_init();
|
|
|
|
/* phy channel freq setting */
|
|
bb_rf_set_fchz(freq);
|
|
ack.result = 0;
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_OPTION_FIX, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_tx_tone_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
cli_rf_tx_tone_t *tx_tone = (cli_rf_tx_tone_t *)iot_pkt_data(buffer);
|
|
switch (tx_tone->mode) {
|
|
case CLI_RF_TX_TONE_MODE_HW:
|
|
{
|
|
rf_phy_tx_tone_hw(tx_tone->option, tx_tone->fchz, tx_tone->on_off,
|
|
tx_tone->tone0_num, tx_tone->tone1_num, tx_tone->att0,
|
|
tx_tone->att1);
|
|
ack.result = ERR_OK;
|
|
break;
|
|
}
|
|
case CLI_RF_TX_TONE_MODE_SW:
|
|
{
|
|
if (tx_tone->on_off) {
|
|
rf_phy_tx_tone_raw_test(tx_tone->tone0_num, tx_tone->option,
|
|
tx_tone->fchz);
|
|
} else {
|
|
rf_phy_tx_tone_raw_test_stop();
|
|
}
|
|
break;
|
|
ack.result = ERR_OK;
|
|
}
|
|
default:
|
|
ack.result = ERR_FAIL;
|
|
break;
|
|
}
|
|
iot_printf("rf tx tone mode:%lu on_off:%d option:%d fchz:%d"
|
|
" tone0_num:%d tone1_num:%d att0:%d att1:%d\n", tx_tone->mode,
|
|
tx_tone->on_off, tx_tone->option, tx_tone->fchz, tx_tone->tone0_num,
|
|
tx_tone->tone1_num, tx_tone->att0, tx_tone->att1);
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_TX_TONE,
|
|
(uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_spi_write_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
|
|
cli_rf_spi_write *spi_write = (cli_rf_spi_write *)iot_pkt_data(buffer);
|
|
|
|
rf_spi_write(spi_write->addr, spi_write->value);
|
|
|
|
ack.result = 0;
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_SPI_WRITE, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_tx_cal_update_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
cli_rf_tx_cal_update_t *cli_cal =
|
|
(cli_rf_tx_cal_update_t *)iot_pkt_data(buffer);
|
|
if (cli_cal->tx_iq_mag_update) {
|
|
bb_rf_set_tx_iq_mag(cli_cal->tx_i_mag, cli_cal->tx_q_mag);
|
|
}
|
|
if (cli_cal->tx_iq_phase_update) {
|
|
bb_rf_set_tx_iq_phase(cli_cal->tx_i_phase, cli_cal->tx_q_phase);
|
|
}
|
|
if (cli_cal->tx_iq_dc_update) {
|
|
bb_rf_set_tx_dc(cli_cal->tx_i_dc, cli_cal->tx_q_dc);
|
|
}
|
|
iot_printf("%s update:[%lu, %lu, %lu], tx_i_mag:%lu, tx_q_mag:%lu,"
|
|
"tx_i_phase:%lu, tx_q_phase:%lu, tx_i_dc:%d, tx_q_dc:%d\n",
|
|
__FUNCTION__, cli_cal->tx_iq_mag_update, cli_cal->tx_iq_phase_update,
|
|
cli_cal->tx_iq_dc_update, cli_cal->tx_i_mag, cli_cal->tx_q_mag,
|
|
cli_cal->tx_i_phase, cli_cal->tx_q_phase,
|
|
cli_cal->tx_i_dc, cli_cal->tx_q_dc);
|
|
ack.result = 0;
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_TX_CAL_UPDATE, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_phy_rxiqm_cali(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
cli_rf_rxiqm_cal_rsp_t ack = { 0 };
|
|
cli_rf_rxiqm_cal_req_t *req =
|
|
(cli_rf_rxiqm_cal_req_t *)iot_pkt_data(buffer);
|
|
int16_t tone_idx;
|
|
uint8_t i_code, q_code;
|
|
uint32_t center_freq = 0;
|
|
if (len < sizeof(*req)) {
|
|
ack.result = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
tone_idx = (int16_t)iot_float_round_int32(
|
|
req->tone_freq * 1024.0 / 12500000);
|
|
/* step 1: calibration rx iq mag */
|
|
rf_phy_rx_iq_mag_cali(4096, tone_idx, &i_code, &q_code);
|
|
ack.i_mag = i_code;
|
|
ack.q_mag = q_code;
|
|
|
|
/* step 2: calibration rx iq phase */
|
|
center_freq = bb_rf_get_fchz();
|
|
bb_rf_set_fchz(center_freq + 2 * req->tone_freq);
|
|
rf_phy_rx_iq_phase_cali(4096, -tone_idx, &i_code, &q_code);
|
|
ack.i_phase = i_code;
|
|
ack.q_phase = q_code;
|
|
bb_rf_set_fchz(center_freq);
|
|
out:
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_CAL_RXIQM,
|
|
(uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_state_cfg_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
ack.result = ERR_OK;
|
|
cli_rf_state_cfg_t *rf_state =
|
|
(cli_rf_state_cfg_t *)iot_pkt_data(buffer);
|
|
switch (rf_state->type) {
|
|
case CLI_RF_STATE_CFG_POWER_DOWN:
|
|
{
|
|
bb_rf_reset();
|
|
mac_rf_disable_pa(1);
|
|
break;
|
|
}
|
|
case CLI_RF_STATE_CFG_POWER_UP:
|
|
{
|
|
mac_rf_disable_pa(0);
|
|
os_delay(10);
|
|
rf_phy_tx_init(PHY_RF_BAND_NSG, rf_state->option);
|
|
break;
|
|
}
|
|
case CLI_RF_STATE_CFG_PLL:
|
|
{
|
|
bb_rf_reset();
|
|
bb_rf_pll_cfg();
|
|
break;
|
|
}
|
|
case CLI_RF_STATE_CFG_STANDBY:
|
|
{
|
|
bb_rf_reset();
|
|
bb_rf_standby_cfg();
|
|
break;
|
|
}
|
|
case CLI_RF_STATE_CFG_RX:
|
|
{
|
|
bb_rf_reset();
|
|
bb_rf_rx_cfg(rf_state->option,
|
|
phy_rf_get_channel_freq_by_id(rf_state->option,
|
|
rf_state->ch_id));
|
|
break;
|
|
}
|
|
case CLI_RF_STATE_CFG_TX:
|
|
{
|
|
bb_rf_reset();
|
|
bb_rf_tx_cfg(rf_state->option,
|
|
phy_rf_get_channel_freq_by_id(rf_state->option,
|
|
rf_state->ch_id));
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
ack.result = ERR_NOSUPP;
|
|
break;
|
|
}
|
|
}
|
|
iot_printf("%s rf_state:%lu, result:%lu\n", __FUNCTION__,
|
|
rf_state->type, ack.result);
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_STATE_CFG, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_spi_read_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
uint16_t value;
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
|
|
cli_rf_spi_read *spi_read = (cli_rf_spi_read *)iot_pkt_data(buffer);
|
|
|
|
value = rf_spi_read(spi_read->addr);
|
|
|
|
ack.result = 0;
|
|
ack.reserved[0] = value & 0xff;
|
|
ack.reserved[1] = (value >> 8) & 0xff;
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_SPI_READ, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_ada_dump_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
uint32_t dump_addr;
|
|
uint32_t buf_len;
|
|
|
|
cli_rf_ada_dump *ada_dump = (cli_rf_ada_dump *)iot_pkt_data(buffer);
|
|
buf_len = phy_ada_dump_addr_get(&dump_addr);
|
|
IOT_ASSERT(ada_dump->dump_len <= buf_len);
|
|
os_mem_set((uint32_t *)dump_addr, 0, ada_dump->dump_len);
|
|
rf_phy_ada_dump_entry(dump_addr, ada_dump->dump_len);
|
|
iot_printf("rf dump end\n");
|
|
ack.result = 0;
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_ADA_DUMP, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_rx_tone_power_get_handler(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
cli_rf_rx_tone_power_info_t ack = { 0 };
|
|
cli_rf_rx_tone_power_query_t *req =
|
|
(cli_rf_rx_tone_power_query_t *)iot_pkt_data(buffer);
|
|
|
|
rf_phy_rx_tone_power_meas(16 * 1024, req->tone_idx, req->dc_idx,
|
|
req->img_idx, &ack.tone_pwr, &ack.dc_pwr, &ack.img_pwr);
|
|
ack.gain = bb_rf_get_cur_gain();
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_RX_TONE_POWER_GET,
|
|
(uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_phy_cal_rxiqm_data_r(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
(void)buffer;
|
|
(void)len;
|
|
iot_cal_data_cfg_t *calcfg;
|
|
uint32_t ret;
|
|
cli_rf_cal_rxiqm_t cal = { 0 };
|
|
ret = iot_cal_data_get_cfg(&calcfg);
|
|
if (ret != ERR_OK) {
|
|
goto out;
|
|
}
|
|
if (iot_cal_data_check_mask(calcfg,
|
|
IOT_PHY_CFG_MASK_CALI_RF_RXIQM) != 0) {
|
|
cal.rx_i_mag = calcfg->halphy_cfg.rf_rxiqm.rx_i_mag;
|
|
cal.rx_q_mag = calcfg->halphy_cfg.rf_rxiqm.rx_q_mag;
|
|
cal.rx_i_phase = calcfg->halphy_cfg.rf_rxiqm.rx_i_phase;
|
|
cal.rx_q_phase = calcfg->halphy_cfg.rf_rxiqm.rx_q_phase;
|
|
}
|
|
out:
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_CAL_RXIQM_DATA_R,
|
|
(uint8_t *)&cal, sizeof(cal));
|
|
}
|
|
|
|
void cli_rf_phy_cal_rxiqm_data_w(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
uint8_t result = ERR_OK;
|
|
iot_cal_data_cfg_t *calcfg;
|
|
uint32_t ret;
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
cli_rf_cal_rxiqm_t *cal;
|
|
uint8_t *data = iot_pkt_data(buffer);
|
|
|
|
if (len < sizeof(*cal)) {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
cal = (cli_rf_cal_rxiqm_t*)data;
|
|
ret = iot_cal_data_get_cfg(&calcfg);
|
|
if (ret) {
|
|
/* update magic */
|
|
if (calcfg->halphy_cfg.magic != IOT_OEM_PHY_MAGIC_NUM) {
|
|
/* initialize */
|
|
calcfg->halphy_cfg.magic = IOT_OEM_PHY_MAGIC_NUM;
|
|
/* update mask */
|
|
calcfg->halphy_cfg.mask = 0;
|
|
}
|
|
/* update pt fw ver */
|
|
calcfg->halphy_cfg.pt_fw_ver = iot_version_hex();
|
|
/* update mask */
|
|
iot_cal_data_set_mask(calcfg, IOT_PHY_CFG_MASK_PT_VER);
|
|
calcfg->halphy_cfg.hw_ver_major = 0;
|
|
calcfg->halphy_cfg.hw_ver_minor = 0;
|
|
}
|
|
calcfg->halphy_cfg.rf_rxiqm.rx_i_mag = cal->rx_i_mag;
|
|
calcfg->halphy_cfg.rf_rxiqm.rx_q_mag = cal->rx_q_mag;
|
|
calcfg->halphy_cfg.rf_rxiqm.rx_i_phase = cal->rx_i_phase;
|
|
calcfg->halphy_cfg.rf_rxiqm.rx_q_phase = cal->rx_q_phase;
|
|
iot_cal_data_set_mask(calcfg, IOT_PHY_CFG_MASK_CALI_RF_RXIQM);
|
|
iot_cal_data_set_cfg(calcfg);
|
|
iot_printf("%s: rx_i_mag:%lu, rx_q_mag:%lu, rx_i_phase:%d, rx_q_phase:%d\n",
|
|
__FUNCTION__, cal->rx_i_mag, cal->rx_q_mag, cal->rx_i_phase,
|
|
cal->rx_q_phase);
|
|
goto out;
|
|
|
|
error:
|
|
iot_printf("%s error, err_code %lu\n", __FUNCTION__, result);
|
|
out:
|
|
ack.result = result;
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_CAL_RXIQM_DATA_W,
|
|
(uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_phy_cal_txiqm_data_w(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
uint8_t result = ERR_OK;
|
|
iot_cal_data_cfg_t *calcfg;
|
|
uint32_t ret;
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
cli_rf_cal_txiqm_t *cal;
|
|
uint8_t *data = iot_pkt_data(buffer);
|
|
|
|
if (len < sizeof(*cal)) {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
cal = (cli_rf_cal_txiqm_t*)data;
|
|
if (!phy_rf_check_rf_version(cal->rf_ver)) {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
ret = iot_cal_data_get_cfg(&calcfg);
|
|
if (ret) {
|
|
/* update magic */
|
|
if (calcfg->halphy_cfg.magic != IOT_OEM_PHY_MAGIC_NUM) {
|
|
/* initialize */
|
|
calcfg->halphy_cfg.magic = IOT_OEM_PHY_MAGIC_NUM;
|
|
/* update mask */
|
|
calcfg->halphy_cfg.mask = 0;
|
|
}
|
|
/* update pt fw ver */
|
|
calcfg->halphy_cfg.pt_fw_ver = iot_version_hex();
|
|
/* update mask */
|
|
iot_cal_data_set_mask(calcfg, IOT_PHY_CFG_MASK_PT_VER);
|
|
calcfg->halphy_cfg.hw_ver_major = 0;
|
|
calcfg->halphy_cfg.hw_ver_minor = 0;
|
|
}
|
|
calcfg->halphy_cfg.rf_txiqm.tx_i_dc = cal->tx_i_dc;
|
|
calcfg->halphy_cfg.rf_txiqm.tx_q_dc = cal->tx_q_dc;
|
|
calcfg->halphy_cfg.rf_txiqm.tx_i_mag = cal->tx_i_mag;
|
|
calcfg->halphy_cfg.rf_txiqm.tx_q_mag = cal->tx_q_mag;
|
|
calcfg->halphy_cfg.rf_txiqm.tx_i_phase = cal->tx_i_phase;
|
|
calcfg->halphy_cfg.rf_txiqm.tx_q_phase = cal->tx_q_phase;
|
|
calcfg->halphy_cfg.rf_txiqm.rf_ver = cal->rf_ver;
|
|
iot_cal_data_set_mask(calcfg, IOT_PHY_CFG_MASK_CALI_RF_TXIQM);
|
|
iot_cal_data_set_cfg(calcfg);
|
|
iot_printf("%s: tx_i_dc:%lu, tx_q_dc:%lu, tx_i_mag:%lu, tx_q_mag:%lu, "
|
|
"tx_i_phase:%d, tx_q_phase:%d, rf_ver:%d\n", __FUNCTION__, cal->tx_i_dc,
|
|
cal->tx_q_dc, cal->tx_i_mag, cal->tx_q_mag, cal->tx_i_phase,
|
|
cal->tx_q_phase, cal->rf_ver);
|
|
goto out;
|
|
|
|
error:
|
|
iot_printf("%s error, err_code %lu\n", __FUNCTION__, result);
|
|
out:
|
|
ack.result = result;
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_CAL_TXIQM_DATA_W,
|
|
(uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_phy_cal_txiqm_data_r(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
(void)buffer;
|
|
(void)len;
|
|
iot_cal_data_cfg_t *calcfg;
|
|
uint32_t ret;
|
|
cli_rf_cal_txiqm_t cal = { 0 };
|
|
ret = iot_cal_data_get_cfg(&calcfg);
|
|
if (ret != ERR_OK) {
|
|
goto out;
|
|
}
|
|
if (iot_cal_data_check_mask(calcfg,
|
|
IOT_PHY_CFG_MASK_CALI_RF_TXIQM) != 0) {
|
|
cal.tx_i_dc = calcfg->halphy_cfg.rf_txiqm.tx_i_dc;
|
|
cal.tx_q_dc = calcfg->halphy_cfg.rf_txiqm.tx_q_dc;
|
|
cal.tx_i_mag = calcfg->halphy_cfg.rf_txiqm.tx_i_mag;
|
|
cal.tx_q_mag = calcfg->halphy_cfg.rf_txiqm.tx_q_mag;
|
|
cal.tx_i_phase = calcfg->halphy_cfg.rf_txiqm.tx_i_phase;
|
|
cal.tx_q_phase = calcfg->halphy_cfg.rf_txiqm.tx_q_phase;
|
|
cal.rf_ver = calcfg->halphy_cfg.rf_txiqm.rf_ver;
|
|
}
|
|
out:
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_CAL_TXIQM_DATA_R,
|
|
(uint8_t *)&cal, sizeof(cal));
|
|
}
|
|
|
|
void cli_rf_phy_cal_txf_data_w(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
uint8_t result = ERR_OK, i, mask;
|
|
iot_cal_data_cfg_t *calcfg;
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
uint32_t ret;
|
|
cli_rf_cal_txf_t *cal;
|
|
uint8_t *data = iot_pkt_data(buffer);
|
|
if (len < sizeof(*cal)) {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
ret = iot_cal_data_get_cfg(&calcfg);
|
|
if (ret) {
|
|
/* update magic */
|
|
if (calcfg->halphy_cfg.magic != IOT_OEM_PHY_MAGIC_NUM) {
|
|
/* initialize */
|
|
calcfg->halphy_cfg.magic = IOT_OEM_PHY_MAGIC_NUM;
|
|
/* update mask */
|
|
calcfg->halphy_cfg.mask = 0;
|
|
}
|
|
/* update pt fw ver */
|
|
calcfg->halphy_cfg.pt_fw_ver = iot_version_hex();
|
|
/* update mask */
|
|
iot_cal_data_set_mask(calcfg, IOT_PHY_CFG_MASK_PT_VER);
|
|
calcfg->halphy_cfg.hw_ver_major = 0;
|
|
calcfg->halphy_cfg.hw_ver_minor = 0;
|
|
}
|
|
cal = (cli_rf_cal_txf_t*)data;
|
|
for (i = RF_OPTION_1; i <= RF_OPTION_MAX; i++) {
|
|
mask = 1 << (i - 1);
|
|
if (cal->valid_mask & mask) {
|
|
calcfg->halphy_cfg.rf_txf.valid_mask |= mask;
|
|
calcfg->halphy_cfg.rf_txf.bw_sel_value[i - 1]
|
|
= cal->bw_sel_value[i - 1];
|
|
} else {
|
|
calcfg->halphy_cfg.rf_txf.valid_mask &=~ mask;
|
|
calcfg->halphy_cfg.rf_txf.bw_sel_value[i - 1] = 0;
|
|
}
|
|
iot_printf("%s: option:%lu, valid:%lu, bw_sel_value:%lu\n",
|
|
__FUNCTION__, i, !!(cal->valid_mask & mask),
|
|
calcfg->halphy_cfg.rf_txf.bw_sel_value[i - 1]);
|
|
}
|
|
iot_cal_data_set_mask(calcfg, IOT_PHY_CFG_MASK_CALI_RF_TXF);
|
|
ret = iot_cal_data_set_cfg(calcfg);
|
|
if (ret != ERR_OK) {
|
|
/* TODO: sync to RF phy */
|
|
result = ERR_FAIL;
|
|
goto error;
|
|
}
|
|
|
|
goto out;
|
|
|
|
error:
|
|
iot_printf("%s error, err_code %lu\n", __FUNCTION__, result);
|
|
out:
|
|
ack.result = result;
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_CAL_TXF_DATA_W,
|
|
(uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_phy_cal_txf_data_r(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
(void)buffer;
|
|
(void)len;
|
|
uint8_t i, mask;
|
|
iot_cal_data_cfg_t *calcfg;
|
|
cli_rf_cal_txf_t cal = { 0 };
|
|
uint32_t ret;
|
|
ret = iot_cal_data_get_cfg(&calcfg);
|
|
if (ret != ERR_OK) {
|
|
goto out;
|
|
}
|
|
if (iot_cal_data_check_mask(calcfg,
|
|
IOT_PHY_CFG_MASK_CALI_RF_TXF) == 0) {
|
|
goto out;
|
|
}
|
|
for (i = RF_OPTION_1; i <= RF_OPTION_MAX; i++) {
|
|
mask = 1 << (i - 1);
|
|
if (calcfg->halphy_cfg.rf_txf.valid_mask & mask) {
|
|
cal.valid_mask |= mask;
|
|
cal.bw_sel_value[i - 1] =
|
|
calcfg->halphy_cfg.rf_txf.bw_sel_value[i - 1];
|
|
} else {
|
|
cal.valid_mask &=~ mask;
|
|
cal.bw_sel_value[i - 1] = 0;
|
|
}
|
|
}
|
|
goto out;
|
|
|
|
out:
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_RF_CAL_TXF_DATA_R,
|
|
(uint8_t *)&cal, sizeof(cal));
|
|
}
|
|
|
|
|
|
static uint32_t fft_data_buf[TOTAL_TONE_MASK_NUM] = {0};
|
|
void phy_rx_dump_fft_data(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
uint32_t ret, data = 0;
|
|
cli_plc_fft_dump_req_t *para;
|
|
cli_plc_fft_dump_rsp_t result = {0};
|
|
int16_t i_value, q_value, i;
|
|
uint32_t energy = 0;
|
|
|
|
(void)len;
|
|
|
|
phy_reset(PHY_RST_REASON_WARM);
|
|
para = (cli_plc_fft_dump_req_t *)iot_pkt_data(buffer);
|
|
for (i = 0; i < para->avg_num; i++) {
|
|
ret = phy_rx_full_fft_dump(fft_data_buf);
|
|
if (ret != ERR_OK)
|
|
break;
|
|
|
|
data = fft_data_buf[para->tone_idx];
|
|
i_value = (int16_t)(data & 0xffff);
|
|
q_value = (int16_t)((data >> 16) & 0xffff);
|
|
/* it is best to directly return the energy value because the energy
|
|
* value is scalar. Do not directly return the average of i/q,
|
|
* as adding vectors will cancel out.
|
|
*/
|
|
energy += i_value * i_value + q_value * q_value;
|
|
}
|
|
if (i > 0) {
|
|
energy /= i;
|
|
}
|
|
|
|
result.err_no = ret;
|
|
if (ret == ERR_OK) {
|
|
result.len = TOTAL_TONE_MASK_NUM;
|
|
result.address = (uint32_t)fft_data_buf;
|
|
result.energy = energy;
|
|
}
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_PLC_FFT_DUMP, (uint8_t *)&result, sizeof(result));
|
|
}
|
|
|
|
void cli_cmmmon_gpio_set(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
cli_gpio_set_t *gpio_set = (cli_gpio_set_t *)iot_pkt_data(buffer);
|
|
cli_gpio_set_rsp_t result = { 0 };
|
|
|
|
iot_gpio_close(gpio_set->gpio);
|
|
result.result = iot_gpio_open_as_output(gpio_set->gpio);
|
|
if (result.result == ERR_OK) {
|
|
iot_gpio_value_set(gpio_set->gpio, gpio_set->val);
|
|
}
|
|
result.gpio_value = gpio_set->val;
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM, CLI_MSGID_FTM_COMMON_GPIO_SET,
|
|
(uint8_t *)&result, sizeof(result));
|
|
}
|
|
|
|
void cli_rf_power_spectrum_meas_handle(iot_pkt_t *buffer, uint32_t len)
|
|
{
|
|
uint8_t rsp[sizeof(power_spectrum_meas_result_t) + sizeof(tone_desc_t) *
|
|
RF_PHY_POWER_MEAS_MAX_TONE_CNT];
|
|
cli_rf_rx_cmd_t *cmd = (cli_rf_rx_cmd_t *)iot_pkt_data(buffer);
|
|
uint32_t freq_list[RF_PHY_POWER_MEAS_MAX_TONE_CNT];
|
|
|
|
os_mem_cpy((uint8_t *)freq_list, &cmd->freq, sizeof(freq_list));
|
|
rf_phy_power_spectrum_meas(cmd->f0 , cmd->gain, freq_list, cmd->num,
|
|
(power_spectrum_meas_result_t *)rsp);
|
|
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_POWER_SPECTRUM_MEAS, (uint8_t *)rsp, sizeof(rsp));
|
|
}
|
|
|
|
void cli_rf_phy_rx_gain_cali_w(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
uint8_t result = ERR_OK;
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
mp_rf_gu_cali_t *cal_data = NULL;
|
|
cli_rf_rx_gain_cali_info_t *cmd =
|
|
(cli_rf_rx_gain_cali_info_t *)iot_pkt_data(buffer);
|
|
|
|
if (len < sizeof(*cmd)) {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
mp_pt_rf_gu_cali_load(&cal_data);
|
|
if (cal_data == NULL) {
|
|
result = ERR_NOT_READY;
|
|
goto error;
|
|
}
|
|
|
|
if (cmd->gain < PHY_RF_GAIN_MIN || (cmd->gain - PHY_RF_GAIN_MIN) >=
|
|
sizeof(cal_data->rx_gain_cal)) {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
|
|
cmd->gain -= PHY_RF_GAIN_MIN;
|
|
if (cmd->gain <= cal_data->valid_rx_gain_item_cnt) {
|
|
cal_data->rx_gain_cal[cmd->gain] = cmd->cal_data;
|
|
} else {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
|
|
if (cmd->gain == cal_data->valid_rx_gain_item_cnt)
|
|
cal_data->valid_rx_gain_item_cnt++;
|
|
|
|
result = mp_pt_rf_gu_cali_commit();
|
|
if (result == ERR_OK) {
|
|
goto out;
|
|
}
|
|
|
|
error:
|
|
iot_printf("%s error, err_code %lu\n", __FUNCTION__, result);
|
|
out:
|
|
ack.result = result;
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_RX_GAIN_CALI_DATA_WRITE, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_phy_rx_gain_cali_r(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
cli_rf_rx_gain_cali_info_t cali_info = {0};
|
|
mp_rf_gu_cali_t *cali_data = NULL;
|
|
cli_rf_rx_gain_cali_read_t *cmd =
|
|
(cli_rf_rx_gain_cali_read_t*)iot_pkt_data(buffer);
|
|
|
|
if (len < sizeof(*cmd)) {
|
|
goto out;
|
|
}
|
|
|
|
mp_pt_rf_gu_cali_load(&cali_data);
|
|
if (cali_data == NULL) {
|
|
iot_printf("%s not ready\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
|
|
if (cmd->gain >= PHY_RF_GAIN_MIN && (cmd->gain - PHY_RF_GAIN_MIN) <
|
|
cali_data->valid_rx_gain_item_cnt) {
|
|
cali_info.gain = cmd->gain;
|
|
cmd->gain -= PHY_RF_GAIN_MIN;
|
|
cali_info.cal_data = cali_data->rx_gain_cal[cmd->gain];
|
|
}
|
|
|
|
out:
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_RX_GAIN_CALI_DATA_READ, (uint8_t *)&cali_info,
|
|
sizeof(cali_info));
|
|
}
|
|
|
|
void cli_rf_phy_tx_power_info_w(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
uint8_t result = ERR_OK, i = 0;
|
|
cli_kl_cmd_ack ack = { 0 };
|
|
mp_rf_gu_cali_t *cali_data = NULL;
|
|
cli_rf_tx_power_info *cmd =
|
|
(cli_rf_tx_power_info *)iot_pkt_data(buffer);
|
|
|
|
if (len < sizeof(*cmd) || cmd->idx > IOT_MP_RF_GU_TX_POWER_INFO_CNT) {
|
|
result = ERR_INVAL;
|
|
goto error;
|
|
}
|
|
mp_pt_rf_gu_cali_load(&cali_data);
|
|
if (cali_data == NULL) {
|
|
result = ERR_NOT_READY;
|
|
goto error;
|
|
}
|
|
|
|
for (i = 0; i < IOT_MP_RF_GU_TX_POWER_INFO_CNT; i++) {
|
|
if (cali_data->power_info[i].power == cmd->power) {
|
|
cali_data->power_info[i].power = -128;
|
|
}
|
|
}
|
|
cali_data->power_info[cmd->idx].power = cmd->power;
|
|
cali_data->power_info[cmd->idx].rf_att = cmd->rf_att;
|
|
cali_data->power_info[cmd->idx].if_gain = cmd->if_gain;
|
|
cali_data->power_info[cmd->idx].ldovs = cmd->ldovs;
|
|
|
|
result = mp_pt_rf_gu_cali_commit();
|
|
if (result == ERR_OK) {
|
|
goto out;
|
|
}
|
|
|
|
error:
|
|
iot_printf("%s error, err_code %lu\n", __FUNCTION__, result);
|
|
out:
|
|
ack.result = result;
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_TX_POWER_INFO_WRITE, (uint8_t *)&ack, sizeof(ack));
|
|
}
|
|
|
|
void cli_rf_phy_tx_power_info_r(iot_pkt_t *buffer, uint16_t len)
|
|
{
|
|
mp_rf_gu_cali_t *cali_data = NULL;
|
|
cli_rf_tx_power_info info = { 0 };
|
|
uint8_t size = sizeof(info);
|
|
cli_rf_tx_power_read_t *cmd =
|
|
(cli_rf_tx_power_read_t *)iot_pkt_data(buffer);
|
|
|
|
if (len < sizeof(*cmd)) {
|
|
goto out;
|
|
}
|
|
|
|
mp_pt_rf_gu_cali_load(&cali_data);
|
|
if (cali_data == NULL) {
|
|
iot_printf("%s not ready\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
|
|
if (cmd->idx < IOT_MP_RF_GU_TX_POWER_INFO_CNT) {
|
|
info.power = cali_data->power_info[cmd->idx].power;
|
|
info.rf_att = cali_data->power_info[cmd->idx].rf_att;
|
|
info.if_gain = cali_data->power_info[cmd->idx].if_gain;
|
|
info.ldovs = cali_data->power_info[cmd->idx].ldovs;
|
|
}
|
|
|
|
out:
|
|
cli_send_module_msg(CLI_MODULEID_FTM,
|
|
CLI_MSGID_FTM_RF_TX_POWER_INFO_READ, (uint8_t *)&info, size);
|
|
}
|
|
|
|
void iot_ic_rf_tool_op(int msgid, iot_pkt_t* buffer, uint32_t len)
|
|
{
|
|
iot_printf("rf msgid:%d len:%d\n", msgid, len);
|
|
|
|
switch (msgid)
|
|
{
|
|
case CLI_MSGID_FTM_RF_OPTION_FIX:
|
|
cli_rf_option_chn_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_TX_TONE:
|
|
cli_rf_tx_tone_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_SPI_READ:
|
|
cli_rf_spi_read_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_SPI_WRITE:
|
|
cli_rf_spi_write_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_ADA_DUMP:
|
|
cli_rf_ada_dump_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_CAL_TXIQM_DATA_W:
|
|
cli_rf_phy_cal_txiqm_data_w(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_CAL_TXIQM_DATA_R:
|
|
cli_rf_phy_cal_txiqm_data_r(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_CAL_TXF_DATA_W:
|
|
cli_rf_phy_cal_txf_data_w(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_CAL_TXF_DATA_R:
|
|
cli_rf_phy_cal_txf_data_r(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_RX_TONE_POWER_GET:
|
|
cli_rf_rx_tone_power_get_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_POWER_SPECTRUM_MEAS:
|
|
cli_rf_power_spectrum_meas_handle(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_PLC_ADA_DUMP:
|
|
cli_plc_ada_dump_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_PLC_FFT_DUMP:
|
|
phy_rx_dump_fft_data(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_TX_CAL_UPDATE:
|
|
cli_rf_tx_cal_update_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_STATE_CFG:
|
|
cli_rf_state_cfg_handler(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_COMMON_GPIO_SET:
|
|
cli_cmmmon_gpio_set(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_CAL_RXIQM_DATA_W:
|
|
cli_rf_phy_cal_rxiqm_data_w(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_CAL_RXIQM_DATA_R:
|
|
cli_rf_phy_cal_rxiqm_data_r(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_CAL_RXIQM:
|
|
cli_rf_phy_rxiqm_cali(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_RX_GAIN_CALI_DATA_WRITE:
|
|
cli_rf_phy_rx_gain_cali_w(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_RX_GAIN_CALI_DATA_READ:
|
|
cli_rf_phy_rx_gain_cali_r(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_TX_POWER_INFO_WRITE:
|
|
cli_rf_phy_tx_power_info_w(buffer, len);
|
|
break;
|
|
case CLI_MSGID_FTM_RF_TX_POWER_INFO_READ:
|
|
cli_rf_phy_tx_power_info_r(buffer, len);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endif /* IOT_CLI_IC_TOOL_EN */
|