mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
refactor(phy): refactor multiple antenna, support for WIFI/BT/BLE/15.4
This commit is contained in:
parent
f231b262b9
commit
92e76a3434
112
components/esp_phy/include/esp_phy.h
Normal file
112
components/esp_phy/include/esp_phy.h
Normal 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
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user