Merge branch 'feature/support_to_query_phy_rf_used_time_v5.2' into 'release/v5.2'

feat(phy): support to query phy used time

See merge request espressif/esp-idf!35876
This commit is contained in:
Jiang Jiang Jian
2024-12-26 17:23:12 +08:00
4 changed files with 144 additions and 2 deletions

View File

@ -74,6 +74,12 @@ menu "PHY"
If enabled, when an error occurs while the PHY init data is updated,
the program will terminate and restart.
If not enabled, the PHY init data will not be updated when an error occurs.
config ESP_PHY_RECORD_USED_TIME
bool "Record PHY used time"
default n
help
Select to support record and query phy used time.
endif
config ESP_PHY_MAX_WIFI_TX_POWER

View File

@ -33,6 +33,7 @@ typedef enum {
PHY_MODEM_WIFI = 1, /*!< PHY modem WIFI */
PHY_MODEM_BT = 2, /*!< PHY modem BT */
PHY_MODEM_IEEE802154 = 4, /*!< PHY modem IEEE802154 */
PHY_MODEM_MAX, /*!< Don't use it. Used by ESP_PHY_MODEM_COUNT_MAX */
} esp_phy_modem_t;
/**
@ -281,6 +282,23 @@ void phy_init_param_set(uint8_t param);
*/
void phy_wifi_enable_set(uint8_t enable);
#if CONFIG_ESP_PHY_RECORD_USED_TIME
/**
* @brief Get phy used time from different modem
* @param used_time pointer of variable to get used time, in microseconds
* @param modem modem type
* @return ESP_ERR_INVALID_ARG on incorrect modem type.
*/
esp_err_t phy_query_used_time(uint64_t *used_time, esp_phy_modem_t modem);
/**
* @brief Clear phy used time for different modem
* @param modem modem type
* @return ESP_ERR_INVALID_ARG on incorrect modem type.
*/
esp_err_t phy_clear_used_time(esp_phy_modem_t modem);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -157,6 +157,60 @@ static phy_country_to_bin_type_t s_country_code_map_type_table[] = {
{"US", ESP_PHY_INIT_DATA_TYPE_FCC},
};
#endif
#if CONFIG_ESP_PHY_RECORD_USED_TIME
#define ESP_PHY_MODEM_COUNT_MAX (__builtin_ffs(PHY_MODEM_MAX - 1))
#define ESP_PHY_IS_VALID_MODEM(modem) (__builtin_popcount(modem) == 1 && __builtin_ctz(modem) < ESP_PHY_MODEM_COUNT_MAX)
static DRAM_ATTR struct {
uint64_t used_time;
uint64_t enabled_time;
uint64_t disabled_time;
} s_phy_rf_used_info[ESP_PHY_MODEM_COUNT_MAX];
static IRAM_ATTR void phy_record_time(bool enabled, esp_phy_modem_t modem) {
uint8_t index = __builtin_ctz(modem);
if (enabled) {
s_phy_rf_used_info[index].enabled_time = esp_timer_get_time();
} else {
s_phy_rf_used_info[index].disabled_time = esp_timer_get_time();
s_phy_rf_used_info[index].used_time += s_phy_rf_used_info[index].disabled_time - s_phy_rf_used_info[index].enabled_time;
}
}
esp_err_t phy_query_used_time(uint64_t *used_time, esp_phy_modem_t modem) {
if (!ESP_PHY_IS_VALID_MODEM(modem)) {
return ESP_ERR_INVALID_ARG;
}
uint8_t index = __builtin_ctz(modem);
_lock_acquire(&s_phy_access_lock);
*used_time = s_phy_rf_used_info[index].used_time;
if (s_phy_rf_used_info[index].disabled_time < s_phy_rf_used_info[index].enabled_time) {
// phy is being used
*used_time += esp_timer_get_time() - s_phy_rf_used_info[index].enabled_time;
}
_lock_release(&s_phy_access_lock);
return ESP_OK;
}
esp_err_t phy_clear_used_time(esp_phy_modem_t modem) {
if (!ESP_PHY_IS_VALID_MODEM(modem)) {
return ESP_ERR_INVALID_ARG;
}
uint8_t index = __builtin_ctz(modem);
_lock_acquire(&s_phy_access_lock);
if (s_phy_rf_used_info[index].enabled_time > s_phy_rf_used_info[index].disabled_time) {
// phy is being used
s_phy_rf_used_info[index].enabled_time = esp_timer_get_time();
} else {
s_phy_rf_used_info[index].enabled_time = s_phy_rf_used_info[index].disabled_time;
}
s_phy_rf_used_info[index].used_time = 0;
_lock_release(&s_phy_access_lock);
return ESP_OK;
}
#endif
uint32_t IRAM_ATTR phy_enter_critical(void)
{
if (xPortInIsrContext()) {
@ -284,13 +338,18 @@ void esp_phy_enable(esp_phy_modem_t modem)
phy_track_pll();
#endif
#if CONFIG_ESP_PHY_RECORD_USED_TIME
phy_record_time(true, modem);
#endif
_lock_release(&s_phy_access_lock);
}
void esp_phy_disable(esp_phy_modem_t modem)
{
_lock_acquire(&s_phy_access_lock);
#if CONFIG_ESP_PHY_RECORD_USED_TIME
phy_record_time(false, modem);
#endif
phy_clr_modem_flag(modem);
if (phy_get_modem_flag() == 0) {
// ESP32 will track pll in the wifi/BT modem interrupt handler.

View File

@ -8,6 +8,7 @@
#include "freertos/portmacro.h"
#include "esp_phy_init.h"
#include "esp_private/phy.h"
#include "esp_timer.h"
#if SOC_MODEM_CLOCK_IS_INDEPENDENT
#include "esp_private/esp_modem_clock.h"
@ -23,6 +24,59 @@ static _lock_t s_phy_access_lock;
/* Reference count of enabling PHY */
static bool s_phy_is_enabled = false;
#if CONFIG_ESP_PHY_RECORD_USED_TIME
#define ESP_PHY_MODEM_COUNT_MAX (__builtin_ffs(PHY_MODEM_MAX - 1))
#define ESP_PHY_IS_VALID_MODEM(modem) (__builtin_popcount(modem) == 1 && __builtin_ctz(modem) < ESP_PHY_MODEM_COUNT_MAX)
static DRAM_ATTR struct {
uint64_t used_time;
uint64_t enabled_time;
uint64_t disabled_time;
} s_phy_rf_used_info[ESP_PHY_MODEM_COUNT_MAX];
static IRAM_ATTR void phy_record_time(bool enabled, esp_phy_modem_t modem) {
uint8_t index = __builtin_ctz(modem);
if (enabled) {
s_phy_rf_used_info[index].enabled_time = esp_timer_get_time();
} else {
s_phy_rf_used_info[index].disabled_time = esp_timer_get_time();
s_phy_rf_used_info[index].used_time += s_phy_rf_used_info[index].disabled_time - s_phy_rf_used_info[index].enabled_time;
}
}
esp_err_t phy_query_used_time(uint64_t *used_time, esp_phy_modem_t modem) {
if (!ESP_PHY_IS_VALID_MODEM(modem)) {
return ESP_ERR_INVALID_ARG;
}
uint8_t index = __builtin_ctz(modem);
_lock_acquire(&s_phy_access_lock);
*used_time = s_phy_rf_used_info[index].used_time;
if (s_phy_rf_used_info[index].disabled_time < s_phy_rf_used_info[index].enabled_time) {
// phy is being used
*used_time += esp_timer_get_time() - s_phy_rf_used_info[index].enabled_time;
}
_lock_release(&s_phy_access_lock);
return ESP_OK;
}
esp_err_t phy_clear_used_time(esp_phy_modem_t modem) {
if (!ESP_PHY_IS_VALID_MODEM(modem)) {
return ESP_ERR_INVALID_ARG;
}
uint8_t index = __builtin_ctz(modem);
_lock_acquire(&s_phy_access_lock);
if (s_phy_rf_used_info[index].enabled_time > s_phy_rf_used_info[index].disabled_time) {
// phy is being used
s_phy_rf_used_info[index].enabled_time = esp_timer_get_time();
} else {
s_phy_rf_used_info[index].enabled_time = s_phy_rf_used_info[index].disabled_time;
}
s_phy_rf_used_info[index].used_time = 0;
_lock_release(&s_phy_access_lock);
return ESP_OK;
}
#endif
uint32_t IRAM_ATTR phy_enter_critical(void)
{
if (xPortInIsrContext()) {
@ -64,13 +118,18 @@ void esp_phy_enable(esp_phy_modem_t modem)
phy_set_modem_flag(modem);
// Immediately track pll when phy enabled.
phy_track_pll();
#if CONFIG_ESP_PHY_RECORD_USED_TIME
phy_record_time(true, modem);
#endif
_lock_release(&s_phy_access_lock);
}
void esp_phy_disable(esp_phy_modem_t modem)
{
_lock_acquire(&s_phy_access_lock);
#if CONFIG_ESP_PHY_RECORD_USED_TIME
phy_record_time(false, modem);
#endif
phy_clr_modem_flag(modem);
if (phy_get_modem_flag() == 0) {