refactor(phy): refactor multiple antenna, support for WIFI/BT/BLE/15.4

This commit is contained in:
alanmaxwell 2023-10-10 16:57:00 +08:00
parent f231b262b9
commit 92e76a3434
4 changed files with 294 additions and 3 deletions

View File

@ -0,0 +1,112 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* PHY API
*/
/**
* @brief PHY antenna
*/
typedef enum {
ESP_PHY_ANT_ANT0, /*!< PHY antenna 0 */
ESP_PHY_ANT_ANT1, /*!< PHY antenna 1 */
ESP_PHY_ANT_MAX, /*!< Invalid PHY antenna */
} esp_phy_ant_t;
/**
* @brief PHY antenna mode
*/
typedef enum {
ESP_PHY_ANT_MODE_ANT0, /*!< Enable PHY antenna 0 only */
ESP_PHY_ANT_MODE_ANT1, /*!< Enable PHY antenna 1 only */
ESP_PHY_ANT_MODE_AUTO, /*!< Enable PHY antenna 0 and 1, automatically select an antenna, suggest not use this mode */
ESP_PHY_ANT_MODE_MAX, /*!< Invalid PHY enabled antenna */
} esp_phy_ant_mode_t;
/**
* @brief PHY GPIO configuration for antenna selection
*/
typedef struct {
uint8_t gpio_select: 1, /*!< Whether this GPIO is connected to external antenna switch */
gpio_num: 7; /*!< The GPIO number that connects to external antenna switch */
} esp_phy_ant_gpio_t;
/**
* @brief PHY GPIOs configuration for antenna selection
*/
typedef struct {
esp_phy_ant_gpio_t gpio_cfg[4]; /*!< The configurations of GPIOs that connect to external antenna switch */
} esp_phy_ant_gpio_config_t;
/**
* @brief PHY antenna configuration
*/
typedef struct {
esp_phy_ant_mode_t rx_ant_mode; /*!< PHY antenna mode for receiving */
esp_phy_ant_t rx_ant_default; /*!< Default antenna mode for receiving, it's ignored if rx_ant_mode is not ESP_PHY_ANT_MODE_AUTO */
esp_phy_ant_mode_t tx_ant_mode; /*!< PHY antenna mode for transmission, it can be set to ESP_PHY_ANT_MODE_ANT1 or ESP_PHY_ANT_MODE_ANT0 */
uint8_t enabled_ant0: 4, /*!< Index (in antenna GPIO configuration) of enabled ESP_PHY_ANT_MODE_ANT0 */
enabled_ant1: 4; /*!< Index (in antenna GPIO configuration) of enabled ESP_PHY_ANT_MODE_ANT1 */
} esp_phy_ant_config_t;
/**
* @brief Set antenna GPIO configuration
*
* @param config : Antenna GPIO configuration.
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_phy_set_ant_gpio(esp_phy_ant_gpio_config_t *config);
/**
* @brief Get current antenna GPIO configuration
*
* @param config : Antenna GPIO configuration.
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_phy_get_ant_gpio(esp_phy_ant_gpio_config_t *config);
/**
* @brief Set antenna configuration
*
* @param config : Antenna configuration.
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_phy_set_ant(esp_phy_ant_config_t *config);
/**
* @brief Get current antenna configuration
*
* @param config : Antenna configuration.
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_phy_get_ant(esp_phy_ant_config_t *config);
#ifdef __cplusplus
}
#endif

View File

@ -180,6 +180,25 @@ _lock_t phy_get_lock(void);
*
*/
void phy_track_pll(void);
/**
* @brief PHY antenna default configuration
*
*/
void ant_dft_cfg(bool default_ant);
/**
* @brief PHY tx antenna config
*
*/
void ant_tx_cfg(uint8_t ant0);
/**
* @brief PHY rx antenna config
*
*/
void ant_rx_cfg(bool auto_en, uint8_t ant0, uint8_t ant1);
#ifdef __cplusplus
}
#endif

@ -1 +1 @@
Subproject commit 603b69583635ffcedf2a5e1d0f70da77edf82d10
Subproject commit c9c0fb3556623ca6e7f0b23fe9a234a177e2bae9

View File

