mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Compare commits
49 Commits
cc7385ee8d
...
c086b2c76c
Author | SHA1 | Date | |
---|---|---|---|
|
c086b2c76c | ||
|
5ca9f2a49a | ||
|
ae8d309f28 | ||
|
f978dd0af9 | ||
|
fabf68803d | ||
|
44f29155c2 | ||
|
d5a1e226d2 | ||
|
2d80380413 | ||
|
609b44dc5d | ||
|
11e780ca20 | ||
|
759a847ba8 | ||
|
3ed188478b | ||
|
ca03a64ed3 | ||
|
9de3e737cf | ||
|
4125c56007 | ||
|
bafb4d323e | ||
|
747d338cfe | ||
|
114dc82ad2 | ||
|
7ccddb8cc2 | ||
|
41d39a419f | ||
|
f889ba1b2f | ||
|
ce4313a569 | ||
|
7696f0f9b2 | ||
|
c59403147c | ||
|
ad70d000b0 | ||
|
bb39360a6d | ||
|
24ea779fda | ||
|
406f341eb1 | ||
|
eceb27a835 | ||
|
1526b80e08 | ||
|
257926cae9 | ||
|
b96e9cd5b5 | ||
|
85e172f0b9 | ||
|
f33de4dece | ||
|
181d1de219 | ||
|
78b59e6b6b | ||
|
01c45476fb | ||
|
d8428420cf | ||
|
4706c474dc | ||
|
b305571a12 | ||
|
371f080046 | ||
|
f9b1789ae8 | ||
|
2e814bdd2b | ||
|
8b2350ce1c | ||
|
469942225b | ||
|
bdfdca24f3 | ||
|
f50b0b76dc | ||
|
fded5b0ce3 | ||
|
3a63cb80bb |
@ -28,6 +28,7 @@
|
||||
#include "hal/mmu_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "hal/mspi_timing_tuning_ll.h"
|
||||
|
||||
void bootloader_flash_update_id()
|
||||
{
|
||||
@ -203,6 +204,12 @@ static void bootloader_spi_flash_resume(void)
|
||||
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
// Set source mspi pll clock as 80M in bootloader stage.
|
||||
// SPLL clock on C5 is 480MHz , and mspi_pll needs 80MHz
|
||||
// in this stage, set divider as 6
|
||||
mspi_ll_clock_src_sel(MSPI_CLK_SRC_SPLL);
|
||||
mspi_ll_fast_set_hs_divider(6);
|
||||
|
||||
bootloader_init_flash_configure();
|
||||
bootloader_spi_flash_resume();
|
||||
bootloader_flash_unlock();
|
||||
|
@ -53,7 +53,7 @@ void bootloader_random_enable(void)
|
||||
|
||||
// create patterns and set them in pattern table
|
||||
uint32_t pattern_one = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation
|
||||
uint32_t pattern_two = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here
|
||||
uint32_t pattern_two = (SAR2_CHANNEL << 2) | SAR1_ATTEN; // we want channel 9 with max attenuation
|
||||
uint32_t pattern_table = 0 | (pattern_two << 3 * PATTERN_BIT_WIDTH) | pattern_one << 2 * PATTERN_BIT_WIDTH;
|
||||
REG_WRITE(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table);
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 8ddd8acac498fcbb76b5a39c5c7d4025238298ab
|
||||
Subproject commit e597ae529761d270f10d0616c375faa0e4b7ca13
|
@ -1 +1 @@
|
||||
Subproject commit 5f428f914114c88470bf0a785f08840c2b35abca
|
||||
Subproject commit 2e05c001042650bca426b672febd23c9ff45754e
|
@ -1 +1 @@
|
||||
Subproject commit ed6c0b4e0ab3b8ddce5d8bc65e417b1adcbca5b4
|
||||
Subproject commit 4a63b2963a8a75958db680df4ace64bbd3d6c618
|
@ -1 +1 @@
|
||||
Subproject commit 2d69367e13a928afb73d1a8c579c0dad98eb9393
|
||||
Subproject commit 96b48749e249d0752f196007b008212cb8b28e07
|
@ -50,38 +50,44 @@ extern "C" {
|
||||
|
||||
#endif //CONFIG_BT_ENABLED
|
||||
|
||||
/**
|
||||
* @brief Internal use only
|
||||
*
|
||||
* @note Please do not modify this value.
|
||||
*/
|
||||
#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20240315
|
||||
|
||||
/**
|
||||
* @brief Bluetooth mode for controller enable/disable
|
||||
* @brief Bluetooth Controller mode
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */
|
||||
ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */
|
||||
ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */
|
||||
ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */
|
||||
ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not operating. */
|
||||
ESP_BT_MODE_BLE = 0x01, /*!< Bluetooth is operating in BLE mode. */
|
||||
ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Bluetooth is operating in Classic Bluetooth mode. */
|
||||
ESP_BT_MODE_BTDM = 0x03, /*!< Bluetooth is operating in Dual mode. */
|
||||
} esp_bt_mode_t;
|
||||
|
||||
/**
|
||||
* @brief BLE sleep clock accuracy(SCA), values for ble_sca field in esp_bt_controller_config_t,
|
||||
* currently only ESP_BLE_SCA_500PPM and ESP_BLE_SCA_250PPM are supported
|
||||
* @brief BLE sleep clock accuracy (SCA)
|
||||
*
|
||||
* @note Currently only ESP_BLE_SCA_500PPM and ESP_BLE_SCA_250PPM are supported.
|
||||
*/
|
||||
enum {
|
||||
ESP_BLE_SCA_500PPM = 0, /*!< BLE SCA at 500ppm */
|
||||
ESP_BLE_SCA_250PPM, /*!< BLE SCA at 250ppm */
|
||||
ESP_BLE_SCA_150PPM, /*!< BLE SCA at 150ppm */
|
||||
ESP_BLE_SCA_100PPM, /*!< BLE SCA at 100ppm */
|
||||
ESP_BLE_SCA_75PPM, /*!< BLE SCA at 75ppm */
|
||||
ESP_BLE_SCA_50PPM, /*!< BLE SCA at 50ppm */
|
||||
ESP_BLE_SCA_30PPM, /*!< BLE SCA at 30ppm */
|
||||
ESP_BLE_SCA_20PPM, /*!< BLE SCA at 20ppm */
|
||||
};
|
||||
typedef enum {
|
||||
ESP_BLE_SCA_500PPM = 0, /*!< BLE SCA at 500 ppm */
|
||||
ESP_BLE_SCA_250PPM, /*!< BLE SCA at 250 ppm */
|
||||
ESP_BLE_SCA_150PPM, /*!< BLE SCA at 150 ppm */
|
||||
ESP_BLE_SCA_100PPM, /*!< BLE SCA at 100 ppm */
|
||||
ESP_BLE_SCA_75PPM, /*!< BLE SCA at 75 ppm */
|
||||
ESP_BLE_SCA_50PPM, /*!< BLE SCA at 50 ppm */
|
||||
ESP_BLE_SCA_30PPM, /*!< BLE SCA at 30 ppm */
|
||||
ESP_BLE_SCA_20PPM, /*!< BLE SCA at 20 ppm */
|
||||
} esp_ble_sca_t;
|
||||
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
|
||||
the adv packet will be discarded until the memory is restored. */
|
||||
the advertising packet will be discarded until the memory is restored. */
|
||||
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
|
||||
/* enable controller log debug when adv lost */
|
||||
/* enable controller log debug when the advertising packet gets lost */
|
||||
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
|
||||
|
||||
#ifdef CONFIG_BTDM_CTRL_HCI_UART_NO
|
||||
@ -102,7 +108,7 @@ the adv packet will be discarded until the memory is restored. */
|
||||
#define SCAN_DUPLICATE_TYPE_VALUE 0
|
||||
#endif
|
||||
|
||||
/* normal adv cache size */
|
||||
/* normal advertising cache size */
|
||||
#ifdef CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE
|
||||
#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE
|
||||
#else
|
||||
@ -172,7 +178,9 @@ the adv packet will be discarded until the memory is restored. */
|
||||
#else
|
||||
#define BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default Bluetooth Controller configuration
|
||||
*/
|
||||
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
|
||||
.controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
|
||||
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
|
||||
@ -201,105 +209,111 @@ the adv packet will be discarded until the memory is restored. */
|
||||
}
|
||||
|
||||
#else
|
||||
/**
|
||||
* @brief Default Bluetooth Controller configuration
|
||||
*/
|
||||
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; ESP_STATIC_ASSERT(0, "please enable bluetooth in menuconfig to use esp_bt.h");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Controller config options, depend on config mask.
|
||||
* Config mask indicate which functions enabled, this means
|
||||
* some options or parameters of some functions enabled by config mask.
|
||||
* @brief Bluetooth Controller config options
|
||||
* @note
|
||||
* 1. For parameters configurable in menuconfig, please refer to menuconfig for details on range and default values.
|
||||
* 2. It is not recommended to modify the default values of `controller_task_stack_size` and `controller_task_prio`.
|
||||
*/
|
||||
typedef struct {
|
||||
/*
|
||||
* Following parameters can be configured runtime, when call esp_bt_controller_init()
|
||||
*/
|
||||
uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */
|
||||
uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
|
||||
uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
|
||||
uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
|
||||
uint8_t scan_duplicate_mode; /*!< scan duplicate mode */
|
||||
uint8_t scan_duplicate_type; /*!< scan duplicate type */
|
||||
uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
|
||||
uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
|
||||
uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
|
||||
uint32_t controller_debug_flag; /*!< Controller debug log flag */
|
||||
uint8_t mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */
|
||||
uint8_t ble_max_conn; /*!< BLE maximum connection numbers */
|
||||
uint8_t bt_max_acl_conn; /*!< BR/EDR maximum ACL connection numbers */
|
||||
uint8_t bt_sco_datapath; /*!< SCO data path, i.e. HCI or PCM module */
|
||||
bool auto_latency; /*!< BLE auto latency, used to enhance classic BT performance */
|
||||
bool bt_legacy_auth_vs_evt; /*!< BR/EDR Legacy auth complete event required to protect from BIAS attack */
|
||||
/*
|
||||
* Following parameters can not be configured runtime when call esp_bt_controller_init()
|
||||
* It will be overwrite with a constant value which in menuconfig or from a macro.
|
||||
* So, do not modify the value when esp_bt_controller_init()
|
||||
*/
|
||||
uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */
|
||||
uint8_t ble_sca; /*!< BLE low power crystal accuracy index */
|
||||
uint8_t pcm_role; /*!< PCM role (master & slave)*/
|
||||
uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge) */
|
||||
bool hli; /*!< Using high level interrupt or not */
|
||||
uint16_t dup_list_refresh_period; /*!< Duplicate scan list refresh period */
|
||||
bool ble_scan_backoff; /*!< BLE scan backoff */
|
||||
uint16_t controller_task_stack_size; /*!< Bluetooth Controller task stack size in bytes */
|
||||
uint8_t controller_task_prio; /*!< Bluetooth Controller task priority */
|
||||
uint8_t hci_uart_no; /*!< Indicates UART number if using UART1/2 as HCI I/O interface. Configurable in menuconfig */
|
||||
uint32_t hci_uart_baudrate; /*!< Indicates UART baudrate if using UART1/2 as HCI I/O interface. Configurable in menuconfig */
|
||||
uint8_t scan_duplicate_mode; /*!< Scan duplicate filtering mode. Configurable in menuconfig */
|
||||
uint8_t scan_duplicate_type; /*!< Scan duplicate filtering type. Configurable in menuconfig */
|
||||
uint16_t normal_adv_size; /*!< Maximum number of devices in scan duplicate filtering list. Configurable in menuconfig */
|
||||
uint16_t mesh_adv_size; /*!< Maximum number of Mesh advertising packets in scan duplicate filtering list. Configurable in menuconfig */
|
||||
uint16_t send_adv_reserved_size; /*!< Controller minimum memory value in bytes. Internal use only */
|
||||
uint32_t controller_debug_flag; /*!< Controller debug log flag. Internal use only */
|
||||
uint8_t mode; /*!< Controller mode:
|
||||
|
||||
1: BLE mode
|
||||
|
||||
2: Classic Bluetooth mode
|
||||
|
||||
3: Dual mode
|
||||
|
||||
Others: Invalid
|
||||
|
||||
Configurable in menuconfig
|
||||
*/
|
||||
uint8_t ble_max_conn; /*!< Maximum number of BLE connections. Configurable in menuconfig */
|
||||
uint8_t bt_max_acl_conn; /*!< Maximum number of BR/EDR ACL connections. Configurable in menuconfig */
|
||||
uint8_t bt_sco_datapath; /*!< SCO data path, i.e. HCI or PCM module. Configurable in menuconfig */
|
||||
bool auto_latency; /*!< True if BLE auto latency is enabled, used to enhance Classic Bluetooth performance; false otherwise. Configurable in menuconfig */
|
||||
bool bt_legacy_auth_vs_evt; /*!< True if BR/EDR Legacy Authentication Vendor Specific Event is enabled, which is required to protect from BIAS attack; false otherwise. Configurable in menuconfig */
|
||||
uint8_t bt_max_sync_conn; /*!< Maximum number of BR/EDR synchronous connections. Configurable in menuconfig */
|
||||
uint8_t ble_sca; /*!< BLE low power crystal accuracy index. Configurable in menuconfig */
|
||||
uint8_t pcm_role; /*!< PCM role (master & slave). Configurable in menuconfig */
|
||||
uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge). Configurable in menuconfig */
|
||||
bool hli; /*!< True if using high level interrupt; false otherwise. Configurable in menuconfig */
|
||||
uint16_t dup_list_refresh_period; /*!< Scan duplicate filtering list refresh period in seconds. Configurable in menuconfig */
|
||||
bool ble_scan_backoff; /*!< True if BLE scan backoff is enabled; false otherwise. Configurable in menuconfig */
|
||||
uint32_t magic; /*!< Magic number */
|
||||
} esp_bt_controller_config_t;
|
||||
|
||||
/**
|
||||
* @brief Bluetooth controller enable/disable/initialised/de-initialised status
|
||||
* @brief Bluetooth Controller status
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BT_CONTROLLER_STATUS_IDLE = 0,
|
||||
ESP_BT_CONTROLLER_STATUS_INITED,
|
||||
ESP_BT_CONTROLLER_STATUS_ENABLED,
|
||||
ESP_BT_CONTROLLER_STATUS_NUM,
|
||||
ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< The Controller is not initialized or has been de-initialized. */
|
||||
ESP_BT_CONTROLLER_STATUS_INITED, /*!< The Controller has been initialized, but not enabled or has been disabled. */
|
||||
ESP_BT_CONTROLLER_STATUS_ENABLED, /*!< The Controller has been initialized and enabled. */
|
||||
ESP_BT_CONTROLLER_STATUS_NUM, /*!< Number of Controller statuses */
|
||||
} esp_bt_controller_status_t;
|
||||
|
||||
/**
|
||||
* @brief BLE tx power type
|
||||
* ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed.
|
||||
* when disconnect, the correspond TX power is not effected.
|
||||
* ESP_BLE_PWR_TYPE_ADV : for advertising/scan response.
|
||||
* ESP_BLE_PWR_TYPE_SCAN : for scan.
|
||||
* ESP_BLE_PWR_TYPE_DEFAULT : if each connection's TX power is not set, it will use this default value.
|
||||
* if neither in scan mode nor in adv mode, it will use this default value.
|
||||
* If none of power type is set, system will use ESP_PWR_LVL_P3 as default for ADV/SCAN/CONN0-9.
|
||||
* @brief BLE TX power type
|
||||
* @note
|
||||
* 1. The connection TX power can only be set after the connection is established.
|
||||
* After disconnecting, the corresponding TX power will not be affected.
|
||||
* 2. `ESP_BLE_PWR_TYPE_DEFAULT` can be used to set the TX power for power types that have not been set before.
|
||||
* It will not affect the TX power values which have been set for the following CONN0-8/ADV/SCAN power types.
|
||||
* 3. If none of power type is set, the system will use `ESP_PWR_LVL_P3` as default for ADV/SCAN/CONN0-8.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< For connection handle 0 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< For connection handle 1 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< For connection handle 2 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< For connection handle 3 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< For connection handle 4 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< For connection handle 5 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< For connection handle 6 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< For connection handle 7 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< For connection handle 8 */
|
||||
ESP_BLE_PWR_TYPE_ADV = 9, /*!< For advertising */
|
||||
ESP_BLE_PWR_TYPE_SCAN = 10, /*!< For scan */
|
||||
ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< For default, if not set other, it will use default value */
|
||||
ESP_BLE_PWR_TYPE_NUM = 12, /*!< TYPE numbers */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< TX power for connection handle 0 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< TX power for connection handle 1 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< TX power for connection handle 2 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< TX power for connection handle 3 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< TX power for connection handle 4 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< TX power for connection handle 5 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< TX power for connection handle 6 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< TX power for connection handle 7 */
|
||||
ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< TX power for connection handle 8 */
|
||||
ESP_BLE_PWR_TYPE_ADV = 9, /*!< TX power for advertising */
|
||||
ESP_BLE_PWR_TYPE_SCAN = 10, /*!< TX power for scan */
|
||||
ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< Default TX power type, which can be used to set the TX power for power types that have not been set before.*/
|
||||
ESP_BLE_PWR_TYPE_NUM = 12, /*!< Number of types */
|
||||
} esp_ble_power_type_t;
|
||||
|
||||
/**
|
||||
* @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm).
|
||||
* @brief Bluetooth TX power level (index). Each index corresponds to a specific power value in dBm.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12dbm */
|
||||
ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9dbm */
|
||||
ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6dbm */
|
||||
ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3dbm */
|
||||
ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0dbm */
|
||||
ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3dbm */
|
||||
ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6dbm */
|
||||
ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9dbm */
|
||||
ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14dbm will actually result to -12dbm */
|
||||
ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11dbm will actually result to -9dbm */
|
||||
ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8dbm will actually result to -6dbm */
|
||||
ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5dbm will actually result to -3dbm */
|
||||
ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2dbm will actually result to 0dbm */
|
||||
ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1dbm will actually result to +3dbm */
|
||||
ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4dbm will actually result to +6dbm */
|
||||
ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7dbm will actually result to +9dbm */
|
||||
ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12 dBm */
|
||||
ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9 dBm */
|
||||
ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6 dBm */
|
||||
ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3 dBm */
|
||||
ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0 dBm */
|
||||
ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3 dBm */
|
||||
ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6 dBm */
|
||||
ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9 dBm */
|
||||
ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14 dBm will actually result in -12 dBm */
|
||||
ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11 dBm will actually result in -9 dBm */
|
||||
ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8 dBm will actually result in -6 dBm */
|
||||
ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5 dBm will actually result in -3 dBm */
|
||||
ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2 dBm will actually result in 0 dBm */
|
||||
ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1 dBm will actually result in +3 dBm */
|
||||
ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4 dBm will actually result in +6 dBm */
|
||||
ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7 dBm will actually result in +9 dBm */
|
||||
} esp_power_level_t;
|
||||
|
||||
/**
|
||||
@ -312,243 +326,308 @@ typedef enum {
|
||||
|
||||
/**
|
||||
* @brief Set BLE TX power
|
||||
* Connection Tx power should only be set after connection created.
|
||||
* @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc
|
||||
* @param power_level: Power level(index) corresponding to absolute value(dbm)
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
* @note Connection TX power should only be set after the connection is established.
|
||||
*
|
||||
* @param[in] power_type The type of TX power. It could be Advertising, Connection, Default, etc.
|
||||
* @param[in] power_level Power level (index) corresponding to the absolute value (dBm)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||
*/
|
||||
esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level);
|
||||
|
||||
/**
|
||||
* @brief Get BLE TX power
|
||||
* Connection Tx power should only be get after connection created.
|
||||
* @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc
|
||||
* @return >= 0 - Power level, < 0 - Invalid
|
||||
*
|
||||
* @note Connection TX power should only be retrieved after the connection is established.
|
||||
*
|
||||
* @param[in] power_type The type of TX power. It could be Advertising/Connection/Default and etc.
|
||||
*
|
||||
* @return
|
||||
* - Power level
|
||||
*
|
||||
*/
|
||||
esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
|
||||
|
||||
/**
|
||||
* @brief Set BR/EDR TX power
|
||||
* BR/EDR power control will use the power in range of minimum value and maximum value.
|
||||
* The power level will effect the global BR/EDR TX power, such inquire, page, connection and so on.
|
||||
* Please call the function after esp_bt_controller_enable and before any function which cause RF do TX.
|
||||
* So you can call the function before doing discovery, profile init and so on.
|
||||
* For example, if you want BR/EDR use the new TX power to do inquire, you should call
|
||||
* this function before inquire. Another word, If call this function when BR/EDR is in inquire(ING),
|
||||
* please do inquire again after call this function.
|
||||
* Default minimum power level is ESP_PWR_LVL_N0, and maximum power level is ESP_PWR_LVL_P3.
|
||||
* @param min_power_level: The minimum power level
|
||||
* @param max_power_level: The maximum power level
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
* BR/EDR power control will use the power within the range of minimum value and maximum value.
|
||||
* The power level will affect the global BR/EDR TX power for operations such as inquiry, page, and connection.
|
||||
*
|
||||
* @note
|
||||
* 1. Please call this function after `esp_bt_controller_enable()` and before any functions that cause RF transmission,
|
||||
* such as performing discovery, profile initialization, and so on.
|
||||
* 2. For BR/EDR to use the new TX power for inquiry, call this function before starting an inquiry.
|
||||
* If BR/EDR is already inquiring, restart the inquiry after calling this function.
|
||||
*
|
||||
* @param[in] min_power_level The minimum power level. The default value is `ESP_PWR_LVL_N0`.
|
||||
* @param[in] max_power_level The maximum power level. The default value is `ESP_PWR_LVL_P3`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
*/
|
||||
esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level);
|
||||
|
||||
/**
|
||||
* @brief Get BR/EDR TX power
|
||||
* If the argument is not NULL, then store the corresponding value.
|
||||
* @param min_power_level: The minimum power level
|
||||
* @param max_power_level: The maximum power level
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
* The corresponding power levels will be stored into the arguments.
|
||||
*
|
||||
* @param[out] min_power_level Pointer to store the minimum power level
|
||||
* @param[out] max_power_level The maximum power level
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||
*/
|
||||
esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level);
|
||||
|
||||
/**
|
||||
* @brief Set default SCO data path
|
||||
* Should be called after controller is enabled, and before (e)SCO link is established
|
||||
* @param data_path: SCO data path
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
* @note This function should be called after the Controller is enabled, and before (e)SCO link is established.
|
||||
*
|
||||
* @param[in] data_path SCO data path
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
*/
|
||||
esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path);
|
||||
|
||||
/**
|
||||
* @brief Initialize BT controller to allocate task and other resource.
|
||||
* This function should be called only once, before any other BT functions are called.
|
||||
* @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some
|
||||
* connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed.
|
||||
* @return ESP_OK - success, other - failed
|
||||
* @brief Initialize the Bluetooth Controller to allocate tasks and other resources
|
||||
*
|
||||
* @note This function should be called only once, before any other Bluetooth functions.
|
||||
*
|
||||
* @param[in] cfg Initial Bluetooth Controller configuration
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
*/
|
||||
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief De-initialize BT controller to free resource and delete task.
|
||||
* You should stop advertising and scanning, as well as
|
||||
* disconnect all existing connections before de-initializing BT controller.
|
||||
* @brief De-initialize Bluetooth Controller to free resources and delete tasks
|
||||
*
|
||||
* This function should be called only once, after any other BT functions are called.
|
||||
* @return ESP_OK - success, other - failed
|
||||
* @note
|
||||
* 1. You should stop advertising and scanning, and disconnect all existing connections before de-initializing Bluetooth Controller.
|
||||
* 2. This function should be called only once, after any other Bluetooth functions.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
* - ESP_ERR_NO_MEM: Out of memory
|
||||
*/
|
||||
esp_err_t esp_bt_controller_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Enable BT controller.
|
||||
* Due to a known issue, you cannot call esp_bt_controller_enable() a second time
|
||||
* to change the controller mode dynamically. To change controller mode, call
|
||||
* esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode.
|
||||
* @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. This mode must be
|
||||
* equal as the mode in "cfg" of esp_bt_controller_init().
|
||||
* @return ESP_OK - success, other - failed
|
||||
* @brief Enable Bluetooth Controller
|
||||
*
|
||||
* @note
|
||||
* 1. Bluetooth Controller cannot be enabled in `ESP_BT_CONTROLLER_STATUS_IDLE` status. It has to be initialized first.
|
||||
* 2. Due to a known issue, you cannot call `esp_bt_controller_enable()` for the second time
|
||||
* to change the Controller mode dynamically. To change the Controller mode, call
|
||||
* `esp_bt_controller_disable()` and then call `esp_bt_controller_enable()` with the new mode.
|
||||
*
|
||||
* @param[in] mode The Bluetooth Controller mode (BLE/Classic Bluetooth/BTDM) to enable
|
||||
*
|
||||
* For API compatibility, retain this argument. This mode must match the mode specified in the `cfg` of `esp_bt_controller_init()`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
*/
|
||||
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Disable BT controller
|
||||
* @return ESP_OK - success, other - failed
|
||||
* @brief Disable Bluetooth Controller
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
*/
|
||||
esp_err_t esp_bt_controller_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Get BT controller is initialised/de-initialised/enabled/disabled
|
||||
* @return status value
|
||||
* @brief Get Bluetooth Controller status
|
||||
*
|
||||
* @return
|
||||
* - ESP_BT_CONTROLLER_STATUS_IDLE: The Controller is not initialized or has been de-initialized.
|
||||
* - ESP_BT_CONTROLLER_STATUS_INITED: The Controller has been initialized, but not enabled or has been disabled.
|
||||
* - ESP_BT_CONTROLLER_STATUS_ENABLED: The Controller has been initialized and enabled.
|
||||
*/
|
||||
esp_bt_controller_status_t esp_bt_controller_get_status(void);
|
||||
|
||||
/** @brief esp_vhci_host_callback
|
||||
* used for vhci call host function to notify what host need to do
|
||||
/**
|
||||
* @brief Vendor HCI (VHCI) callback functions to notify the Host on the next operation
|
||||
*/
|
||||
typedef struct esp_vhci_host_callback {
|
||||
void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */
|
||||
int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/
|
||||
void (*notify_host_send_available)(void); /*!< Callback to notify the Host that the Controller is ready to receive the packet */
|
||||
int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< Callback to notify the Host that the Controller has a packet to send */
|
||||
} esp_vhci_host_callback_t;
|
||||
|
||||
/** @brief esp_vhci_host_check_send_available
|
||||
* used for check actively if the host can send packet to controller or not.
|
||||
* @return true for ready to send, false means cannot send packet
|
||||
/**
|
||||
* @brief Check whether the Controller is ready to receive the packet
|
||||
*
|
||||
* If the return value is True, the Host can send the packet to the Controller.
|
||||
*
|
||||
* @note This function should be called before each `esp_vhci_host_send_packet()`.
|
||||
*
|
||||
* @return
|
||||
* True if the Controller is ready to receive packets; false otherwise
|
||||
*/
|
||||
bool esp_vhci_host_check_send_available(void);
|
||||
|
||||
/** @brief esp_vhci_host_send_packet
|
||||
* host send packet to controller
|
||||
/**
|
||||
* @brief Send the packet to the Controller
|
||||
*
|
||||
* Should not call this function from within a critical section
|
||||
* or when the scheduler is suspended.
|
||||
* @note
|
||||
* 1. This function shall not be called within a critical section or when the scheduler is suspended.
|
||||
* 2. This function should be called only if `esp_vhci_host_check_send_available()` returns True.
|
||||
*
|
||||
* @param data the packet point
|
||||
* @param len the packet length
|
||||
* @param[in] data Pointer to the packet data
|
||||
* @param[in] len The packet length
|
||||
*/
|
||||
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
|
||||
|
||||
/** @brief esp_vhci_host_register_callback
|
||||
* register the vhci reference callback
|
||||
* struct defined by vhci_host_callback structure.
|
||||
* @param callback esp_vhci_host_callback type variable
|
||||
* @return ESP_OK - success, ESP_FAIL - failed
|
||||
/**
|
||||
* @brief Register the VHCI callback funations defined in `esp_vhci_host_callback` structure.
|
||||
*
|
||||
* @param[in] callback `esp_vhci_host_callback` type variable
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_FAIL: Failure
|
||||
*/
|
||||
esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
|
||||
|
||||
/** @brief esp_bt_controller_mem_release
|
||||
* release the controller memory as per the mode
|
||||
/**
|
||||
* @brief Release the Controller memory as per the mode
|
||||
*
|
||||
* This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes.
|
||||
* This function releases the BSS, data and other sections of the Controller to heap. The total size is about 70 KB.
|
||||
*
|
||||
* esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init()
|
||||
* or after esp_bt_controller_deinit().
|
||||
* If the app calls `esp_bt_controller_enable(ESP_BT_MODE_BLE)` to use BLE only,
|
||||
* then it is safe to call `esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)` at initialization time to free unused Classic Bluetooth memory.
|
||||
*
|
||||
* Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth
|
||||
* mode which you have released by this function.
|
||||
* If the mode is `ESP_BT_MODE_BTDM`, then it may be useful to call API `esp_bt_mem_release(ESP_BT_MODE_BTDM)` instead,
|
||||
* which internally calls `esp_bt_controller_mem_release(ESP_BT_MODE_BTDM)` and additionally releases the BSS and data
|
||||
* consumed by the Classic Bluetooth/BLE Host stack to heap. For more details about usage please refer to the documentation of `esp_bt_mem_release()` function.
|
||||
*
|
||||
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
|
||||
* then do not call this function.
|
||||
* @note
|
||||
* 1. This function should be called only before `esp_bt_controller_init()` or after `esp_bt_controller_deinit()`.
|
||||
* 2. Once Bluetooth Controller memory is released, the process cannot be reversed. This means you cannot use the Bluetooth Controller mode that you have released using this function.
|
||||
* 3. If your firmware will upgrade the Bluetooth Controller mode later (such as switching from BLE to Classic Bluetooth or from disabled to enabled), then do not call this function.
|
||||
*
|
||||
* If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call
|
||||
* esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory.
|
||||
* @param[in] mode The Bluetooth Controller mode
|
||||
*
|
||||
* If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead,
|
||||
* which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data
|
||||
* consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of
|
||||
* esp_bt_mem_release() function
|
||||
*
|
||||
* @param mode : the mode want to release memory
|
||||
* @return ESP_OK - success, other - failed
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
* - ESP_ERR_NOT_FOUND: Requested resource not found
|
||||
*/
|
||||
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode);
|
||||
|
||||
/** @brief esp_bt_mem_release
|
||||
* release controller memory and BSS and data section of the BT/BLE host stack as per the mode
|
||||
/** @brief Release the Controller memory, BSS and data section of the Classic Bluetooth/BLE Host stack as per the mode
|
||||
*
|
||||
* This function first releases controller memory by internally calling esp_bt_controller_mem_release().
|
||||
* Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap
|
||||
* This function first releases Controller memory by internally calling `esp_bt_controller_mem_release()`.
|
||||
* Additionally, if the mode is set to `ESP_BT_MODE_BTDM`, it also releases the BSS and data consumed by the Classic Bluetooth and BLE Host stack to heap.
|
||||
*
|
||||
* Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth
|
||||
* mode which you have released by this function.
|
||||
* If you never intend to use Bluetooth in a current boot-up cycle, you can call `esp_bt_mem_release(ESP_BT_MODE_BTDM)`
|
||||
* before `esp_bt_controller_init()` or after `esp_bt_controller_deinit()`.
|
||||
*
|
||||
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
|
||||
* then do not call this function.
|
||||
*
|
||||
* If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM)
|
||||
* before esp_bt_controller_init or after esp_bt_controller_deinit.
|
||||
*
|
||||
* For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation".
|
||||
* In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory.
|
||||
* For example, if you only use Bluetooth for setting the Wi-Fi configuration, and do not use Bluetooth in the rest of the product operation,
|
||||
* after receiving the Wi-Fi configuration, you can disable/de-init Bluetooth and release its memory.
|
||||
* Below is the sequence of APIs to be called for such scenarios:
|
||||
*
|
||||
* esp_bluedroid_disable();
|
||||
* esp_bluedroid_deinit();
|
||||
* esp_bt_controller_disable();
|
||||
* esp_bt_controller_deinit();
|
||||
* esp_bt_mem_release(ESP_BT_MODE_BTDM);
|
||||
* esp_bluedroid_disable();
|
||||
* esp_bluedroid_deinit();
|
||||
* esp_bt_controller_disable();
|
||||
* esp_bt_controller_deinit();
|
||||
* esp_bt_mem_release(ESP_BT_MODE_BTDM);
|
||||
*
|
||||
* @note In case of NimBLE host, to release BSS and data memory to heap, the mode needs to be
|
||||
* set to ESP_BT_MODE_BTDM as controller is dual mode.
|
||||
* @param mode : the mode whose memory is to be released
|
||||
* @return ESP_OK - success, other - failed
|
||||
* @note
|
||||
* 1. Once Bluetooth Controller memory is released, the process cannot be reversed. This means you cannot use the Bluetooth Controller mode that you have released using this function.
|
||||
* 2. If your firmware will upgrade the Bluetooth Controller mode later (such as switching from BLE to Classic Bluetooth or from disabled to enabled), then do not call this function.
|
||||
* 3. In case of NimBLE Host, to release BSS and data memory to heap, the mode needs to be set to `ESP_BT_MODE_BTDM` as the Controller is in Dual mode.
|
||||
*
|
||||
* @param[in] mode The Bluetooth Controller mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
* - ESP_ERR_NOT_FOUND: Requested resource not found
|
||||
*/
|
||||
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief enable bluetooth to enter modem sleep
|
||||
* @brief Enable Bluetooth modem sleep
|
||||
*
|
||||
* Note that this function shall not be invoked before esp_bt_controller_enable()
|
||||
* There are currently two options for Bluetooth modem sleep: ORIG mode and EVED mode. The latter is intended for BLE only.
|
||||
* The modem sleep mode could be configured in menuconfig.
|
||||
*
|
||||
* There are currently two options for bluetooth modem sleep, one is ORIG mode, and another is EVED Mode. EVED Mode is intended for BLE only.
|
||||
* In ORIG mode, if there is no event to process, the Bluetooth Controller will periodically switch off some components and pause operation, then wake up according to the scheduled interval and resume work.
|
||||
* It can also wakeup earlier upon external request using function `esp_bt_controller_wakeup_request()`.
|
||||
*
|
||||
* For ORIG mode:
|
||||
* Bluetooth modem sleep is enabled in controller start up by default if CONFIG_CTRL_BTDM_MODEM_SLEEP is set and "ORIG mode" is selected. In ORIG modem sleep mode, bluetooth controller will switch off some components and pause to work every now and then, if there is no event to process; and wakeup according to the scheduled interval and resume the work. It can also wakeup earlier upon external request using function "esp_bt_controller_wakeup_request".
|
||||
* @note This function shall not be invoked before `esp_bt_controller_enable()`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
* - ESP_ERR_NOT_SUPPORTED: Operation or feature not supported
|
||||
*/
|
||||
esp_err_t esp_bt_sleep_enable(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief disable bluetooth modem sleep
|
||||
* @brief Disable Bluetooth modem sleep
|
||||
*
|
||||
* Note that this function shall not be invoked before esp_bt_controller_enable()
|
||||
*
|
||||
* If esp_bt_sleep_disable() is called, bluetooth controller will not be allowed to enter modem sleep;
|
||||
*
|
||||
* If ORIG modem sleep mode is in use, if this function is called, bluetooth controller may not immediately wake up if it is dormant then.
|
||||
* In this case, esp_bt_controller_wakeup_request() can be used to shorten the time for wakeup.
|
||||
* @note
|
||||
* 1. Bluetooth Controller will not be allowed to enter modem sleep after calling this function.
|
||||
* 2. In ORIG modem sleep mode, calling this function may not immediately wake up the Controller if it is currently dormant.
|
||||
* In this case, `esp_bt_controller_wakeup_request()` can be used to shorten the wake-up time.
|
||||
* 3. This function shall not be invoked before `esp_bt_controller_enable()`.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
* - ESP_ERR_NOT_SUPPORTED: Operation or feature not supported
|
||||
*/
|
||||
esp_err_t esp_bt_sleep_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Manually clear scan duplicate list
|
||||
* @brief Manually clear the scan duplicate list
|
||||
*
|
||||
* Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached
|
||||
* the amount of device in the filter can be configured in menuconfig.
|
||||
*
|
||||
* @note This function name is incorrectly spelled, it will be fixed in release 5.x version.
|
||||
* @note
|
||||
* 1. This function name is incorrectly spelled, it will be fixed in release 5.x version.
|
||||
* 2. The scan duplicate list will be automatically cleared when the maximum amount of devices in the filter is reached.
|
||||
* The amount of devices in the filter can be configured in menuconfig.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state
|
||||
*/
|
||||
esp_err_t esp_ble_scan_dupilcate_list_flush(void);
|
||||
|
||||
/**
|
||||
* @brief bt Wi-Fi power domain power on
|
||||
*/
|
||||
* @brief Power on Bluetooth Wi-Fi power domain
|
||||
*
|
||||
* @note This function is not recommended to use due to potential risk.
|
||||
*/
|
||||
void esp_wifi_bt_power_domain_on(void);
|
||||
|
||||
/**
|
||||
* @brief bt Wi-Fi power domain power off
|
||||
*/
|
||||
* @brief Power off Bluetooth Wi-Fi power domain
|
||||
*
|
||||
* @note This function is not recommended to use due to potential risk.
|
||||
*/
|
||||
void esp_wifi_bt_power_domain_off(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -3,6 +3,6 @@
|
||||
components/esp_common/test_apps/esp_common:
|
||||
disable:
|
||||
- if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1
|
||||
- if: CONFIG_NAME == "psram" and IDF_TARGET in ["esp32p4"]
|
||||
- if: CONFIG_NAME == "psram" and IDF_TARGET in ["esp32p4", "esp32c5"]
|
||||
temporary: true
|
||||
reason: esp32p4 is not supported yet # TODO: IDF-7557
|
||||
reason: esp32p4/c5 is not supported yet # TODO: IDF-7557
|
||||
|
@ -182,6 +182,7 @@ void esp_cpu_configure_region_protection(void)
|
||||
|
||||
// 5. LP memory
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
extern int _rtc_text_start;
|
||||
extern int _rtc_text_end;
|
||||
/* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits
|
||||
* Bootloader might have given extra permissions and those won't be cleared
|
||||
@ -191,13 +192,10 @@ void esp_cpu_configure_region_protection(void)
|
||||
PMP_ENTRY_CFG_RESET(13);
|
||||
PMP_ENTRY_CFG_RESET(14);
|
||||
PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE);
|
||||
#if CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
// First part of LP mem is reserved for coprocessor
|
||||
PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW);
|
||||
#else // CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
// Repeat same previous entry, to ensure next entry has correct base address (TOR)
|
||||
PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW, NONE);
|
||||
#endif // !CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
|
||||
// First part of LP mem is reserved for ULP coprocessor
|
||||
PMP_ENTRY_SET(12, (int)&_rtc_text_start, PMP_TOR | RW);
|
||||
|
||||
PMP_ENTRY_SET(13, (int)&_rtc_text_end, PMP_TOR | RX);
|
||||
PMP_ENTRY_SET(14, SOC_RTC_IRAM_HIGH, PMP_TOR | RW);
|
||||
#else
|
||||
|
@ -178,6 +178,7 @@ void esp_cpu_configure_region_protection(void)
|
||||
|
||||
// 6. LP memory
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
extern int _rtc_text_start;
|
||||
extern int _rtc_text_end;
|
||||
/* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits
|
||||
* Bootloader might have given extra permissions and those won't be cleared
|
||||
@ -187,13 +188,10 @@ void esp_cpu_configure_region_protection(void)
|
||||
PMP_ENTRY_CFG_RESET(13);
|
||||
PMP_ENTRY_CFG_RESET(14);
|
||||
PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE);
|
||||
#if CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
// First part of LP mem is reserved for coprocessor
|
||||
PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW);
|
||||
#else // CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
// Repeat same previous entry, to ensure next entry has correct base address (TOR)
|
||||
PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW, NONE);
|
||||
#endif // !CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
|
||||
// First part of LP mem is reserved for ULP coprocessor
|
||||
PMP_ENTRY_SET(12, (int)&_rtc_text_start, PMP_TOR | RW);
|
||||
|
||||
PMP_ENTRY_SET(13, (int)&_rtc_text_end, PMP_TOR | RX);
|
||||
PMP_ENTRY_SET(14, SOC_RTC_IRAM_HIGH, PMP_TOR | RW);
|
||||
#else
|
||||
|
@ -267,6 +267,10 @@ esp_err_t esp_netif_start_ppp(esp_netif_t *esp_netif)
|
||||
}
|
||||
#endif // CONFIG_LWIP_PPP_SERVER_SUPPORT
|
||||
|
||||
#if ESP_IPV6_AUTOCONFIG
|
||||
ppp_ctx->ppp->netif->ip6_autoconfig_enabled = 1;
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "%s: Starting PPP connection: %p", __func__, ppp_ctx->ppp);
|
||||
#ifdef CONFIG_LWIP_PPP_SERVER_SUPPORT
|
||||
esp_err_t err = ppp_listen(ppp_ctx->ppp);
|
||||
|
48
components/esp_psram/esp32c5/Kconfig.spiram
Normal file
48
components/esp_psram/esp32c5/Kconfig.spiram
Normal file
@ -0,0 +1,48 @@
|
||||
config SPIRAM
|
||||
bool "Support for external, SPI-connected RAM"
|
||||
default "n"
|
||||
help
|
||||
This enables support for an external SPI RAM chip, connected in parallel with the
|
||||
main SPI flash chip.
|
||||
|
||||
menu "SPI RAM config"
|
||||
depends on SPIRAM
|
||||
|
||||
choice SPIRAM_MODE
|
||||
prompt "Mode of SPI RAM chip in use"
|
||||
default SPIRAM_MODE_QUAD
|
||||
|
||||
config SPIRAM_MODE_QUAD
|
||||
bool "Quad Mode PSRAM"
|
||||
|
||||
endchoice
|
||||
|
||||
config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||
bool "Allow external memory as an argument to xTaskCreateStatic"
|
||||
default y
|
||||
help
|
||||
Accessing memory in SPIRAM has certain restrictions, so task stacks allocated by xTaskCreate
|
||||
are by default allocated from internal RAM.
|
||||
|
||||
This option allows for passing memory allocated from SPIRAM to be passed to xTaskCreateStatic.
|
||||
This should only be used for tasks where the stack is never accessed while the cache is disabled.
|
||||
|
||||
choice SPIRAM_SPEED
|
||||
prompt "Set RAM clock speed"
|
||||
default SPIRAM_SPEED_40M
|
||||
help
|
||||
Select the speed for the SPI RAM chip.
|
||||
|
||||
config SPIRAM_SPEED_80M
|
||||
bool "80MHz clock speed"
|
||||
config SPIRAM_SPEED_40M
|
||||
bool "40Mhz clock speed"
|
||||
endchoice
|
||||
|
||||
config SPIRAM_SPEED
|
||||
int
|
||||
default 80 if SPIRAM_SPEED_80M
|
||||
default 40 if SPIRAM_SPEED_40M
|
||||
|
||||
source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here
|
||||
endmenu
|
411
components/esp_psram/esp32c5/esp_psram_impl_quad.c
Normal file
411
components/esp_psram/esp32c5/esp_psram_impl_quad.c
Normal file
@ -0,0 +1,411 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2013-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "string.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_bit_defs.h"
|
||||
#include "esp_log.h"
|
||||
#include "../esp_psram_impl.h"
|
||||
#include "esp32c5/rom/spi_flash.h"
|
||||
#include "esp32c5/rom/opi_flash.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "esp_private/esp_gpio_reserve.h"
|
||||
#include "soc/spi1_mem_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
|
||||
static const char* TAG = "quad_psram";
|
||||
|
||||
//Commands for PSRAM chip
|
||||
#define PSRAM_READ 0x03
|
||||
#define PSRAM_FAST_READ 0x0B
|
||||
#define PSRAM_FAST_READ_QUAD 0xEB
|
||||
#define PSRAM_WRITE 0x02
|
||||
#define PSRAM_QUAD_WRITE 0x38
|
||||
#define PSRAM_ENTER_QMODE 0x35
|
||||
#define PSRAM_EXIT_QMODE 0xF5
|
||||
#define PSRAM_RESET_EN 0x66
|
||||
#define PSRAM_RESET 0x99
|
||||
#define PSRAM_SET_BURST_LEN 0xC0
|
||||
#define PSRAM_DEVICE_ID 0x9F
|
||||
|
||||
#define PSRAM_FAST_READ_DUMMY 4
|
||||
#define PSRAM_FAST_READ_QUAD_DUMMY 6
|
||||
|
||||
// ID
|
||||
#define PSRAM_ID_KGD_M 0xff
|
||||
#define PSRAM_ID_KGD_S 8
|
||||
#define PSRAM_ID_KGD 0x5d
|
||||
#define PSRAM_ID_EID_M 0xff
|
||||
#define PSRAM_ID_EID_S 16
|
||||
|
||||
// Use the [7:5](bit7~bit5) of EID to distinguish the psram size:
|
||||
//
|
||||
// BIT7 | BIT6 | BIT5 | SIZE(MBIT)
|
||||
// -------------------------------------
|
||||
// 0 | 0 | 0 | 16
|
||||
// 0 | 0 | 1 | 32
|
||||
// 0 | 1 | 0 | 64
|
||||
#define PSRAM_EID_SIZE_M 0x07
|
||||
#define PSRAM_EID_SIZE_S 5
|
||||
|
||||
#define PSRAM_KGD(id) (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M)
|
||||
#define PSRAM_EID(id) (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M)
|
||||
#define PSRAM_SIZE_ID(id) ((PSRAM_EID(id) >> PSRAM_EID_SIZE_S) & PSRAM_EID_SIZE_M)
|
||||
#define PSRAM_IS_VALID(id) (PSRAM_KGD(id) == PSRAM_ID_KGD)
|
||||
|
||||
#define PSRAM_IS_64MBIT_TRIAL(id) (PSRAM_EID(id) == 0x26)
|
||||
#define PSRAM_IS_2T_APS3204(id) ((((id) >> 21) && 0xfffff) == 1)
|
||||
|
||||
// IO-pins for PSRAM.
|
||||
// WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
|
||||
// hardcode the flash pins as well, making this code incompatible with either a setup
|
||||
// that has the flash on non-standard pins or ESP32s with built-in flash.
|
||||
#define FLASH_CLK_IO SPI_CLK_GPIO_NUM
|
||||
#define FLASH_CS_IO SPI_CS0_GPIO_NUM
|
||||
// PSRAM clock and cs IO should be configured based on hardware design.
|
||||
#define PSRAM_CLK_IO SPI_CLK_GPIO_NUM
|
||||
#define PSRAM_CS_IO SPI_CS1_GPIO_NUM
|
||||
#define PSRAM_SPIQ_SD0_IO SPI_Q_GPIO_NUM
|
||||
#define PSRAM_SPID_SD1_IO SPI_D_GPIO_NUM
|
||||
#define PSRAM_SPIWP_SD3_IO SPI_WP_GPIO_NUM
|
||||
#define PSRAM_SPIHD_SD2_IO SPI_HD_GPIO_NUM
|
||||
|
||||
#define CS_PSRAM_SEL SPI_MEM_CS1_DIS_M
|
||||
#define CS_FLASH_SEL SPI_MEM_CS0_DIS_M
|
||||
|
||||
#define SPI1_NUM 1
|
||||
#define SPI0_NUM 0
|
||||
|
||||
typedef enum {
|
||||
PSRAM_CMD_QPI,
|
||||
PSRAM_CMD_SPI,
|
||||
} psram_cmd_mode_t;
|
||||
|
||||
typedef esp_rom_spi_cmd_t psram_cmd_t;
|
||||
|
||||
static uint32_t s_psram_id = 0;
|
||||
static uint32_t s_psram_size = 0; //this stands for physical psram size in bytes
|
||||
static void config_psram_spi_phases(void);
|
||||
extern void esp_rom_spi_set_op_mode(int spi_num, esp_rom_spiflash_read_mode_t mode);
|
||||
|
||||
static uint8_t s_psram_cs_io = (uint8_t) -1;
|
||||
|
||||
uint8_t esp_psram_impl_get_cs_io(void)
|
||||
{
|
||||
return s_psram_cs_io;
|
||||
}
|
||||
|
||||
static void psram_set_op_mode(int spi_num, psram_cmd_mode_t mode)
|
||||
{
|
||||
if (mode == PSRAM_CMD_QPI) {
|
||||
esp_rom_spi_set_op_mode(spi_num, ESP_ROM_SPIFLASH_QIO_MODE);
|
||||
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(spi_num), SPI_MEM_FCMD_QUAD_M);
|
||||
} else if (mode == PSRAM_CMD_SPI) {
|
||||
esp_rom_spi_set_op_mode(spi_num, ESP_ROM_SPIFLASH_SLOWRD_MODE);
|
||||
}
|
||||
}
|
||||
static void _psram_exec_cmd(int spi_num,
|
||||
uint32_t cmd, int cmd_bit_len,
|
||||
uint32_t addr, int addr_bit_len,
|
||||
int dummy_bits,
|
||||
uint8_t* mosi_data, int mosi_bit_len,
|
||||
uint8_t* miso_data, int miso_bit_len)
|
||||
{
|
||||
esp_rom_spi_cmd_t conf;
|
||||
uint32_t _addr = addr;
|
||||
conf.addr = &_addr;
|
||||
conf.addrBitLen = addr_bit_len;
|
||||
conf.cmd = cmd;
|
||||
conf.cmdBitLen = cmd_bit_len;
|
||||
conf.dummyBitLen = dummy_bits;
|
||||
conf.txData = (uint32_t*) mosi_data;
|
||||
conf.txDataBitLen = mosi_bit_len;
|
||||
conf.rxData = (uint32_t*) miso_data;
|
||||
conf.rxDataBitLen = miso_bit_len;
|
||||
esp_rom_spi_cmd_config(spi_num, &conf);
|
||||
}
|
||||
|
||||
void psram_exec_cmd(int spi_num, psram_cmd_mode_t mode,
|
||||
uint32_t cmd, int cmd_bit_len,
|
||||
uint32_t addr, int addr_bit_len,
|
||||
int dummy_bits,
|
||||
uint8_t* mosi_data, int mosi_bit_len,
|
||||
uint8_t* miso_data, int miso_bit_len,
|
||||
uint32_t cs_mask,
|
||||
bool is_write_erase_operation)
|
||||
{
|
||||
uint32_t backup_usr = READ_PERI_REG(SPI_MEM_USER_REG(spi_num));
|
||||
uint32_t backup_usr1 = READ_PERI_REG(SPI_MEM_USER1_REG(spi_num));
|
||||
uint32_t backup_usr2 = READ_PERI_REG(SPI_MEM_USER2_REG(spi_num));
|
||||
uint32_t backup_ctrl = READ_PERI_REG(SPI_MEM_CTRL_REG(spi_num));
|
||||
psram_set_op_mode(spi_num, mode);
|
||||
_psram_exec_cmd(spi_num, cmd, cmd_bit_len, addr, addr_bit_len,
|
||||
dummy_bits, mosi_data, mosi_bit_len, miso_data, miso_bit_len);
|
||||
esp_rom_spi_cmd_start(spi_num, miso_data, miso_bit_len / 8, cs_mask, is_write_erase_operation);
|
||||
|
||||
WRITE_PERI_REG(SPI_MEM_USER_REG(spi_num), backup_usr);
|
||||
WRITE_PERI_REG(SPI_MEM_USER1_REG(spi_num), backup_usr1);
|
||||
WRITE_PERI_REG(SPI_MEM_USER2_REG(spi_num), backup_usr2);
|
||||
WRITE_PERI_REG(SPI_MEM_CTRL_REG(spi_num), backup_ctrl);
|
||||
}
|
||||
|
||||
//exit QPI mode(set back to SPI mode)
|
||||
static void psram_disable_qio_mode(int spi_num)
|
||||
{
|
||||
psram_exec_cmd(spi_num, PSRAM_CMD_QPI,
|
||||
PSRAM_EXIT_QMODE, 8, /* command and command bit len*/
|
||||
0, 0, /* address and address bit len*/
|
||||
0, /* dummy bit len */
|
||||
NULL, 0, /* tx data and tx bit len*/
|
||||
NULL, 0, /* rx data and rx bit len*/
|
||||
CS_PSRAM_SEL, /* cs bit mask*/
|
||||
false); /* whether is program/erase operation */
|
||||
}
|
||||
|
||||
//TODO IDF-4307
|
||||
//switch psram burst length(32 bytes or 1024 bytes)
|
||||
//datasheet says it should be 1024 bytes by default
|
||||
static void psram_set_wrap_burst_length(int spi_num, psram_cmd_mode_t mode)
|
||||
{
|
||||
psram_exec_cmd(spi_num, mode,
|
||||
PSRAM_SET_BURST_LEN, 8, /* command and command bit len*/
|
||||
0, 0, /* address and address bit len*/
|
||||
0, /* dummy bit len */
|
||||
NULL, 0, /* tx data and tx bit len*/
|
||||
NULL, 0, /* rx data and rx bit len*/
|
||||
CS_PSRAM_SEL, /* cs bit mask*/
|
||||
false); /* whether is program/erase operation */
|
||||
}
|
||||
|
||||
//send reset command to psram, in spi mode
|
||||
static void psram_reset_mode(int spi_num)
|
||||
{
|
||||
psram_exec_cmd(spi_num, PSRAM_CMD_SPI,
|
||||
PSRAM_RESET_EN, 8, /* command and command bit len*/
|
||||
0, 0, /* address and address bit len*/
|
||||
0, /* dummy bit len */
|
||||
NULL, 0, /* tx data and tx bit len*/
|
||||
NULL, 0, /* rx data and rx bit len*/
|
||||
CS_PSRAM_SEL, /* cs bit mask*/
|
||||
false); /* whether is program/erase operation */
|
||||
|
||||
psram_exec_cmd(spi_num, PSRAM_CMD_SPI,
|
||||
PSRAM_RESET, 8, /* command and command bit len*/
|
||||
0, 0, /* address and address bit len*/
|
||||
0, /* dummy bit len */
|
||||
NULL, 0, /* tx data and tx bit len*/
|
||||
NULL, 0, /* rx data and rx bit len*/
|
||||
CS_PSRAM_SEL, /* cs bit mask*/
|
||||
false); /* whether is program/erase operation */
|
||||
}
|
||||
|
||||
esp_err_t psram_enable_wrap(uint32_t wrap_size)
|
||||
{
|
||||
//TODO: IDF-4307
|
||||
static uint32_t current_wrap_size = 0;
|
||||
if (current_wrap_size == wrap_size) {
|
||||
return ESP_OK;
|
||||
}
|
||||
switch (wrap_size) {
|
||||
case 32:
|
||||
case 0:
|
||||
psram_set_wrap_burst_length(1, PSRAM_CMD_QPI);
|
||||
current_wrap_size = wrap_size;
|
||||
return ESP_OK;
|
||||
case 16:
|
||||
case 64:
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
bool psram_support_wrap_size(uint32_t wrap_size)
|
||||
{
|
||||
switch (wrap_size) {
|
||||
case 0:
|
||||
case 32:
|
||||
return true;
|
||||
case 16:
|
||||
case 64:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Read ID operation only supports SPI CMD and mode, should issue `psram_disable_qio_mode` before calling this
|
||||
static void psram_read_id(int spi_num, uint32_t* dev_id)
|
||||
{
|
||||
psram_exec_cmd(spi_num, PSRAM_CMD_SPI,
|
||||
PSRAM_DEVICE_ID, 8, /* command and command bit len*/
|
||||
0, 24, /* address and address bit len*/
|
||||
0, /* dummy bit len */
|
||||
NULL, 0, /* tx data and tx bit len*/
|
||||
(uint8_t*) dev_id, 24, /* rx data and rx bit len*/
|
||||
CS_PSRAM_SEL, /* cs bit mask*/
|
||||
false); /* whether is program/erase operation */
|
||||
}
|
||||
|
||||
//enter QPI mode
|
||||
static void psram_enable_qio_mode(int spi_num)
|
||||
{
|
||||
psram_exec_cmd(spi_num, PSRAM_CMD_SPI,
|
||||
PSRAM_ENTER_QMODE, 8, /* command and command bit len*/
|
||||
0, 0, /* address and address bit len*/
|
||||
0, /* dummy bit len */
|
||||
NULL, 0, /* tx data and tx bit len*/
|
||||
NULL, 0, /* rx data and rx bit len*/
|
||||
CS_PSRAM_SEL, /* cs bit mask*/
|
||||
false); /* whether is program/erase operation */
|
||||
}
|
||||
|
||||
static void psram_set_cs_timing(void)
|
||||
{
|
||||
//SPI0/1 share the cs_hold / cs_setup, cd_hold_time / cd_setup_time registers for PSRAM, so we only need to set SPI0 related registers here
|
||||
SET_PERI_REG_BITS(SPI_SMEM_AC_REG(0), SPI_SMEM_CS_HOLD_TIME_V, 3, SPI_SMEM_CS_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_SMEM_AC_REG(0), SPI_SMEM_CS_SETUP_TIME_V, 3, SPI_SMEM_CS_SETUP_TIME_S);
|
||||
SET_PERI_REG_MASK(SPI_SMEM_AC_REG(0), SPI_SMEM_CS_HOLD_M | SPI_SMEM_CS_SETUP_M);
|
||||
|
||||
SET_PERI_REG_BITS(SPI_SMEM_AC_REG(0), SPI_SMEM_CS_HOLD_DELAY_V, 3, SPI_SMEM_CS_HOLD_DELAY_S);
|
||||
}
|
||||
|
||||
static void psram_gpio_config(void)
|
||||
{
|
||||
//CS1
|
||||
uint8_t cs1_io = PSRAM_CS_IO;
|
||||
if (cs1_io == SPI_CS1_GPIO_NUM) {
|
||||
gpio_hal_iomux_func_sel(IO_MUX_GPIO15_REG, FUNC_SPICS1_SPICS1);
|
||||
} else {
|
||||
esp_rom_gpio_connect_out_signal(cs1_io, FSPICS1_OUT_IDX, 0, 0);
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cs1_io], PIN_FUNC_GPIO);
|
||||
}
|
||||
s_psram_cs_io = cs1_io;
|
||||
|
||||
//WP HD
|
||||
uint8_t wp_io = PSRAM_SPIWP_SD3_IO;
|
||||
//This ROM function will init both WP and HD pins.
|
||||
esp_rom_spiflash_select_qio_pins(wp_io, 0);
|
||||
|
||||
// Reserve psram pins
|
||||
esp_gpio_reserve(BIT64(cs1_io) | BIT64(wp_io));
|
||||
}
|
||||
|
||||
esp_err_t esp_psram_impl_enable(void) //psram init
|
||||
{
|
||||
psram_gpio_config();
|
||||
psram_set_cs_timing();
|
||||
|
||||
//We use SPI1 to init PSRAM
|
||||
psram_disable_qio_mode(SPI1_NUM);
|
||||
psram_read_id(SPI1_NUM, &s_psram_id);
|
||||
if (!PSRAM_IS_VALID(s_psram_id)) {
|
||||
/* 16Mbit psram ID read error workaround:
|
||||
* treat the first read id as a dummy one as the pre-condition,
|
||||
* Send Read ID command again
|
||||
*/
|
||||
psram_read_id(SPI1_NUM, &s_psram_id);
|
||||
if (!PSRAM_IS_VALID(s_psram_id)) {
|
||||
ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08x, PSRAM chip not found or not supported, or wrong PSRAM line mode", (uint32_t)s_psram_id);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (PSRAM_IS_64MBIT_TRIAL(s_psram_id)) {
|
||||
s_psram_size = PSRAM_SIZE_8MB;
|
||||
} else if (PSRAM_IS_2T_APS3204(s_psram_id)) {
|
||||
s_psram_size = PSRAM_SIZE_4MB;
|
||||
} else {
|
||||
uint8_t density = PSRAM_SIZE_ID(s_psram_id);
|
||||
s_psram_size = density == 0x0 ? PSRAM_SIZE_2MB :
|
||||
density == 0x1 ? PSRAM_SIZE_4MB :
|
||||
density == 0x2 ? PSRAM_SIZE_8MB : 0;
|
||||
}
|
||||
|
||||
//SPI1: send psram reset command
|
||||
psram_reset_mode(SPI1_NUM);
|
||||
//SPI1: send QPI enable command
|
||||
psram_enable_qio_mode(SPI1_NUM);
|
||||
|
||||
//Configure SPI0 PSRAM related SPI Phases
|
||||
config_psram_spi_phases();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void IRAM_ATTR psram_clock_set(int spi_num, int8_t freqdiv)
|
||||
{
|
||||
uint32_t freqbits = 0;
|
||||
if (1 >= freqdiv) {
|
||||
WRITE_PERI_REG(SPI_MEM_SRAM_CLK_REG(spi_num), SPI_MEM_SCLK_EQU_SYSCLK);
|
||||
} else {
|
||||
freqbits = (((freqdiv - 1) << SPI_MEM_SCLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI_MEM_SCLKCNT_H_S)) | ((freqdiv - 1) << SPI_MEM_SCLKCNT_L_S);
|
||||
WRITE_PERI_REG(SPI_MEM_SRAM_CLK_REG(spi_num), freqbits);
|
||||
}
|
||||
}
|
||||
|
||||
//Configure PSRAM SPI0 phase related registers here according to the PSRAM chip requirement
|
||||
static void config_psram_spi_phases(void)
|
||||
{
|
||||
#if (CONFIG_SPIRAM_SPEED == 80)
|
||||
psram_clock_set(0, 1);
|
||||
#elif (CONFIG_SPIRAM_SPEED == 40)
|
||||
psram_clock_set(0, 2);
|
||||
#endif
|
||||
|
||||
//Config CMD phase
|
||||
CLEAR_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_USR_SRAM_DIO_M); //disable dio mode for cache command
|
||||
SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_USR_SRAM_QIO_M); //enable qio mode for cache command
|
||||
SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_CACHE_SRAM_USR_RCMD_M); //enable cache read command
|
||||
SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_CACHE_SRAM_USR_WCMD_M); //enable cache write command
|
||||
SET_PERI_REG_BITS(SPI_MEM_SRAM_DWR_CMD_REG(0), SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN, 7, SPI_MEM_CACHE_SRAM_USR_WR_CMD_BITLEN_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_SRAM_DWR_CMD_REG(0), SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE, PSRAM_QUAD_WRITE, SPI_MEM_CACHE_SRAM_USR_WR_CMD_VALUE_S); //0x38
|
||||
SET_PERI_REG_BITS(SPI_MEM_SRAM_DRD_CMD_REG(0), SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 7, SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_S);
|
||||
SET_PERI_REG_BITS(SPI_MEM_SRAM_DRD_CMD_REG(0), SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_V, PSRAM_FAST_READ_QUAD, SPI_MEM_CACHE_SRAM_USR_RD_CMD_VALUE_S); //0xEB
|
||||
|
||||
//Config ADDR phase
|
||||
SET_PERI_REG_BITS(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_SRAM_ADDR_BITLEN_V, 23, SPI_MEM_SRAM_ADDR_BITLEN_S);
|
||||
|
||||
//Dummy
|
||||
/**
|
||||
* We set the PSRAM chip required dummy here. If timing tuning is needed,
|
||||
* the dummy length will be updated in `mspi_timing_enter_high_speed_mode()`
|
||||
*/
|
||||
SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_USR_RD_SRAM_DUMMY_M); //enable cache read dummy
|
||||
SET_PERI_REG_BITS(SPI_MEM_CACHE_SCTRL_REG(0), SPI_MEM_SRAM_RDUMMY_CYCLELEN_V, (PSRAM_FAST_READ_QUAD_DUMMY - 1), SPI_MEM_SRAM_RDUMMY_CYCLELEN_S); //dummy
|
||||
|
||||
CLEAR_PERI_REG_MASK(SPI_MEM_MISC_REG(0), SPI_MEM_CS1_DIS_M); //ENABLE SPI0 CS1 TO PSRAM(CS0--FLASH; CS1--SRAM)
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------
|
||||
* Following APIs are not required to be IRAM-Safe
|
||||
*
|
||||
* Consider moving these to another file if this kind of APIs grows dramatically
|
||||
*-------------------------------------------------------------------------------*/
|
||||
esp_err_t esp_psram_impl_get_physical_size(uint32_t *out_size_bytes)
|
||||
{
|
||||
if (!out_size_bytes) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*out_size_bytes = s_psram_size;
|
||||
return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
|
||||
}
|
||||
|
||||
esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes)
|
||||
{
|
||||
if (!out_size_bytes) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*out_size_bytes = s_psram_size;
|
||||
|
||||
return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
| Supported Targets | ESP32 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C5 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
|
||||
This test app is used to test PSRAM
|
||||
|
@ -86,3 +86,16 @@ def test_psram_esp32s3_octal(dut: Dut) -> None:
|
||||
)
|
||||
def test_psram_esp32p4(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'esp32c5_release',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
def test_psram_esp32c5(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
@ -0,0 +1,7 @@
|
||||
CONFIG_IDF_TARGET="esp32c5"
|
||||
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
|
||||
CONFIG_SPIRAM=y
|
@ -973,7 +973,6 @@ r_ble_lll_adv_coex_dpc_update_on_event_scheduled = 0x40001418;
|
||||
r_ble_lll_adv_done = 0x4000141c;
|
||||
r_ble_lll_adv_event_done = 0x40001424;
|
||||
r_ble_lll_adv_event_rmvd_from_sched = 0x40001428;
|
||||
r_ble_lll_adv_ext_estimate_data_itvl = 0x4000142c;
|
||||
r_ble_lll_adv_get_sec_pdu_len = 0x40001430;
|
||||
r_ble_lll_adv_make_done = 0x40001438;
|
||||
r_ble_lll_adv_periodic_done = 0x4000143c;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef _ROM_CACHE_H_
|
||||
#define _ROM_CACHE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sdkconfig.h>
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32S2
|
||||
#error This file should only be included for ESP32-S2 target
|
||||
#endif
|
||||
|
@ -17,8 +17,12 @@ SECTIONS
|
||||
*/
|
||||
.rtc.text :
|
||||
{
|
||||
ALIGNED_SYMBOL(4, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(4, _rtc_text_start)
|
||||
/* Align the start of RTC code region as per PMP granularity
|
||||
* this ensures we do not overwrite the permissions for the previous
|
||||
* region (ULP mem) regardless of its end alignment
|
||||
*/
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
|
||||
|
||||
*(.rtc.entry.text)
|
||||
|
||||
|
@ -17,8 +17,12 @@ SECTIONS
|
||||
*/
|
||||
.rtc.text :
|
||||
{
|
||||
ALIGNED_SYMBOL(4, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(4, _rtc_text_start)
|
||||
/* Align the start of RTC code region as per PMP granularity
|
||||
* this ensures we do not overwrite the permissions for the previous
|
||||
* region (ULP mem) regardless of its end alignment
|
||||
*/
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
|
||||
|
||||
*(.rtc.entry.text)
|
||||
|
||||
@ -27,7 +31,10 @@ SECTIONS
|
||||
*rtc_wake_stub*.*(.text .text.*)
|
||||
*(.rtc_text_end_test)
|
||||
|
||||
ALIGNED_SYMBOL(4, _rtc_text_end)
|
||||
/* Align the end of RTC code region as per PMP granularity */
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
|
||||
_rtc_text_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/**
|
||||
|
@ -17,8 +17,12 @@ SECTIONS
|
||||
*/
|
||||
.rtc.text :
|
||||
{
|
||||
ALIGNED_SYMBOL(4, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(4, _rtc_text_start)
|
||||
/* Align the start of RTC code region as per PMP granularity
|
||||
* this ensures we do not overwrite the permissions for any potential previous
|
||||
* region regardless of its end alignment
|
||||
*/
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
|
||||
|
||||
*(.rtc.entry.text)
|
||||
|
||||
@ -27,6 +31,9 @@ SECTIONS
|
||||
*rtc_wake_stub*.*(.text .text.*)
|
||||
*(.rtc_text_end_test)
|
||||
|
||||
/* Align the end of RTC code region as per PMP granularity */
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
|
||||
_rtc_text_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
|
@ -17,8 +17,12 @@ SECTIONS
|
||||
*/
|
||||
.rtc.text :
|
||||
{
|
||||
ALIGNED_SYMBOL(4, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(4, _rtc_text_start)
|
||||
/* Align the start of RTC code region as per PMP granularity
|
||||
* this ensures we do not overwrite the permissions for any potential previous
|
||||
* region regardless of its end alignment
|
||||
*/
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_fast_start)
|
||||
ALIGNED_SYMBOL(_esp_pmp_align_size, _rtc_text_start)
|
||||
|
||||
*(.rtc.entry.text)
|
||||
|
||||
@ -27,7 +31,10 @@ SECTIONS
|
||||
*rtc_wake_stub*.*(.text .text.*)
|
||||
*(.rtc_text_end_test)
|
||||
|
||||
ALIGNED_SYMBOL(4, _rtc_text_end)
|
||||
/* Align the end of RTC code region as per PMP granularity */
|
||||
. = ALIGN(_esp_pmp_align_size);
|
||||
|
||||
_rtc_text_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/**
|
||||
|
@ -879,6 +879,7 @@ typedef struct {
|
||||
typedef enum {
|
||||
WPS_FAIL_REASON_NORMAL = 0, /**< WPS normal fail reason */
|
||||
WPS_FAIL_REASON_RECV_M2D, /**< WPS receive M2D frame */
|
||||
WPS_FAIL_REASON_RECV_DEAUTH, /**< Recv deauth from AP while wps handshake */
|
||||
WPS_FAIL_REASON_MAX
|
||||
} wifi_event_sta_wps_fail_reason_t;
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 73ed5e75a6b8d456583c84428d3f3e3713c99944
|
||||
Subproject commit 7fbc7d9f5a205177f28c4ce48e67d9eaa28908d8
|
@ -61,12 +61,12 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
return (words + 0xF) & ~0xF;
|
||||
}
|
||||
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
}
|
||||
|
@ -55,12 +55,12 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
return words;
|
||||
}
|
||||
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
|
||||
int i;
|
||||
for (i = 0; i < (int)rd_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break;
|
||||
buf[i] = HAL_FORCE_READ_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte);
|
||||
buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -136,7 +136,7 @@ static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t w
|
||||
int i;
|
||||
for (i = 0; i < (int)wr_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte, buf[i]);
|
||||
USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -187,7 +187,6 @@ __attribute__((always_inline))
|
||||
static inline uint32_t mmu_ll_format_paddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t target)
|
||||
{
|
||||
(void)mmu_id;
|
||||
(void)target;
|
||||
mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
|
||||
uint32_t shift_code = 0;
|
||||
switch (page_size) {
|
||||
@ -219,12 +218,11 @@ static inline uint32_t mmu_ll_format_paddr(uint32_t mmu_id, uint32_t paddr, mmu_
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void mmu_ll_write_entry(uint32_t mmu_id, uint32_t entry_id, uint32_t mmu_val, mmu_target_t target)
|
||||
{
|
||||
(void)mmu_id;
|
||||
(void)target;
|
||||
uint32_t mmu_raw_value;
|
||||
if (mmu_ll_cache_encryption_enabled()) {
|
||||
mmu_val |= SOC_MMU_SENSITIVE;
|
||||
}
|
||||
mmu_val |= (target == MMU_TARGET_FLASH0) ? SOC_MMU_ACCESS_FLASH : SOC_MMU_ACCESS_SPIRAM;
|
||||
|
||||
mmu_raw_value = mmu_val | SOC_MMU_VALID;
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id);
|
||||
@ -240,7 +238,6 @@ __attribute__((always_inline)) static inline void mmu_ll_write_entry(uint32_t mm
|
||||
*/
|
||||
__attribute__((always_inline)) static inline uint32_t mmu_ll_read_entry(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
(void)mmu_id;
|
||||
uint32_t mmu_raw_value;
|
||||
uint32_t ret;
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id);
|
||||
@ -263,7 +260,6 @@ __attribute__((always_inline)) static inline uint32_t mmu_ll_read_entry(uint32_t
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void mmu_ll_set_entry_invalid(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
(void)mmu_id;
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), entry_id);
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_CONTENT_REG(0), SOC_MMU_INVALID);
|
||||
}
|
||||
@ -322,7 +318,6 @@ static inline mmu_target_t mmu_ll_get_entry_target(uint32_t mmu_id, uint32_t ent
|
||||
*/
|
||||
static inline uint32_t mmu_ll_entry_id_to_paddr_base(uint32_t mmu_id, uint32_t entry_id)
|
||||
{
|
||||
(void)mmu_id;
|
||||
HAL_ASSERT(entry_id < SOC_MMU_ENTRY_NUM);
|
||||
|
||||
mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
|
||||
@ -361,7 +356,6 @@ static inline uint32_t mmu_ll_entry_id_to_paddr_base(uint32_t mmu_id, uint32_t e
|
||||
*/
|
||||
static inline int mmu_ll_find_entry_id_based_on_map_value(uint32_t mmu_id, uint32_t mmu_val, mmu_target_t target)
|
||||
{
|
||||
(void)mmu_id;
|
||||
for (int i = 0; i < SOC_MMU_ENTRY_NUM; i++) {
|
||||
if (mmu_ll_check_entry_valid(mmu_id, i)) {
|
||||
if (mmu_ll_get_entry_target(mmu_id, i) == target) {
|
||||
@ -385,7 +379,6 @@ static inline int mmu_ll_find_entry_id_based_on_map_value(uint32_t mmu_id, uint3
|
||||
*/
|
||||
static inline uint32_t mmu_ll_entry_id_to_vaddr_base(uint32_t mmu_id, uint32_t entry_id, mmu_vaddr_t type)
|
||||
{
|
||||
(void)mmu_id;
|
||||
mmu_page_size_t page_size = mmu_ll_get_page_size(mmu_id);
|
||||
uint32_t shift_code = 0;
|
||||
|
||||
|
@ -49,14 +49,14 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
return words;
|
||||
}
|
||||
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
/* Power up the MPI peripheral (default is power-down state) */
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD);
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
/* Power down the MPI peripheral */
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PU);
|
||||
|
69
components/hal/esp32c5/include/hal/mspi_timing_tuning_ll.h
Normal file
69
components/hal/esp32c5/include/hal/mspi_timing_tuning_ll.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/************************** MSPI pll clock configurations **************************/
|
||||
|
||||
/**
|
||||
* @brief Select mspi clock source
|
||||
*
|
||||
* @param clk_src the clock source of mspi clock
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void mspi_ll_clock_src_sel(soc_periph_mspi_clk_src_t clk_src)
|
||||
{
|
||||
switch (clk_src) {
|
||||
case MSPI_CLK_SRC_XTAL:
|
||||
PCR.mspi_clk_conf.mspi_func_clk_sel = 0;
|
||||
break;
|
||||
case MSPI_CLK_SRC_RC_FAST:
|
||||
PCR.mspi_clk_conf.mspi_func_clk_sel = 1;
|
||||
break;
|
||||
case MSPI_CLK_SRC_SPLL:
|
||||
PCR.mspi_clk_conf.mspi_func_clk_sel = 2;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
|
||||
*
|
||||
* @param divider Divider.
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void mspi_ll_fast_set_hs_divider(uint32_t divider)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, divider - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the mspi bus clock
|
||||
*
|
||||
* @param enable enable the bus clock
|
||||
*/
|
||||
static inline __attribute__((always_inline)) void mspi_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
PCR.mspi_conf.mspi_clk_en = enable;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -116,7 +116,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
|
||||
int i;
|
||||
for (i = 0; i < (int)rd_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break;
|
||||
buf[i] = HAL_FORCE_READ_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte);
|
||||
buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -135,7 +135,7 @@ static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t w
|
||||
int i;
|
||||
for (i = 0; i < (int)wr_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte, buf[i]);
|
||||
USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -47,14 +47,14 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
return words;
|
||||
}
|
||||
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
/* Power up the MPI peripheral */
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD);
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
/* Power down the MPI peripheral */
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PU);
|
||||
|
@ -117,7 +117,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
|
||||
int i;
|
||||
for (i = 0; i < (int)rd_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break;
|
||||
buf[i] = HAL_FORCE_READ_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte);
|
||||
buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -136,7 +136,7 @@ static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t w
|
||||
int i;
|
||||
for (i = 0; i < (int)wr_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte, buf[i]);
|
||||
USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -48,14 +48,14 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
return words;
|
||||
}
|
||||
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
/* Power up the MPI peripheral */
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD);
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
/* Power down the MPI peripheral */
|
||||
REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_FORCE_PU);
|
||||
|
@ -117,7 +117,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
|
||||
int i;
|
||||
for (i = 0; i < (int)rd_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break;
|
||||
buf[i] = HAL_FORCE_READ_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte);
|
||||
buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -136,7 +136,7 @@ static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t w
|
||||
int i;
|
||||
for (i = 0; i < (int)wr_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte, buf[i]);
|
||||
USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -56,11 +56,11 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
}
|
||||
|
||||
// No need to initialize Power Control Registers in case of ESP32-P4
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len)
|
||||
int i;
|
||||
for (i = 0; i < (int)rd_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break;
|
||||
buf[i] = HAL_FORCE_READ_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte);
|
||||
buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -139,7 +139,7 @@ static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t w
|
||||
int i;
|
||||
for (i = 0; i < (int)wr_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte, buf[i]);
|
||||
USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -58,12 +58,12 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
return words;
|
||||
}
|
||||
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_MEM_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
}
|
||||
|
@ -55,12 +55,12 @@ static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
return words;
|
||||
}
|
||||
|
||||
static inline void mpi_ll_clear_power_control_bit(void)
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_set_power_control_bit(void)
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ static inline uint32_t usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_
|
||||
uint32_t i;
|
||||
for (i = 0; i < rd_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break;
|
||||
buf[i] = HAL_FORCE_READ_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte);
|
||||
buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -138,7 +138,7 @@ static inline uint32_t usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint3
|
||||
uint32_t i;
|
||||
for (i = 0; i < wr_len; i++) {
|
||||
if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(USB_SERIAL_JTAG.ep1, rdwr_byte, buf[i]);
|
||||
USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ size_t mpi_hal_calc_hardware_words(size_t words)
|
||||
|
||||
void mpi_hal_enable_hardware_hw_op(void)
|
||||
{
|
||||
mpi_ll_clear_power_control_bit();
|
||||
mpi_ll_power_up();
|
||||
while (mpi_ll_check_memory_init_complete()) {
|
||||
}
|
||||
// Note: from enabling RSA clock to here takes about 1.3us
|
||||
@ -27,7 +27,7 @@ void mpi_hal_enable_hardware_hw_op(void)
|
||||
|
||||
void mpi_hal_disable_hardware_hw_op(void)
|
||||
{
|
||||
mpi_ll_set_power_control_bit();
|
||||
mpi_ll_power_down();
|
||||
}
|
||||
|
||||
void mpi_hal_interrupt_enable(bool enable)
|
||||
|
@ -381,11 +381,15 @@ esp_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int func,
|
||||
esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function,
|
||||
uint32_t addr, void* dst, size_t size)
|
||||
{
|
||||
uint32_t arg = SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT;
|
||||
//Extract and unset the bit used to indicate the OP Code (inverted logic)
|
||||
uint32_t arg = SD_ARG_CMD53_READ;
|
||||
bool incr_addr = true;
|
||||
//Extract and unset the bit used to indicate the OP Code
|
||||
if (addr & SDMMC_IO_FIXED_ADDR) {
|
||||
arg &= ~SD_ARG_CMD53_INCREMENT;
|
||||
addr &= ~SDMMC_IO_FIXED_ADDR;
|
||||
incr_addr = false;
|
||||
}
|
||||
if (incr_addr) {
|
||||
arg |= SD_ARG_CMD53_INCREMENT;
|
||||
}
|
||||
|
||||
/* host quirk: SDIO transfer with length not divisible by 4 bytes
|
||||
@ -405,7 +409,9 @@ esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function,
|
||||
}
|
||||
pc_dst += will_transfer;
|
||||
size -= will_transfer;
|
||||
addr += will_transfer;
|
||||
if (incr_addr) {
|
||||
addr += will_transfer;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -413,11 +419,15 @@ esp_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function,
|
||||
esp_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function,
|
||||
uint32_t addr, const void* src, size_t size)
|
||||
{
|
||||
uint32_t arg = SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT;
|
||||
//Extract and unset the bit used to indicate the OP Code (inverted logic)
|
||||
uint32_t arg = SD_ARG_CMD53_WRITE;
|
||||
bool incr_addr = true;
|
||||
//Extract and unset the bit used to indicate the OP Code
|
||||
if (addr & SDMMC_IO_FIXED_ADDR) {
|
||||
arg &= ~SD_ARG_CMD53_INCREMENT;
|
||||
addr &= ~SDMMC_IO_FIXED_ADDR;
|
||||
incr_addr = false;
|
||||
}
|
||||
if (incr_addr) {
|
||||
arg |= SD_ARG_CMD53_INCREMENT;
|
||||
}
|
||||
|
||||
/* same host quirk as in sdmmc_io_read_bytes */
|
||||
@ -434,7 +444,9 @@ esp_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function,
|
||||
}
|
||||
pc_src += will_transfer;
|
||||
size -= will_transfer;
|
||||
addr += will_transfer;
|
||||
if (incr_addr) {
|
||||
addr += will_transfer;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -163,6 +163,10 @@ config SOC_MODEM_CLOCK_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPIRAM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_XTAL_SUPPORT_40M
|
||||
bool
|
||||
default y
|
||||
|
@ -502,7 +502,7 @@ typedef enum {
|
||||
/**
|
||||
* @brief MSPI digital controller clock source
|
||||
*/
|
||||
typedef enum { // TODO: [ESP32C5] IDF-8649
|
||||
typedef enum {
|
||||
MSPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||
MSPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
|
||||
MSPI_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SPLL as the source clock */
|
||||
|
@ -137,6 +137,7 @@ extern "C" {
|
||||
#define SPI_CLK_GPIO_NUM 21
|
||||
#define SPI_D_GPIO_NUM 22
|
||||
#define SPI_Q_GPIO_NUM 17
|
||||
#define SPI_CS1_GPIO_NUM 15
|
||||
|
||||
#define USB_INT_PHY0_DM_GPIO_NUM 13
|
||||
#define USB_INT_PHY0_DP_GPIO_NUM 14
|
||||
|
@ -77,6 +77,7 @@
|
||||
// #define SOC_DEEP_SLEEP_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638
|
||||
#define SOC_MODEM_CLOCK_SUPPORTED 1
|
||||
// #define SOC_PM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8643
|
||||
#define SOC_SPIRAM_SUPPORTED 1
|
||||
|
||||
/*-------------------------- XTAL CAPS ---------------------------------------*/
|
||||
#define SOC_XTAL_SUPPORT_40M 1
|
||||
|
@ -11,10 +11,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** SPI_MEM_CMD_REG register
|
||||
/** SPI_MEM_CMD_REG(i) register
|
||||
* SPI1 memory command register
|
||||
*/
|
||||
#define SPI_MEM_CMD_REG (DR_REG_SPI_MEM_BASE + 0x0)
|
||||
#define SPI_MEM_CMD_REG(i) (REG_SPI_MEM_BASE(i) + 0x0)
|
||||
/** SPI_MEM_MST_ST : RO; bitpos: [3:0]; default: 0;
|
||||
* The current status of SPI1 master FSM.
|
||||
*/
|
||||
@ -155,10 +155,10 @@ extern "C" {
|
||||
#define SPI_MEM_FLASH_READ_V 0x00000001U
|
||||
#define SPI_MEM_FLASH_READ_S 31
|
||||
|
||||
/** SPI_MEM_ADDR_REG register
|
||||
/** SPI_MEM_ADDR_REG(i) register
|
||||
* SPI1 address register
|
||||
*/
|
||||
#define SPI_MEM_ADDR_REG (DR_REG_SPI_MEM_BASE + 0x4)
|
||||
#define SPI_MEM_ADDR_REG(i) (REG_SPI_MEM_BASE(i) + 0x4)
|
||||
/** SPI_MEM_USR_ADDR_VALUE : R/W; bitpos: [31:0]; default: 0;
|
||||
* In user mode, it is the memory address. other then the bit0-bit23 is the memory
|
||||
* address, the bit24-bit31 are the byte length of a transfer.
|
||||
@ -168,10 +168,10 @@ extern "C" {
|
||||
#define SPI_MEM_USR_ADDR_VALUE_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_USR_ADDR_VALUE_S 0
|
||||
|
||||
/** SPI_MEM_CTRL_REG register
|
||||
/** SPI_MEM_CTRL_REG(i) register
|
||||
* SPI1 control register.
|
||||
*/
|
||||
#define SPI_MEM_CTRL_REG (DR_REG_SPI_MEM_BASE + 0x8)
|
||||
#define SPI_MEM_CTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x8)
|
||||
/** SPI_MEM_FDUMMY_RIN : R/W; bitpos: [2]; default: 1;
|
||||
* In the dummy phase of a MSPI read data transfer when accesses to flash, the signal
|
||||
* level of SPI bus is output by the MSPI controller.
|
||||
@ -314,10 +314,10 @@ extern "C" {
|
||||
#define SPI_MEM_FREAD_QIO_V 0x00000001U
|
||||
#define SPI_MEM_FREAD_QIO_S 24
|
||||
|
||||
/** SPI_MEM_CTRL1_REG register
|
||||
/** SPI_MEM_CTRL1_REG(i) register
|
||||
* SPI1 control1 register.
|
||||
*/
|
||||
#define SPI_MEM_CTRL1_REG (DR_REG_SPI_MEM_BASE + 0xc)
|
||||
#define SPI_MEM_CTRL1_REG(i) (REG_SPI_MEM_BASE(i) + 0xc)
|
||||
/** SPI_MEM_CLK_MODE : R/W; bitpos: [1:0]; default: 0;
|
||||
* SPI clock mode bits. 0: SPI clock is off when CS inactive 1: SPI clock is delayed
|
||||
* one cycle after CS inactive 2: SPI clock is delayed two cycles after CS inactive 3:
|
||||
@ -336,10 +336,10 @@ extern "C" {
|
||||
#define SPI_MEM_CS_HOLD_DLY_RES_V 0x000003FFU
|
||||
#define SPI_MEM_CS_HOLD_DLY_RES_S 2
|
||||
|
||||
/** SPI_MEM_CTRL2_REG register
|
||||
/** SPI_MEM_CTRL2_REG(i) register
|
||||
* SPI1 control2 register.
|
||||
*/
|
||||
#define SPI_MEM_CTRL2_REG (DR_REG_SPI_MEM_BASE + 0x10)
|
||||
#define SPI_MEM_CTRL2_REG(i) (REG_SPI_MEM_BASE(i) + 0x10)
|
||||
/** SPI_MEM_SYNC_RESET : WT; bitpos: [31]; default: 0;
|
||||
* The FSM will be reset.
|
||||
*/
|
||||
@ -348,10 +348,10 @@ extern "C" {
|
||||
#define SPI_MEM_SYNC_RESET_V 0x00000001U
|
||||
#define SPI_MEM_SYNC_RESET_S 31
|
||||
|
||||
/** SPI_MEM_CLOCK_REG register
|
||||
/** SPI_MEM_CLOCK_REG(i) register
|
||||
* SPI1 clock division control register.
|
||||
*/
|
||||
#define SPI_MEM_CLOCK_REG (DR_REG_SPI_MEM_BASE + 0x14)
|
||||
#define SPI_MEM_CLOCK_REG(i) (REG_SPI_MEM_BASE(i) + 0x14)
|
||||
/** SPI_MEM_CLKCNT_L : R/W; bitpos: [7:0]; default: 3;
|
||||
* In the master mode it must be equal to spi_mem_clkcnt_N.
|
||||
*/
|
||||
@ -382,10 +382,10 @@ extern "C" {
|
||||
#define SPI_MEM_CLK_EQU_SYSCLK_V 0x00000001U
|
||||
#define SPI_MEM_CLK_EQU_SYSCLK_S 31
|
||||
|
||||
/** SPI_MEM_USER_REG register
|
||||
/** SPI_MEM_USER_REG(i) register
|
||||
* SPI1 user register.
|
||||
*/
|
||||
#define SPI_MEM_USER_REG (DR_REG_SPI_MEM_BASE + 0x18)
|
||||
#define SPI_MEM_USER_REG(i) (REG_SPI_MEM_BASE(i) + 0x18)
|
||||
/** SPI_MEM_CK_OUT_EDGE : R/W; bitpos: [9]; default: 0;
|
||||
* the bit combined with spi_mem_mosi_delay_mode bits to set mosi signal delay mode.
|
||||
*/
|
||||
@ -480,10 +480,10 @@ extern "C" {
|
||||
#define SPI_MEM_USR_COMMAND_V 0x00000001U
|
||||
#define SPI_MEM_USR_COMMAND_S 31
|
||||
|
||||
/** SPI_MEM_USER1_REG register
|
||||
/** SPI_MEM_USER1_REG(i) register
|
||||
* SPI1 user1 register.
|
||||
*/
|
||||
#define SPI_MEM_USER1_REG (DR_REG_SPI_MEM_BASE + 0x1c)
|
||||
#define SPI_MEM_USER1_REG(i) (REG_SPI_MEM_BASE(i) + 0x1c)
|
||||
/** SPI_MEM_USR_DUMMY_CYCLELEN : R/W; bitpos: [5:0]; default: 7;
|
||||
* The length in spi_mem_clk cycles of dummy phase. The register value shall be
|
||||
* (cycle_num-1).
|
||||
@ -500,10 +500,10 @@ extern "C" {
|
||||
#define SPI_MEM_USR_ADDR_BITLEN_V 0x0000003FU
|
||||
#define SPI_MEM_USR_ADDR_BITLEN_S 26
|
||||
|
||||
/** SPI_MEM_USER2_REG register
|
||||
/** SPI_MEM_USER2_REG(i) register
|
||||
* SPI1 user2 register.
|
||||
*/
|
||||
#define SPI_MEM_USER2_REG (DR_REG_SPI_MEM_BASE + 0x20)
|
||||
#define SPI_MEM_USER2_REG(i) (REG_SPI_MEM_BASE(i) + 0x20)
|
||||
/** SPI_MEM_USR_COMMAND_VALUE : R/W; bitpos: [15:0]; default: 0;
|
||||
* The value of command.
|
||||
*/
|
||||
@ -519,10 +519,10 @@ extern "C" {
|
||||
#define SPI_MEM_USR_COMMAND_BITLEN_V 0x0000000FU
|
||||
#define SPI_MEM_USR_COMMAND_BITLEN_S 28
|
||||
|
||||
/** SPI_MEM_MOSI_DLEN_REG register
|
||||
/** SPI_MEM_MOSI_DLEN_REG(i) register
|
||||
* SPI1 send data bit length control register.
|
||||
*/
|
||||
#define SPI_MEM_MOSI_DLEN_REG (DR_REG_SPI_MEM_BASE + 0x24)
|
||||
#define SPI_MEM_MOSI_DLEN_REG(i) (REG_SPI_MEM_BASE(i) + 0x24)
|
||||
/** SPI_MEM_USR_MOSI_DBITLEN : R/W; bitpos: [9:0]; default: 0;
|
||||
* The length in bits of write-data. The register value shall be (bit_num-1).
|
||||
*/
|
||||
@ -531,10 +531,10 @@ extern "C" {
|
||||
#define SPI_MEM_USR_MOSI_DBITLEN_V 0x000003FFU
|
||||
#define SPI_MEM_USR_MOSI_DBITLEN_S 0
|
||||
|
||||
/** SPI_MEM_MISO_DLEN_REG register
|
||||
/** SPI_MEM_MISO_DLEN_REG(i) register
|
||||
* SPI1 receive data bit length control register.
|
||||
*/
|
||||
#define SPI_MEM_MISO_DLEN_REG (DR_REG_SPI_MEM_BASE + 0x28)
|
||||
#define SPI_MEM_MISO_DLEN_REG(i) (REG_SPI_MEM_BASE(i) + 0x28)
|
||||
/** SPI_MEM_USR_MISO_DBITLEN : R/W; bitpos: [9:0]; default: 0;
|
||||
* The length in bits of read-data. The register value shall be (bit_num-1).
|
||||
*/
|
||||
@ -543,10 +543,10 @@ extern "C" {
|
||||
#define SPI_MEM_USR_MISO_DBITLEN_V 0x000003FFU
|
||||
#define SPI_MEM_USR_MISO_DBITLEN_S 0
|
||||
|
||||
/** SPI_MEM_RD_STATUS_REG register
|
||||
/** SPI_MEM_RD_STATUS_REG(i) register
|
||||
* SPI1 status register.
|
||||
*/
|
||||
#define SPI_MEM_RD_STATUS_REG (DR_REG_SPI_MEM_BASE + 0x2c)
|
||||
#define SPI_MEM_RD_STATUS_REG(i) (REG_SPI_MEM_BASE(i) + 0x2c)
|
||||
/** SPI_MEM_STATUS : R/W/SS; bitpos: [15:0]; default: 0;
|
||||
* The value is stored when set spi_mem_flash_rdsr bit and spi_mem_flash_res bit.
|
||||
*/
|
||||
@ -576,10 +576,10 @@ extern "C" {
|
||||
#define SPI_MEM_WB_MODE_EN_V 0x00000001U
|
||||
#define SPI_MEM_WB_MODE_EN_S 27
|
||||
|
||||
/** SPI_MEM_MISC_REG register
|
||||
/** SPI_MEM_MISC_REG(i) register
|
||||
* SPI1 misc register
|
||||
*/
|
||||
#define SPI_MEM_MISC_REG (DR_REG_SPI_MEM_BASE + 0x34)
|
||||
#define SPI_MEM_MISC_REG(i) (REG_SPI_MEM_BASE(i) + 0x34)
|
||||
/** SPI_MEM_CS0_DIS : R/W; bitpos: [0]; default: 0;
|
||||
* SPI_CS0 pin enable, 1: disable SPI_CS0, 0: SPI_CS0 pin is active to select SPI
|
||||
* device, such as flash, external RAM and so on.
|
||||
@ -611,10 +611,10 @@ extern "C" {
|
||||
#define SPI_MEM_CS_KEEP_ACTIVE_V 0x00000001U
|
||||
#define SPI_MEM_CS_KEEP_ACTIVE_S 10
|
||||
|
||||
/** SPI_MEM_TX_CRC_REG register
|
||||
/** SPI_MEM_TX_CRC_REG(i) register
|
||||
* SPI1 TX CRC data register.
|
||||
*/
|
||||
#define SPI_MEM_TX_CRC_REG (DR_REG_SPI_MEM_BASE + 0x38)
|
||||
#define SPI_MEM_TX_CRC_REG(i) (REG_SPI_MEM_BASE(i) + 0x38)
|
||||
/** SPI_MEM_TX_CRC_DATA : RO; bitpos: [31:0]; default: 4294967295;
|
||||
* For SPI1, the value of crc32.
|
||||
*/
|
||||
@ -623,10 +623,10 @@ extern "C" {
|
||||
#define SPI_MEM_TX_CRC_DATA_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_TX_CRC_DATA_S 0
|
||||
|
||||
/** SPI_MEM_CACHE_FCTRL_REG register
|
||||
/** SPI_MEM_CACHE_FCTRL_REG(i) register
|
||||
* SPI1 bit mode control register.
|
||||
*/
|
||||
#define SPI_MEM_CACHE_FCTRL_REG (DR_REG_SPI_MEM_BASE + 0x3c)
|
||||
#define SPI_MEM_CACHE_FCTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x3c)
|
||||
/** SPI_MEM_CACHE_USR_ADDR_4BYTE : R/W; bitpos: [1]; default: 0;
|
||||
* For SPI1, cache read flash with 4 bytes address, 1: enable, 0:disable.
|
||||
*/
|
||||
@ -683,10 +683,10 @@ extern "C" {
|
||||
#define SPI_MEM_FADDR_QUAD_V 0x00000001U
|
||||
#define SPI_MEM_FADDR_QUAD_S 8
|
||||
|
||||
/** SPI_MEM_W0_REG register
|
||||
/** SPI_MEM_W0_REG(i) register
|
||||
* SPI1 memory data buffer0
|
||||
*/
|
||||
#define SPI_MEM_W0_REG (DR_REG_SPI_MEM_BASE + 0x58)
|
||||
#define SPI_MEM_W0_REG(i) (REG_SPI_MEM_BASE(i) + 0x58)
|
||||
/** SPI_MEM_BUF0 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -695,10 +695,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF0_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF0_S 0
|
||||
|
||||
/** SPI_MEM_W1_REG register
|
||||
/** SPI_MEM_W1_REG(i) register
|
||||
* SPI1 memory data buffer1
|
||||
*/
|
||||
#define SPI_MEM_W1_REG (DR_REG_SPI_MEM_BASE + 0x5c)
|
||||
#define SPI_MEM_W1_REG(i) (REG_SPI_MEM_BASE(i) + 0x5c)
|
||||
/** SPI_MEM_BUF1 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -707,10 +707,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF1_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF1_S 0
|
||||
|
||||
/** SPI_MEM_W2_REG register
|
||||
/** SPI_MEM_W2_REG(i) register
|
||||
* SPI1 memory data buffer2
|
||||
*/
|
||||
#define SPI_MEM_W2_REG (DR_REG_SPI_MEM_BASE + 0x60)
|
||||
#define SPI_MEM_W2_REG(i) (REG_SPI_MEM_BASE(i) + 0x60)
|
||||
/** SPI_MEM_BUF2 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -719,10 +719,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF2_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF2_S 0
|
||||
|
||||
/** SPI_MEM_W3_REG register
|
||||
/** SPI_MEM_W3_REG(i) register
|
||||
* SPI1 memory data buffer3
|
||||
*/
|
||||
#define SPI_MEM_W3_REG (DR_REG_SPI_MEM_BASE + 0x64)
|
||||
#define SPI_MEM_W3_REG(i) (REG_SPI_MEM_BASE(i) + 0x64)
|
||||
/** SPI_MEM_BUF3 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -731,10 +731,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF3_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF3_S 0
|
||||
|
||||
/** SPI_MEM_W4_REG register
|
||||
/** SPI_MEM_W4_REG(i) register
|
||||
* SPI1 memory data buffer4
|
||||
*/
|
||||
#define SPI_MEM_W4_REG (DR_REG_SPI_MEM_BASE + 0x68)
|
||||
#define SPI_MEM_W4_REG(i) (REG_SPI_MEM_BASE(i) + 0x68)
|
||||
/** SPI_MEM_BUF4 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -743,10 +743,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF4_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF4_S 0
|
||||
|
||||
/** SPI_MEM_W5_REG register
|
||||
/** SPI_MEM_W5_REG(i) register
|
||||
* SPI1 memory data buffer5
|
||||
*/
|
||||
#define SPI_MEM_W5_REG (DR_REG_SPI_MEM_BASE + 0x6c)
|
||||
#define SPI_MEM_W5_REG(i) (REG_SPI_MEM_BASE(i) + 0x6c)
|
||||
/** SPI_MEM_BUF5 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -755,10 +755,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF5_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF5_S 0
|
||||
|
||||
/** SPI_MEM_W6_REG register
|
||||
/** SPI_MEM_W6_REG(i) register
|
||||
* SPI1 memory data buffer6
|
||||
*/
|
||||
#define SPI_MEM_W6_REG (DR_REG_SPI_MEM_BASE + 0x70)
|
||||
#define SPI_MEM_W6_REG(i) (REG_SPI_MEM_BASE(i) + 0x70)
|
||||
/** SPI_MEM_BUF6 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -767,10 +767,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF6_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF6_S 0
|
||||
|
||||
/** SPI_MEM_W7_REG register
|
||||
/** SPI_MEM_W7_REG(i) register
|
||||
* SPI1 memory data buffer7
|
||||
*/
|
||||
#define SPI_MEM_W7_REG (DR_REG_SPI_MEM_BASE + 0x74)
|
||||
#define SPI_MEM_W7_REG(i) (REG_SPI_MEM_BASE(i) + 0x74)
|
||||
/** SPI_MEM_BUF7 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -779,10 +779,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF7_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF7_S 0
|
||||
|
||||
/** SPI_MEM_W8_REG register
|
||||
/** SPI_MEM_W8_REG(i) register
|
||||
* SPI1 memory data buffer8
|
||||
*/
|
||||
#define SPI_MEM_W8_REG (DR_REG_SPI_MEM_BASE + 0x78)
|
||||
#define SPI_MEM_W8_REG(i) (REG_SPI_MEM_BASE(i) + 0x78)
|
||||
/** SPI_MEM_BUF8 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -791,10 +791,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF8_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF8_S 0
|
||||
|
||||
/** SPI_MEM_W9_REG register
|
||||
/** SPI_MEM_W9_REG(i) register
|
||||
* SPI1 memory data buffer9
|
||||
*/
|
||||
#define SPI_MEM_W9_REG (DR_REG_SPI_MEM_BASE + 0x7c)
|
||||
#define SPI_MEM_W9_REG(i) (REG_SPI_MEM_BASE(i) + 0x7c)
|
||||
/** SPI_MEM_BUF9 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -803,10 +803,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF9_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF9_S 0
|
||||
|
||||
/** SPI_MEM_W10_REG register
|
||||
/** SPI_MEM_W10_REG(i) register
|
||||
* SPI1 memory data buffer10
|
||||
*/
|
||||
#define SPI_MEM_W10_REG (DR_REG_SPI_MEM_BASE + 0x80)
|
||||
#define SPI_MEM_W10_REG(i) (REG_SPI_MEM_BASE(i) + 0x80)
|
||||
/** SPI_MEM_BUF10 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -815,10 +815,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF10_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF10_S 0
|
||||
|
||||
/** SPI_MEM_W11_REG register
|
||||
/** SPI_MEM_W11_REG(i) register
|
||||
* SPI1 memory data buffer11
|
||||
*/
|
||||
#define SPI_MEM_W11_REG (DR_REG_SPI_MEM_BASE + 0x84)
|
||||
#define SPI_MEM_W11_REG(i) (REG_SPI_MEM_BASE(i) + 0x84)
|
||||
/** SPI_MEM_BUF11 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -827,10 +827,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF11_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF11_S 0
|
||||
|
||||
/** SPI_MEM_W12_REG register
|
||||
/** SPI_MEM_W12_REG(i) register
|
||||
* SPI1 memory data buffer12
|
||||
*/
|
||||
#define SPI_MEM_W12_REG (DR_REG_SPI_MEM_BASE + 0x88)
|
||||
#define SPI_MEM_W12_REG(i) (REG_SPI_MEM_BASE(i) + 0x88)
|
||||
/** SPI_MEM_BUF12 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -839,10 +839,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF12_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF12_S 0
|
||||
|
||||
/** SPI_MEM_W13_REG register
|
||||
/** SPI_MEM_W13_REG(i) register
|
||||
* SPI1 memory data buffer13
|
||||
*/
|
||||
#define SPI_MEM_W13_REG (DR_REG_SPI_MEM_BASE + 0x8c)
|
||||
#define SPI_MEM_W13_REG(i) (REG_SPI_MEM_BASE(i) + 0x8c)
|
||||
/** SPI_MEM_BUF13 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -851,10 +851,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF13_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF13_S 0
|
||||
|
||||
/** SPI_MEM_W14_REG register
|
||||
/** SPI_MEM_W14_REG(i) register
|
||||
* SPI1 memory data buffer14
|
||||
*/
|
||||
#define SPI_MEM_W14_REG (DR_REG_SPI_MEM_BASE + 0x90)
|
||||
#define SPI_MEM_W14_REG(i) (REG_SPI_MEM_BASE(i) + 0x90)
|
||||
/** SPI_MEM_BUF14 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -863,10 +863,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF14_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF14_S 0
|
||||
|
||||
/** SPI_MEM_W15_REG register
|
||||
/** SPI_MEM_W15_REG(i) register
|
||||
* SPI1 memory data buffer15
|
||||
*/
|
||||
#define SPI_MEM_W15_REG (DR_REG_SPI_MEM_BASE + 0x94)
|
||||
#define SPI_MEM_W15_REG(i) (REG_SPI_MEM_BASE(i) + 0x94)
|
||||
/** SPI_MEM_BUF15 : R/W/SS; bitpos: [31:0]; default: 0;
|
||||
* data buffer
|
||||
*/
|
||||
@ -875,10 +875,10 @@ extern "C" {
|
||||
#define SPI_MEM_BUF15_V 0xFFFFFFFFU
|
||||
#define SPI_MEM_BUF15_S 0
|
||||
|
||||
/** SPI_MEM_FLASH_WAITI_CTRL_REG register
|
||||
/** SPI_MEM_FLASH_WAITI_CTRL_REG(i) register
|
||||
* SPI1 wait idle control register
|
||||
*/
|
||||
#define SPI_MEM_FLASH_WAITI_CTRL_REG (DR_REG_SPI_MEM_BASE + 0x98)
|
||||
#define SPI_MEM_FLASH_WAITI_CTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x98)
|
||||
/** SPI_MEM_WAITI_EN : R/W; bitpos: [0]; default: 1;
|
||||
* 1: The hardware will wait idle after SE/PP/WRSR automatically, and hardware auto
|
||||
* Suspend/Resume can be enabled. 0: The functions of hardware wait idle and auto
|
||||
@ -934,10 +934,10 @@ extern "C" {
|
||||
#define SPI_MEM_WAITI_CMD_V 0x0000FFFFU
|
||||
#define SPI_MEM_WAITI_CMD_S 16
|
||||
|
||||
/** SPI_MEM_FLASH_SUS_CTRL_REG register
|
||||
/** SPI_MEM_FLASH_SUS_CTRL_REG(i) register
|
||||
* SPI1 flash suspend control register
|
||||
*/
|
||||
#define SPI_MEM_FLASH_SUS_CTRL_REG (DR_REG_SPI_MEM_BASE + 0x9c)
|
||||
#define SPI_MEM_FLASH_SUS_CTRL_REG(i) (REG_SPI_MEM_BASE(i) + 0x9c)
|
||||
/** SPI_MEM_FLASH_PER : R/W/SC; bitpos: [0]; default: 0;
|
||||
* program erase resume bit, program erase suspend operation will be triggered when
|
||||
* the bit is set. The bit will be cleared once the operation done.1: enable 0:
|
||||
@ -1032,10 +1032,10 @@ extern "C" {
|
||||
#define SPI_MEM_SUS_TIMEOUT_CNT_V 0x0000007FU
|
||||
#define SPI_MEM_SUS_TIMEOUT_CNT_S 25
|
||||
|
||||
/** SPI_MEM_FLASH_SUS_CMD_REG register
|
||||
/** SPI_MEM_FLASH_SUS_CMD_REG(i) register
|
||||
* SPI1 flash suspend command register
|
||||
*/
|
||||
#define SPI_MEM_FLASH_SUS_CMD_REG (DR_REG_SPI_MEM_BASE + 0xa0)
|
||||
#define SPI_MEM_FLASH_SUS_CMD_REG(i) (REG_SPI_MEM_BASE(i) + 0xa0)
|
||||
/** SPI_MEM_FLASH_PES_COMMAND : R/W; bitpos: [15:0]; default: 30069;
|
||||
* Program/Erase suspend command.
|
||||
*/
|
||||
@ -1052,10 +1052,10 @@ extern "C" {
|
||||
#define SPI_MEM_WAIT_PESR_COMMAND_V 0x0000FFFFU
|
||||
#define SPI_MEM_WAIT_PESR_COMMAND_S 16
|
||||
|
||||
/** SPI_MEM_SUS_STATUS_REG register
|
||||
/** SPI_MEM_SUS_STATUS_REG(i) register
|
||||
* SPI1 flash suspend status register
|
||||
*/
|
||||
#define SPI_MEM_SUS_STATUS_REG (DR_REG_SPI_MEM_BASE + 0xa4)
|
||||
#define SPI_MEM_SUS_STATUS_REG(i) (REG_SPI_MEM_BASE(i) + 0xa4)
|
||||
/** SPI_MEM_FLASH_SUS : R/W/SS/SC; bitpos: [0]; default: 0;
|
||||
* The status of flash suspend, only used in SPI1.
|
||||
*/
|
||||
@ -1141,10 +1141,10 @@ extern "C" {
|
||||
#define SPI_MEM_FLASH_PER_COMMAND_V 0x0000FFFFU
|
||||
#define SPI_MEM_FLASH_PER_COMMAND_S 16
|
||||
|
||||
/** SPI_MEM_FLASH_WAITI_CTRL1_REG register
|
||||
/** SPI_MEM_FLASH_WAITI_CTRL1_REG(i) register
|
||||
* SPI1 wait idle control register
|
||||
*/
|
||||
#define SPI_MEM_FLASH_WAITI_CTRL1_REG (DR_REG_SPI_MEM_BASE + 0xac)
|
||||
#define SPI_MEM_FLASH_WAITI_CTRL1_REG(i) (REG_SPI_MEM_BASE(i) + 0xac)
|
||||
/** SPI_MEM_WAITI_IDLE_DELAY_TIME : R/W; bitpos: [9:0]; default: 0;
|
||||
* SPI1 wait idle gap time configuration. SPI1 slv fsm will count during SPI1 IDLE.
|
||||
*/
|
||||
@ -1160,10 +1160,10 @@ extern "C" {
|
||||
#define SPI_MEM_WAITI_IDLE_DELAY_TIME_EN_V 0x00000001U
|
||||
#define SPI_MEM_WAITI_IDLE_DELAY_TIME_EN_S 10
|
||||
|
||||
/** SPI_MEM_INT_ENA_REG register
|
||||
/** SPI_MEM_INT_ENA_REG(i) register
|
||||
* SPI1 interrupt enable register
|
||||
*/
|
||||
#define SPI_MEM_INT_ENA_REG (DR_REG_SPI_MEM_BASE + 0xc0)
|
||||
#define SPI_MEM_INT_ENA_REG(i) (REG_SPI_MEM_BASE(i) + 0xc0)
|
||||
/** SPI_MEM_PER_END_INT_ENA : R/W; bitpos: [0]; default: 0;
|
||||
* The enable bit for SPI_MEM_PER_END_INT interrupt.
|
||||
*/
|
||||
@ -1207,10 +1207,10 @@ extern "C" {
|
||||
#define SPI_MEM_BROWN_OUT_INT_ENA_V 0x00000001U
|
||||
#define SPI_MEM_BROWN_OUT_INT_ENA_S 10
|
||||
|
||||
/** SPI_MEM_INT_CLR_REG register
|
||||
/** SPI_MEM_INT_CLR_REG(i) register
|
||||
* SPI1 interrupt clear register
|
||||
*/
|
||||
#define SPI_MEM_INT_CLR_REG (DR_REG_SPI_MEM_BASE + 0xc4)
|
||||
#define SPI_MEM_INT_CLR_REG(i) (REG_SPI_MEM_BASE(i) + 0xc4)
|
||||
/** SPI_MEM_PER_END_INT_CLR : WT; bitpos: [0]; default: 0;
|
||||
* The clear bit for SPI_MEM_PER_END_INT interrupt.
|
||||
*/
|
||||
@ -1254,10 +1254,10 @@ extern "C" {
|
||||
#define SPI_MEM_BROWN_OUT_INT_CLR_V 0x00000001U
|
||||
#define SPI_MEM_BROWN_OUT_INT_CLR_S 10
|
||||
|
||||
/** SPI_MEM_INT_RAW_REG register
|
||||
/** SPI_MEM_INT_RAW_REG(i) register
|
||||
* SPI1 interrupt raw register
|
||||
*/
|
||||
#define SPI_MEM_INT_RAW_REG (DR_REG_SPI_MEM_BASE + 0xc8)
|
||||
#define SPI_MEM_INT_RAW_REG(i) (REG_SPI_MEM_BASE(i) + 0xc8)
|
||||
/** SPI_MEM_PER_END_INT_RAW : R/WTC/SS; bitpos: [0]; default: 0;
|
||||
* The raw bit for SPI_MEM_PER_END_INT interrupt. 1: Triggered when Auto Resume
|
||||
* command (0x7A) is sent and flash is resumed successfully. 0: Others.
|
||||
@ -1310,10 +1310,10 @@ extern "C" {
|
||||
#define SPI_MEM_BROWN_OUT_INT_RAW_V 0x00000001U
|
||||
#define SPI_MEM_BROWN_OUT_INT_RAW_S 10
|
||||
|
||||
/** SPI_MEM_INT_ST_REG register
|
||||
/** SPI_MEM_INT_ST_REG(i) register
|
||||
* SPI1 interrupt status register
|
||||
*/
|
||||
#define SPI_MEM_INT_ST_REG (DR_REG_SPI_MEM_BASE + 0xcc)
|
||||
#define SPI_MEM_INT_ST_REG(i) (REG_SPI_MEM_BASE(i) + 0xcc)
|
||||
/** SPI_MEM_PER_END_INT_ST : RO; bitpos: [0]; default: 0;
|
||||
* The status bit for SPI_MEM_PER_END_INT interrupt.
|
||||
*/
|
||||
@ -1357,10 +1357,10 @@ extern "C" {
|
||||
#define SPI_MEM_BROWN_OUT_INT_ST_V 0x00000001U
|
||||
#define SPI_MEM_BROWN_OUT_INT_ST_S 10
|
||||
|
||||
/** SPI_MEM_DDR_REG register
|
||||
/** SPI_MEM_DDR_REG(i) register
|
||||
* SPI1 DDR control register
|
||||
*/
|
||||
#define SPI_MEM_DDR_REG (DR_REG_SPI_MEM_BASE + 0xd4)
|
||||
#define SPI_MEM_DDR_REG(i) (REG_SPI_MEM_BASE(i) + 0xd4)
|
||||
/** SPI_MEM_FMEM_DDR_EN : R/W; bitpos: [0]; default: 0;
|
||||
* 1: in ddr mode, 0 in sdr mode
|
||||
*/
|
||||
@ -1466,10 +1466,10 @@ extern "C" {
|
||||
#define SPI_MEM_FMEM_HYPERBUS_CA_V 0x00000001U
|
||||
#define SPI_MEM_FMEM_HYPERBUS_CA_S 30
|
||||
|
||||
/** SPI_MEM_TIMING_CALI_REG register
|
||||
/** SPI_MEM_TIMING_CALI_REG(i) register
|
||||
* SPI1 timing control register
|
||||
*/
|
||||
#define SPI_MEM_TIMING_CALI_REG (DR_REG_SPI_MEM_BASE + 0x180)
|
||||
#define SPI_MEM_TIMING_CALI_REG(i) (REG_SPI_MEM_BASE(i) + 0x180)
|
||||
/** SPI_MEM_TIMING_CALI : R/W; bitpos: [1]; default: 0;
|
||||
* The bit is used to enable timing auto-calibration for all reading operations.
|
||||
*/
|
||||
@ -1485,10 +1485,10 @@ extern "C" {
|
||||
#define SPI_MEM_EXTRA_DUMMY_CYCLELEN_V 0x00000007U
|
||||
#define SPI_MEM_EXTRA_DUMMY_CYCLELEN_S 2
|
||||
|
||||
/** SPI_MEM_CLOCK_GATE_REG register
|
||||
/** SPI_MEM_CLOCK_GATE_REG(i) register
|
||||
* SPI1 clk_gate register
|
||||
*/
|
||||
#define SPI_MEM_CLOCK_GATE_REG (DR_REG_SPI_MEM_BASE + 0x200)
|
||||
#define SPI_MEM_CLOCK_GATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x200)
|
||||
/** SPI_MEM_CLK_EN : R/W; bitpos: [0]; default: 1;
|
||||
* Register clock gate enable signal. 1: Enable. 0: Disable.
|
||||
*/
|
||||
@ -1497,10 +1497,10 @@ extern "C" {
|
||||
#define SPI_MEM_CLK_EN_V 0x00000001U
|
||||
#define SPI_MEM_CLK_EN_S 0
|
||||
|
||||
/** SPI_MEM_DATE_REG register
|
||||
/** SPI_MEM_DATE_REG(i) register
|
||||
* Version control register
|
||||
*/
|
||||
#define SPI_MEM_DATE_REG (DR_REG_SPI_MEM_BASE + 0x3fc)
|
||||
#define SPI_MEM_DATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x3fc)
|
||||
/** SPI_MEM_DATE : R/W; bitpos: [27:0]; default: 36774400;
|
||||
* Version control register
|
||||
*/
|
||||
|
@ -23,8 +23,7 @@ typedef union {
|
||||
* can check USB_SERIAL_JTAG_OUT_EP1_WR_ADDR USB_SERIAL_JTAG_OUT_EP0_RD_ADDR to know
|
||||
* how many data is received, then read data from UART Rx FIFO.
|
||||
*/
|
||||
uint32_t rdwr_byte:8;
|
||||
uint32_t reserved_8:24;
|
||||
uint32_t rdwr_byte:32;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_serial_jtag_ep1_reg_t;
|
||||
|
@ -419,6 +419,10 @@ config SOC_CPU_IDRAM_SPLIT_USING_PMP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CPU_PMP_REGION_GRANULARITY
|
||||
int
|
||||
default 4
|
||||
|
||||
config SOC_DS_SIGNATURE_MAX_BIT_LEN
|
||||
int
|
||||
default 3072
|
||||
|
@ -155,6 +155,7 @@
|
||||
|
||||
#define SOC_CPU_HAS_PMA 1
|
||||
#define SOC_CPU_IDRAM_SPLIT_USING_PMP 1
|
||||
#define SOC_CPU_PMP_REGION_GRANULARITY 4
|
||||
|
||||
// TODO: IDF-5360 (Copy from esp32c3, need check)
|
||||
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -23,8 +23,7 @@ typedef union {
|
||||
* can check USB_SERIAL_JTAG_OUT_EP1_WR_ADDR USB_SERIAL_JTAG_OUT_EP0_RD_ADDR to know
|
||||
* how many data is received, then read data from UART Rx FIFO.
|
||||
*/
|
||||
uint32_t rdwr_byte:8;
|
||||
uint32_t reserved_8:24;
|
||||
uint32_t rdwr_byte:32;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_serial_jtag_ep1_reg_t;
|
||||
@ -131,7 +130,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t test_enable:1;
|
||||
/** test_usb_oe : R/W; bitpos: [1]; default: 0;
|
||||
* USB pad oen in test
|
||||
* USB pad output enable in test
|
||||
*/
|
||||
uint32_t test_usb_oe:1;
|
||||
/** test_tx_dp : R/W; bitpos: [2]; default: 0;
|
||||
@ -290,7 +289,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t serial_out_afifo_reset_rd:1;
|
||||
/** serial_out_afifo_rempty : RO; bitpos: [4]; default: 1;
|
||||
* CDC_ACM OUTOUT async FIFO empty signal in read clock domain.
|
||||
* CDC_ACM OUTPUT async FIFO empty signal in read clock domain.
|
||||
*/
|
||||
uint32_t serial_out_afifo_rempty:1;
|
||||
/** serial_in_afifo_wfull : RO; bitpos: [5]; default: 0;
|
||||
|
@ -135,6 +135,10 @@ config SOC_CPU_IDRAM_SPLIT_USING_PMP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CPU_PMP_REGION_GRANULARITY
|
||||
int
|
||||
default 128
|
||||
|
||||
config SOC_DS_SIGNATURE_MAX_BIT_LEN
|
||||
int
|
||||
default 3072
|
||||
|
@ -153,6 +153,8 @@
|
||||
|
||||
#define SOC_CPU_HAS_PMA 1
|
||||
#define SOC_CPU_IDRAM_SPLIT_USING_PMP 1
|
||||
#define SOC_CPU_PMP_REGION_GRANULARITY 128 // TODO IDF-9580 check when doing PMP bringup
|
||||
|
||||
|
||||
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
|
||||
//TODO: [ESP32C61] IDF-9325 (Copy from esp32c6, need check)
|
||||
|
@ -23,8 +23,7 @@ typedef union {
|
||||
* can check USB_SERIAL_JTAG_OUT_EP1_WR_ADDR USB_SERIAL_JTAG_OUT_EP0_RD_ADDR to know
|
||||
* how many data is received, then read data from UART Rx FIFO.
|
||||
*/
|
||||
uint32_t rdwr_byte:8;
|
||||
uint32_t reserved_8:24;
|
||||
uint32_t rdwr_byte:32;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_serial_jtag_ep1_reg_t;
|
||||
@ -131,7 +130,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t test_enable:1;
|
||||
/** test_usb_oe : R/W; bitpos: [1]; default: 0;
|
||||
* USB pad oen in test
|
||||
* USB pad output enable in test
|
||||
*/
|
||||
uint32_t test_usb_oe:1;
|
||||
/** test_tx_dp : R/W; bitpos: [2]; default: 0;
|
||||
@ -290,7 +289,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t serial_out_afifo_reset_rd:1;
|
||||
/** serial_out_afifo_rempty : RO; bitpos: [4]; default: 1;
|
||||
* CDC_ACM OUTOUT async FIFO empty signal in read clock domain.
|
||||
* CDC_ACM OUTPUT async FIFO empty signal in read clock domain.
|
||||
*/
|
||||
uint32_t serial_out_afifo_rempty:1;
|
||||
/** serial_in_afifo_wfull : RO; bitpos: [5]; default: 0;
|
||||
|
@ -407,6 +407,10 @@ config SOC_CPU_IDRAM_SPLIT_USING_PMP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CPU_PMP_REGION_GRANULARITY
|
||||
int
|
||||
default 4
|
||||
|
||||
config SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
bool
|
||||
default y
|
||||
|
@ -152,6 +152,7 @@
|
||||
|
||||
#define SOC_CPU_HAS_PMA 1
|
||||
#define SOC_CPU_IDRAM_SPLIT_USING_PMP 1
|
||||
#define SOC_CPU_PMP_REGION_GRANULARITY 4
|
||||
|
||||
/*-------------------------- MMU CAPS ----------------------------------------*/
|
||||
#define SOC_MMU_PAGE_SIZE_CONFIGURABLE (1)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -23,8 +23,7 @@ typedef union {
|
||||
* can check USB_SERIAL_JTAG_OUT_EP1_WR_ADDR USB_SERIAL_JTAG_OUT_EP0_RD_ADDR to know
|
||||
* how many data is received, then read data from UART Rx FIFO.
|
||||
*/
|
||||
uint32_t rdwr_byte:8;
|
||||
uint32_t reserved_8:24;
|
||||
uint32_t rdwr_byte:32;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_serial_jtag_ep1_reg_t;
|
||||
@ -131,7 +130,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t test_enable:1;
|
||||
/** test_usb_oe : R/W; bitpos: [1]; default: 0;
|
||||
* USB pad oen in test
|
||||
* USB pad output enable in test
|
||||
*/
|
||||
uint32_t test_usb_oe:1;
|
||||
/** test_tx_dp : R/W; bitpos: [2]; default: 0;
|
||||
@ -290,7 +289,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t serial_out_afifo_reset_rd:1;
|
||||
/** serial_out_afifo_rempty : RO; bitpos: [4]; default: 1;
|
||||
* CDC_ACM OUTOUT async FIFO empty signal in read clock domain.
|
||||
* CDC_ACM OUTPUT async FIFO empty signal in read clock domain.
|
||||
*/
|
||||
uint32_t serial_out_afifo_rempty:1;
|
||||
/** serial_in_afifo_wfull : RO; bitpos: [5]; default: 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -23,8 +23,7 @@ typedef union {
|
||||
* USB_DEVICE_OUT_EP1_WR_ADDR USB_DEVICE_OUT_EP0_RD_ADDR to know how many data is
|
||||
* received, then read data from UART Rx FIFO.
|
||||
*/
|
||||
uint32_t rdwr_byte:8;
|
||||
uint32_t reserved_8:24;
|
||||
uint32_t rdwr_byte:32;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_serial_jtag_ep1_reg_t;
|
||||
@ -131,7 +130,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t test_enable:1;
|
||||
/** test_usb_oe : R/W; bitpos: [1]; default: 0;
|
||||
* USB pad oen in test
|
||||
* USB pad output enable in test
|
||||
*/
|
||||
uint32_t test_usb_oe:1;
|
||||
/** test_tx_dp : R/W; bitpos: [2]; default: 0;
|
||||
@ -290,7 +289,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t serial_out_afifo_reset_rd:1;
|
||||
/** serial_out_afifo_rempty : RO; bitpos: [4]; default: 1;
|
||||
* CDC_ACM OUTOUT async FIFO empty signal in read clock domain.
|
||||
* CDC_ACM OUTPUT async FIFO empty signal in read clock domain.
|
||||
*/
|
||||
uint32_t serial_out_afifo_rempty:1;
|
||||
/** serial_in_afifo_wfull : RO; bitpos: [5]; default: 0;
|
||||
|
@ -3,10 +3,6 @@
|
||||
components/ulp/test_apps/lp_core:
|
||||
disable:
|
||||
- if: SOC_LP_CORE_SUPPORTED != 1
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32c5"
|
||||
temporary: true
|
||||
reason: test not pass, should be re-enable # TODO: [ESP32C5] IDF-10336
|
||||
depends_components:
|
||||
- ulp
|
||||
|
||||
|
@ -4,7 +4,7 @@ import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
# @pytest.mark.esp32c5 # TODO: [ESP32C5] IDF-10336
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.generic
|
||||
|
@ -94,7 +94,7 @@ typedef struct {
|
||||
|
||||
struct {
|
||||
TAILQ_HEAD(tailhead_devs, dev_tree_node_s) dev_nodes_tailq; /**< Tailq of attached devices */
|
||||
uint8_t next_uid; /**< Unique ID for next upcoming device */
|
||||
unsigned int next_uid; /**< Unique ID for next upcoming device */
|
||||
} single_thread; /**< Single thread members don't require a critical section so long as they are never accessed from multiple threads */
|
||||
|
||||
struct {
|
||||
|
@ -110,7 +110,7 @@ struct client_s {
|
||||
uint32_t val;
|
||||
} flags;
|
||||
uint32_t num_done_ctrl_xfer;
|
||||
uint32_t opened_dev_addr_map;
|
||||
uint32_t opened_dev_addr_map[4];
|
||||
} dynamic;
|
||||
// Mux protected members must be protected by host library the mux_lock when accessed
|
||||
struct {
|
||||
@ -163,26 +163,25 @@ const char *USB_HOST_TAG = "USB HOST";
|
||||
|
||||
static inline void _record_client_opened_device(client_t *client_obj, uint8_t dev_addr)
|
||||
{
|
||||
assert(dev_addr != 0);
|
||||
client_obj->dynamic.opened_dev_addr_map |= (1 << (dev_addr - 1));
|
||||
assert(dev_addr != 0 && dev_addr <= 127);
|
||||
client_obj->dynamic.opened_dev_addr_map[dev_addr / 32] |= (uint32_t)(1 << (dev_addr % 32));
|
||||
}
|
||||
|
||||
static inline void _clear_client_opened_device(client_t *client_obj, uint8_t dev_addr)
|
||||
{
|
||||
assert(dev_addr != 0);
|
||||
client_obj->dynamic.opened_dev_addr_map &= ~(1 << (dev_addr - 1));
|
||||
assert(dev_addr != 0 && dev_addr <= 127);
|
||||
client_obj->dynamic.opened_dev_addr_map[dev_addr / 32] &= ~(uint32_t)(1 << (dev_addr % 32));
|
||||
}
|
||||
|
||||
static inline bool _check_client_opened_device(client_t *client_obj, uint8_t dev_addr)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
assert(dev_addr <= 127);
|
||||
if (dev_addr != 0) {
|
||||
ret = client_obj->dynamic.opened_dev_addr_map & (1 << (dev_addr - 1));
|
||||
ret = client_obj->dynamic.opened_dev_addr_map[dev_addr / 32] & (uint32_t)(1 << (dev_addr % 32));
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -820,7 +819,10 @@ esp_err_t usb_host_client_deregister(usb_host_client_handle_t client_hdl)
|
||||
client_obj->dynamic.flags.taking_mux ||
|
||||
client_obj->dynamic.flags.num_intf_claimed != 0 ||
|
||||
client_obj->dynamic.num_done_ctrl_xfer != 0 ||
|
||||
client_obj->dynamic.opened_dev_addr_map != 0) {
|
||||
client_obj->dynamic.opened_dev_addr_map[0] != 0 ||
|
||||
client_obj->dynamic.opened_dev_addr_map[1] != 0 ||
|
||||
client_obj->dynamic.opened_dev_addr_map[2] != 0 ||
|
||||
client_obj->dynamic.opened_dev_addr_map[3] != 0) {
|
||||
can_deregister = false;
|
||||
} else {
|
||||
can_deregister = true;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "esp_owe_i.h"
|
||||
|
||||
#include "esp_wps.h"
|
||||
#include "esp_wps_i.h"
|
||||
#include "eap_server/eap.h"
|
||||
#include "eapol_auth/eapol_auth_sm.h"
|
||||
#include "ap/ieee802_1x.h"
|
||||
@ -303,6 +304,11 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
struct wps_sm_funcs *wps_sm_cb = wps_get_wps_sm_cb();
|
||||
if (wps_sm_cb && wps_sm_cb->wps_sm_notify_deauth) {
|
||||
wps_sm_cb->wps_sm_notify_deauth();
|
||||
}
|
||||
#ifdef CONFIG_OWE_STA
|
||||
owe_deinit();
|
||||
#endif /* CONFIG_OWE_STA */
|
||||
|
@ -45,6 +45,7 @@ struct wps_rx_param {
|
||||
};
|
||||
static STAILQ_HEAD(, wps_rx_param) s_wps_rxq;
|
||||
|
||||
static struct wps_sm_funcs *s_wps_sm_cb = NULL;
|
||||
static void *s_wps_task_hdl = NULL;
|
||||
static void *s_wps_queue = NULL;
|
||||
static void *s_wps_data_lock = NULL;
|
||||
@ -839,6 +840,13 @@ int wps_finish(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wps_sm_notify_deauth(void)
|
||||
{
|
||||
if (gWpsSm && gWpsSm->wps->state != WPS_FINISHED) {
|
||||
wps_stop_process(WPS_FAIL_REASON_RECV_DEAUTH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add current ap to discard ap list */
|
||||
void wps_add_discard_ap(u8 *bssid)
|
||||
{
|
||||
@ -1385,6 +1393,11 @@ int wps_init_cfg_pin(struct wps_config *cfg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct wps_sm_funcs* wps_get_wps_sm_cb(void)
|
||||
{
|
||||
return s_wps_sm_cb;
|
||||
}
|
||||
|
||||
static int wifi_station_wps_init(const esp_wps_config_t *config)
|
||||
{
|
||||
struct wps_funcs *wps_cb;
|
||||
@ -1466,6 +1479,12 @@ static int wifi_station_wps_init(const esp_wps_config_t *config)
|
||||
wps_cb->wps_start_pending = wps_start_pending;
|
||||
esp_wifi_set_wps_cb_internal(wps_cb);
|
||||
|
||||
s_wps_sm_cb = os_malloc(sizeof(struct wps_sm_funcs));
|
||||
if (s_wps_sm_cb == NULL) {
|
||||
goto _err;
|
||||
}
|
||||
s_wps_sm_cb->wps_sm_notify_deauth = wps_sm_notify_deauth;
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
_err:
|
||||
@ -1539,6 +1558,10 @@ wifi_station_wps_deinit(void)
|
||||
wps_deinit(sm->wps);
|
||||
sm->wps = NULL;
|
||||
}
|
||||
if (s_wps_sm_cb) {
|
||||
os_free(s_wps_sm_cb);
|
||||
s_wps_sm_cb = NULL;
|
||||
}
|
||||
os_free(gWpsSm);
|
||||
gWpsSm = NULL;
|
||||
|
||||
|
@ -118,6 +118,11 @@ int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
|
||||
int wps_dev_deinit(struct wps_device_data *dev);
|
||||
int wps_dev_init(void);
|
||||
int wps_set_factory_info(const esp_wps_config_t *config);
|
||||
struct wps_sm_funcs {
|
||||
void (*wps_sm_notify_deauth)(void);
|
||||
};
|
||||
|
||||
struct wps_sm_funcs* wps_get_wps_sm_cb(void);
|
||||
|
||||
static inline int wps_get_type(void)
|
||||
{
|
||||
|
BIN
docs/_static/itwt_10s_current.png
vendored
Normal file
BIN
docs/_static/itwt_10s_current.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
BIN
docs/_static/itwt_30s_current.png
vendored
Normal file
BIN
docs/_static/itwt_30s_current.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
BIN
docs/_static/itwt_setup.png
vendored
Normal file
BIN
docs/_static/itwt_setup.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
docs/_static/itwt_suspend.png
vendored
Normal file
BIN
docs/_static/itwt_suspend.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
BIN
docs/_static/itwt_teardown.png
vendored
Normal file
BIN
docs/_static/itwt_teardown.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
@ -1,6 +1,8 @@
|
||||
Analog Comparator
|
||||
=================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
{IDF_TARGET_ANA_CMPR_SRC_CHAN0: default="NOT UPDATED", esp32h2="GPIO11", esp32p4="GPIO52"}
|
||||
{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN0: default="NOT UPDATED", esp32h2="GPIO10", esp32p4="GPIO51"}
|
||||
{IDF_TARGET_ANA_CMPR_SRC_CHAN1: default="NOT UPDATED", esp32p4="GPIO54"}
|
||||
@ -9,17 +11,17 @@ Analog Comparator
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Analog Comparator is a peripheral that can be used to compare a source signal with the internal reference voltage or an external reference signal.
|
||||
Analog comparator is a peripheral that can be used to compare a source signal with the internal reference voltage or an external reference signal.
|
||||
|
||||
It is a cost effective way to replace an amplifier comparator in some scenarios. But unlike the continuous comparing of the amplifier comparator, ESP Analog Comparator is driven by a source clock, which decides the sampling frequency.
|
||||
Under the scenario of comparing the analog signals, the integrated analog comparator is a cost effective scheme to replace an operational amplifier. But unlike the continuous comparing of the operational amplifier, ESP analog comparator is driven by a source clock, which decides the sampling frequency.
|
||||
|
||||
Analog Comparator on {IDF_TARGET_NAME} has {IDF_TARGET_SOC_ANA_CMPR_NUM} unit(s), the channels in the unit(s) are:
|
||||
Analog comparator on {IDF_TARGET_NAME} has {IDF_TARGET_SOC_ANA_CMPR_NUM} unit(s), the channels in the unit(s) are:
|
||||
|
||||
**UNIT0**
|
||||
|
||||
- Source Channel: {IDF_TARGET_ANA_CMPR_SRC_CHAN0}
|
||||
- External Reference Channel: {IDF_TARGET_ANA_CMPR_EXT_REF_CHAN0}
|
||||
- Internal Reference Channel: Range 0% ~ 70% of the VDD, the step is 10% of the VDD
|
||||
- Internal Reference Channel: Range is 0% ~ 70% of the VDD, and the step is 10% of the VDD
|
||||
|
||||
.. only:: esp32p4
|
||||
|
||||
@ -32,33 +34,35 @@ Analog Comparator on {IDF_TARGET_NAME} has {IDF_TARGET_SOC_ANA_CMPR_NUM} unit(s)
|
||||
Functional Overview
|
||||
-------------------
|
||||
|
||||
The following sections of this document cover the typical steps to install and operate an Analog Comparator unit:
|
||||
The following sections of this document cover the typical steps to install and operate an analog comparator unit:
|
||||
|
||||
- `Resource Allocation <#resource-allocation>`__ - covers which parameters should be set up to get a unit handle and how to recycle the resources when it finishes working.
|
||||
- `Further Configurations <#further-configurations>`__ - covers the other configurations that might need to specific and what they are used for.
|
||||
- `Enable and Disable Unit <#enable-and-disable-unit>`__ - covers how to enable and disable the unit.
|
||||
- `Power Management <#power-management>`__ - describes how different source clock selections can affect power consumption.
|
||||
- `IRAM Safe <#iram-safe>`__ - lists which functions are supposed to work even when the cache is disabled.
|
||||
- `Thread Safety <#thread-safety>`__ - lists which APIs are guaranteed to be thread safe by the driver.
|
||||
- `Kconfig Options <#kconfig-options>`__ - lists the supported Kconfig options that can be used to make a different effect on driver behavior.
|
||||
- :ref:`anacmpr-resource-allocation` - covers which parameters should be set up to get a unit handle and how to recycle the resources when it finishes working.
|
||||
- :ref:`anacmpr-further-configurations` - covers the other configurations that might need to specify and what they are used for.
|
||||
- :ref:`anacmpr-enable-and-disable-unit` - covers how to enable and disable the unit.
|
||||
- :ref:`anacmpr-power-management` - describes how different source clock selections can affect power consumption.
|
||||
- :ref:`anacmpr-iram-safe` - lists which functions are supposed to work even when the cache is disabled.
|
||||
- :ref:`anacmpr-thread-safety` - lists which APIs are guaranteed to be thread safe by the driver.
|
||||
- :ref:`anacmpr-kconfig-options` - lists the supported Kconfig options that can be used to make a different effect on driver behavior.
|
||||
|
||||
.. only:: SOC_ANA_CMPR_SUPPORT_ETM
|
||||
|
||||
- `ETM Events <#etm-events>`__ -
|
||||
- :ref:`anacmpr-etm-events` - covers how to create an analog comparator cross event.
|
||||
|
||||
.. _anacmpr-resource-allocation:
|
||||
|
||||
Resource Allocation
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
An Analog Comparator unit channel is represented by :cpp:type:`ana_cmpr_handle_t`. Each unit can support either an internal or an external reference.
|
||||
An analog comparator unit channel is represented by :cpp:type:`ana_cmpr_handle_t`. Each unit can support either an internal or an external reference.
|
||||
|
||||
To allocate the resource of the Analog Comparator unit, :cpp:func:`ana_cmpr_new_unit` need to be called to get the handle of the unit. Configurations :cpp:type:`ana_cmpr_config_t` need to be specified while allocating the unit:
|
||||
To allocate the resource of the analog comparator unit, :cpp:func:`ana_cmpr_new_unit` need to be called to get the handle of the unit. Configurations :cpp:type:`ana_cmpr_config_t` need to be specified while allocating the unit:
|
||||
|
||||
- :cpp:member:`ana_cmpr_config_t::unit` selects the Analog Comparator unit.
|
||||
- :cpp:member:`ana_cmpr_config_t::clk_src` selects the source clock for Analog Comparator, it can affect the sampling frequency. Note that the clock source of the Analog Comparator comes from the io mux, it is shared with GPIO extension peripherals like SDM (Sigma-Delta Modulation) and Glitch Filter. The configuration will fail if you specific different clock sources for multiple GPIO extension peripherals. The default clock sources of these peripherals are same, typically, we select :cpp:enumerator:`soc_periph_ana_cmpr_clk_src_t::ANA_CMPR_CLK_SRC_DEFAULT` as the clock source.
|
||||
- :cpp:member:`ana_cmpr_config_t::unit` selects the analog comparator unit.
|
||||
- :cpp:member:`ana_cmpr_config_t::clk_src` selects the source clock for analog comparator, and it can affect the sampling frequency. Note that the clock source of the analog comparator comes from the IO MUX. It is shared with GPIO extension peripherals like SDM (Sigma-Delta Modulation) and Glitch Filter. The configuration will fail if you specify different clock sources for multiple GPIO extension peripherals. The default clock sources of these peripherals are same, and typically, we select :cpp:enumerator:`soc_periph_ana_cmpr_clk_src_t::ANA_CMPR_CLK_SRC_DEFAULT` as the clock source.
|
||||
- :cpp:member:`ana_cmpr_config_t::ref_src` selects the reference source from internal voltage or external signal.
|
||||
- :cpp:member:`ana_cmpr_config_t::cross_type` selects which kind of cross type can trigger the interrupt.
|
||||
|
||||
The function :cpp:func:`ana_cmpr_new_unit` can fail due to various errors such as insufficient memory, invalid arguments, etc. If a previously created Analog Comparator unit is no longer required, you should recycle it by calling :cpp:func:`ana_cmpr_del_unit`. It allows the underlying HW channel to be used for other purposes. Before deleting an Analog Comparator unit handle, you should disable it by :cpp:func:`ana_cmpr_unit_disable` in advance, or make sure it has not enabled yet by :cpp:func:`ana_cmpr_unit_enable`.
|
||||
The function :cpp:func:`ana_cmpr_new_unit` can fail due to various errors such as insufficient memory, invalid arguments, etc. If a previously created analog comparator unit is no longer required, you should recycle it by calling :cpp:func:`ana_cmpr_del_unit`. It allows the underlying HW channel to be used for other purposes. Before deleting an analog comparator unit handle, you should disable it by :cpp:func:`ana_cmpr_disable` in advance, or make sure it has not enabled yet by :cpp:func:`ana_cmpr_enable`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@ -75,12 +79,14 @@ The function :cpp:func:`ana_cmpr_new_unit` can fail due to various errors such a
|
||||
// ...
|
||||
ESP_ERROR_CHECK(ana_cmpr_del_unit(cmpr));
|
||||
|
||||
.. _anacmpr-further-configurations:
|
||||
|
||||
Further Configurations
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_intl_reference` - Specify the internal reference voltage when :cpp:enumerator:`ana_cmpr_ref_source_t::ANA_CMPR_REF_SRC_INTERNAL` is selected as reference source.
|
||||
- :cpp:func:`ana_cmpr_set_internal_reference` - Specify the internal reference voltage when :cpp:enumerator:`ana_cmpr_ref_source_t::ANA_CMPR_REF_SRC_INTERNAL` is selected as reference source.
|
||||
|
||||
It requires :cpp:member:`ana_cmpr_internal_ref_config_t::ref_volt` to specify the voltage. The voltage related to the VDD power supply, which can only support a certain fixed percentage of VDD. Currently on {IDF_TARGET_NAME}, the internal reference voltage can be range to 0 ~ 70% VDD with a step 10%.
|
||||
It requires :cpp:member:`ana_cmpr_internal_ref_config_t::ref_volt` to specify the voltage. The voltage is related to the VDD power supply, which can only support a certain fixed percentage of VDD. Currently on {IDF_TARGET_NAME}, the internal reference voltage can be range to 0 ~ 70% VDD with a step 10%.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@ -93,7 +99,7 @@ It requires :cpp:member:`ana_cmpr_internal_ref_config_t::ref_volt` to specify th
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_debounce` - Set the debounce configuration.
|
||||
|
||||
It requires :cpp:member:`ana_cmpr_debounce_config_t::wait_us` to set the interrupt waiting time. The interrupt is disabled temporarily for :cpp:member:`ana_cmpr_debounce_config_t::wait_us` micro seconds, so that the frequent triggering can be avoid while the source signal crossing the reference signal. That is, the waiting time is supposed to be inverse ratio to the relative frequency between the source and reference. If the waiting time is set too short, it can not bypass the jitter totally, but if too long, the next crossing interrupt might be missed.
|
||||
It requires :cpp:member:`ana_cmpr_debounce_config_t::wait_us` to set the interrupt waiting time. The interrupt is disabled temporarily for :cpp:member:`ana_cmpr_debounce_config_t::wait_us` microseconds, so that the frequent triggering can be avoid while the source signal is crossing the reference signal. That is, the waiting time is supposed to be inverse ratio to the relative frequency between the source and reference. If the waiting time is set too short, it can not bypass the jitter totally, but if too long, the next crossing interrupt might be missed.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@ -106,7 +112,7 @@ It requires :cpp:member:`ana_cmpr_debounce_config_t::wait_us` to set the interru
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_cross_type` - Set the source signal cross type.
|
||||
|
||||
The initial cross type is set int :cpp:func:`ana_cmpr_new_unit`, this function can update the cross type, even in ISR context.
|
||||
The initial cross type is set in :cpp:func:`ana_cmpr_new_unit`. This function can update the cross type, even in ISR context.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@ -116,7 +122,7 @@ The initial cross type is set int :cpp:func:`ana_cmpr_new_unit`, this function c
|
||||
|
||||
- :cpp:func:`ana_cmpr_register_event_callbacks` - Register the callbacks.
|
||||
|
||||
Currently it supports :cpp:member:`ana_cmpr_event_callbacks_t::on_cross`, it will be called when the crossing event (specified by :cpp:member:`ana_cmpr_config_t::cross_type`) occurs.
|
||||
Currently it supports :cpp:member:`ana_cmpr_event_callbacks_t::on_cross`, and it will be called when the crossing event (specified by :cpp:member:`ana_cmpr_config_t::cross_type`) occurs.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@ -136,35 +142,41 @@ Currently it supports :cpp:member:`ana_cmpr_event_callbacks_t::on_cross`, it wil
|
||||
|
||||
.. note::
|
||||
|
||||
When :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` is enabled, you should guarantee the callback context and involved data to be in internal RAM by add the attribute ``IRAM_ATTR``. (See more in `IRAM Safe <#iram-safe>`__)
|
||||
When :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` is enabled, you should guarantee that the callback context and involved data are in internal RAM by adding the attribute ``IRAM_ATTR`` (See more in :ref:`anacmpr-iram-safe`).
|
||||
|
||||
.. _anacmpr-enable-and-disable-unit:
|
||||
|
||||
Enable and Disable Unit
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- :cpp:func:`ana_cmpr_enable` - Enable the Analog Comparator unit.
|
||||
- :cpp:func:`ana_cmpr_disable` - Disable the Analog Comparator unit.
|
||||
- :cpp:func:`ana_cmpr_enable` - Enable the analog comparator unit.
|
||||
- :cpp:func:`ana_cmpr_disable` - Disable the analog comparator unit.
|
||||
|
||||
After the Analog Comparator unit is enabled and the crossing event interrupt is enabled, a power management lock will be acquired if the power management is enabled (see `Power Management <#power-management>`__). Under the **enable** state, only :cpp:func:`ana_cmpr_set_intl_reference` and :cpp:func:`ana_cmpr_set_debounce` can be called, other functions can only be called after the unit is disabled.
|
||||
After the analog comparator unit is enabled and the crossing event interrupt is enabled, a power management lock will be acquired if the power management is enabled (see :ref:`anacmpr-power-management`). Under the **enable** state, only :cpp:func:`ana_cmpr_set_internal_reference` and :cpp:func:`ana_cmpr_set_debounce` can be called, other functions can only be called after the unit is disabled.
|
||||
|
||||
Calling :cpp:func:`ana_cmpr_disable` does the opposite.
|
||||
|
||||
.. _anacmpr-power-management:
|
||||
|
||||
Power Management
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
When power management is enabled (i.e., :ref:`CONFIG_PM_ENABLE` is on), the system will adjust the APB frequency before going into light sleep, thus potentially changing the resolution of the Analog Comparator.
|
||||
When power management is enabled (i.e., :ref:`CONFIG_PM_ENABLE` is on), the system will adjust the APB frequency before going into Light-sleep mode, thus potentially changing the resolution of the analog comparator.
|
||||
|
||||
However, the driver can prevent the system from changing APB frequency by acquiring a power management lock of type :cpp:enumerator:`ESP_PM_NO_LIGHT_SLEEP`. Whenever the driver creates a Analog Comparator unit instance that has selected the clock source like :cpp:enumerator:`ANA_CMPR_CLK_SRC_DEFAULT` or :cpp:enumerator:`ANA_CMPR_CLK_SRC_XTAL` as its clock source, the driver guarantees that the power management lock is acquired when enable the channel by :cpp:func:`ana_cmpr_enable`. Likewise, the driver releases the lock when :cpp:func:`ana_cmpr_disable` is called for that channel.
|
||||
However, the driver can prevent the system from changing APB frequency by acquiring a power management lock of type :cpp:enumerator:`ESP_PM_NO_LIGHT_SLEEP`. Whenever the driver creates an analog comparator unit instance that has selected the clock source like :cpp:enumerator:`ANA_CMPR_CLK_SRC_DEFAULT` or :cpp:enumerator:`ANA_CMPR_CLK_SRC_XTAL`, the driver guarantees that the power management lock is acquired when enable the channel by :cpp:func:`ana_cmpr_enable`. Likewise, the driver releases the lock when :cpp:func:`ana_cmpr_disable` is called for that channel.
|
||||
|
||||
.. _anacmpr-iram-safe:
|
||||
|
||||
IRAM Safe
|
||||
^^^^^^^^^
|
||||
|
||||
By default, the Analog Comparator interrupt will be deferred when the Cache is disabled for reasons like programming/erasing Flash. Thus the alarm interrupt will not get executed in time, which is not expected in a real-time application.
|
||||
By default, the analog comparator interrupt will be deferred when the cache is disabled for reasons like programming or erasing the flash. Thus the alarm interrupt will not get executed in time, which is not expected in a real-time application.
|
||||
|
||||
There is a Kconfig option :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` that:
|
||||
|
||||
1. Enables the interrupt being serviced even when cache is disabled
|
||||
2. Places all functions that used by the ISR into IRAM [1]_
|
||||
3. Places driver object into DRAM (in case it is allocated on PSRAM)
|
||||
1. Enables the interrupt being serviced even when cache is disabled.
|
||||
2. Places all functions that used by the ISR into IRAM. [1]_
|
||||
3. Places driver object into DRAM (in case it is allocated on PSRAM).
|
||||
|
||||
This allows the interrupt to run while the cache is disabled but comes at the cost of increased IRAM consumption.
|
||||
|
||||
@ -174,27 +186,34 @@ There is a Kconfig option :ref:`CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM` that can put
|
||||
- :cpp:func:`ana_cmpr_set_debounce`
|
||||
- :cpp:func:`ana_cmpr_set_cross_type`
|
||||
|
||||
.. _anacmpr-thread-safety:
|
||||
|
||||
Thread Safety
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The factory function :cpp:func:`ana_cmpr_new_unit` is guaranteed to be thread safe by the driver, which means, user can call it from different RTOS tasks without protection by extra locks.
|
||||
The following functions are allowed to run under ISR context, the driver uses a critical section to prevent them being called concurrently in both task and ISR.
|
||||
The factory function :cpp:func:`ana_cmpr_new_unit` is guaranteed to be thread safe by the driver, which means, it can be called from different RTOS tasks without protection by extra locks.
|
||||
|
||||
The following functions are allowed to run under ISR context. The driver uses a critical section to prevent them being called concurrently in both task and ISR:
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_internal_reference`
|
||||
- :cpp:func:`ana_cmpr_set_debounce`
|
||||
- :cpp:func:`ana_cmpr_set_cross_type`
|
||||
|
||||
Other functions that take the :cpp:type:`ana_cmpr_handle_t` as the first positional parameter, are not treated as thread safe. Which means the user should avoid calling them from multiple tasks.
|
||||
Other functions that take :cpp:type:`ana_cmpr_handle_t` as the first positional parameter, are not treated as thread safe. As a result, users should avoid calling them from multiple tasks.
|
||||
|
||||
.. _anacmpr-kconfig-options:
|
||||
|
||||
Kconfig Options
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
- :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` controls whether the default ISR handler can work when cache is disabled, see `IRAM Safe <#iram-safe>`__ for more information.
|
||||
- :ref:`CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM` controls where to place the Analog Comparator control functions (IRAM or Flash), see `IRAM Safe <#iram-safe>`__ for more information.
|
||||
- :ref:`CONFIG_ANA_CMPR_ENABLE_DEBUG_LOG` is used to enabled the debug log output. Enabling this option increases the firmware binary size.
|
||||
- :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` controls whether the default ISR handler can work when cache is disabled. See :ref:`anacmpr-iram-safe` for more information.
|
||||
- :ref:`CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM` controls where to place the analog comparator control functions (IRAM or flash). See :ref:`anacmpr-iram-safe` for more information.
|
||||
- :ref:`CONFIG_ANA_CMPR_ENABLE_DEBUG_LOG` is used to enable the debug log output. Enabling this option increases the firmware binary size.
|
||||
|
||||
.. only:: SOC_ANA_CMPR_SUPPORT_ETM
|
||||
|
||||
.. _anacmpr-etm-events:
|
||||
|
||||
ETM Events
|
||||
^^^^^^^^^^
|
||||
|
||||
@ -212,4 +231,4 @@ API Reference
|
||||
.. include-build-file:: inc/ana_cmpr_types.inc
|
||||
|
||||
.. [1]
|
||||
:cpp:member:`ana_cmpr_event_callbacks_t::on_cross` callback and the functions invoked by itself should also be placed in IRAM, you need to take care of them by themselves.
|
||||
:cpp:member:`ana_cmpr_event_callbacks_t::on_cross` callback and the functions invoked by it should also be placed in IRAM. Please take care of them.
|
||||
|
@ -743,3 +743,293 @@ Deep-sleep 有如下可配置选项:
|
||||
.. only:: esp32c2
|
||||
|
||||
平均电流约 4.9 μA
|
||||
|
||||
.. only:: esp32c6
|
||||
|
||||
目标唤醒时间 (TWT)
|
||||
----------------------------------
|
||||
|
||||
目标唤醒时间 (Target Wake Time, TWT) 是 Wi-Fi 6 中引入的一项特性,旨在降低设备功耗和提高网络效率。
|
||||
|
||||
在以往的 Wi-Fi 节能机制中,设备可能需要在每个 DTIM 周期醒来与 AP 交换数据,而在 TWT 机制中支持 AP 和设备协商得到特定的唤醒时间,设备会在这些时间点醒来与 AP 进行数据交换,而其余时间则处于休眠状态。TWT 协商的唤醒和休眠时间取决于设备具体的应用需求。例如,有些传感器设备需要定时上传数据,在该场景下设备可以与 AP 建立 TWT 协商,相隔多个小时交换一次数据。实际应用中可根据具体需求定制唤醒时间,在不影响设备正常工作的情况下降低功耗。
|
||||
|
||||
AP 可以与多个设备建立 TWT 协商。利用 Wi-Fi 6 的多用户特性,AP 可以对上行和下行数据传输做出合理协调,从而减少信道竞争,提高传输效率。
|
||||
|
||||
TWT 类型
|
||||
++++++++++
|
||||
|
||||
根据协商类型和工作模式,可以把 TWT 分为:
|
||||
|
||||
- **Individual TWT (iTWT)**
|
||||
|
||||
iTWT 模式下,AP 与终端设备建立的是一对一的 TWT 协商。
|
||||
|
||||
- **Broadcast TWT (bTWT)**
|
||||
|
||||
在 bTWT 模式下,AP 通过 Beacon 帧广播 TWT 信息,以组的形式来管理多个终端设备的 TWT 过程。终端设备可以根据 Beacon 中的 TWT 信息选择执行加组操作。
|
||||
|
||||
.. note::
|
||||
在建立 TWT 协商前,需要确认 AP 是否支持并开启了 TWT 功能。{IDF_TARGET_NAME} 当前只支持 iTWT 模式。
|
||||
|
||||
TWT 工作流程
|
||||
++++++++++++
|
||||
TWT 工作流程一般分为 TWT 协商建立、TWT 协商暂停/恢复、TWT 协商终止。TWT 协商建立后,Station 就可以按照协商的参数进入休眠状态,直到约定好的下一个 TWT 时间点到来时苏醒。
|
||||
对已经建立的 TWT,用户可以根据需求协商暂停/恢复 TWT 或者终止 TWT。
|
||||
|
||||
- TWT 协商建立
|
||||
|
||||
- Individual TWT 协商建立
|
||||
|
||||
在 iTWT 协商建立过程中,通常由 Station 充当请求发起方发送 TWT 请求,而后 AP 作为接收方对该请求做出回应。AP 也可以主动向 Station 发起 TWT 协商建立过程。
|
||||
在成功建立起 iTWT 协商后,Station 可以进入休眠状态,直到约定好的下一个 TWT 时间点到来时苏醒,该时间点通过和 AP 间的协商得到。Station 醒来后和 AP 进行数据交换,这段时间被称为 TWT 服务时间 (Service Period, SP)。
|
||||
TWT SP 的持续时间被称为 TWT Wake Duration,其最小值为 256 微秒。当一次 TWT SP 结束后,Station 进入休眠状态直到下次 TWT SP 醒来进行数据传输。本次 TWT SP 的起始到下次 TWT SP 的起始的时间间隔被称为 TWT Wake Interval。下图为基本的 iTWT 示例:
|
||||
|
||||
.. figure:: ../../_static/itwt_setup.png
|
||||
:align: center
|
||||
|
||||
Individual TWT 协商建立过程示例
|
||||
|
||||
Station 在 iTWT 协商建立时可以发送不同类型的请求,AP 会根据请求类型及参数做出对应的回复。用户需要根据 AP 回复中的类型和具体参数决定后续的操作逻辑。Station 所发送的请求类型有 ``Request``、``Suggest`` 和 ``Demand``。
|
||||
AP 的回复类型可分为 ``Accept``、``Alternate`` 和 ``Dictate``。下表描述了发送不同请求时 AP 可能的回复以及不同情况下对应的含义:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 20 10 40
|
||||
|
||||
* - 请求类型
|
||||
- AP 回复
|
||||
- 含义
|
||||
* - Request, Suggest or Demand
|
||||
- No response
|
||||
- 在该情况下 AP 不会与 Station 建立 iTWT 协商。
|
||||
* - Suggest or Request
|
||||
- Accept
|
||||
- AP 同意建立 iTWT 协商,其使用的参数以回复中 TWT 参数为准。回复中的 TWT 参数有可能与请求中不一致。
|
||||
* - Demand
|
||||
- Accept
|
||||
- AP 同意建立 iTWT 协商,且回复中的 TWT 参数与请求中的一致。
|
||||
* - Demand or Suggest
|
||||
- Alternate
|
||||
- AP 使用该回复类型代表给 Station提供一组备选 TWT 参数,此时不会建立 iTWT 协商。后续 Station 可以发送新的请求,但 AP 仍有可能使用该组参数。
|
||||
* - Demand or Suggest
|
||||
- Dictate
|
||||
- AP 使用该回复类型代表给 Station 提供一组备选 TWT 参数,此时不会建立 iTWT 协商,同时也表明 AP 不接受除该组参数以外的其他参数。后续 Station 可以发送新的请求,但只有参数与所提供的备选参数一致才会收到 Accept 回复。
|
||||
* - Request, Suggest or Demand
|
||||
- Reject
|
||||
- 在该情况下 AP 不会与 station 建立 iTWT 协商。后续 Station 可以更改 TWT 参数发送新的请求。
|
||||
|
||||
在 TWT SP 中依照数据交互时的操作可以将 TWT 进一步地细分为多种类型,下表描述了这些类型间的差异:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 10 20
|
||||
|
||||
* - Types
|
||||
- 含义
|
||||
* - Trigger-enabled
|
||||
- AP 会在 SP 中使用 Trigger 帧来协调 Station 的数据传输。
|
||||
* - Non trigger-enabled
|
||||
- 在 SP 中不需要使用 Trigger 帧。
|
||||
* - Announced
|
||||
- Station 会发送 QoS Null 帧告知 AP 其唤醒状态。
|
||||
* - Unannounced
|
||||
- 不需要发送 QoS Null 帧。
|
||||
|
||||
- Broadcast TWT 协商建立
|
||||
|
||||
与 iTWT 不同的是,在 bTWT 模式下 AP 将 TWT 信息放在 Beacon 帧中进行广播宣告。Station 接收到 Beacon 后,可以向 AP 发送请求申请选择加入某个 TWT。
|
||||
当建立起 bTWT 协商后, Station 和 AP 会在协商好的 TWT SP 中进行数据传输。
|
||||
|
||||
与 iTWT 类似,可以把 bTWT 进一步分成 Trigger-enabled 和 Non trigger-enabled 类型,以及 Announced 和 Unannounced 类型,具体的行为差异可以参考 iTWT 中的描述。
|
||||
|
||||
- TWT 协商暂停/恢复
|
||||
|
||||
建立起 TWT 协商后, Station 可以通过向 AP 发送 TWT Information 帧暂停或者恢复指定的 TWT 协商。由 flow_id 来标识需要暂停或者恢复的 TWT 协商,具体可以参考 TWT 参数配置。
|
||||
|
||||
.. figure:: ../../_static/itwt_suspend.png
|
||||
:align: center
|
||||
|
||||
Individual TWT 协商暂停/恢复过程示例
|
||||
|
||||
- TWT 协商终止
|
||||
|
||||
建立起 TWT 协商后, Station 可以通过向 AP 发送 TWT Teardown 帧终止指定的 TWT 协商。由 flow_id 来标识需要终止的 TWT 协商,具体可以参考 TWT 参数配置。
|
||||
|
||||
.. figure:: ../../_static/itwt_teardown.png
|
||||
:align: center
|
||||
|
||||
Individual TWT 协商终止过程示例
|
||||
|
||||
TWT 参数配置
|
||||
++++++++++++
|
||||
|
||||
在使用过程中,需要配置 TWT 和低功耗模式的相关参数,其中低功耗模式相关参数决定了设备在休眠状态下的行为模式。本小节将主要阐述如何配置 TWT,有关低功耗模式下的参数配置,请参考 `如何配置 Wi-Fi 场景下低功耗模式`_。
|
||||
|
||||
- Individual TWT 参数配置
|
||||
|
||||
在建立 Station 和 AP 间的 iTWT 时,使用 :component_file:`esp_wifi/include/esp_wifi_he_types.h` 中定义的结构体 :cpp:type:`wifi_twt_setup_config_t` 来配置 TWT 的相关参数,其定义如下:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wifi_twt_setup_cmds_t setup_cmd;
|
||||
uint16_t trigger :1;
|
||||
uint16_t flow_type :1;
|
||||
uint16_t flow_id :3;
|
||||
uint16_t wake_invl_expn :5;
|
||||
uint16_t wake_duration_unit :1;
|
||||
uint16_t reserved :5;
|
||||
uint8_t min_wake_dura;
|
||||
uint16_t wake_invl_mant;
|
||||
uint16_t twt_id;
|
||||
uint16_t timeout_time_ms;
|
||||
} wifi_twt_setup_config_t;
|
||||
|
||||
:cpp:type:`wifi_twt_setup_config_t` 中各个字段的含义如下:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 15 45
|
||||
:align: center
|
||||
|
||||
* - 字段
|
||||
- 描述
|
||||
* - setup_cmd
|
||||
- 指示了 TWT 建立时请求和回复使用的命令类型,具体类型请参阅 :cpp:type:`wifi_twt_setup_cmds_t` 。
|
||||
* - trigger
|
||||
- 值为 1 时配置 TWT 类型为 Trigger-enabled,值为 0 时配置为 Non trigger-enabled。
|
||||
* - flow_type
|
||||
- 值为 1 时配置 TWT 类型为 Unannounced,值为 0 时配置为 Announced。
|
||||
* - flow_id
|
||||
- 当建立起一个 iTWT 协商后,AP 会为其分配 flow_id。Station 在协商建立请求中可以指定 flow_id,但在 AP 的回复中该字段可能会被改变。
|
||||
* - wake_invl_expn
|
||||
- TWT Wake Interval 指数部分。
|
||||
* - wake_duration_unit
|
||||
- TWT Wake Duration 计数单元。为 0 代表 256 微秒,为 1 代表以 TU (1024 微秒) 为单位。
|
||||
* - reserved
|
||||
- 保留字段。
|
||||
* - min_wake_dura
|
||||
- 该字段代表 Station 期望处于唤醒状态的时间,以 ``wake_duration_unit`` 作为基本单位。
|
||||
* - wake_invl_mant
|
||||
- TWT Wake Interval 尾数部分。
|
||||
* - twt_id
|
||||
- TWT 配置标识。在发起多个 TWT 请求时,该字段用于在 handler 中区分不同的 TWT 参数配置。
|
||||
* - timeout_time_ms
|
||||
- TWT 请求超时时间,单位为毫秒。
|
||||
|
||||
需要指出的是,Station 在协商中所期望的 TWT Wake Interval 为 wake_invl_mant * 2\ :sup:`wake_invl_expn`\,单位是微秒。
|
||||
而所期望的 TWT Wake Duration 为 min_wake_dura * wake_duration_unit。
|
||||
|
||||
.. note::
|
||||
注意, TWT Wake Interval 和 TWT Wake Duration 的差值需要大于 10 毫秒。
|
||||
|
||||
配置示例如下:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
wifi_twt_setup_config_t setup_config = {
|
||||
.setup_cmd = TWT_REQUEST,
|
||||
.flow_id = 0,
|
||||
.twt_id = 0,
|
||||
.flow_type = 0,
|
||||
.min_wake_dura = 255,
|
||||
.wake_duration_unit = 0,
|
||||
.wake_invl_expn = 10,
|
||||
.wake_invl_mant = 512,
|
||||
.trigger = 1,
|
||||
.timeout_time_ms = 5000,
|
||||
};
|
||||
|
||||
以上配置指定建立 TWT 请求时使用的类型为 Trigger-enabled,Announced,期望的 TWT Wake Interval 为 524288 微秒, TWT Wake Duration 为 65280 微秒。配置好 :cpp:type:`wifi_twt_setup_config_t` 后,调用 API :cpp:func:`esp_wifi_sta_itwt_setup` 向 AP 发起 iTWT 建立请求。
|
||||
|
||||
.. note::
|
||||
{IDF_TARGET_NAME} 支持用户调用 API :cpp:func:`esp_wifi_sta_itwt_set_target_wake_time_offset` 配置相对于目标唤醒时间的偏移时间。
|
||||
|
||||
TWT 事件
|
||||
++++++++++
|
||||
|
||||
- WIFI_EVENT_ITWT_SETUP
|
||||
|
||||
发送请求后,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_SETUP` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_setup_t` 结构体中,其成员变量 status 指示了此次事件的状态。
|
||||
当 status 为 :c:macro:`ITWT_SETUP_SUCCESS` 时代表请求成功收到了对应回复,为其他值代表请求失败。在得到请求成功的状态后,用户可以从该结构体中的 config 成员变量中得到 AP 回复中的具体参数,并根据具体参数决定后续的处理逻辑。
|
||||
例如,Station 发送了类型为 Demand 的 TWT 请求,收到 AP 的回复类型为 Dictate,用户此时可以考察回复中的 TWT 参数是否可行,若可行便可以发送一个新的 TWT 请求与 AP 继续建立 TWT 协商,并且该请求中的 TWT 参数需要与 AP 回复中一致。
|
||||
|
||||
在 Station 未主动发送请求时也有可能触发 :cpp:enumerator:`WIFI_EVENT_ITWT_SETUP` 事件,这种情况下对应的是 AP 主动向 Station 发起 iTWT 协商建立过程,此时 AP 向 Station 发送的帧中会带有 TWT 参数。同样地,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_SETUP` 事件的对应处理程序中获取结果并自定义处理逻辑。
|
||||
用户需要检查 config 成员变量中 AP 发送的 TWT 参数类型,一般有两种情况:
|
||||
1. AP 发送的 TWT 参数为 Accept 类型,此时 Station 会与 AP 建立起使用该 TWT 参数的 iTWT 协商。若用户不希望建立此 iTWT 协商,可以向 AP 发送 Teardown 帧。
|
||||
2. AP 发送的 TWT 参数为 Alternate 或 Dictate 类型,此时 Station 不会与 AP 建立起 iTWT 协商,但可以在接下来使用该参数向 AP 发起 iTWT 协商建立请求。
|
||||
|
||||
- WIFI_EVENT_ITWT_SUSPEND
|
||||
|
||||
在调用 API :cpp:func:`esp_wifi_sta_itwt_suspend` 请求暂停已经建立的 iTWT 协商时, 用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_SUSPEND` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_suspend_t` 结构体中,其成员变量 status 指示了此次事件的状态。
|
||||
当 status 为 :c:macro:`ESP_OK` 时代表成功暂停了指定的 iTWT 协商,为其他值代表请求暂停失败。
|
||||
|
||||
.. note::
|
||||
注意,调用 API :cpp:func:`esp_wifi_sta_itwt_suspend` 请求暂停 iTWT 时,用户需要指定对应 iTWT 的 flow_id 以及暂停时间。需要注意的是,当暂停时间大于 0 时,对应 iTWT 会在暂停指定时间后恢复,而当暂停时间为 0 时,对应的 iTWT 会暂停,直到被用户调用 API 手动恢复为止。
|
||||
|
||||
- WIFI_EVENT_ITWT_TEARDOWN
|
||||
|
||||
在调用 API :cpp:func:`esp_wifi_sta_itwt_teardown` 请求终止 iTWT 时,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_TEARDOWN` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_teardown_t` 结构体中,其成员变量 status 指示了此次事件的状态。
|
||||
当 status 为 :cpp:enumerator:`ITWT_TEARDOWN_SUCCESS` 时代表成功终止了指定的 iTWT 协商,为其他值代表终止 iTWT 失败。调用 API 时用户需要指定需要终止的 iTWT 的 flow_id。
|
||||
|
||||
- WIFI_EVENT_TWT_WAKEUP
|
||||
|
||||
当 Station 在休眠中醒来时,Wi-Fi 驱动程序将会上报 :cpp:enumerator:`WIFI_EVENT_TWT_WAKEUP` 事件,用户可以在该事件的对应处理程序中自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_twt_wakeup_t` 结构体中,成员变量 twt_type 指示了此次事件 TWT 的类型,成员变量 flow_id 指示了此次醒来的具体的 TWT。
|
||||
|
||||
- WIFI_EVENT_ITWT_PROBE
|
||||
|
||||
调用 API :cpp:func:`esp_wifi_sta_itwt_send_probe_req` 在 iTWT 期间发送 probe request 时,用户可以在 :cpp:enumerator:`WIFI_EVENT_ITWT_PROBE` 事件的对应处理程序中获取请求结果并自定义处理逻辑。事件结果保存在 :cpp:type:`wifi_event_sta_itwt_probe_t` 结构体中,其成员变量 status 指示了此次事件的状态。
|
||||
当 status 为 :cpp:enumerator:`ITWT_PROBE_SUCCESS` 时代表成功发送 probe request 并且接收到 AP 回复的 probe response,为其他值代表发送或者接收 probe 失败。
|
||||
|
||||
|
||||
有关 iTWT 使用的更多信息,可以参考示例 :example:`wifi/itwt` 。
|
||||
|
||||
TWT 功耗分析
|
||||
+++++++++++++
|
||||
|
||||
为了展现 TWT 在节省设备功耗方面的优势,我们使用功率分析仪追踪了 {IDF_TARGET_NAME} 在不同模式下的电流情况。如下图所示,{IDF_TARGET_NAME} 首先处于 DTIM 模式,接着与 AP 建立起 iTWT 协商,TWT Wake Interval 为 10 s,在 TWT SP 结束后,{IDF_TARGET_NAME} 会进入 Light-sleep 状态直到下个 SP 到来时唤醒。
|
||||
其中 :cpp:type:`wifi_twt_setup_config_t` 配置示例如下:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
wifi_twt_setup_config_t setup_config = {
|
||||
.setup_cmd = TWT_REQUEST,
|
||||
.flow_id = 0,
|
||||
.twt_id = 0,
|
||||
.flow_type = 0,
|
||||
.min_wake_dura = 255,
|
||||
.wake_duration_unit = 0,
|
||||
.wake_invl_expn = 10,
|
||||
.wake_invl_mant = 10000,
|
||||
.trigger = 1,
|
||||
.timeout_time_ms = 5000,
|
||||
};
|
||||
|
||||
.. figure:: ../../_static/itwt_10s_current.png
|
||||
:align: center
|
||||
|
||||
DTIM 与 iTWT 模式下的电流图
|
||||
|
||||
进一步,将 TWT 协商中的 TWT Wake Interval 参数更改为 30 s,下图展现了参数变化对于电流的影响。
|
||||
其中 :cpp:type:`wifi_twt_setup_config_t` 配置示例如下:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
wifi_twt_setup_config_t setup_config = {
|
||||
.setup_cmd = TWT_REQUEST,
|
||||
.flow_id = 0,
|
||||
.twt_id = 0,
|
||||
.flow_type = 0,
|
||||
.min_wake_dura = 255,
|
||||
.wake_duration_unit = 0,
|
||||
.wake_invl_expn = 10,
|
||||
.wake_invl_mant = 30000,
|
||||
.trigger = 1,
|
||||
.timeout_time_ms = 5000,
|
||||
};
|
||||
|
||||
.. figure:: ../../_static/itwt_30s_current.png
|
||||
:align: center
|
||||
|
||||
更改参数后的 DTIM 与 iTWT 模式下的电流图
|
||||
|
@ -1 +1,234 @@
|
||||
.. include:: ../../../en/api-reference/peripherals/ana_cmpr.rst
|
||||
模拟比较器
|
||||
==========
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
{IDF_TARGET_ANA_CMPR_SRC_CHAN0: default="未更新", esp32h2="GPIO11", esp32p4="GPIO52"}
|
||||
{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN0: default="未更新", esp32h2="GPIO10", esp32p4="GPIO51"}
|
||||
{IDF_TARGET_ANA_CMPR_SRC_CHAN1: default="未更新", esp32p4="GPIO54"}
|
||||
{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN1: default="未更新", esp32p4="GPIO53"}
|
||||
|
||||
简介
|
||||
----
|
||||
|
||||
模拟比较器是一种用于比较信号源与内部参考电压或外部参考信号的外设。
|
||||
|
||||
当用于比较模拟信号时,集成模拟比较器可以低成本替代运算放大器。不同于运算放大器的连续比较,ESP 模拟比较器由时钟源驱动,其采样频率取决于时钟的频率。
|
||||
|
||||
{IDF_TARGET_NAME} 上的模拟比较器有 {IDF_TARGET_SOC_ANA_CMPR_NUM} 个单元,单元中的通道如下:
|
||||
|
||||
**UNIT0**
|
||||
|
||||
- 源通道:{IDF_TARGET_ANA_CMPR_SRC_CHAN0}
|
||||
- 外部参考通道:{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN0}
|
||||
- 内部参考通道:电压范围是 VDD 的 0% ~ 70%,步长为 VDD 的 10%
|
||||
|
||||
.. only:: esp32p4
|
||||
|
||||
**UNIT1**
|
||||
|
||||
- 源通道:{IDF_TARGET_ANA_CMPR_SRC_CHAN1}
|
||||
- 外部参考通道:{IDF_TARGET_ANA_CMPR_EXT_REF_CHAN1}
|
||||
- 内部参考通道:电压范围是 VDD 的 0% ~ 70%,步长为 VDD 的 10%
|
||||
|
||||
功能概述
|
||||
--------
|
||||
|
||||
本文中的以下章节涵盖了安装及操作模拟比较器单元的基本步骤:
|
||||
|
||||
- :ref:`anacmpr-resource-allocation` - 涵盖了应设置哪些参数以获取单元句柄,以及完成工作后如何回收资源。
|
||||
- :ref:`anacmpr-further-configurations` - 涵盖了可能需要指定的其他配置及其用途。
|
||||
- :ref:`anacmpr-enable-and-disable-unit` - 涵盖了如何启用和禁用单元。
|
||||
- :ref:`anacmpr-power-management` - 描述了不同时钟源对功耗的影响。
|
||||
- :ref:`anacmpr-iram-safe` - 列出了在 cache 被禁用时也能起效的函数。
|
||||
- :ref:`anacmpr-thread-safety` - 列出了驱动程序中线程安全的 API。
|
||||
- :ref:`anacmpr-kconfig-options` - 列出了支持的 Kconfig 选项,这些选项可以对驱动程序产生不同影响。
|
||||
|
||||
.. only:: SOC_ANA_CMPR_SUPPORT_ETM
|
||||
|
||||
- :ref:`anacmpr-etm-events` - 介绍了如何创建一个模拟比较器跨越事件。
|
||||
|
||||
.. _anacmpr-resource-allocation:
|
||||
|
||||
资源分配
|
||||
^^^^^^^^
|
||||
|
||||
模拟比较器单元由 :cpp:type:`ana_cmpr_handle_t` 表示,每个单元都可支持内部或外部的参考信号。
|
||||
|
||||
通过调用 :cpp:func:`ana_cmpr_new_unit` 来获取单元句柄以分配资源。在分配单元时需要指定 :cpp:type:`ana_cmpr_config_t` 配置:
|
||||
|
||||
- :cpp:member:`ana_cmpr_config_t::unit` 选择模拟比较器单元。
|
||||
- :cpp:member:`ana_cmpr_config_t::clk_src` 选择模拟比较器的时钟源,这将影响采样频率。请注意,模拟比较器的时钟源来自 IO MUX,与 Sigma-Delta 调制器 (SDM) 和毛刺过滤器 (Glitch Filter) 等 GPIO 扩展外设共享时钟源。如果为多个 GPIO 扩展外设指定不同的时钟源,则配置将失败。这些外设的默认时钟源是相同的,通常选择 :cpp:enumerator:`soc_periph_ana_cmpr_clk_src_t::ANA_CMPR_CLK_SRC_DEFAULT` 即可。
|
||||
- :cpp:member:`ana_cmpr_config_t::ref_src` 选择内部参考电压或外部参考信号为参考信号源。
|
||||
- :cpp:member:`ana_cmpr_config_t::cross_type` 选择哪种类型的跨零信号可以触发中断。
|
||||
|
||||
函数 :cpp:func:`ana_cmpr_new_unit` 可能因内存不足、参数无效等各种错误而失败。如果不再需要先前创建的模拟比较器单元,可通过调用 :cpp:func:`ana_cmpr_del_unit` 来回收资源,从而释放底层硬件通道的资源供其他用途。在删除模拟比较器单元句柄之前,首先应通过 :cpp:func:`ana_cmpr_disable` 禁用句柄,或者确保尚未通过 :cpp:func:`ana_cmpr_enable` 启用该单元。
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "driver/ana_cmpr.h"
|
||||
|
||||
ana_cmpr_handle_t cmpr = NULL;
|
||||
ana_cmpr_config_t config = {
|
||||
.unit = 0,
|
||||
.clk_src = ANA_CMPR_CLK_SRC_DEFAULT,
|
||||
.ref_src = ANA_CMPR_REF_SRC_INTERNAL,
|
||||
.cross_type = ANA_CMPR_CROSS_ANY,
|
||||
};
|
||||
ESP_ERROR_CHECK(ana_cmpr_new_unit(&config, &cmpr));
|
||||
// ...
|
||||
ESP_ERROR_CHECK(ana_cmpr_del_unit(cmpr));
|
||||
|
||||
.. _anacmpr-further-configurations:
|
||||
|
||||
进一步配置
|
||||
^^^^^^^^^^
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_internal_reference` - 选择 :cpp:enumerator:`ana_cmpr_ref_source_t::ANA_CMPR_REF_SRC_INTERNAL` 作为参考源时,该函数可以指定内部参考电压。
|
||||
|
||||
需要由 :cpp:member:`ana_cmpr_internal_ref_config_t::ref_volt` 来指定电压。该电压受 VDD 电源电压限制,只能支持固定百分比的 VDD。目前在 {IDF_TARGET_NAME} 上,内部参考电压范围是 VDD 的 0% ~ 70%,步长为 VDD 的 10%。
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "driver/ana_cmpr.h"
|
||||
|
||||
ana_cmpr_internal_ref_config_t ref_cfg = {
|
||||
.ref_volt = ANA_CMPR_REF_VOLT_50_PCT_VDD,
|
||||
};
|
||||
ESP_ERROR_CHECK(ana_cmpr_set_internal_reference(cmpr, &ref_cfg));
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_debounce` - 设置去抖配置。
|
||||
|
||||
通过 :cpp:member:`ana_cmpr_debounce_config_t::wait_us` 可设置中断等待时间。跨零中断触发后,中断将暂时禁用 :cpp:member:`ana_cmpr_debounce_config_t::wait_us` 微秒,这样可以避免信号源跨越参考信号时频繁触发中断。因此,等待时间应与信号源和参考信号之间的相对频率成反比。如果中断等待时间设置得太短,则无法完全避免抖动,但如果设置得太长,则可能会错过下一个跨越中断。
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "driver/ana_cmpr.h"
|
||||
|
||||
ana_cmpr_debounce_config_t dbc_cfg = {
|
||||
.wait_us = 1,
|
||||
};
|
||||
ESP_ERROR_CHECK(ana_cmpr_set_debounce(cmpr, &dbc_cfg));
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_cross_type` - 设置信号源跨越类型。
|
||||
|
||||
初始跨越类型在 :cpp:func:`ana_cmpr_new_unit` 中设置。即便在中断服务程序 (ISR) 的上下文中,此函数也可以更新跨越类型。
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "driver/ana_cmpr.h"
|
||||
|
||||
ESP_ERROR_CHECK(ana_cmpr_set_cross_type(cmpr, ANA_CMPR_CROSS_POS));
|
||||
|
||||
- :cpp:func:`ana_cmpr_register_event_callbacks` - 注册回调函数。
|
||||
|
||||
目前支持 :cpp:member:`ana_cmpr_event_callbacks_t::on_cross`。当发生跨越事件(由 :cpp:member:`ana_cmpr_config_t::cross_type` 指定)时,将调用该回调函数。
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "driver/ana_cmpr.h"
|
||||
|
||||
static bool IRAM_ATTR example_ana_cmpr_on_cross_callback(ana_cmpr_handle_t cmpr,
|
||||
const ana_cmpr_cross_event_data_t *edata,
|
||||
void *user_ctx)
|
||||
{
|
||||
// ...
|
||||
return false;
|
||||
}
|
||||
ana_cmpr_event_callbacks_t cbs = {
|
||||
.on_cross = example_ana_cmpr_on_cross_callback,
|
||||
};
|
||||
ESP_ERROR_CHECK(ana_cmpr_register_event_callbacks(cmpr, &cbs, NULL));
|
||||
|
||||
.. note::
|
||||
|
||||
当启用 :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` 时,应添加属性 ``IRAM_ATTR``,确保回调上下文和涉及的数据位于内部 RAM 中(详情请参阅 :ref:`anacmpr-iram-safe`)。
|
||||
|
||||
.. _anacmpr-enable-and-disable-unit:
|
||||
|
||||
启用和禁用单元
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
- :cpp:func:`ana_cmpr_enable` - 启用模拟比较器单元。
|
||||
- :cpp:func:`ana_cmpr_disable` - 禁用模拟比较器单元。
|
||||
|
||||
启用模拟比较器单元与跨越事件中断后,若同时启用了电源管理(详见 :ref:`anacmpr-power-management`),则将获得电源管理锁。在 **启用** 状态下,只能调用 :cpp:func:`ana_cmpr_set_internal_reference` 和 :cpp:func:`ana_cmpr_set_debounce`,其他函数可在禁用单元后调用。
|
||||
|
||||
调用 :cpp:func:`ana_cmpr_disable` 则会执行与上述过程相反的操作。
|
||||
|
||||
.. _anacmpr-power-management:
|
||||
|
||||
电源管理
|
||||
^^^^^^^^
|
||||
|
||||
当启用电源管理时(即开启 :ref:`CONFIG_PM_ENABLE`),系统会在进入 Light-sleep 模式前调整 APB 频率,因此模拟比较器的分辨率也可能随之更改。
|
||||
|
||||
通过获取类型为 :cpp:enumerator:`ESP_PM_NO_LIGHT_SLEEP` 的电源管理锁,驱动程序可以防止系统更改 APB 频率。只要驱动程序创建的模拟比较器单元实例选择 :cpp:enumerator:`ANA_CMPR_CLK_SRC_DEFAULT` 或 :cpp:enumerator:`ANA_CMPR_CLK_SRC_XTAL` 作为其时钟源,驱动程序会确保通过 :cpp:func:`ana_cmpr_enable` 启用通道,并获取电源管理锁。同理,当为该通道调用 :cpp:func:`ana_cmpr_disable` 时,驱动程序会释放锁。
|
||||
|
||||
.. _anacmpr-iram-safe:
|
||||
|
||||
IRAM 安全
|
||||
^^^^^^^^^
|
||||
|
||||
默认情况下,当 cache 因写入或擦除 flash 等原因而被禁用时,模拟比较器的中断服务将会延迟,造成警报中断无法及时执行。在实时应用程序中通常需要避免这一情况发生。
|
||||
|
||||
Kconfig 选项 :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` 支持:
|
||||
|
||||
1. 即使 cache 被禁用也能启用中断服务。
|
||||
2. 将 ISR 使用的所有函数放入 IRAM。 [1]_
|
||||
3. 将驱动程序对象放入 DRAM(以防它被分配到 PSRAM上)。
|
||||
|
||||
启用上述 Kconfig 选项以保证在禁用 cache 时可以正常使用函数,但这会增加 IRAM 消耗。
|
||||
|
||||
另一个 Kconfig 选项 :ref:`CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM` 也支持将常用的 IO 控制函数放入 IRAM 中,以保证在禁用 cache 时可以正常使用函数。IO 控制函数如下所示:
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_internal_reference`
|
||||
- :cpp:func:`ana_cmpr_set_debounce`
|
||||
- :cpp:func:`ana_cmpr_set_cross_type`
|
||||
|
||||
.. _anacmpr-thread-safety:
|
||||
|
||||
线程安全
|
||||
^^^^^^^^
|
||||
|
||||
驱动程序会确保工厂函数 :cpp:func:`ana_cmpr_new_unit` 的线程安全。使用时,可以直接从不同的 RTOS 任务中调用此类函数,无需额外锁保护。
|
||||
|
||||
驱动程序设置了临界区,以防函数同时在任务和 ISR 中被调用。因此,以下函数支持在 ISR 上下文运行:
|
||||
|
||||
- :cpp:func:`ana_cmpr_set_internal_reference`
|
||||
- :cpp:func:`ana_cmpr_set_debounce`
|
||||
- :cpp:func:`ana_cmpr_set_cross_type`
|
||||
|
||||
其他以 :cpp:type:`ana_cmpr_handle_t` 为第一个位置参数的函数均非线程安全,因此应避免从多个任务中调用这类函数。
|
||||
|
||||
.. _anacmpr-kconfig-options:
|
||||
|
||||
Kconfig 选项
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- :ref:`CONFIG_ANA_CMPR_ISR_IRAM_SAFE` 控制默认的 ISR 句柄在 cache 被禁用时是否可以正常工作,详见 :ref:`anacmpr-iram-safe`。
|
||||
- :ref:`CONFIG_ANA_CMPR_CTRL_FUNC_IN_IRAM` 控制模拟比较器控制函数的存放位置(IRAM 或 flash),详见 :ref:`anacmpr-iram-safe`。
|
||||
- :ref:`CONFIG_ANA_CMPR_ENABLE_DEBUG_LOG` 用于启用调试日志输出。启用此选项将增加固件的二进制文件大小。
|
||||
|
||||
.. only:: SOC_ANA_CMPR_SUPPORT_ETM
|
||||
|
||||
.. _anacmpr-etm-events:
|
||||
|
||||
ETM 事件
|
||||
^^^^^^^^
|
||||
|
||||
创建一个模拟比较器跨越事件,需要额外包含头文件 ``driver/ana_cmpr_etm.h``,并调用函数 :cpp:func:`ana_cmpr_new_etm_event` 来分配事件。有关如何将事件连接到任务,请参考 :doc:`ETM </api-reference/peripherals/etm>`。
|
||||
|
||||
应用示例
|
||||
--------
|
||||
|
||||
* :example:`peripherals/analog_comparator` 展示了模拟比较器的基本用法以及其他用途(如迟滞比较器和 SPWM 发生器)。
|
||||
|
||||
API 参考
|
||||
--------
|
||||
|
||||
.. include-build-file:: inc/ana_cmpr.inc
|
||||
.. include-build-file:: inc/ana_cmpr_types.inc
|
||||
|
||||
.. [1]
|
||||
:cpp:member:`ana_cmpr_event_callbacks_t::on_cross` 回调函数,以及由其调用的其他函数也应放置在 IRAM 中,请妥善处理。
|
||||
|
@ -386,7 +386,7 @@ examples/system/unit_test/:
|
||||
|
||||
examples/system/xip_from_psram:
|
||||
enable:
|
||||
- if: SOC_SPIRAM_SUPPORTED == 1
|
||||
- if: SOC_SPIRAM_SUPPORTED == 1 and SOC_SPIRAM_XIP_SUPPORTED == 1
|
||||
reason: this feature is supported on chips that have PSRAM
|
||||
disable:
|
||||
- if: IDF_TARGET == "esp32"
|
||||
|
@ -56,9 +56,9 @@ menu "Example Configuration"
|
||||
default ESP_WIFI_AUTH_WPA2_PSK
|
||||
help
|
||||
The weakest authmode to accept in the scan mode.
|
||||
This value defaults to ESP_WIFI_AUTH_WPA2_PSK incase password is present
|
||||
This value defaults to ESP_WIFI_AUTH_WPA2_PSK in case password is present
|
||||
and ESP_WIFI_AUTH_OPEN is used. Please select ESP_WIFI_AUTH_WEP / ESP_WIFI_AUTH_WPA_PSK
|
||||
incase AP is operating in WEP / WPA mode.
|
||||
in case AP is operating in WEP / WPA mode.
|
||||
|
||||
config ESP_WIFI_AUTH_OPEN
|
||||
bool "OPEN"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -73,6 +73,9 @@
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_FAIL_BIT BIT1
|
||||
|
||||
/*DHCP server option*/
|
||||
#define DHCPS_OFFER_DNS 0x02
|
||||
|
||||
static const char *TAG_AP = "WiFi SoftAP";
|
||||
static const char *TAG_STA = "WiFi Sta";
|
||||
|
||||
@ -162,6 +165,17 @@ esp_netif_t *wifi_init_sta(void)
|
||||
return esp_netif_sta;
|
||||
}
|
||||
|
||||
void softap_set_dns_addr(esp_netif_t *esp_netif_ap,esp_netif_t *esp_netif_sta)
|
||||
{
|
||||
esp_netif_dns_info_t dns;
|
||||
esp_netif_get_dns_info(esp_netif_sta,ESP_NETIF_DNS_MAIN,&dns);
|
||||
uint8_t dhcps_offer_option = DHCPS_OFFER_DNS;
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(esp_netif_ap));
|
||||
ESP_ERROR_CHECK(esp_netif_dhcps_option(esp_netif_ap, ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, &dhcps_offer_option, sizeof(dhcps_offer_option)));
|
||||
ESP_ERROR_CHECK(esp_netif_set_dns_info(esp_netif_ap, ESP_NETIF_DNS_MAIN, &dns));
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_start(esp_netif_ap));
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
@ -223,6 +237,7 @@ void app_main(void)
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
ESP_LOGI(TAG_STA, "connected to ap SSID:%s password:%s",
|
||||
EXAMPLE_ESP_WIFI_STA_SSID, EXAMPLE_ESP_WIFI_STA_PASSWD);
|
||||
softap_set_dns_addr(esp_netif_ap,esp_netif_sta);
|
||||
} else if (bits & WIFI_FAIL_BIT) {
|
||||
ESP_LOGI(TAG_STA, "Failed to connect to SSID:%s, password:%s",
|
||||
EXAMPLE_ESP_WIFI_STA_SSID, EXAMPLE_ESP_WIFI_STA_PASSWD);
|
||||
|
@ -77,23 +77,6 @@ components/esp_coex/include/private/esp_coexist_adapter.h
|
||||
components/esp_coex/include/esp_coex_i154.h
|
||||
### To be fixed: headers that rely on implicit inclusion
|
||||
#
|
||||
components/esp_rom/esp32/include/esp32/rom/rtc.h
|
||||
components/esp_rom/esp32c3/include/esp32c3/rom/rtc.h
|
||||
components/esp_rom/esp32s2/include/esp32s2/rom/rtc.h
|
||||
components/esp_rom/esp32s3/include/esp32s3/rom/rtc.h
|
||||
components/esp_rom/esp32c2/include/esp32c2/rom/rtc.h
|
||||
components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h
|
||||
components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h
|
||||
components/esp_rom/esp32h2/include/esp32h2/rom/rtc.h
|
||||
components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h
|
||||
components/esp_rom/esp32c61/include/esp32c61/rom/rtc.h
|
||||
components/esp_rom/esp32/include/esp32/rom/sha.h
|
||||
components/esp_rom/esp32/include/esp32/rom/secure_boot.h
|
||||
components/esp_rom/esp32c3/include/esp32c3/rom/spi_flash.h
|
||||
components/esp_rom/esp32s2/include/esp32s2/rom/spi_flash.h
|
||||
components/esp_rom/esp32s2/include/esp32s2/rom/cache.h
|
||||
components/esp_rom/esp32s2/include/esp32s2/rom/secure_boot.h
|
||||
components/esp_rom/esp32s2/include/esp32s2/rom/opi_flash.h
|
||||
components/esp_ringbuf/include/freertos/ringbuf.h
|
||||
components/esp_netif/include/esp_netif_defaults.h
|
||||
components/esp_netif/include/esp_netif_net_stack.h
|
||||
@ -116,8 +99,6 @@ components/spi_flash/include/esp_private/spi_flash_os.h
|
||||
### To be fixed: files which don't compile for esp32s2 target:
|
||||
|
||||
components/esp_psram/include/esp32/himem.h
|
||||
components/esp_rom/esp32/include/esp32/rom/ets_sys.h
|
||||
components/esp_rom/esp32/include/esp32/rom/uart.h
|
||||
|
||||
|
||||
### To be fixed: files which don't compile for esp32s3 target:
|
||||
|
Loading…
Reference in New Issue
Block a user