risc-v/esp32c3: Add SPIFlash support

Co-Authored-By: Dong Heng <dongheng@espressif.com>
Co-authored-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
Co-authored-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
This commit is contained in:
Alan Carvalho de Assis 2021-03-20 13:27:56 -03:00 committed by Abdelatif Guettouche
parent 653bbdedec
commit 4f8ff0765f
8 changed files with 2601 additions and 0 deletions

View File

@ -216,6 +216,13 @@ config ESP32C3_TIMER1
---help---
Enables Timer 1
config ESP32C3_SPIFLASH
bool "SPI Flash"
default n
select MTD
select MTD_BYTE_WRITE
select MTD_PARTITION
config ESP32C3_MWDT0
bool "Main System Watchdog Timer (Group 0)"
default n
@ -301,6 +308,13 @@ config ESP32C3_UART1_RXPIN
endif # ESP32C3_UART1
config ESP32C3_PARTITION
bool "ESP32-C3 Partition"
default n
select ESP32C3_SPIFLASH
---help---
Decode partition file and initialize partition as MTD.
endmenu
menu "Real-Time Timer"
@ -383,4 +397,42 @@ config ESP32C3_WIFI_FS_MOUNTPT
endmenu # ESP32C3_WIRELESS
menu "SPI Flash configuration"
depends on ESP32C3_SPIFLASH
config ESP32C3_MTD_OFFSET
hex "MTD base address in SPI Flash"
default 0x180000
help
MTD base address in SPI Flash.
config ESP32C3_MTD_SIZE
hex "MTD size in SPI Flash"
default 0x100000
help
MTD size in SPI Flash.
config ESP32C3_SPIFLASH_DEBUG
bool "Debug SPI Flash"
default n
depends on DEBUG_FS_INFO
help
If this option is enabled, SPI Flash driver read and write functions
will output input parameters and return values (if applicable).
endmenu # ESP32C3_SPIFLASH
menu "Partition Configuration"
depends on ESP32C3_PARTITION
config ESP32C3_PARTITION_OFFSET
hex "Partition offset"
default "0x8000"
config ESP32C3_PARTITION_MOUNT
string "Partition mount point"
default "/dev/esp/partition/"
endmenu # ESP32C3_PARTITION
endif # ARCH_CHIP_ESP32C3

View File

@ -63,6 +63,14 @@ ifeq ($(CONFIG_ESP32C3_I2C),y)
CHIP_CSRCS += esp32c3_i2c.c
endif
ifeq ($(CONFIG_ESP32C3_SPIFLASH),y)
CHIP_CSRCS += esp32c3_spiflash.c
endif
ifeq ($(CONFIG_ESP32C3_PARTITION),y)
CHIP_CSRCS += esp32c3_partition.c
endif
ifeq ($(CONFIG_ESP32C3_WDT),y)
CHIP_CSRCS += esp32c3_wdt.c
ifeq ($(CONFIG_WATCHDOG),y)

View File