@ -4,11 +4,19 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_log.h"
#include <stdint.h>
#include <string.h>
#include "esp_timer.h"
#include "esp_log.h"
#include "esp_private/esp_gpio_reserve.h"
#include "soc/gpio_sig_map.h"
#include "driver/gpio.h"
#include "esp_rom_gpio.h"
#include "esp_phy_init.h"
#include "esp_private/phy.h"
#include <stdint.h>
#include "esp_phy.h"
static const char* TAG = "phy_comm";
static volatile uint16_t s_phy_modem_flag = 0;
@ -23,6 +31,9 @@ static volatile int64_t s_bt_154_prev_timestamp;
#define PHY_TRACK_PLL_PERIOD_IN_US 1000000
static void phy_track_pll_internal(void);
static esp_phy_ant_gpio_config_t s_phy_ant_gpio_config = { 0 };
static esp_phy_ant_config_t s_phy_ant_config = { 0 };
#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED || CONFIG_ESP_WIFI_ENABLED
bool phy_enabled_modem_contains(esp_phy_modem_t modem)
{
@ -119,3 +130,152 @@ esp_phy_modem_t phy_get_modem_flag(void)
{
return s_phy_modem_flag;
}
static void phy_ant_set_gpio_output(uint32_t io_num)
{
gpio_config_t io_conf = {};
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1ULL << io_num);
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
}
esp_err_t esp_phy_set_ant_gpio(esp_phy_ant_gpio_config_t *config)
{
if (config == NULL) {
ESP_LOGE(TAG, "Invalid configuration");
return ESP_ERR_INVALID_ARG;
}
for (int i = 0; i < 4; i++) {
if (config->gpio_cfg[i].gpio_select == 1) {
if(esp_gpio_is_reserved(config->gpio_cfg[i].gpio_num)) {
ESP_LOGE(TAG, "gpio[%d] number: %d is reserved\n", i, config->gpio_cfg[i].gpio_num);
return ESP_ERR_INVALID_ARG;
}
}
}
for (int i = 0; i < 4; i++) {
if (config->gpio_cfg[i].gpio_select == 1) {
phy_ant_set_gpio_output(config->gpio_cfg[i].gpio_num);
esp_rom_gpio_connect_out_signal(config->gpio_cfg[i].gpio_num, ANT_SEL0_IDX + i, 0, 0);
}
}
memcpy(&s_phy_ant_gpio_config, config, sizeof(esp_phy_ant_gpio_config_t));
return ESP_OK;
}
esp_err_t esp_phy_get_ant_gpio(esp_phy_ant_gpio_config_t *config)
{
if (config == NULL) {
ESP_LOGE(TAG, "Invalid configuration");
return ESP_ERR_INVALID_ARG;
}
memcpy(config, &s_phy_ant_gpio_config, sizeof(esp_phy_ant_gpio_config_t));
return ESP_OK;
}
static bool phy_ant_config_check(esp_phy_ant_config_t *config)
{
if ((config->rx_ant_mode >= ESP_PHY_ANT_MODE_MAX)
||(config->tx_ant_mode >= ESP_PHY_ANT_MODE_MAX)
||(config->rx_ant_default >= ESP_PHY_ANT_MAX)) {
ESP_LOGE(TAG, "Invalid antenna: rx=%d, tx=%d, default=%d",
config->rx_ant_mode, config->tx_ant_mode, config->rx_ant_default);
return ESP_ERR_INVALID_ARG;
}
if ((config->tx_ant_mode == ESP_PHY_ANT_MODE_AUTO) && (config->rx_ant_mode != ESP_PHY_ANT_MODE_AUTO)) {
ESP_LOGE(TAG, "If tx ant is AUTO, also need to set rx ant to AUTO");
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t esp_phy_set_ant(esp_phy_ant_config_t *config)
{
uint8_t ant0;
uint8_t ant1;
uint8_t rx_ant0;
uint8_t rx_ant1;
uint8_t def_ant;
uint8_t tx_ant0;
bool rx_auto;
if (!config || (phy_ant_config_check(config) != ESP_OK)) {
return ESP_ERR_INVALID_ARG;
}
if ( phy_get_modem_flag() == 0 ) {
ESP_LOGE(TAG, "PHY not enabled");
return ESP_ERR_INVALID_STATE;
}
ant0 = config->enabled_ant0;
ant1 = config->enabled_ant1;
rx_auto = false;
def_ant = 0;
switch (config->rx_ant_mode) {
case ESP_PHY_ANT_MODE_ANT0:
rx_ant0 = ant0;
rx_ant1 = ant0;
break;
case ESP_PHY_ANT_MODE_ANT1:
rx_ant0 = ant1;
rx_ant1 = ant1;
break;
case ESP_PHY_ANT_MODE_AUTO:
rx_ant0 = ant0;
rx_ant1 = ant1;
rx_auto = true;
break;
default:
return ESP_ERR_INVALID_ARG;
}
switch (config->tx_ant_mode) {
case ESP_PHY_ANT_MODE_ANT0:
tx_ant0 = ant0;
break;
case ESP_PHY_ANT_MODE_ANT1:
tx_ant0 = ant1;
break;
default:
return ESP_ERR_INVALID_ARG;
}
switch (config->rx_ant_default) {
case ESP_PHY_ANT_ANT0:
def_ant = 0;
break;
case ESP_PHY_ANT_ANT1:
def_ant = 1;
break;
default:
return ESP_ERR_INVALID_ARG;
}
memcpy(&s_phy_ant_config, config, sizeof(esp_phy_ant_config_t));
ant_dft_cfg(def_ant);
ant_tx_cfg(tx_ant0);
ant_rx_cfg(rx_auto, rx_ant0, rx_ant1);
return ESP_OK;
}
esp_err_t esp_phy_get_ant(esp_phy_ant_config_t *config)
{
if (config == NULL) {
ESP_LOGE(TAG, "Invalid args");
return ESP_ERR_INVALID_ARG;
}
memcpy(config, &s_phy_ant_config, sizeof(esp_phy_ant_config_t));
return ESP_OK;
}