Files
esp-idf/components/spi_flash/include/spi_flash_lowlevel_generic.h
2019-06-18 06:32:52 +00:00

152 lines
7.1 KiB
C

#pragma once
#include "spi_flash_lowlevel_driver.h"
/* The 'generic' SPI flash operations are a lowest common subset of SPI flash commands, that work across most chips.
*
* These can be used as-is vai the esp_flash_common_chip_driver driver, or they can be used as "base driver" functions when
* creating a new esp_flash_driver_t driver structure.
*
*
* All of the functions in this header are internal functions, not part of a public API. See spi_flash_lowlevel.h for
* the public API.
*/
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
Suitable for use with spi_flash_common_command static function.
*/
#define CMD_RDID 0x9F
#define CMD_WRSR 0x01
#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */
#define CMD_WREN 0x06
#define CMD_WRDI 0x04
#define CMD_RDSR 0x05
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
#define CMD_FASTRD_QIO 0xEB
#define CMD_FASTRD_QUAD 0x6B
#define CMD_FASTRD_DIO 0xBB
#define CMD_FASTRD_DUAL 0x3B
#define CMD_FASTRD 0x0B
#define CMD_READ 0x03 /* Speed limited */
#define CMD_CHIP_ERASE 0xC7
#define CMD_SECTOR_ERASE 0x20
#define CMD_LARGE_BLOCK_ERASE 0xD8 /* 64KB block erase command */
#define SR_WIP (1<<0) /* Status register write-in-progress bit */
#define SR_WREN (1<<1) /* Status register write enable bit */
/** @brief Execute a simple SPI flash command against the chip.
*
* @param chip Pointer to the chip to use.
* @param command Command to execute (an on-wire hex command.)
* @param mosi_data Up to 32 bits of MOSI data to write after the command.
* @param mosi_len Length of MOSI data (in bits.)
* @param miso_len Length of MISO data (in bits.)
* @return MISO value read back, if any (depending on miso_len value.)
*/
uint32_t spi_flash_common_command(const esp_flash_chip_t *chip, uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len);
/** @brief Returns true if the pin configuration for this chip uses the GPIO matrix for any signals. */
bool spi_flash_uses_gpio_matrix(const esp_flash_chip_t *chip);
/** @brief Generic probe function
*
* If chip->drv_read_id succeeds, the probe succeeds.
*/
esp_flash_err_t spi_flash_generic_probe(esp_flash_chip_t *chip, uint32_t flash_id);
/** @brief Generic implementation of esp_flash_driver_t->read_id
*
* Uses the RDID command (9Fh) supported by most SPI flash chips.
*
* Results of all-zeroes or all-ones are considered failures (probably no chip attached.)
*/
esp_flash_err_t spi_flash_generic_read_id(const esp_flash_chip_t *chip, uint32_t *id);
/** @brief Generic size detection function
*
* Tries to detect the size of chip by using the lower 4 bits of the chip->drv->read_id result = N, and assuming size is 2 ^ N.
*/
esp_flash_err_t spi_flash_generic_detect_size(const esp_flash_chip_t *chip, uint32_t *size);
/** @brief Erase chip by using the generic erase chip (C7h) command. */
esp_flash_err_t spi_flash_generic_erase_chip(const esp_flash_chip_t *chip);
/** @brief Erase sector by using the generic sector erase (20h) command. */
esp_flash_err_t spi_flash_generic_erase_sector(const esp_flash_chip_t *chip, uint32_t start_address);
/** @brief Erase block by using the generic 64KB block erase (D8h) command */
esp_flash_err_t spi_flash_generic_erase_block(const esp_flash_chip_t *chip, uint32_t start_address);
/** @brief Read from flash by using a read command that matches the programmed read mode. */
esp_flash_err_t spi_flash_generic_read(const esp_flash_chip_t *chip, void *buffer, uint32_t address, uint32_t length);
/** @brief Perform a page program using the page program (02h) command. */
esp_flash_err_t spi_flash_generic_page_program(const esp_flash_chip_t *chip, uint32_t address, const void *buffer, uint32_t length);
/** @brief Perform a generic write. Split the write buffer into
one page operations, and call chip->drv->page-program() for each.
*/
esp_flash_err_t spi_flash_generic_write(const esp_flash_chip_t *chip, uint32_t address, const void *buffer, uint32_t length);
/** @brief Perform a write using on-chip flash encryption */
esp_flash_err_t spi_flash_generic_write_encrypted(const esp_flash_chip_t *chip, uint32_t address, const void *buffer, uint32_t length);
/** @brief Send the write enable (06h) command and verify the expected bit (1) in the status register is set. */
esp_flash_err_t spi_flash_generic_write_enable(const esp_flash_chip_t *chip);
/** @brief Wait for the SPI host hardware state machine to be idle.
This isn't a flash driver operation, but it's called by spi_flash_generic_wait_idle() and may be useful when implementing alternative drivers.
timeout_ms will be decremented if the function needs to wait until the host hardware is idle.
*/
esp_flash_err_t spi_flash_generic_wait_host_idle(const esp_flash_chip_t *chip, uint32_t *timeout_ms);
/** @brief Read flash status via the RDSR command (05h) and wait for bit 0 (write in progress bit) to be cleared. */
esp_flash_err_t spi_flash_generic_wait_idle(const esp_flash_chip_t *chip, uint32_t timeout_ms);
/** @brief Utility function to configure the SPI host hardware registers for the specified read mode.
Called by spi_flash_generic_set_read_mode() but may also be useful
when implementing other SPI flash drivers.
Note that calling this configures SPI host registers, so if running any other commands as part of set_read_mode() then these must be run before calling this function.
*/
esp_flash_err_t spi_flash_common_configure_host_read_mode(const esp_flash_chip_t *chip);
/** @brief Utility function for set_read_mode driver function
*
* Most setting of read mode follows a common pattern, except for how to enable Quad I/O modes (QIO/QOUT).
* These use different commands to read/write the status register, and a different bit is set/cleared.
*
* This is a generic utility function to implement set_read_mode() for this pattern. Also configures host
* registers via spi_flash_common_configure_host_read_mode().
*
* @param qe_rdsr_command SPI flash command to read status register
* @param qe_wrsr_command SPI flash command to write status register
* @param qe_sr_bitwidth Width of the status register these commands operate on, in bits.
* @param qe_sr_bit Bit mask for enabling Quad Enable functions on this chio.
*/
esp_flash_err_t spi_flash_common_set_read_mode(const esp_flash_chip_t *chip, uint8_t qe_rdsr_command, uint8_t qe_wrsr_command, uint8_t qe_sr_bitwidth, unsigned qe_sr_bit);
/** @brief Set the specified SPI read mode.
*
* Includes setting SPI host hardware registers, but also setting quad enable status register bit if needed.
*/
esp_flash_err_t spi_flash_generic_set_read_mode(const esp_flash_chip_t *chip);
/** @brief Returns true if chip is configured for Quad I/O or
Quad Fast Read */
inline static bool spi_flash_is_quad_mode(const esp_flash_chip_t *chip)
{
return chip->read_mode == ESP_FLASH_QIO || chip->read_mode == ESP_FLASH_QOUT;
}
/* Generic SPI flash driver, uses all the above functions for its operations. In default autodetection, this is used as
a catchall if a more specific driver is not found.
*/
extern const esp_flash_driver_t esp_flash_generic_chip_driver;