feat(spi_flash): Modify SPI flash driver

This commit is contained in:
Dong Heng
2018-06-05 13:33:48 +08:00
committed by Wu Jian Gang
parent 7f91cf4a0e
commit df9a5d6bb1
9 changed files with 536 additions and 906 deletions

View File

@ -133,4 +133,22 @@
#define PAD_XPD_DCDC_CONF (REG_RTC_BASE + 0x0A0) #define PAD_XPD_DCDC_CONF (REG_RTC_BASE + 0x0A0)
//}} //}}
//CACHE{{
#define CACHE_FLASH_CTRL_REG (0x3ff00000 + 0x0c)
#define CACHE_READ_EN_BIT BIT8
//}}
#define DRAM_BASE (0x3FFE8000)
#define DRAM_SIZE (96 * 1024)
#define IRAM_BASE (0x40100000)
#define IRAM_SIZE (48 * 1024)
#define FLASH_BASE (0x40200000)
#define FLASH_SIZE (16 * 1024 * 1024)
#define IS_DRAM(a) ((size_t)(a) >= DRAM_BASE && (size_t)(a) < (DRAM_BASE + DRAM_SIZE))
#define IS_IRAM(a) ((size_t)(a) >= IRAM_BASE && (size_t)(a) < (IRAM_BASE + IRAM_SIZE))
#define IS_FLASH(a) ((size_t)(a) >= FLASH_BASE && (size_t)(a) < (FLASH_BASE + FLASH_SIZE))
#endif //_EAGLE_SOC_H_ #endif //_EAGLE_SOC_H_

View File

@ -4,6 +4,15 @@
#include <stdint.h> #include <stdint.h>
#include <stdarg.h> #include <stdarg.h>
typedef struct esp_spi_flash_chip {
uint32_t deviceId;
uint32_t chip_size; // chip size in byte
uint32_t block_size;
uint32_t sector_size;
uint32_t page_size;
uint32_t status_mask;
} esp_spi_flash_chip_t;
uint32_t Wait_SPI_Idle(); uint32_t Wait_SPI_Idle();
void uart_div_modify(uint32_t uart_no, uint32_t baud_div); void uart_div_modify(uint32_t uart_no, uint32_t baud_div);
@ -15,4 +24,14 @@ void system_soft_wdt_feed();
void Cache_Read_Enable_New(); void Cache_Read_Enable_New();
int SPI_page_program(esp_spi_flash_chip_t *chip, uint32_t dst_addr, void *pbuf, uint32_t len);
int SPI_read_data(esp_spi_flash_chip_t *chip, uint32_t dst_addr, void *pbuf, uint32_t len);
int SPI_write_enable(esp_spi_flash_chip_t *chip);
int SPI_sector_erase(esp_spi_flash_chip_t *chip, uint32_t sect_addr);
int SPI_write_status(esp_spi_flash_chip_t *chip, uint32_t status);
int SPI_read_status(esp_spi_flash_chip_t *chip, uint32_t *status);
int Enable_QMode(esp_spi_flash_chip_t *chip);
void Cache_Read_Disable();
#endif #endif

View File

@ -103,7 +103,7 @@ SECTIONS
*(.init.literal) *(.init.literal)
*(.init) *(.init)
*(.iram1 .iram1.*) *(.iram1 .iram1.*)
*libcore.a:spi_flash.o(.literal .text .literal.* .text.*) *libspi_flash.a:spi_flash.o(.literal .text .literal.* .text.*)
*(.literal .text .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.literal .text .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal) *(.fini.literal)
*(.fini) *(.fini)

View File

@ -1,7 +1,7 @@
gwen: gwen:
crypto: 0181338 crypto: 0181338
espnow: 0181338 espnow: 0181338
core: 0181338 core: fddcd95
minic: 5fc5b4f minic: 5fc5b4f
net80211: fd9b17b net80211: fd9b17b
pp: 0181338 pp: 0181338

Binary file not shown.

View File

@ -123,7 +123,7 @@ task.h is included from an application file. */
#ifdef MEMLEAK_DEBUG #ifdef MEMLEAK_DEBUG
#include "spi_flash.h" #include "spi_flash.h"
extern SpiFlashChip flashchip; extern esp_spi_flash_chip_t flashchip;
#endif #endif
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE

View File

@ -0,0 +1,15 @@
// Copyright 2018-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.
#include "spi_flash.h"

