48 #ifndef EXT_FLASH_SPI_CONTROLLER 50 #define EXT_FLASH_SPI_CONTROLLER 0xFF 52 #define EXT_FLASH_SPI_PIN_SCK GPIO_HAL_PIN_UNKNOWN 53 #define EXT_FLASH_SPI_PIN_MOSI GPIO_HAL_PIN_UNKNOWN 54 #define EXT_FLASH_SPI_PIN_MISO GPIO_HAL_PIN_UNKNOWN 55 #define EXT_FLASH_SPI_PIN_CS GPIO_HAL_PIN_UNKNOWN 57 #define EXT_FLASH_DEVICE_ID 0xFF 58 #define EXT_FLASH_MID 0xFF 60 #define EXT_FLASH_PROGRAM_PAGE_SIZE 256 61 #define EXT_FLASH_ERASE_SECTOR_SIZE 4096 66 #define LOG_MODULE "ext-flash" 67 #define LOG_LEVEL LOG_LEVEL_NONE 71 #define BLS_CODE_PROGRAM 0x02 72 #define BLS_CODE_READ 0x03 73 #define BLS_CODE_READ_STATUS 0x05 74 #define BLS_CODE_WRITE_ENABLE 0x06 75 #define BLS_CODE_SECTOR_ERASE 0x20 76 #define BLS_CODE_MDID 0x90 78 #define BLS_CODE_PD 0xB9 79 #define BLS_CODE_RPD 0xAB 83 #define BLS_CODE_ERASE_4K 0x20 84 #define BLS_CODE_ERASE_32K 0x52 85 #define BLS_CODE_ERASE_64K 0xD8 86 #define BLS_CODE_ERASE_ALL 0xC7 90 #define BLS_STATUS_SRWD_BM 0x80 91 #define BLS_STATUS_BP_BM 0x0C 92 #define BLS_STATUS_WEL_BM 0x02 93 #define BLS_STATUS_WIP_BM 0x01 95 #define BLS_STATUS_BIT_BUSY 0x01 97 #define VERIFY_PART_LOCKED -2 98 #define VERIFY_PART_ERROR -1 99 #define VERIFY_PART_POWERED_DOWN 0 100 #define VERIFY_PART_OK 1 102 static const spi_device_t flash_spi_configuration_default = {
103 .spi_controller = EXT_FLASH_SPI_CONTROLLER,
104 .pin_spi_sck = EXT_FLASH_SPI_PIN_SCK,
105 .pin_spi_miso = EXT_FLASH_SPI_PIN_MISO,
106 .pin_spi_mosi = EXT_FLASH_SPI_PIN_MOSI,
107 .pin_spi_cs = EXT_FLASH_SPI_PIN_CS,
108 .spi_bit_rate = 4000000,
120 return &flash_spi_configuration_default;
131 if(
spi_select(flash_spi_configuration) == SPI_DEV_STATUS_OK) {
160 ret =
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf));
162 if(ret != SPI_DEV_STATUS_OK) {
174 ret =
spi_read(flash_spi_configuration, &buf,
sizeof(buf));
176 if(ret != SPI_DEV_STATUS_OK) {
202 uint8_t rbuf[2] = { 0, 0 };
206 return VERIFY_PART_LOCKED;
209 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
211 return VERIFY_PART_ERROR;
214 ret =
spi_read(flash_spi_configuration, rbuf,
sizeof(rbuf));
216 if(ret != SPI_DEV_STATUS_OK) {
217 return VERIFY_PART_ERROR;
220 LOG_DBG(
"Verify: %02x %02x\n", rbuf[0], rbuf[1]);
222 if(rbuf[0] != EXT_FLASH_MID || rbuf[1] != EXT_FLASH_DEVICE_ID) {
223 return VERIFY_PART_POWERED_DOWN;
225 return VERIFY_PART_OK;
239 if(
wait_ready(flash_spi_configuration) ==
false) {
249 if(
spi_write_byte(flash_spi_configuration, cmd) != SPI_DEV_STATUS_OK) {
257 if(
verify_part(flash_spi_configuration) == VERIFY_PART_POWERED_DOWN) {
284 success = (
spi_write(flash_spi_configuration, &cmd,
sizeof(cmd)) == SPI_DEV_STATUS_OK);
287 success =
wait_ready(flash_spi_configuration) ==
true ? true :
false;
309 ret = (
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) == SPI_DEV_STATUS_OK);
330 if(
spi_acquire(flash_spi_configuration) != SPI_DEV_STATUS_OK) {
339 if(
verify_part(flash_spi_configuration) == VERIFY_PART_OK) {
360 if(
spi_release(flash_spi_configuration) != SPI_DEV_STATUS_OK) {
378 if(
wait_ready(flash_spi_configuration) ==
false) {
387 wbuf[1] = (offset >> 16) & 0xff;
388 wbuf[2] = (offset >> 8) & 0xff;
389 wbuf[3] = offset & 0xff;
395 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
401 ret = (
spi_read(flash_spi_configuration, buf, length) == SPI_DEV_STATUS_OK);
420 if(
wait_ready(flash_spi_configuration) ==
false) {
428 ilen = EXT_FLASH_PROGRAM_PAGE_SIZE - (offset % EXT_FLASH_PROGRAM_PAGE_SIZE);
434 wbuf[1] = (offset >> 16) & 0xff;
435 wbuf[2] = (offset >> 8) & 0xff;
436 wbuf[3] = offset & 0xff;
450 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
456 if(
spi_write(flash_spi_configuration, buf, ilen) != SPI_DEV_STATUS_OK) {
477 uint32_t i, numsectors;
478 uint32_t endoffset = offset + length - 1;
484 offset = (offset / EXT_FLASH_ERASE_SECTOR_SIZE) * EXT_FLASH_ERASE_SECTOR_SIZE;
485 numsectors = (endoffset - offset + EXT_FLASH_ERASE_SECTOR_SIZE - 1) / EXT_FLASH_ERASE_SECTOR_SIZE;
489 for(i = 0; i < numsectors; i++) {
491 if(
wait_ready(flash_spi_configuration) ==
false) {
499 wbuf[1] = (offset >> 16) & 0xff;
500 wbuf[2] = (offset >> 8) & 0xff;
501 wbuf[3] = offset & 0xff;
507 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
514 offset += EXT_FLASH_ERASE_SECTOR_SIZE;
531 LOG_INFO(
"Flash init successful\n");
#define BLS_CODE_WRITE_ENABLE
Write Enable.
#define BLS_CODE_PROGRAM
Page Program.
spi_status_t spi_select(const spi_device_t *dev)
Selects the SPI peripheral.
static void deselect(const spi_device_t *flash_spi_configuration)
Set external flash CSN line.
bool ext_flash_read(const spi_device_t *conf, uint32_t offset, uint32_t length, uint8_t *buf)
Read storage content.
static bool write_enable(const spi_device_t *flash_spi_configuration)
Enable write.
spi_status_t spi_read(const spi_device_t *dev, uint8_t *buf, int size)
Reads a buffer from an SPI device.
spi_status_t spi_write_byte(const spi_device_t *dev, uint8_t data)
Writes a single byte to an SPI device.
#define BLS_CODE_READ_STATUS
Read Status Register.
#define GPIO_HAL_PIN_UNKNOWN
Unknown GPIO.
#define BLS_CODE_PD
Power down.
bool ext_flash_open(const spi_device_t *conf)
Initialize storage driver.
bool ext_flash_erase(const spi_device_t *conf, uint32_t offset, uint32_t length)
Erase storage sectors corresponding to the range.
Header file for the SPI HAL.
static bool power_down(const spi_device_t *flash_spi_configuration)
Put the device in power save mode.
static bool select_on_bus(const spi_device_t *flash_spi_configuration)
Clear external flash CSN line.
spi_status_t spi_write(const spi_device_t *dev, const uint8_t *data, int size)
Writes a buffer to an SPI device.
spi_status_t spi_acquire(const spi_device_t *dev)
Locks and then opens an SPI controller.
spi_status_t spi_deselect(const spi_device_t *dev)
Deselects the SPI peripheral.
bool ext_flash_close(const spi_device_t *conf)
Close the storage driver.
static bool wait_ready(const spi_device_t *flash_spi_configuration)
Wait till previous erase/program operation completes.
#define BLS_CODE_MDID
Manufacturer Device ID.
Header file for the external SPI flash API.
static bool power_standby(const spi_device_t *flash_spi_configuration)
Take device out of power save mode and prepare it for normal operation.
bool ext_flash_init(const spi_device_t *conf)
Initialise the external flash.
SPI Device Configuration.
spi_status_t spi_release(const spi_device_t *dev)
Closes and then unlocks an SPI controller.
#define BLS_CODE_RPD
Release Power-Down.
#define BLS_CODE_READ
Read Data.
Header file for the GPIO HAL.
Header file for the logging system
#define BLS_CODE_SECTOR_ERASE
Sector Erase.
#define BLS_STATUS_BIT_BUSY
Busy bit of the status register.
static uint8_t verify_part(const spi_device_t *flash_spi_configuration)
Verify the flash part.
bool ext_flash_write(const spi_device_t *conf, uint32_t offset, uint32_t length, const uint8_t *buf)
Write to storage sectors.
static const spi_device_t * get_spi_conf(const spi_device_t *conf)
Get spi configuration, return default configuration if NULL.