@ -0,0 +1,678 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp32c3_partition.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <string.h>
#include <debug.h>
#include <stdio.h>
#include <sys/errno.h>
#include <nuttx/kmalloc.h>
#include "esp32c3_spiflash.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Partition table max size */
#define PARTITION_MAX_SIZE (0xc00)
/* Partition table header magic value */
#define PARTITION_MAGIC (0x50aa)
/* Partition table member label length */
#define PARTITION_LABEL_LEN (16)
/* OTA data offset in OTA partition */
#define OTA_DATA_OFFSET (4096)
/* OTA data number */
#define OTA_DATA_NUM (2)
/* Partition offset in SPI Flash */
#define ESP32C3_PARTITION_OFFSET CONFIG_ESP32C3_PARTITION_OFFSET
/* Partition MTD device mount point */
#define ESP32C3_PARTITION_MOUNT CONFIG_ESP32C3_PARTITION_MOUNT
/****************************************************************************
* Private Types
****************************************************************************/
/* OTA image operation code */
enum ota_img_ctrl_e
{
OTA_IMG_GET_BOOT = 0xe1,
OTA_IMG_SET_BOOT = 0xe2
};
/* OTA image state */
enum ota_img_state_e
{
/**
* Monitor the first boot. In bootloader of esp-idf this state is changed
* to ESP_OTA_IMG_PENDING_VERIFY if this bootloader enable app rollback.
*
* So this driver doesn't use this state currently.
*/
OTA_IMG_NEW = 0x0,
/**
* First boot for this app was. If while the second boot this state is then
* it will be changed to ABORTED if this bootloader enable app rollback.
*
* So this driver doesn't use this state currently.
*/
OTA_IMG_PENDING_VERIFY = 0x1,
/* App was confirmed as workable. App can boot and work without limits. */
OTA_IMG_VALID = 0x2,
/* App was confirmed as non-workable. This app will not selected to boot. */
OTA_IMG_INVALID = 0x3,
/**
* App could not confirm the workable or non-workable. In bootloader
* IMG_PENDING_VERIFY state will be changed to IMG_ABORTED. This app will
* not selected to boot at all if this bootloader enable app rollback.
*
* So this driver doesn't use this state currently.
*/
OTA_IMG_ABORTED = 0x4,
/**
* Undefined. App can boot and work without limits in esp-idf.
*
* This state is not used.
*/
OTA_IMG_UNDEFINED = 0xffffffff,
};
/* OTA image boot sequency */
enum ota_img_bootseq_e
{
OTA_IMG_BOOT_FACTORY = 0,
OTA_IMG_BOOT_OTA_0 = 1,
OTA_IMG_BOOT_OTA_1 = 2,
OTA_IMG_BOOT_SEQ_MAX
};
/* Partition information data */
struct partition_info_priv_s
{
uint16_t magic; /* Partition magic */
uint8_t type; /* Partition type */
uint8_t subtype; /* Partition sub-type */
uint32_t offset; /* Offset in SPI Flash */
uint32_t size; /* Size by byte */
uint8_t label[PARTITION_LABEL_LEN]; /* Partition label */
uint32_t flags; /* Partition flags */
};
/* Partition device data */
struct mtd_dev_priv_s
{
struct mtd_dev_s mtd; /* MTD data */
uint8_t type; /* Partition type */
uint8_t subtype; /* Partition sub-type */
uint32_t flags; /* Partition flags */
struct mtd_dev_s *ll_mtd; /* Low-level MTD data */
struct mtd_dev_s *part_mtd; /* Partition MTD data */
};
/* OTA data entry */
struct ota_data_entry_s
{
uint32_t ota_seq; /* Boot sequence */
uint8_t seq_label[20]; /* Boot sequence label */
uint32_t ota_state; /* Boot entry state */
uint32_t crc; /* Boot ota_seq CRC32 */
};
/****************************************************************************
* External Function Prototypes
****************************************************************************/
extern uint32_t crc32_le(uint32_t crc, uint8_t const *buf, uint32_t len);
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ota_is_valid
*
* Description:
* Check if OTA data is valid
*
* Input Parameters:
* ota_data - OTA data
*
* Returned Value:
* true if checking success or false if fail
*
****************************************************************************/
static bool ota_is_valid(struct ota_data_entry_s *ota_data)
{
if ((ota_data->ota_seq >= OTA_IMG_BOOT_SEQ_MAX) ||
(ota_data->ota_state != OTA_IMG_VALID) ||
(ota_data->crc != crc32_le(UINT32_MAX, (uint8_t *)ota_data, 4)))
{
return false;
}
return true;
}
/****************************************************************************
* Name: ota_get_bootseq
*
* Description:
* Get boot sequence
*
* Input Parameters:
* dev - Partition private MTD data
* num - boot sequence buffer
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
static int ota_get_bootseq(struct mtd_dev_priv_s *dev, int *num)
{
int i;
int ret;
struct ota_data_entry_s ota_data;
int size = sizeof(struct ota_data_entry_s);
/* Each OTA data locates in independent sector */
for (i = 0; i < OTA_DATA_NUM; i++)
{
ret = MTD_READ(dev->part_mtd, i * OTA_DATA_OFFSET,
size, (uint8_t *)&ota_data);
if (ret != size)
{
ferr("ERROR: Failed to read OTA%d data error=%d\n", i, ret);
return -EIO;
}
if (ota_is_valid(&ota_data))
{
*num = i + OTA_IMG_BOOT_OTA_0;
break;
}
}
if (i >= 2)
{
*num = OTA_IMG_BOOT_FACTORY;
}
return 0;
}
/****************************************************************************
* Name: ota_set_bootseq
*
* Description:
* Set boot sequence
*
* Input Parameters:
* dev - Partition private MTD data
* num - boot sequence buffer
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
static int ota_set_bootseq(struct mtd_dev_priv_s *dev, int num)
{
int ret;
int id;
int old_id;
struct ota_data_entry_s ota_data;
int size = sizeof(struct ota_data_entry_s);
finfo("INFO: num=%d\n", num);
switch (num)
{
case OTA_IMG_BOOT_FACTORY:
/* Erase all OTA data to force use factory app */
ret = MTD_ERASE(dev->part_mtd, 0, OTA_DATA_NUM);
if (ret != OTA_DATA_NUM)
{
ferr("ERROR: Failed to erase OTA data error=%d\n", ret);
return -EIO;
}
break;
case OTA_IMG_BOOT_OTA_0:
case OTA_IMG_BOOT_OTA_1:
{
id = num - 1;
old_id = num == OTA_IMG_BOOT_OTA_0 ? OTA_IMG_BOOT_OTA_1 - 1:
OTA_IMG_BOOT_OTA_0 - 1;
ret = MTD_ERASE(dev->part_mtd, id, 1);
if (ret != 1)
{
ferr("ERROR: Failed to erase OTA%d data error=%d\n", id, ret);
return -EIO;
}
ota_data.ota_state = OTA_IMG_VALID;
ota_data.ota_seq = num;
ota_data.crc = crc32_le(UINT32_MAX, (uint8_t *)&ota_data, 4);
ret = MTD_WRITE(dev->part_mtd, id * OTA_DATA_OFFSET,
size, (uint8_t *)&ota_data);
if (ret != size)
{
ferr("ERROR: Failed to write OTA%d data error=%d\n",
id, ret);
return -1;
}
/* Erase old OTA data to force new OTA bin */
ret = MTD_ERASE(dev->part_mtd, old_id, 1);
if (ret != 1)
{
ferr("ERROR: Failed to erase OTA%d data error=%d\n",
old_id, ret);
return -EIO;
}
}
break;
default:
ferr("ERROR: num=%d is error\n", num);
return -EINVAL;
}
return 0;
}
/****************************************************************************
* Name: esp32c3_part_erase
*
* Description:
* Erase SPI Flash designated sectors.
*
* Input Parameters:
* dev - ESP32-C3 MTD device data
* startblock - start block number, it is not equal to SPI Flash's block
* nblocks - blocks number
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
static int esp32c3_part_erase(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks)
{
struct mtd_dev_priv_s *mtd_priv = (struct mtd_dev_priv_s *)dev;
return MTD_ERASE(mtd_priv->ll_mtd, startblock, nblocks);
}
/****************************************************************************
* Name: esp32c3_part_read
*
* Description:
* Read data from SPI Flash at designated address.
*
* Input Parameters:
* dev - ESP32-C3 MTD device data
* offset - target address offset
* nbytes - data number
* buffer - data buffer pointer
*
* Returned Value:
* Read data bytes if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_part_read(FAR struct mtd_dev_s *dev, off_t offset,
size_t nbytes, FAR uint8_t *buffer)
{
struct mtd_dev_priv_s *mtd_priv = (struct mtd_dev_priv_s *)dev;
return MTD_READ(mtd_priv->ll_mtd, offset, nbytes, buffer);
}
/****************************************************************************
* Name: esp32c3_part_bread
*
* Description:
* Read data from designated blocks.
*
* Input Parameters:
* dev - ESP32-C3 MTD device data
* startblock - start block number, it is not equal to SPI Flash's block
* nblocks - blocks number
* buffer - data buffer pointer
*
* Returned Value:
* Read block number if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_part_bread(FAR struct mtd_dev_s *dev,
off_t startblock, size_t nblocks,
FAR uint8_t *buffer)
{
struct mtd_dev_priv_s *mtd_priv = (struct mtd_dev_priv_s *)dev;
return MTD_BREAD(mtd_priv->ll_mtd, startblock, nblocks, buffer);
}
/****************************************************************************
* Name: esp32c3_part_write
*
* Description:
* write data to SPI Flash at designated address.
*
* Input Parameters:
* dev - ESP32-C3 MTD device data
* offset - target address offset
* nbytes - data number
* buffer - data buffer pointer
*
* Returned Value:
* Written bytes if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_part_write(FAR struct mtd_dev_s *dev, off_t offset,
size_t nbytes, FAR const uint8_t *buffer)
{
struct mtd_dev_priv_s *mtd_priv = (struct mtd_dev_priv_s *)dev;
return MTD_WRITE(mtd_priv->ll_mtd, offset, nbytes, buffer);
}
/****************************************************************************
* Name: esp32c3_part_bwrite
*
* Description:
* Write data to designated blocks.
*
* Input Parameters:
* dev - ESP32-C3 MTD device data
* startblock - start MTD block number,
* it is not equal to SPI Flash's block
* nblocks - blocks number
* buffer - data buffer pointer
*
* Returned Value:
* Written block number if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_part_bwrite(FAR struct mtd_dev_s *dev,
off_t startblock, size_t nblocks,
FAR const uint8_t *buffer)
{
struct mtd_dev_priv_s *mtd_priv = (struct mtd_dev_priv_s *)dev;
return MTD_BWRITE(mtd_priv->ll_mtd, startblock, nblocks, buffer);
}
/****************************************************************************
* Name: esp32c3_part_ioctl
*
* Description:
* Set/Get option to/from ESP32-C3 SPI Flash MTD device data.
*
* Input Parameters:
* dev - ESP32-C3 MTD device data
* cmd - operation command
* arg - operation argument
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
static int esp32c3_part_ioctl(FAR struct mtd_dev_s *dev, int cmd,
unsigned long arg)
{
int ret;
struct mtd_dev_priv_s *mtd_priv = (struct mtd_dev_priv_s *)dev;
finfo("INFO: cmd=%d(0x%x) arg=0x%" PRIx32 "\n", cmd, cmd, arg);
if (!_MTDIOCVALID(cmd))
{
ferr("ERROR: cmd=%d(0x%x) is error\n", cmd, cmd);
return -EINVAL;
}
switch (_IOC_NR(cmd))
{
case OTA_IMG_GET_BOOT:
{
int *num = (int *)arg;
ret = ota_get_bootseq(mtd_priv, num);
if (ret < 0)
{
ferr("ERROR: Failed to get boot img\n");
}
}
break;
case OTA_IMG_SET_BOOT:
{
ret = ota_set_bootseq(mtd_priv, arg);
if (ret < 0)
{
ferr("ERROR: Failed to set boot img\n");
}
}
break;
default:
{
ret = MTD_IOCTL(mtd_priv->ll_mtd, cmd, arg);
}
break;
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: esp32c3_partition_init
*
* Initialize ESP32-C3 partition. Read partition information, and use
* these data for creating MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
int esp32c3_partition_init(void)
{
int i;
struct partition_info_priv_s *info;
uint8_t *pbuf;
struct mtd_dev_s *mtd;
struct mtd_dev_s *mtd_part;
struct mtd_geometry_s geo;
struct mtd_dev_priv_s *mtd_priv;
int ret = 0;
const int num = PARTITION_MAX_SIZE / sizeof(struct partition_info_priv_s);
const char path_base[] = ESP32C3_PARTITION_MOUNT;
char label[PARTITION_LABEL_LEN + 1];
char path[PARTITION_LABEL_LEN + sizeof(path_base)];
pbuf = kmm_malloc(PARTITION_MAX_SIZE);
if (pbuf == NULL)
{
ferr("ERROR: Failed to allocate %d byte\n", PARTITION_MAX_SIZE);
ret = -ENOMEM;
goto errout_with_malloc;
}
mtd = esp32c3_spiflash_mtd();
if (mtd == NULL)
{
ferr("ERROR: Failed to get SPI flash MTD\n");
ret = -EIO;
goto errout_with_mtd;
}
ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)&geo);
if (ret < 0)
{
ferr("ERROR: Failed to get info from MTD\n");
ret = -EIO;
goto errout_with_mtd;
}
ret = MTD_READ(mtd, ESP32C3_PARTITION_OFFSET,
PARTITION_MAX_SIZE, pbuf);
if (ret != PARTITION_MAX_SIZE)
{
ferr("ERROR: Failed to get read data from MTD\n");
ret = -EIO;
goto errout_with_mtd;
}
info = (struct partition_info_priv_s *)pbuf;
for (i = 0; i < num; i++)
{
if (info->magic != PARTITION_MAGIC)
{
break;
}
strncpy(label, (char *)info->label, PARTITION_LABEL_LEN);
label[PARTITION_LABEL_LEN] = '\0';
sprintf(path, "%s%s", path_base, label);
finfo("INFO: [label]: %s\n", label);
finfo("INFO: [type]: %d\n", info->type);
finfo("INFO: [subtype]: %d\n", info->subtype);
finfo("INFO: [offset]: 0x%08" PRIx32 "\n", info->offset);
finfo("INFO: [size]: 0x%08" PRIx32 "\n", info->size);
finfo("INFO: [flags]: 0x%08" PRIx32 "\n", info->flags);
finfo("INFO: [mount]: %s\n", path);
mtd_priv = kmm_malloc(sizeof(struct mtd_dev_priv_s));
if (!mtd_priv)
{
ferr("ERROR: Failed to allocate %d byte\n",
sizeof(struct mtd_dev_priv_s));
ret = -1;
goto errout_with_mtd;
}
mtd_priv->ll_mtd = mtd;
mtd_priv->mtd.bread = esp32c3_part_bread;
mtd_priv->mtd.bwrite = esp32c3_part_bwrite;
mtd_priv->mtd.erase = esp32c3_part_erase;
mtd_priv->mtd.ioctl = esp32c3_part_ioctl;
mtd_priv->mtd.read = esp32c3_part_read;
mtd_priv->mtd.write = esp32c3_part_write;
mtd_priv->mtd.name = label;
mtd_part = mtd_partition(&mtd_priv->mtd,
info->offset / geo.blocksize,
info->size / geo.blocksize);
if (!mtd_part)
{
ferr("ERROR: Failed to create MTD partition\n");
kmm_free(mtd_priv);
ret = -1;
goto errout_with_mtd;
}
mtd_priv->part_mtd = mtd_part;
ret = register_mtddriver(path, mtd_part, 0777, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to regitser MTD @ %s\n", path);
kmm_free(mtd_priv);
ret = -1;
goto errout_with_mtd;
}
info++;
}
ret = 0;
errout_with_mtd:
kmm_free(pbuf);
errout_with_malloc:
return ret;
}

View File

@ -0,0 +1,72 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp32c3_partition.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_PARTITION_H
#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_PARTITION_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <nuttx/mtd/mtd.h>
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp32c3_partition_init
*
* Description:
* Initialize ESP32-C3 partition. Read partition information
* and use these data for creating MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
int esp32c3_partition_init(void);
#ifdef __cplusplus
}
#endif
#undef EXTERN
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_PARTITION_H */