View File

@ -1,167 +1,154 @@
/* // Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
* ESPRSSIF MIT License //
* // Licensed under the Apache License, Version 2.0 (the "License");
* Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD> // you may not use this file except in compliance with the License.
* // You may obtain a copy of the License at
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, //
* it is free of charge, to any person obtaining a copy of this software and associated // http://www.apache.org/licenses/LICENSE-2.0
* documentation files (the "Software"), to deal in the Software without restriction, including //
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, // Unless required by applicable law or agreed to in writing, software
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished // distributed under the License is distributed on an "AS IS" BASIS,
* to do so, subject to the following conditions: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* // See the License for the specific language governing permissions and
* The above copyright notice and this permission notice shall be included in all copies or // limitations under the License.
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __SPI_FLASH_H__ #ifndef _SPI_FLASH_H
#define __SPI_FLASH_H__ #define _SPI_FLASH_H
#include <stdint.h> #include <stdint.h>
#include <stddef.h>
#include "esp_err.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** \defgroup Driver_APIs Driver APIs #define ESP_ERR_FLASH_BASE 0x10010
* @brief Driver APIs #define ESP_ERR_FLASH_OP_FAIL (ESP_ERR_FLASH_BASE + 1)
*/ #define ESP_ERR_FLASH_OP_TIMEOUT (ESP_ERR_FLASH_BASE + 2)
/** @addtogroup Driver_APIs
* @{
*/
/** \defgroup SPI_Driver_APIs SPI Driver APIs
* @brief SPI Flash APIs
*/
/** @addtogroup SPI_Driver_APIs
* @{
*/
typedef enum {
SPI_FLASH_RESULT_OK, /**< SPI Flash operating OK */
SPI_FLASH_RESULT_ERR, /**< SPI Flash operating fail */
SPI_FLASH_RESULT_TIMEOUT /**< SPI Flash operating time out */
} SpiFlashOpResult;
typedef struct{
uint32_t deviceId;
uint32_t chip_size; // chip size in byte
uint32_t block_size;
uint32_t sector_size;
uint32_t page_size;
uint32_t status_mask;
} SpiFlashChip;
#define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */ #define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */
#ifdef CONFIG_ENABLE_FLASH_MMAP
/** /**
* @brief Get ID info of SPI Flash. * @brief Enumeration which specifies memory space requested in an mmap call
*
* @param null
*
* @return SPI Flash ID
*/ */
uint32_t spi_flash_get_id(void); typedef enum {
SPI_FLASH_MMAP_DATA, /**< map to data memory (Vaddr0), allows byte-aligned access, 4 MB total */
SPI_FLASH_MMAP_INST, /**< map to instruction memory (Vaddr1-3), allows only 4-byte-aligned access, 11 MB total */
} spi_flash_mmap_memory_t;
/** /**
* @brief Read state register of SPI Flash. * @brief Opaque handle for memory region obtained from spi_flash_mmap.
*
* @param uint32_t *status : the read value (pointer) of state register.
*
* @return SpiFlashOpResult
*/ */
SpiFlashOpResult spi_flash_read_status(uint32_t *status); typedef uint32_t spi_flash_mmap_handle_t;
#endif
/**
* @brief Write state register of SPI Flash.
*
* @param uint32_t status_value : Write state register value.
*
* @return SpiFlashOpResult
*/
SpiFlashOpResult spi_flash_write_status(uint32_t status_value);
/** /**
* @brief Erase the Flash sector. * @brief Erase the Flash sector.
* *
* @param uint16_t sec : Sector number, the count starts at sector 0, 4KB per sector. * @param sector Sector number, the count starts at sector 0, 4KB per sector.
* *
* @return SpiFlashOpResult * @return esp_err_t
*/ */
SpiFlashOpResult spi_flash_erase_sector(uint16_t sec); esp_err_t spi_flash_erase_sector(size_t sector);
/**
* @brief Erase a range of flash sectors
*
* @param start_address Address where erase operation has to start.
* Must be 4kB-aligned
* @param size Size of erased range, in bytes. Must be divisible by 4kB.
*
* @return esp_err_t
*/
esp_err_t spi_flash_erase_range(size_t start_address, size_t size);
/** /**
* @brief Write data to Flash. * @brief Write data to Flash.
* *
* @param uint32_t des_addr : destination address in Flash. * @note For fastest write performance, write a 4 byte aligned size at a
* @param uint32_t *src_addr : source address of the data. * 4 byte aligned offset in flash from a source buffer in DRAM. Varying any of
* @param uint32_t size : length of data * these parameters will still work, but will be slower due to buffering.
* *
* @return SpiFlashOpResult * @note Writing more than 8KB at a time will be split into multiple
* write operations to avoid disrupting other tasks in the system.
*
* @param dest_addr Destination address in Flash.
* @param src Pointer to the source buffer.
* @param size Length of data, in bytes.
*
* @return esp_err_t
*/ */
SpiFlashOpResult spi_flash_write(uint32_t des_addr, uint32_t *src_addr, uint32_t size); esp_err_t spi_flash_write(size_t dest_addr, const void *src, size_t size);
/** /**
* @brief Read data from Flash. * @brief Read data from Flash.
* *
* @param uint32_t src_addr : source address of the data. * @note For fastest read performance, all parameters should be
* @param uint32_t *des_addr : destination address in Flash. * 4 byte aligned. If source address and read size are not 4 byte
* @param uint32_t size : length of data * aligned, read may be split into multiple flash operations. If
* destination buffer is not 4 byte aligned, a temporary buffer will
* be allocated on the stack.
* *
* @return SpiFlashOpResult * @note Reading more than 16KB of data at a time will be split
* into multiple reads to avoid disruption to other tasks in the
* system. Consider using spi_flash_mmap() to read large amounts
* of data.
*
* @param src_addr source address of the data in Flash.
* @param dest pointer to the destination buffer
* @param size length of data
*
*
* @return esp_err_t
*/ */
SpiFlashOpResult spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size); esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size);
#ifdef CONFIG_ENABLE_FLASH_MMAP
/** /**
* @brief Registered function for spi_flash_set_read_func. * @brief Map region of flash memory into data or instruction address space
* *
* @attention used for sdk internal, don't need to care about params * This function allocates sufficient number of 64kB MMU pages and configures
* them to map the requested region of flash memory into the address space.
* It may reuse MMU pages which already provide the required mapping.
* *
* @param SpiFlashChip *spi : spi flash struct pointer. * As with any allocator, if mmap/munmap are heavily used then the address space
* @param uint32_t src_addr : source address of the data. * may become fragmented. To troubleshoot issues with page allocation, use
* @param uint32_t *des_addr : destination address in Flash. * spi_flash_mmap_dump() function.
* @param uint32_t size : length of data
* *
* @return SpiFlashOpResult * @param src_addr Physical address in flash where requested region starts.
* This address *must* be aligned to 64kB boundary
* (SPI_FLASH_MMU_PAGE_SIZE)
* @param size Size of region to be mapped. This size will be rounded
* up to a 64kB boundary
* @param memory Address space where the region should be mapped (data or instruction)
* @param out_ptr Output, pointer to the mapped memory region
* @param out_handle Output, handle which should be used for spi_flash_munmap call
*
* @return ESP_OK on success, ESP_ERR_NO_MEM if pages can not be allocated
*/ */
typedef SpiFlashOpResult (* user_spi_flash_read)( esp_err_t spi_flash_mmap(size_t src_addr, size_t size, spi_flash_mmap_memory_t memory,
SpiFlashChip *spi, const void** out_ptr, spi_flash_mmap_handle_t* out_handle);
uint32_t src_addr,
uint32_t *des_addr,
uint32_t size);
/** /**
* @brief Register user-define SPI flash read API. * @brief Release region previously obtained using spi_flash_mmap
* *
* @attention This API can be only used in SPI overlap mode, please refer to ESP8266_RTOS_SDK * @note Calling this function will not necessarily unmap memory region.
* \examples\driver_lib\driver\spi_overlap.c * Region will only be unmapped when there are no other handles which
* reference this region. In case of partially overlapping regions
* it is possible that memory will be unmapped partially.
* *
* @param user_spi_flash_read read : user-define SPI flash read API . * @param handle Handle obtained from spi_flash_mmap
*
* @return none
*/ */
void spi_flash_set_read_func(user_spi_flash_read read); void spi_flash_munmap(spi_flash_mmap_handle_t handle);
/** #endif /* CONFIG_ENABLE_FLASH_MMAP */
* @}
*/
/**
* @}
*/
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif /* _SPI_FLASH_H */

File diff suppressed because it is too large Load Diff