mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: mocking should be possible now
The following three headers will be mockes: * esp_flash.h * esp_spi_flash.h * esp_partition.h * counter functions live in own header * add spi_flash sim dir for esp_err.h to Unity * modified gen_esp_err_to_name.py to ignore sim/ dir in spi_flash component Add cmock .yaml config file Add spi hal header until soc can mock the hal layer as well.
This commit is contained in:
parent
52093fa4ef
commit
c233ce0449
@ -1,63 +1,125 @@
|
||||
if(BOOTLOADER_BUILD)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
# ESP32 Bootloader needs SPIUnlock from this file, but doesn't
|
||||
# need other parts of this component
|
||||
set(srcs "esp32/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S2)
|
||||
set(srcs "esp32s2/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
set(srcs "esp32s3/spi_flash_rom_patch.c")
|
||||
idf_build_get_property(spi_flash_mock CONFIG_SPI_FLASH_MOCK)
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
if(${spi_flash_mock})
|
||||
|
||||
message(STATUS "building SPI FLASH MOCKS")
|
||||
|
||||
set(IDF_PATH $ENV{IDF_PATH})
|
||||
set(CMOCK_DIR "${IDF_PATH}/components/cmock/CMock")
|
||||
set(MOCK_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/mocks")
|
||||
|
||||
file(MAKE_DIRECTORY ${MOCK_GEN_DIR})
|
||||
|
||||
set(MOCK_OUTPUT
|
||||
"${MOCK_GEN_DIR}/Mockesp_partition.c" "${MOCK_GEN_DIR}/Mockesp_partition.h"
|
||||
"${MOCK_GEN_DIR}/Mockesp_flash.c" "${MOCK_GEN_DIR}/Mockesp_flash.h"
|
||||
"${MOCK_GEN_DIR}/Mockesp_spi_flash.c" "${MOCK_GEN_DIR}/Mockesp_spi_flash.h")
|
||||
|
||||
set(MOCK_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/esp_partition.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/esp_flash.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/esp_spi_flash.h
|
||||
)
|
||||
|
||||
set(ENV{UNITY_DIR} "$ENV{IDF_PATH}/components/cmock/CMock")
|
||||
|
||||
set(include_dirs
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${MOCK_GEN_DIR}")
|
||||
|
||||
set(srcs "${MOCK_GEN_DIR}/Mockesp_partition.c"
|
||||
"${MOCK_GEN_DIR}/Mockesp_spi_flash.c"
|
||||
"${MOCK_GEN_DIR}/Mockesp_flash.c")
|
||||
|
||||
if(${target} STREQUAL "linux")
|
||||
list(APPEND include_dirs
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../spi_flash/sim/stubs/soc/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../spi_flash/sim/stubs/xtensa")
|
||||
endif()
|
||||
set(cache_srcs "")
|
||||
set(priv_requires bootloader_support soc)
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS ${include_dirs}
|
||||
REQUIRES cmock)
|
||||
|
||||
# This command builds the mocks.
|
||||
# First, environment variable UNITY_DIR is set. This is necessary to prevent unity from looking in its own submodule
|
||||
# which doesn't work in our CI yet...
|
||||
# The rest is a straight forward call to cmock.rb, consult cmock's documentation for more information.
|
||||
add_custom_command(
|
||||
OUTPUT ${MOCK_OUTPUT}
|
||||
COMMAND ${CMAKE_COMMAND} -E env "UNITY_DIR=${IDF_PATH}/components/unity/unity"
|
||||
ruby
|
||||
${CMOCK_DIR}/lib/cmock.rb
|
||||
-o${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_config.yaml
|
||||
${MOCK_HEADERS}
|
||||
)
|
||||
|
||||
else()
|
||||
set(cache_srcs
|
||||
"cache_utils.c"
|
||||
"flash_mmap.c"
|
||||
"flash_ops.c"
|
||||
"${IDF_TARGET}/flash_ops_${IDF_TARGET}.c"
|
||||
)
|
||||
set(srcs
|
||||
"partition.c")
|
||||
if(BOOTLOADER_BUILD)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
# ESP32 Bootloader needs SPIUnlock from this file, but doesn't
|
||||
# need other parts of this component
|
||||
set(srcs "esp32/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S2)
|
||||
set(srcs "esp32s2/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
set(srcs "esp32s3/spi_flash_rom_patch.c")
|
||||
else()
|
||||
# but on other platforms no source files are needed for bootloader
|
||||
set(srcs)
|
||||
endif()
|
||||
set(cache_srcs "")
|
||||
set(priv_requires bootloader_support soc)
|
||||
else()
|
||||
set(cache_srcs
|
||||
"cache_utils.c"
|
||||
"flash_mmap.c"
|
||||
"flash_ops.c"
|
||||
"${IDF_TARGET}/flash_ops_${IDF_TARGET}.c"
|
||||
)
|
||||
set(srcs
|
||||
"partition.c")
|
||||
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
list(APPEND srcs
|
||||
"esp32/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S2)
|
||||
list(APPEND srcs
|
||||
"esp32s2/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
list(APPEND srcs
|
||||
"esp32s3/spi_flash_rom_patch.c")
|
||||
endif()
|
||||
|
||||
# New implementation after IDF v4.0
|
||||
list(APPEND srcs
|
||||
"esp32/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S2)
|
||||
list(APPEND srcs
|
||||
"esp32s2/spi_flash_rom_patch.c")
|
||||
elseif(CONFIG_IDF_TARGET_ESP32S3)
|
||||
list(APPEND srcs
|
||||
"esp32s3/spi_flash_rom_patch.c")
|
||||
"spi_flash_chip_drivers.c"
|
||||
"spi_flash_chip_generic.c"
|
||||
"spi_flash_chip_issi.c"
|
||||
"spi_flash_chip_mxic.c"
|
||||
"spi_flash_chip_gd.c"
|
||||
"spi_flash_chip_winbond.c"
|
||||
"memspi_host_driver.c")
|
||||
|
||||
list(APPEND cache_srcs
|
||||
"esp_flash_api.c"
|
||||
"esp_flash_spi_init.c"
|
||||
"spi_flash_os_func_app.c"
|
||||
"spi_flash_os_func_noos.c")
|
||||
|
||||
list(APPEND srcs ${cache_srcs})
|
||||
set(priv_requires bootloader_support app_update soc esp_ipc)
|
||||
endif()
|
||||
|
||||
# New implementation after IDF v4.0
|
||||
list(APPEND srcs
|
||||
"spi_flash_chip_drivers.c"
|
||||
"spi_flash_chip_generic.c"
|
||||
"spi_flash_chip_issi.c"
|
||||
"spi_flash_chip_mxic.c"
|
||||
"spi_flash_chip_gd.c"
|
||||
"spi_flash_chip_winbond.c"
|
||||
"memspi_host_driver.c")
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
REQUIRES hal
|
||||
PRIV_REQUIRES "${priv_requires}"
|
||||
INCLUDE_DIRS include
|
||||
PRIV_INCLUDE_DIRS private_include
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
list(APPEND cache_srcs
|
||||
"esp_flash_api.c"
|
||||
"esp_flash_spi_init.c"
|
||||
"spi_flash_os_func_app.c"
|
||||
"spi_flash_os_func_noos.c")
|
||||
# Avoid cache miss by unexpected inlineing when built by -Os
|
||||
set_source_files_properties(${cache_srcs} PROPERTIES COMPILE_FLAGS
|
||||
"-fno-inline-functions -fno-inline-small-functions -fno-inline-functions-called-once")
|
||||
|
||||
list(APPEND srcs ${cache_srcs})
|
||||
set(priv_requires bootloader_support app_update soc esp_ipc)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
REQUIRES hal
|
||||
PRIV_REQUIRES "${priv_requires}"
|
||||
INCLUDE_DIRS include
|
||||
PRIV_INCLUDE_DIRS private_include
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
# Avoid cache miss by unexpected inlineing when built by -Os
|
||||
set_source_files_properties(${cache_srcs} PROPERTIES COMPILE_FLAGS
|
||||
"-fno-inline-functions -fno-inline-small-functions -fno-inline-functions-called-once")
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_spi_flash_counters.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -419,43 +420,6 @@ extern const spi_flash_guard_funcs_t g_flash_guard_default_ops;
|
||||
*/
|
||||
extern const spi_flash_guard_funcs_t g_flash_guard_no_os_ops;
|
||||
|
||||
#if CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
||||
/**
|
||||
* Structure holding statistics for one type of operation
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t count; // number of times operation was executed
|
||||
uint32_t time; // total time taken, in microseconds
|
||||
uint32_t bytes; // total number of bytes
|
||||
} spi_flash_counter_t;
|
||||
|
||||
typedef struct {
|
||||
spi_flash_counter_t read;
|
||||
spi_flash_counter_t write;
|
||||
spi_flash_counter_t erase;
|
||||
} spi_flash_counters_t;
|
||||
|
||||
/**
|
||||
* @brief Reset SPI flash operation counters
|
||||
*/
|
||||
void spi_flash_reset_counters(void);
|
||||
|
||||
/**
|
||||
* @brief Print SPI flash operation counters
|
||||
*/
|
||||
void spi_flash_dump_counters(void);
|
||||
|
||||
/**
|
||||
* @brief Return current SPI flash operation counters
|
||||
*
|
||||
* @return pointer to the spi_flash_counters_t structure holding values
|
||||
* of the operation counters
|
||||
*/
|
||||
const spi_flash_counters_t* spi_flash_get_counters(void);
|
||||
|
||||
#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
66
components/spi_flash/include/esp_spi_flash_counters.h
Normal file
66
components/spi_flash/include/esp_spi_flash_counters.h
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Structure holding statistics for one type of operation
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t count; // number of times operation was executed
|
||||
uint32_t time; // total time taken, in microseconds
|
||||
uint32_t bytes; // total number of bytes
|
||||
} spi_flash_counter_t;
|
||||
|
||||
typedef struct {
|
||||
spi_flash_counter_t read;
|
||||
spi_flash_counter_t write;
|
||||
spi_flash_counter_t erase;
|
||||
} spi_flash_counters_t;
|
||||
|
||||
/**
|
||||
* @brief Reset SPI flash operation counters
|
||||
*/
|
||||
void spi_flash_reset_counters(void);
|
||||
|
||||
/**
|
||||
* @brief Print SPI flash operation counters
|
||||
*/
|
||||
void spi_flash_dump_counters(void);
|
||||
|
||||
/**
|
||||
* @brief Return current SPI flash operation counters
|
||||
*
|
||||
* @return pointer to the spi_flash_counters_t structure holding values
|
||||
* of the operation counters
|
||||
*/
|
||||
const spi_flash_counters_t* spi_flash_get_counters(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
|
7
components/spi_flash/mock/mock_config.yaml
Normal file
7
components/spi_flash/mock/mock_config.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
:cmock:
|
||||
:plugins:
|
||||
- expect
|
||||
- expect_any_args
|
||||
- return_thru_ptr
|
||||
- array
|
||||
- callback
|
149
components/spi_flash/sim/stubs/esp_common/esp_err.h
Normal file
149
components/spi_flash/sim/stubs/esp_common/esp_err.h
Normal file
@ -0,0 +1,149 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int32_t esp_err_t;
|
||||
|
||||
/* Definitions for error constants. */
|
||||
#define ESP_OK 0 /*!< esp_err_t value indicating success (no error) */
|
||||
#define ESP_FAIL -1 /*!< Generic esp_err_t code indicating failure */
|
||||
|
||||
#define ESP_ERR_NO_MEM 0x101 /*!< Out of memory */
|
||||
#define ESP_ERR_INVALID_ARG 0x102 /*!< Invalid argument */
|
||||
#define ESP_ERR_INVALID_STATE 0x103 /*!< Invalid state */
|
||||
#define ESP_ERR_INVALID_SIZE 0x104 /*!< Invalid size */
|
||||
#define ESP_ERR_NOT_FOUND 0x105 /*!< Requested resource not found */
|
||||
#define ESP_ERR_NOT_SUPPORTED 0x106 /*!< Operation or feature not supported */
|
||||
#define ESP_ERR_TIMEOUT 0x107 /*!< Operation timed out */
|
||||
#define ESP_ERR_INVALID_RESPONSE 0x108 /*!< Received response was invalid */
|
||||
#define ESP_ERR_INVALID_CRC 0x109 /*!< CRC or checksum was invalid */
|
||||
#define ESP_ERR_INVALID_VERSION 0x10A /*!< Version was invalid */
|
||||
#define ESP_ERR_INVALID_MAC 0x10B /*!< MAC address was invalid */
|
||||
|
||||
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
|
||||
#define ESP_ERR_MESH_BASE 0x4000 /*!< Starting number of MESH error codes */
|
||||
#define ESP_ERR_FLASH_BASE 0x6000 /*!< Starting number of flash error codes */
|
||||
|
||||
/**
|
||||
* @brief Returns string for esp_err_t error codes
|
||||
*
|
||||
* This function finds the error code in a pre-generated lookup-table and
|
||||
* returns its string representation.
|
||||
*
|
||||
* The function is generated by the Python script
|
||||
* tools/gen_esp_err_to_name.py which should be run each time an esp_err_t
|
||||
* error is modified, created or removed from the IDF project.
|
||||
*
|
||||
* @param code esp_err_t error code
|
||||
* @return string error message
|
||||
*/
|
||||
const char *esp_err_to_name(esp_err_t code);
|
||||
|
||||
/**
|
||||
* @brief Returns string for esp_err_t and system error codes
|
||||
*
|
||||
* This function finds the error code in a pre-generated lookup-table of
|
||||
* esp_err_t errors and returns its string representation. If the error code
|
||||
* is not found then it is attempted to be found among system errors.
|
||||
*
|
||||
* The function is generated by the Python script
|
||||
* tools/gen_esp_err_to_name.py which should be run each time an esp_err_t
|
||||
* error is modified, created or removed from the IDF project.
|
||||
*
|
||||
* @param code esp_err_t error code
|
||||
* @param[out] buf buffer where the error message should be written
|
||||
* @param buflen Size of buffer buf. At most buflen bytes are written into the buf buffer (including the terminating null byte).
|
||||
* @return buf containing the string error message
|
||||
*/
|
||||
const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen);
|
||||
|
||||
/** @cond */
|
||||
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn));
|
||||
|
||||
/** @cond */
|
||||
void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression);
|
||||
|
||||
#ifndef __ASSERT_FUNC
|
||||
/* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which
|
||||
uses /usr/include/assert.h or equivalent.
|
||||
*/
|
||||
#ifdef __ASSERT_FUNCTION
|
||||
#define __ASSERT_FUNC __ASSERT_FUNCTION /* used in glibc assert.h */
|
||||
#else
|
||||
#define __ASSERT_FUNC "??"
|
||||
#endif
|
||||
#endif
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* Macro which can be used to check the error code,
|
||||
* and terminate the program in case the code is not ESP_OK.
|
||||
* Prints the error code, error location, and the failed statement to serial output.
|
||||
*
|
||||
* Disabled if assertions are disabled.
|
||||
*/
|
||||
#ifdef NDEBUG
|
||||
#define ESP_ERROR_CHECK(x) do { \
|
||||
esp_err_t __err_rc = (x); \
|
||||
(void) sizeof(__err_rc); \
|
||||
} while(0)
|
||||
#elif defined(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT)
|
||||
#define ESP_ERROR_CHECK(x) do { \
|
||||
esp_err_t __err_rc = (x); \
|
||||
if (__err_rc != ESP_OK) { \
|
||||
abort(); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define ESP_ERROR_CHECK(x) do { \
|
||||
esp_err_t __err_rc = (x); \
|
||||
if (__err_rc != ESP_OK) { \
|
||||
_esp_error_check_failed(__err_rc, __FILE__, __LINE__, \
|
||||
__ASSERT_FUNC, #x); \
|
||||
} \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro which can be used to check the error code. Prints the error code, error location, and the failed statement to
|
||||
* serial output.
|
||||
* In comparison with ESP_ERROR_CHECK(), this prints the same error message but isn't terminating the program.
|
||||
*/
|
||||
#ifdef NDEBUG
|
||||
#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \
|
||||
esp_err_t __err_rc = (x); \
|
||||
__err_rc; \
|
||||
})
|
||||
#else
|
||||
#define ESP_ERROR_CHECK_WITHOUT_ABORT(x) ({ \
|
||||
esp_err_t __err_rc = (x); \
|
||||
if (__err_rc != ESP_OK) { \
|
||||
_esp_error_check_failed_without_abort(__err_rc, __FILE__, __LINE__, \
|
||||
__ASSERT_FUNC, #x); \
|
||||
} \
|
||||
__err_rc; \
|
||||
})
|
||||
#endif //NDEBUG
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
148
components/spi_flash/sim/stubs/soc/include/hal/spi_flash_types.h
Normal file
148
components/spi_flash/sim/stubs/soc/include/hal/spi_flash_types.h
Normal file
@ -0,0 +1,148 @@
|
||||
// Copyright 2010-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Definition of a common transaction. Also holds the return value. */
|
||||
typedef struct {
|
||||
uint8_t command; ///< Command to send, always 8bits
|
||||
uint8_t mosi_len; ///< Output data length, in bytes
|
||||
uint8_t miso_len; ///< Input data length, in bytes
|
||||
uint8_t address_bitlen; ///< Length of address in bits, set to 0 if command does not need an address
|
||||
uint32_t address; ///< Address to perform operation on
|
||||
const uint8_t *mosi_data; ///< Output data to salve
|
||||
uint8_t *miso_data; ///< [out] Input data from slave, little endian
|
||||
} spi_flash_trans_t;
|
||||
|
||||
/** @brief Mode used for reading from SPI flash */
|
||||
typedef enum {
|
||||
SPI_FLASH_SLOWRD = 0, ///< Data read using single I/O, some limits on speed
|
||||
SPI_FLASH_FASTRD, ///< Data read using single I/O, no limit on speed
|
||||
SPI_FLASH_DOUT, ///< Data read using dual I/O
|
||||
SPI_FLASH_DIO, ///< Both address & data transferred using dual I/O
|
||||
SPI_FLASH_QOUT, ///< Data read using quad I/O
|
||||
SPI_FLASH_QIO, ///< Both address & data transferred using quad I/O
|
||||
|
||||
SPI_FLASH_READ_MODE_MAX, ///< The fastest io mode supported by the host is ``ESP_FLASH_READ_MODE_MAX-1``.
|
||||
} esp_flash_io_mode_t;
|
||||
|
||||
struct spi_flash_host_driver_s;
|
||||
typedef struct spi_flash_host_driver_s spi_flash_host_driver_t;
|
||||
|
||||
/** SPI Flash Host driver instance */
|
||||
typedef struct {
|
||||
const struct spi_flash_host_driver_s* driver; ///< Pointer to the implementation function table
|
||||
// Implementations can wrap this structure into their own ones, and append other data here
|
||||
} spi_flash_host_inst_t ;
|
||||
|
||||
/** Host driver configuration and context structure. */
|
||||
struct spi_flash_host_driver_s {
|
||||
/**
|
||||
* Configure the device-related register before transactions. This saves
|
||||
* some time to re-configure those registers when we send continuously
|
||||
*/
|
||||
esp_err_t (*dev_config)(spi_flash_host_inst_t *host);
|
||||
/**
|
||||
* Send an user-defined spi transaction to the device.
|
||||
*/
|
||||
esp_err_t (*common_command)(spi_flash_host_inst_t *host, spi_flash_trans_t *t);
|
||||
/**
|
||||
* Read flash ID.
|
||||
*/
|
||||
esp_err_t (*read_id)(spi_flash_host_inst_t *host, uint32_t *id);
|
||||
/**
|
||||
* Erase whole flash chip.
|
||||
*/
|
||||
void (*erase_chip)(spi_flash_host_inst_t *host);
|
||||
/**
|
||||
* Erase a specific sector by its start address.
|
||||
*/
|
||||
void (*erase_sector)(spi_flash_host_inst_t *host, uint32_t start_address);
|
||||
/**
|
||||
* Erase a specific block by its start address.
|
||||
*/
|
||||
void (*erase_block)(spi_flash_host_inst_t *host, uint32_t start_address);
|
||||
/**
|
||||
* Read the status of the flash chip.
|
||||
*/
|
||||
esp_err_t (*read_status)(spi_flash_host_inst_t *host, uint8_t *out_sr);
|
||||
/**
|
||||
* Disable write protection.
|
||||
*/
|
||||
esp_err_t (*set_write_protect)(spi_flash_host_inst_t *host, bool wp);
|
||||
/**
|
||||
* Program a page of the flash. Check ``max_write_bytes`` for the maximum allowed writing length.
|
||||
*/
|
||||
void (*program_page)(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
|
||||
/** Check whether given buffer can be directly used to write */
|
||||
bool (*supports_direct_write)(spi_flash_host_inst_t *host, const void *p);
|
||||
/**
|
||||
* Slicer for write data. The `program_page` should be called iteratively with the return value
|
||||
* of this function.
|
||||
*
|
||||
* @param address Beginning flash address to write
|
||||
* @param len Length request to write
|
||||
* @param align_addr Output of the aligned address to write to
|
||||
* @param page_size Physical page size of the flash chip
|
||||
* @return Length that can be actually written in one `program_page` call
|
||||
*/
|
||||
int (*write_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr,
|
||||
uint32_t page_size);
|
||||
/**
|
||||
* Read data from the flash. Check ``max_read_bytes`` for the maximum allowed reading length.
|
||||
*/
|
||||
esp_err_t (*read)(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
|
||||
/** Check whether given buffer can be directly used to read */
|
||||
bool (*supports_direct_read)(spi_flash_host_inst_t *host, const void *p);
|
||||
/**
|
||||
* Slicer for read data. The `read` should be called iteratively with the return value
|
||||
* of this function.
|
||||
*
|
||||
* @param address Beginning flash address to read
|
||||
* @param len Length request to read
|
||||
* @param align_addr Output of the aligned address to read
|
||||
* @param page_size Physical page size of the flash chip
|
||||
* @return Length that can be actually read in one `read` call
|
||||
*/
|
||||
int (*read_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr, uint32_t page_size);
|
||||
/**
|
||||
* Check whether the host is idle to perform new operations.
|
||||
*/
|
||||
bool (*host_idle)(spi_flash_host_inst_t *host);
|
||||
/**
|
||||
* Configure the host to work at different read mode. Responsible to compensate the timing and set IO mode.
|
||||
*/
|
||||
esp_err_t (*configure_host_io_mode)(spi_flash_host_inst_t *host, uint32_t command,
|
||||
uint32_t addr_bitlen, int dummy_bitlen_base,
|
||||
esp_flash_io_mode_t io_mode);
|
||||
/**
|
||||
* Internal use, poll the HW until the last operation is done.
|
||||
*/
|
||||
void (*poll_cmd_done)(spi_flash_host_inst_t *host);
|
||||
/**
|
||||
* For some host (SPI1), they are shared with a cache. When the data is
|
||||
* modified, the cache needs to be flushed. Left NULL if not supported.
|
||||
*/
|
||||
esp_err_t (*flush_cache)(spi_flash_host_inst_t* host, uint32_t addr, uint32_t size);
|
||||
};
|
||||
///Slowest io mode supported by ESP32, currently SlowRd
|
||||
#define SPI_FLASH_READ_MODE_MIN SPI_FLASH_SLOWRD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -27,7 +27,7 @@ else()
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "include" "unity/src" "unity/extras/fixture/src")
|
||||
INCLUDE_DIRS ${includes})
|
||||
|
||||
if(NOT ${IDF_TARGET} STREQUAL "linux")
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC
|
||||
|
@ -46,7 +46,9 @@ ignore_files = [os.path.join('components', 'mdns', 'test_afl_fuzz_host', 'esp32_
|
||||
]
|
||||
|
||||
# add directories here which should not be parsed, this is a tuple since it will be used with *.startswith()
|
||||
ignore_dirs = (os.path.join('examples'), os.path.join('components', 'cmock', 'CMock', 'test'))
|
||||
ignore_dirs = (os.path.join('examples'),
|
||||
os.path.join('components', 'cmock', 'CMock', 'test'),
|
||||
os.path.join('components', 'spi_flash', 'sim'))
|
||||
|
||||
# macros from here have higher priorities in case of collisions
|
||||
priority_headers = [os.path.join('components', 'esp_common', 'include', 'esp_err.h')]
|
||||
|
Loading…
x
Reference in New Issue
Block a user