View File

@ -0,0 +1,745 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp32c3_spiflash.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <debug.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <nuttx/arch.h>
#include <nuttx/init.h>
#include <nuttx/semaphore.h>
#include <nuttx/mtd/mtd.h>
#include "esp32c3_spiflash.h"
#include "rom/esp32c3_spiflash.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define SPI_FLASH_BLK_SIZE 256
#define SPI_FLASH_ERASE_SIZE 4096
#define SPI_FLASH_SIZE (4 * 1024 * 1024)
#define ESP32C3_MTD_OFFSET CONFIG_ESP32C3_MTD_OFFSET
#define ESP32C3_MTD_SIZE CONFIG_ESP32C3_MTD_SIZE
#define MTD2PRIV(_dev) ((FAR struct esp32c3_spiflash_s *)_dev)
#define MTD_SIZE(_priv) ((_priv)->chip->chip_size)
#define MTD_BLKSIZE(_priv) ((_priv)->chip->page_size)
#define MTD_ERASESIZE(_priv) ((_priv)->chip->sector_size)
#define MTD_BLK2SIZE(_priv, _b) (MTD_BLKSIZE(_priv) * (_b))
#define MTD_SIZE2BLK(_priv, _s) ((_s) / MTD_BLKSIZE(_priv))
/****************************************************************************
* Private Types
****************************************************************************/
/* ESP32-C3 SPI Flash device private data */
struct esp32c3_spiflash_s
{
struct mtd_dev_s mtd;
/* SPI Flash data */
esp32c3_spiflash_chip_t *chip;
};
/****************************************************************************
* Private Functions Prototypes
****************************************************************************/
/* MTD driver methods */
static int esp32c3_erase(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks);
static ssize_t esp32c3_read(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, uint8_t *buffer);
static ssize_t esp32c3_read_decrypt(struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
uint8_t *buffer);
static ssize_t esp32c3_bread(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, uint8_t *buffer);
static ssize_t esp32c3_bread_decrypt(struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
uint8_t *buffer);
static ssize_t esp32c3_write(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, const uint8_t *buffer);
static ssize_t esp32c3_bwrite(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, const uint8_t *buffer);
static ssize_t esp32c3_bwrite_encrypt(struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
const uint8_t *buffer);
static int esp32c3_ioctl(struct mtd_dev_s *dev, int cmd,
unsigned long arg);
/****************************************************************************
* Private Data
****************************************************************************/
static struct esp32c3_spiflash_s g_esp32c3_spiflash =
{
.mtd =
{
.erase = esp32c3_erase,
.bread = esp32c3_bread,
.bwrite = esp32c3_bwrite,
.read = esp32c3_read,
.ioctl = esp32c3_ioctl,
#ifdef CONFIG_MTD_BYTE_WRITE
.write = esp32c3_write,
#endif
.name = "esp32c3_spiflash"
},
.chip = &g_rom_flashchip,
};
static struct esp32c3_spiflash_s g_esp32c3_spiflash_encrypt =
{
.mtd =
{
.erase = esp32c3_erase,
.bread = esp32c3_bread_decrypt,
.bwrite = esp32c3_bwrite_encrypt,
.read = esp32c3_read_decrypt,
.ioctl = esp32c3_ioctl,
#ifdef CONFIG_MTD_BYTE_WRITE
.write = NULL,
#endif
.name = "esp32c3_spiflash_encrypt"
}
};
/* Ensure exclusive access to the driver */
static sem_t g_exclsem = SEM_INITIALIZER(1);
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: esp32c3_erase
*
* Description:
* Erase SPI Flash designated sectors.
*
* Input Parameters:
* dev - MTD device data
* startblock - start block number, it is not equal to SPI Flash's block
* nblocks - Number of blocks
*
* Returned Value:
* Erased blocks if success or a negative value if fail.
*
****************************************************************************/
static int esp32c3_erase(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks)
{
ssize_t ret;
uint32_t offset = startblock * SPI_FLASH_ERASE_SIZE;
uint32_t nbytes = nblocks * SPI_FLASH_ERASE_SIZE;
if ((offset > SPI_FLASH_SIZE) || ((offset + nbytes) > SPI_FLASH_SIZE))
{
return -EINVAL;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("(%p, %d, %d)\n", dev, startblock, nblocks);
#endif
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
return ret;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("spi_flash_erase_range(%p, 0x%x, %d)\n", dev, offset, nbytes);
#endif
ret = spi_flash_erase_range(offset, nbytes);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nblocks;
}
else
{
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("Failed to erase the flash range!\n");
#endif
ret = -1;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp32c3_read
*
* Description:
* Read data from SPI Flash at designated address.
*
* Input Parameters:
* dev - MTD device data
* offset - target address offset
* nbytes - data number
* buffer - data buffer pointer
*
* Returned Value:
* Read data bytes if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_read(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, uint8_t *buffer)
{
ssize_t ret;
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer);
#endif
/* Acquire the semaphore. */
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
goto error_with_buffer;
}
ret = spi_flash_read(offset, buffer, nbytes);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nbytes;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
error_with_buffer:
return ret;
}
/****************************************************************************
* Name: esp32c3_bread
*
* Description:
* Read data from designated blocks.
*
* Input Parameters:
* dev - MTD device data
* startblock - start block number, it is not equal to SPI Flash's block
* nblocks - blocks number
* buffer - data buffer pointer
*
* Returned Value:
* Read block number if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_bread(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, uint8_t *buffer)
{
ssize_t ret;
uint32_t addr = startblock * SPI_FLASH_BLK_SIZE;
uint32_t size = nblocks * SPI_FLASH_BLK_SIZE;
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, nblocks,
buffer);
#endif
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
return ret;
}
ret = spi_flash_read(addr, buffer, size);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nblocks;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp32c3_read_decrypt
*
* Description:
* Read encrypted data and decrypt automatically from SPI Flash
* at designated address.
*
* Input Parameters:
* dev - MTD device data
* offset - target address offset
* nbytes - data number
* buffer - data buffer pointer
*
* Returned Value:
* Read data bytes if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_read_decrypt(struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
uint8_t *buffer)
{
ssize_t ret;
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer);
#endif
/* Acquire the semaphore. */
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
return ret;
}
ret = spi_flash_read_encrypted(offset, buffer, nbytes);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nbytes;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp32c3_bread_decrypt
*
* Description:
* Read encrypted data and decrypt automatically from designated blocks.
*
* Input Parameters:
* dev - MTD device data
* startblock - start block number, it is not equal to SPI Flash's block
* nblocks - blocks number
* buffer - data buffer pointer
*
* Returned Value:
* Read block number if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_bread_decrypt(struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
uint8_t *buffer)
{
ssize_t ret;
uint32_t addr = startblock * SPI_FLASH_BLK_SIZE;
uint32_t size = nblocks * SPI_FLASH_BLK_SIZE;
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock, nblocks,
buffer);
#endif
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
return ret;
}
ret = spi_flash_read_encrypted(addr, buffer, size);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nblocks;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp32c3_write
*
* Description:
* write data to SPI Flash at designated address.
*
* Input Parameters:
* dev - MTD device data
* offset - target address offset
* nbytes - data number
* buffer - data buffer pointer
*
* Returned Value:
* Writen bytes if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_write(struct mtd_dev_s *dev, off_t offset,
size_t nbytes, const uint8_t *buffer)
{
int ret;
ASSERT(buffer);
if ((offset > SPI_FLASH_SIZE) || ((offset + nbytes) > SPI_FLASH_SIZE))
{
return -EINVAL;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, offset, nbytes, buffer);
#endif
/* Acquire the semaphore. */
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
goto error_with_buffer;
}
ret = spi_flash_write(offset, buffer, nbytes);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nbytes;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
error_with_buffer:
return (ssize_t)ret;
}
/****************************************************************************
* Name: esp32c3_bwrite
*
* Description:
* Write data to designated blocks.
*
* Input Parameters:
* dev - MTD device data
* startblock - start MTD block number,
* it is not equal to SPI Flash's block
* nblocks - blocks number
* buffer - data buffer pointer
*
* Returned Value:
* Writen block number if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_bwrite(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, const uint8_t *buffer)
{
ssize_t ret;
uint32_t addr = startblock * SPI_FLASH_BLK_SIZE;
uint32_t size = nblocks * SPI_FLASH_BLK_SIZE;
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock,
nblocks, buffer);
#endif
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
return ret;
}
ret = spi_flash_write(addr, buffer, size);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nblocks;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
return ret;
}
/****************************************************************************
* Name: esp32c3_bwrite_encrypt
*
* Description:
* Write data to designated blocks by SPI Flash hardware encryption.
*
* Input Parameters:
* dev - MTD device data
* startblock - start MTD block number,
* it is not equal to SPI Flash's block
* nblocks - blocks number
* buffer - data buffer pointer
*
* Returned Value:
* Writen block number if success or a negative value if fail.
*
****************************************************************************/
static ssize_t esp32c3_bwrite_encrypt(struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
const uint8_t *buffer)
{
ssize_t ret;
uint32_t addr = startblock * SPI_FLASH_BLK_SIZE;
uint32_t size = nblocks * SPI_FLASH_BLK_SIZE;
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s(%p, 0x%x, %d, %p)\n", __func__, dev, startblock,
nblocks, buffer);
#endif
ret = nxsem_wait(&g_exclsem);
if (ret < 0)
{
goto error_with_buffer;
}
ret = spi_flash_write_encrypted(addr, buffer, size);
nxsem_post(&g_exclsem);
if (ret == OK)
{
ret = nblocks;
}
#ifdef CONFIG_ESP32C3_SPIFLASH_DEBUG
finfo("%s()=%d\n", __func__, ret);
#endif
error_with_buffer:
return ret;
}
/****************************************************************************
* Name: esp32c3_ioctl
*
* Description:
* Set/Get option to/from ESP32-C3 SPI Flash MTD device data.
*
* Input Parameters:
* dev - ESP32-C3 MTD device data
* cmd - operation command
* arg - operation argument
*
* Returned Value:
* 0 if success or a negative value if fail.
*
****************************************************************************/
static int esp32c3_ioctl(struct mtd_dev_s *dev, int cmd,
unsigned long arg)
{
int ret = OK;
struct mtd_geometry_s *geo;
finfo("cmd: %d \n", cmd);
switch (cmd)
{
case MTDIOC_GEOMETRY:
{
geo = (struct mtd_geometry_s *)arg;
if (geo)
{
geo->blocksize = SPI_FLASH_BLK_SIZE;
geo->erasesize = SPI_FLASH_ERASE_SIZE;
geo->neraseblocks = SPI_FLASH_SIZE / SPI_FLASH_ERASE_SIZE;
ret = OK;
finfo("blocksize: %" PRId32 " erasesize: %" PRId32 \
" neraseblocks: %" PRId32 "\n",
geo->blocksize, geo->erasesize, geo->neraseblocks);
}
}
break;
default:
ret = -ENOTTY;
break;
}
finfo("return %d\n", ret);
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: esp32c3_spiflash_alloc_mtdpart
*
* Description:
* Allocate SPI Flash MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* SPI Flash MTD data pointer if success or NULL if fail.
*
****************************************************************************/
FAR struct mtd_dev_s *esp32c3_spiflash_alloc_mtdpart(void)
{
struct esp32c3_spiflash_s *priv = &g_esp32c3_spiflash;
esp32c3_spiflash_chip_t *chip = priv->chip;
FAR struct mtd_dev_s *mtd_part;
uint32_t blocks;
uint32_t startblock;
uint32_t size;
ASSERT((ESP32C3_MTD_OFFSET + ESP32C3_MTD_SIZE) <= chip->chip_size);
ASSERT((ESP32C3_MTD_OFFSET % chip->sector_size) == 0);
ASSERT((ESP32C3_MTD_SIZE % chip->sector_size) == 0);
finfo("ESP32 SPI Flash information:\n");
finfo("\tID = 0x%" PRIx32 "\n", chip->device_id);
finfo("\tStatus mask = 0x%" PRIx32 "\n", chip->status_mask);
finfo("\tChip size = %" PRId32 " KB\n", chip->chip_size / 1024);
finfo("\tPage size = %" PRId32 " B\n", chip->page_size);
finfo("\tSector size = %" PRId32 " KB\n", chip->sector_size / 1024);
finfo("\tBlock size = %" PRId32 " KB\n", chip->block_size / 1024);
#if ESP32C3_MTD_SIZE == 0
size = chip->chip_size - ESP32C3_MTD_OFFSET;
#else
size = ESP32C3_MTD_SIZE;
#endif
finfo("\tMTD offset = 0x%x\n", ESP32C3_MTD_OFFSET);
finfo("\tMTD size = 0x%" PRIx32 "\n", size);
startblock = MTD_SIZE2BLK(priv, ESP32C3_MTD_OFFSET);
blocks = MTD_SIZE2BLK(priv, size);
mtd_part = mtd_partition(&priv->mtd, startblock, blocks);
if (!mtd_part)
{
ferr("ERROR: Failed to create MTD partition\n");
return NULL;
}
return mtd_part;
}
/****************************************************************************
* Name: esp32c3_spiflash_mtd
*
* Description:
* Get SPI Flash MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* ESP32-C3 SPI Flash MTD pointer.
*
****************************************************************************/
struct mtd_dev_s *esp32c3_spiflash_mtd(void)
{
struct esp32c3_spiflash_s *priv = &g_esp32c3_spiflash;
return &priv->mtd;
}
/****************************************************************************
* Name: esp32c3_spiflash_encrypt_mtd
*
* Description:
* Get SPI Flash encryption MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* SPI Flash encryption MTD pointer.
*
****************************************************************************/
struct mtd_dev_s *esp32c3_spiflash_encrypt_mtd(void)
{
struct esp32c3_spiflash_s *priv = &g_esp32c3_spiflash_encrypt;
return &priv->mtd;
}

View File

@ -0,0 +1,251 @@
/****************************************************************************
* arch/risc-v/src/esp32c3/esp32c3_spiflash.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_SPIFLASH_H
#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_SPIFLASH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <nuttx/mtd/mtd.h>
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp32c3_spiflash_mtd
*
* Description:
* Get ESP32-C3 SPI Flash MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* ESP32-C3 SPI Flash MTD pointer.
*
****************************************************************************/
struct mtd_dev_s *esp32c3_spiflash_mtd(void);
/****************************************************************************
* Name: esp32c3_spiflash_alloc_mtdpart
*
* Description:
* Alloc ESP32-C3 SPI Flash MTD
*
* Input Parameters:
* None
*
* Returned Value:
* ESP32-C3 SPI Flash MTD data pointer if success or NULL if fail
*
****************************************************************************/
FAR struct mtd_dev_s *esp32c3_spiflash_alloc_mtdpart(void);
/****************************************************************************
* Name: esp32c3_spiflash_encrypt_mtd
*
* Description:
* Get ESP32-C3 SPI Flash encryption MTD.
*
* Input Parameters:
* None
*
* Returned Value:
* ESP32-C3 SPI Flash encryption MTD pointer.
*
****************************************************************************/
struct mtd_dev_s *esp32c3_spiflash_encrypt_mtd(void);
/****************************************************************************
* Name: spi_flash_write_encrypted
*
* Description:
* Write data encrypted to Flash.
*
* Flash encryption must be enabled for this function to work.
*
* Flash encryption must be enabled when calling this function.
* If flash encryption is disabled, the function returns
* ESP_ERR_INVALID_STATE. Use esp_flash_encryption_enabled()
* function to determine if flash encryption is enabled.
*
* Both dest_addr and size must be multiples of 16 bytes. For
* absolute best performance, both dest_addr and size arguments should
* be multiples of 32 bytes.
*
* Input Parameters:
* dest_addr - Destination address in Flash. Must be a multiple of 16
* bytes.
* src - Pointer to the source buffer.
* size - Length of data, in bytes. Must be a multiple of 16 bytes.
*
* Returned Values:
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
int spi_flash_write_encrypted(uint32_t dest_addr, const void *src,
uint32_t size);
/****************************************************************************
* Name: spi_flash_write
*
* Description:
*
* Write data to Flash.
*
* Note: For fastest write performance, write a 4 byte aligned size at a
* 4 byte aligned offset in flash from a source buffer in DRAM. Varying
* any of these parameters will still work, but will be slower due to
* buffering.
*
* Writing more than 8KB at a time will be split into multiple
* write operations to avoid disrupting other tasks in the system.
*
* Parameters:
* dest_addr - Destination address in Flash.
* src - Pointer to the source buffer.
* size - Length of data, in bytes.
*
* Returned Values:
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
int spi_flash_write(uint32_t dest_addr, const void *src, uint32_t size);
/****************************************************************************
* Name: spi_flash_read_encrypted
*
* Description:
*
* Read data from Encrypted Flash.
*
* If flash encryption is enabled, this function will transparently
* decrypt data as it is read.
* If flash encryption is not enabled, this function behaves the same as
* spi_flash_read().
*
* See esp_flash_encryption_enabled() for a function to check if flash
* encryption is enabled.
*
* Parameters:
* src - source address of the data in Flash.
* dest - pointer to the destination buffer
* size - length of data
*
* Returned Values: esp_err_t
*
****************************************************************************/
int spi_flash_read_encrypted(uint32_t src, void *dest, uint32_t size);
/****************************************************************************
* Name: spi_flash_read
*
* Description:
* Read data from Flash.
*
* Note: For fastest read performance, all parameters should be
* 4 byte aligned. If source address and read size are not 4 byte
* 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.
*
* 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.
*
* Parameters:
* src_addr - source address of the data in Flash.
* dest - pointer to the destination buffer
* size - length of data
*
* Returned Values:
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
int spi_flash_read(uint32_t src_addr, void *dest, uint32_t size);
/****************************************************************************
* Name: spi_flash_erase_sector
*
* Description:
* Erase the Flash sector.
*
* Parameters:
* sector - Sector number, the count starts at sector 0, 4KB per sector.
*
* Returned Values: esp_err_t
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
int spi_flash_erase_sector(uint32_t sector);
/****************************************************************************
* Name: spi_flash_erase_range
*
* Description:
* Erase a range of flash sectors
*
* Parameters:
* start_address - Address where erase operation has to start.
* Must be 4kB-aligned
* size - Size of erased range, in bytes. Must be divisible by
* 4kB.
*
* Returned Values:
* Zero (OK) is returned or a negative error.
*
****************************************************************************/
int spi_flash_erase_range(uint32_t start_address, uint32_t size);
#ifdef __cplusplus
}
#endif
#undef EXTERN
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_SPIFLASH_H */

