213 lines
7.0 KiB
C
Executable File
213 lines
7.0 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 "mac_rf_tx_power.h"
|
|
#include "os_types.h"
|
|
#include "iot_io.h"
|
|
#include "iot_utils_api.h"
|
|
#include "phy_txrx_pwr.h"
|
|
#include "plc_const.h"
|
|
#include "mac_cfg.h"
|
|
#include "mac_pdev.h"
|
|
#include "mac_vdev.h"
|
|
#include "phy_temperature.h"
|
|
#include "phy_nf.h"
|
|
|
|
#if HPLC_RF_DEV_SUPPORT
|
|
|
|
#include "mac_rf_common_hw.h"
|
|
|
|
/* define the stability period of the temperature compensation check */
|
|
#define MAC_RF_TX_POWER_TEMP_COMPEN_STABLE_THR 10
|
|
|
|
/* define threshold exit hysteresis interval of the temperature compensation
|
|
* check, unit is 0.1 centigrade
|
|
*/
|
|
#define MAC_RF_TX_POWER_TEMP_COMPEN_THR_HYST 50
|
|
|
|
/* definition of temperature compensation region */
|
|
typedef struct {
|
|
/* start threshold for compensation region, unit is 0.1 centigrade */
|
|
int16_t start_thr;
|
|
/* end threshold for compensation region, unit is 0.1 centigrade */
|
|
int16_t end_thr;
|
|
/* max tx power for current compensation region, unit is 1dBm */
|
|
int8_t max_tx_power;
|
|
} rf_temp_compen_region_t;
|
|
|
|
/* temperature compensation region table */
|
|
static const rf_temp_compen_region_t rf_power_compen_tab[] = {
|
|
{-1000, -50, 10},
|
|
{ 600, 2000, 10},
|
|
};
|
|
|
|
void mac_rf_fix_power_apply()
|
|
{
|
|
int8_t tx_pwr_by_temp;
|
|
int8_t pwr = 0;
|
|
uint32_t ret;
|
|
mac_vdev_t *vdev = get_vdev_ptr(PLC_PDEV_ID, PLC_DEFAULT_VDEV);
|
|
mac_rf_vdev_t *rf_vdev = get_rf_vdev_ptr(PLC_PDEV_ID, RF_PDEV_ID,
|
|
PLC_DEFAULT_VDEV);
|
|
if (phy_get_pwr_ctl_en()) {
|
|
return;
|
|
}
|
|
if (rf_vdev->fixed_rf_power_flag) {
|
|
mac_rf_set_target_tx_power(rf_vdev->fixed_rf_power_cap);
|
|
} else {
|
|
if (vdev->high_power_req_ena == 0) {
|
|
mac_rf_set_target_tx_power(RF_TX_PWR_INVALID);
|
|
} else {
|
|
if (vdev->high_power_req_reason_bitmap != 0) {
|
|
mac_rf_set_target_tx_power(mac_cfg_get_rf_auto_high_power_dbm());
|
|
} else {
|
|
mac_rf_set_target_tx_power(RF_TX_PWR_INVALID);
|
|
}
|
|
}
|
|
}
|
|
if (rf_vdev->power_temp_compen_idx != -1) {
|
|
tx_pwr_by_temp =
|
|
rf_power_compen_tab[rf_vdev->power_temp_compen_idx].max_tx_power;
|
|
ret = mac_rf_get_target_tx_power(&pwr);
|
|
if (ret != ERR_OK) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (tx_pwr_by_temp < pwr) {
|
|
iot_printf("%s temperature compen apply, power:%d\n", __FUNCTION__,
|
|
tx_pwr_by_temp);
|
|
mac_rf_set_target_tx_power(tx_pwr_by_temp);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void mac_rf_tx_power_compen_check(void)
|
|
{
|
|
mac_rf_vdev_t *rf_vdev = get_rf_vdev_ptr(PLC_PDEV_ID, RF_PDEV_ID,
|
|
PLC_DEFAULT_VDEV);
|
|
const rf_temp_compen_region_t *tab = rf_power_compen_tab;
|
|
uint8_t i, change = 0;
|
|
int8_t chk_idx = -1;
|
|
int16_t cur_temp;
|
|
if (!rf_vdev->power_temp_compen_en) {
|
|
return;
|
|
}
|
|
cur_temp = (int16_t)(phy_temperature_val_get() * 10);
|
|
for (i = 0; i < IOT_ARRAY_CNT(rf_power_compen_tab); i++) {
|
|
if (cur_temp >= tab[i].start_thr &&
|
|
cur_temp <= tab[i].end_thr) {
|
|
chk_idx = i;
|
|
break;
|
|
}
|
|
}
|
|
if (rf_vdev->power_temp_compen_idx != -1
|
|
&& chk_idx == -1) {
|
|
i = rf_vdev->power_temp_compen_idx;
|
|
if (cur_temp > (tab[i].start_thr -
|
|
MAC_RF_TX_POWER_TEMP_COMPEN_THR_HYST)
|
|
&& cur_temp < (tab[i].end_thr +
|
|
MAC_RF_TX_POWER_TEMP_COMPEN_THR_HYST)) {
|
|
chk_idx = i;
|
|
}
|
|
}
|
|
if (rf_vdev->last_temp_compen_chk_idx != chk_idx) {
|
|
rf_vdev->stable_cnt = 0;
|
|
rf_vdev->last_temp_compen_chk_idx = chk_idx;
|
|
} else {
|
|
rf_vdev->stable_cnt++;
|
|
if (rf_vdev->stable_cnt == MAC_RF_TX_POWER_TEMP_COMPEN_STABLE_THR) {
|
|
if (rf_vdev->power_temp_compen_idx !=
|
|
rf_vdev->last_temp_compen_chk_idx) {
|
|
rf_vdev->power_temp_compen_idx =
|
|
rf_vdev->last_temp_compen_chk_idx;
|
|
change = 1;
|
|
}
|
|
}
|
|
}
|
|
iot_printf("%s temp:%d, chk_idx:%d, temp_compen_idx:%d, stable_cnt:%lu, "
|
|
"change:%lu\n", __FUNCTION__, cur_temp, chk_idx,
|
|
rf_vdev->power_temp_compen_idx, rf_vdev->stable_cnt, change);
|
|
if (change) {
|
|
mac_rf_fix_power_apply();
|
|
}
|
|
}
|
|
|
|
void mac_rf_set_tx_power_cap(mac_rf_vdev_t *rf_vdev, int8_t power,
|
|
uint8_t is_force)
|
|
{
|
|
IOT_ASSERT(rf_vdev);
|
|
mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
|
|
int8_t min_pwr, max_pwr;
|
|
|
|
if (phy_get_pwr_ctl_en()) {
|
|
return;
|
|
}
|
|
|
|
if (!is_force && pdev->mac_pm.mac_pm_flag) {
|
|
/* if power off happen, not care set power cap */
|
|
return;
|
|
}
|
|
phy_rf_get_power(&min_pwr, &max_pwr, NULL, NULL);
|
|
|
|
if (power == RF_TX_PWR_INVALID) {
|
|
/* clear power cap */
|
|
rf_vdev->fixed_rf_power_flag = 0;
|
|
} else if (power >= max_pwr) {
|
|
/* high power */
|
|
rf_vdev->fixed_rf_power_flag = 1;
|
|
rf_vdev->fixed_rf_power_cap = max_pwr;
|
|
} else {
|
|
/* low power */
|
|
rf_vdev->fixed_rf_power_flag = 1;
|
|
rf_vdev->fixed_rf_power_cap = (uint8_t)max(power, min_pwr);
|
|
}
|
|
mac_rf_fix_power_apply();
|
|
}
|
|
|
|
void mac_rf_fix_power_init()
|
|
{
|
|
mac_rf_vdev_t *rf_vdev = get_rf_vdev_ptr(PLC_PDEV_ID, RF_PDEV_ID,
|
|
PLC_DEFAULT_VDEV);
|
|
rf_vdev->fixed_rf_power_flag = 0;
|
|
rf_vdev->power_temp_compen_idx = -1;
|
|
rf_vdev->last_temp_compen_chk_idx = -1;
|
|
rf_vdev->stable_cnt = 0;
|
|
rf_vdev->fixed_rf_power_cap = 0;
|
|
rf_vdev->power_temp_compen_en = !!HPLC_RF_TX_POWER_TEMP_COMPEN_EN_DEFAULT;
|
|
|
|
#if HW_PLATFORM != HW_PLATFORM_SIMU
|
|
register_phy_rf_tx_power_comen_cb(mac_rf_tx_power_compen_check);
|
|
#endif
|
|
|
|
}
|
|
|
|
void mac_rf_tx_power_comen_en(uint8_t en)
|
|
{
|
|
mac_rf_vdev_t *rf_vdev = get_rf_vdev_ptr(PLC_PDEV_ID, RF_PDEV_ID,
|
|
PLC_DEFAULT_VDEV);
|
|
if (rf_vdev->power_temp_compen_en && !en) {
|
|
/* disable rf tx power temperature compensation function */
|
|
rf_vdev->power_temp_compen_en = 0;
|
|
rf_vdev->stable_cnt = 0;
|
|
rf_vdev->power_temp_compen_idx = -1;
|
|
rf_vdev->last_temp_compen_chk_idx = -1;
|
|
mac_rf_fix_power_apply();
|
|
} else if (!rf_vdev->power_temp_compen_en && en) {
|
|
/* enable rf tx power temperature compensation function */
|
|
rf_vdev->power_temp_compen_en = 1;
|
|
}
|
|
}
|
|
|
|
#endif /* HPLC_RF_DEV_SUPPORT */
|