View File

@ -0,0 +1,794 @@
/*****************************************************************************
* arch/risc-v/src/esp32c3/rom/esp32c3_spiflash.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
*****************************************************************************/
#ifndef _ROM_SPI_FLASH_H_
#define _ROM_SPI_FLASH_H_
/*****************************************************************************
* Included Files
*****************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C"
{
#endif
/*****************************************************************************
* Pre-processor Definitions
*****************************************************************************/
#define PERIPHS_SPI_FLASH_CMD SPI_CMD_REG(1)
#define PERIPHS_SPI_FLASH_ADDR SPI_ADDR_REG(1)
#define PERIPHS_SPI_FLASH_CTRL SPI_CTRL_REG(1)
#define PERIPHS_SPI_FLASH_CTRL1 SPI_CTRL1_REG(1)
#define PERIPHS_SPI_FLASH_STATUS SPI_RD_STATUS_REG(1)
#define PERIPHS_SPI_FLASH_USRREG SPI_USER_REG(1)
#define PERIPHS_SPI_FLASH_USRREG1 SPI_USER1_REG(1)
#define PERIPHS_SPI_FLASH_USRREG2 SPI_USER2_REG(1)
#define PERIPHS_SPI_FLASH_C0 SPI_W0_REG(1)
#define PERIPHS_SPI_FLASH_C1 SPI_W1_REG(1)
#define PERIPHS_SPI_FLASH_C2 SPI_W2_REG(1)
#define PERIPHS_SPI_FLASH_C3 SPI_W3_REG(1)
#define PERIPHS_SPI_FLASH_C4 SPI_W4_REG(1)
#define PERIPHS_SPI_FLASH_C5 SPI_W5_REG(1)
#define PERIPHS_SPI_FLASH_C6 SPI_W6_REG(1)
#define PERIPHS_SPI_FLASH_C7 SPI_W7_REG(1)
#define PERIPHS_SPI_FLASH_TX_CRC SPI_TX_CRC_REG(1)
#define SPI0_R_QIO_DUMMY_CYCLELEN 3
#define SPI0_R_QIO_ADDR_BITSLEN 31
#define SPI0_R_FAST_DUMMY_CYCLELEN 7
#define SPI0_R_DIO_DUMMY_CYCLELEN 1
#define SPI0_R_DIO_ADDR_BITSLEN 27
#define SPI0_R_FAST_ADDR_BITSLEN 23
#define SPI0_R_SIO_ADDR_BITSLEN 23
#define SPI1_R_QIO_DUMMY_CYCLELEN 3
#define SPI1_R_QIO_ADDR_BITSLEN 31
#define SPI1_R_FAST_DUMMY_CYCLELEN 7
#define SPI1_R_DIO_DUMMY_CYCLELEN 3
#define SPI1_R_DIO_ADDR_BITSLEN 31
#define SPI1_R_FAST_ADDR_BITSLEN 23
#define SPI1_R_SIO_ADDR_BITSLEN 23
#define ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN 23
#define ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN SPI_WRSR_2B
/* SPI address register */
#define ESP_ROM_SPIFLASH_BYTES_LEN 24
#define ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM 32
#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM 64
#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_BITS 0x3f
/* SPI status register */
#define ESP_ROM_SPIFLASH_BUSY_FLAG BIT0
#define ESP_ROM_SPIFLASH_WRENABLE_FLAG BIT1
#define ESP_ROM_SPIFLASH_BP0 BIT2
#define ESP_ROM_SPIFLASH_BP1 BIT3
#define ESP_ROM_SPIFLASH_BP2 BIT4
#define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|\
ESP_ROM_SPIFLASH_BP1|\
ESP_ROM_SPIFLASH_BP2)
#define ESP_ROM_SPIFLASH_QE BIT9
/* Extra dummy for flash read */
#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M 0
#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M 1
#define ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M 2
#define FLASH_ID_GD25LQ32C 0xC86016
/*****************************************************************************
* Public Types
*****************************************************************************/
typedef enum
{
ESP_ROM_SPIFLASH_QIO_MODE = 0,
ESP_ROM_SPIFLASH_QOUT_MODE,
ESP_ROM_SPIFLASH_DIO_MODE,
ESP_ROM_SPIFLASH_DOUT_MODE,
ESP_ROM_SPIFLASH_FASTRD_MODE,
ESP_ROM_SPIFLASH_SLOWRD_MODE
} esp_rom_spiflash_read_mode_t;
typedef enum
{
ESP_ROM_SPIFLASH_RESULT_OK,
ESP_ROM_SPIFLASH_RESULT_ERR,
ESP_ROM_SPIFLASH_RESULT_TIMEOUT
} esp_rom_spiflash_result_t;
typedef struct
{
uint32_t device_id;
uint32_t chip_size; /* chip size in bytes */
uint32_t block_size;
uint32_t sector_size;
uint32_t page_size;
uint32_t status_mask;
} esp32c3_spiflash_chip_t;
typedef struct
{
uint8_t data_length;
uint8_t read_cmd0;
uint8_t read_cmd1;
uint8_t write_cmd;
uint16_t data_mask;
uint16_t data;
} esp_rom_spiflash_common_cmd_t;
/*****************************************************************************
* Public Function Prototypes
*****************************************************************************/
/*****************************************************************************
* Name: esp_rom_spiflash_fix_dummylen
*
* Description:
* Fix the bug in SPI hardware communication with Flash/Ext-SRAM in High
* Speed.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint8_t spi: 0 for SPI0(Cache Access), 1 for SPI1(Flash read/write).
*
* uint8_t freqdiv: Pll is 80M, 4 for 20M, 3 for 26.7M, 2 for 40M,
* 1 for 80M.
*
* Returned Value:
* None
*
*****************************************************************************/
void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv);
/*****************************************************************************
* Name: esp_rom_spiflash_select_qiomode
*
* Description:
* Select SPI Flash to QIO mode when WP pad is read from Flash.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint8_t wp_gpio_num: WP gpio number.
*
* uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid,
* bit[23:18] spics0, bit[29:24] spihd
*
* Returned Value:
* None
*****************************************************************************/
void esp_rom_spiflash_select_qiomode(uint8_t wp_gpio_num,
uint32_t ishspi);
/*****************************************************************************
* Name: esp_rom_spiflash_set_drvs
*
* Description:
* Set SPI Flash pad drivers.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint8_t wp_gpio_num: WP gpio number.
*
* uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid,
* bit[23:18] spics0, bit[29:24] spihd
*
* uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq,
* drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid
* drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp.
* Values usually read from flash by rom code, function
* usually callde by rom code.
* if value with bit(3) set, the value is valid, bit[2:0]
* is the real value.
*
* Returned Value:
* None
*
*****************************************************************************/
void esp_rom_spiflash_set_drvs(uint8_t wp_gpio_num,
uint32_t ishspi,
uint8_t *drvs);
/*****************************************************************************
* Name: esp_rom_spiflash_select_padsfunc
*
* Description:
* Select SPI Flash function for pads.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid,
* bit[23:18] spics0, bit[29:24] spihd
*
* Returned Value:
* None
*
*****************************************************************************/
void esp_rom_spiflash_select_padsfunc(uint32_t ishspi);
/*****************************************************************************
* Name: esp_rom_spiflash_attach
*
* Description:
* SPI Flash init, clock divisor is 4, use 1 line Slow read mode.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid,
* bit[23:18] spics0, bit[29:24] spihd
*
* uint8_t legacy: In legacy mode, more SPI command is used in line.
*
* Returned Value:
* None
*
*****************************************************************************/
void esp_rom_spiflash_attach(uint32_t ishspi, bool legacy);
/*****************************************************************************
* Name: esp_rom_spiflash_read_status
*
* Description:
* SPI Read Flash status register. We use CMD 0x05 (RDSR).
*
* Please do not call this function in SDK.
*
* Input Parameters:
* esp32c3_spiflash_chip_t *spi : The information for Flash, which is
* exported from ld file.
*
* uint32_t *status : The pointer to which to return the Flash status value.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : read OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : read error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_read_status(esp32c3_spiflash_chip_t *spi,
uint32_t *status);
/*****************************************************************************
* Name: esp32c3_spiflash_read_statushigh
*
* Description:
* SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2).
*
* Please do not call this function in SDK.
*
* Input Parameters:
* esp32c3_spiflash_chip_t *spi : The information for Flash, which is
* exported from ld file.
*
* uint32_t *status : The pointer to which to return the Flash status value.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : read OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : read error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp32c3_spiflash_read_statushigh(esp32c3_spiflash_chip_t *spi,
uint32_t *status);
/*****************************************************************************
* Name: esp32c3_spiflash_write_status
*
* Description:
* Write status to Falsh status register.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* esp32c3_spiflash_chip_t *spi : The information for Flash, which is
* exported from ld file.
*
* uint32_t status_value : Value to .
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : write OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : write error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : write timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp32c3_spiflash_write_status(esp32c3_spiflash_chip_t *spi,
uint32_t status_value);
/*****************************************************************************
* Name: esp_rom_spiflash_read_user_cmd
*
* Description:
* Use a command to Read Flash status register.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* esp32c3_spiflash_chip_t *spi : The information for Flash, which is
* exported from ld file.
*
* uint32_t*status : The pointer to which to return the Flash status value.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : read OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : read error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_read_user_cmd(uint32_t *status,
uint8_t cmd);
/*****************************************************************************
* Name: esp_rom_spiflash_config_readmode
*
* Description:
* Config SPI Flash read mode when init.
*
* Please do not call this function in SDK.
*
* Input Parameter:
* esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
*
* This function does not try to set the QIO Enable bit in the status
* register, caller is responsible for this.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : config OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : config error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode);
/*****************************************************************************
* Name: esp_rom_spiflash_config_clk
*
* Description:
* Config SPI Flash clock divisor.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint8_t freqdiv: clock divisor.
*
* uint8_t spi: 0 for SPI0, 1 for SPI1.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : config OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : config error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_config_clk(uint8_t freqdiv,
uint8_t spi);
/*****************************************************************************
* Name: esp_rom_spiflash_common_cmd
*
* Description:
* Send CommonCmd to Flash so that is can go into QIO mode, some Flash use
* different CMD.
*
* Please do not call this function in SDK.
*
* Input Paramater:
* esp_rom_spiflash_common_cmd_t *cmd : A struct to show the action of a
* command.
*
* Returned Value:
* uint16_t 0 : do not send command any more.
* 1 : go to the next command.
* n > 1 : skip (n - 1) commands.
*
*****************************************************************************/
uint16_t esp_rom_spiflash_common_cmd(esp_rom_spiflash_common_cmd_t *cmd);
/*****************************************************************************
* Name: esp_rom_spiflash_unlock
*
* Description:
* Unlock SPI write protect.
*
* Please do not call this function in SDK.
*
* Input Value:
* None.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Unlock OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Unlock error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Unlock timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void);
/*****************************************************************************
* Name: esp_rom_spiflash_lock
*
* Description:
* SPI write protect.
*
* Please do not call this function in SDK.
*
* Input Parameter:
* None.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Lock OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Lock error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Lock timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t esp_rom_spiflash_lock(void);
/*****************************************************************************
* Name: esp_rom_spiflash_config_param
*
* Description:
* Update SPI Flash parameter.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t deviceId : Device ID read from SPI, the low 32 bit.
*
* uint32_t chip_size : The Flash size.
*
* uint32_t block_size : The Flash block size.
*
* uint32_t sector_size : The Flash sector size.
*
* uint32_t page_size : The Flash page size.
*
* uint32_t status_mask : The Mask used when read status from Flash
* (use single CMD).
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Update OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Update error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Update timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_config_param(uint32_t deviceid,
uint32_t chip_size,
uint32_t block_size,
uint32_t sector_size,
uint32_t page_size,
uint32_t status_mask);
/*****************************************************************************
* Name: esp_rom_spiflash_erase_chip
*
* Description:
* Erase whole flash chip.
*
* Please do not call this function in SDK.
*
* Input Parameter:
* None
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void);
/*****************************************************************************
* Name: esp_rom_spiflash_erase_block
*
* Description:
* Erase a 64KB block of flash
* Uses SPI flash command D8H.
*
* Please do not call this function in SDK.
*
* Input Parameter:
* uint32_t block_num : Which block to erase.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num);
/*****************************************************************************
* Name: esp_rom_spiflash_erase_sector
*
* Description:
* Erase a sector of flash.
* Uses SPI flash command 20H.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t sector_num : Which sector to erase.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num);
/*****************************************************************************
* Name: esp_rom_spiflash_erase_area
*
* Description:
* Erase some sectors.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t start_addr : Start addr to erase, should be sector aligned.
*
* uint32_t area_len : Length to erase, should be sector aligned.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Erase OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Erase error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_erase_area(uint32_t start_addr,
uint32_t area_len);
/*****************************************************************************
* Name: esp_rom_spiflash_write
*
* Description:
* Write Data to Flash, you should Erase it yourself if need.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t dest_addr : Address to write, should be 4 bytes aligned.
*
* const uint32_t *src : The pointer to data which is to write.
*
* uint32_t len : Length to write, should be 4 bytes aligned.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Write OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Write error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Write timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_write(uint32_t dest_addr,
const uint32_t *src,
int32_t len);
/*****************************************************************************
* Name: esp_rom_spiflash_read
*
* Description:
* Read Data from Flash, you should Erase it yourself if need.
*
* Please do not call this function in SDK.
*
* Input Values:
* uint32_t src_addr : Address to read, should be 4 bytes aligned.
*
* uint32_t *dest : The buf to read the data.
*
* uint32_t len : Length to read, should be 4 bytes aligned.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Read OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Read error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Read timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_read(uint32_t src_addr,
uint32_t *dest,
int32_t len);
/*****************************************************************************
* Name: esp_rom_spiflash_write_encrypted_enable
*
* Description:
* SPI1 go into encrypto mode.
*
* Please do not call this function in SDK.
*
*****************************************************************************/
void esp_rom_spiflash_write_encrypted_enable(void);
/*****************************************************************************
* Name: esp_rom_spiflash_prepare_encrypted_data
*
* Description:
* Prepare 32 Bytes data to encrpto writing, you should Erase it yourself
* if need.
*
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t flash_addr : Address to write, should be 32 bytes aligned.
*
* uint32_t *data : The pointer to data which is to write.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Prepare OK.
* ESP_ROM_SPIFLASH_RESULT_ERR : Prepare error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Prepare timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_prepare_encrypted_data(uint32_t flash_addr,
uint32_t *data);
/*****************************************************************************
* Name: esp_rom_spiflash_write_encrypted_disable
*
* Description:
* SPI1 go out of encrypto mode.
*
* Please do not call this function in SDK.
*
*****************************************************************************/
void esp_rom_spiflash_write_encrypted_disable(void);
/*****************************************************************************
* Name: esp_rom_spiflash_write_encrypted
*
* Description:
* Write data to flash with transparent encryption.
* Sectors to be written should already be erased.
* Please do not call this function in SDK.
*
* Input Parameters:
* uint32_t flash_addr : Address to write, should be 32 byte aligned.
*
* uint32_t *data : The pointer to data to write. Note, this pointer must
* be 32 bit aligned and the content of the data will be
* modified by the encryption function.
*
* uint32_t len : Length to write, should be 32 bytes aligned.
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Data written successfully.
* ESP_ROM_SPIFLASH_RESULT_ERR : Encryption write error.
* ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Encrypto write timeout.
*
*****************************************************************************/
esp_rom_spiflash_result_t
esp_rom_spiflash_write_encrypted(uint32_t flash_addr,
uint32_t *data,
uint32_t len);
/*****************************************************************************
* Name: esp_rom_spiflash_wait_idle
*
* Description:
* Wait until SPI flash write operation is complete
*
* Please do not call this function in SDK.
*
* Reads the Write In Progress bit of the SPI flash status register,
* repeats until this bit is zero (indicating write complete).
*
* Returned Value:
* ESP_ROM_SPIFLASH_RESULT_OK : Write is complete
* ESP_ROM_SPIFLASH_RESULT_ERR : Error while reading status.
*
*****************************************************************************/
esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp32c3_spiflash_chip_t
*spi);
/*****************************************************************************
* Name: esp_rom_spiflash_select_qio_pins
*
* Description:
* Enable Quad I/O pin functions
*
* Please do not call this function in SDK.
*
* Sets the HD & WP pin functions for Quad I/O modes, based on the
* efuse SPI pin configuration.
*
* Input Parameters:
* wp_gpio_num - Number of the WP pin to reconfigure for quad I/O.
* spiconfig - Pin configuration, as returned from
* ets_efuse_get_spiconfig().
* - If this parameter is 0, default SPI pins are used and
* wp_gpio_num parameter is ignored.
* - If this parameter is 1, default HSPI pins are used and
* wp_gpio_num parameter is ignored.
* - For other values, this parameter encodes the HD pin number
* and also the CLK pin number. CLK pin selection is used to
* determine if HSPI or SPI peripheral will be used (use HSPI
* if CLK pin is the HSPI clock pin, otherwise use SPI).
* Both HD & WP pins are configured via GPIO matrix to map to the selected
* peripheral.
*
*****************************************************************************/
void esp_rom_spiflash_select_qio_pins(uint8_t wp_gpio_num,
uint32_t spiconfig);
/* Global esp32c3_spiflash_chip_t structure used by ROM functions */
extern esp32c3_spiflash_chip_t g_rom_flashchip;
extern uint8_t g_rom_spiflash_dummy_len_plus[];
#ifdef __cplusplus
}
#endif
#endif /* _ROM_SPI_FLASH_H_ */

View File

@ -173,6 +173,7 @@ PROVIDE( Enable_QMode = 0x40000228 );
/* Data (.data, .bss, .rodata) */
PROVIDE( rom_spiflash_legacy_funcs = 0x3fcdfff4 );
PROVIDE( rom_spiflash_legacy_data = 0x3fcdfff0 );
PROVIDE( g_rom_flashchip = 0x3fcdf730 );
PROVIDE( g_flash_guard_ops = 0x3fcdfff8 );