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 #if GPIO_HAL_PORT_PIN_NUMBERING 104 .port_spi_sck = EXT_FLASH_SPI_PORT_SCK,
105 .port_spi_miso = EXT_FLASH_SPI_PORT_MISO,
106 .port_spi_mosi = EXT_FLASH_SPI_PORT_MOSI,
107 .port_spi_cs = EXT_FLASH_SPI_PORT_CS,
109 .spi_controller = EXT_FLASH_SPI_CONTROLLER,
110 .pin_spi_sck = EXT_FLASH_SPI_PIN_SCK,
111 .pin_spi_miso = EXT_FLASH_SPI_PIN_MISO,
112 .pin_spi_mosi = EXT_FLASH_SPI_PIN_MOSI,
113 .pin_spi_cs = EXT_FLASH_SPI_PIN_CS,
114 .spi_bit_rate = 4000000,
126 return &flash_spi_configuration_default;
137 if(
spi_select(flash_spi_configuration) == SPI_DEV_STATUS_OK) {
166 ret =
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf));
168 if(ret != SPI_DEV_STATUS_OK) {
180 ret =
spi_read(flash_spi_configuration, &buf,
sizeof(buf));
182 if(ret != SPI_DEV_STATUS_OK) {
208 uint8_t rbuf[2] = { 0, 0 };
212 return VERIFY_PART_LOCKED;
215 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
217 return VERIFY_PART_ERROR;
220 ret =
spi_read(flash_spi_configuration, rbuf,
sizeof(rbuf));
222 if(ret != SPI_DEV_STATUS_OK) {
223 return VERIFY_PART_ERROR;
226 LOG_DBG(
"Verify: %02x %02x\n", rbuf[0], rbuf[1]);
228 if(rbuf[0] != EXT_FLASH_MID || rbuf[1] != EXT_FLASH_DEVICE_ID) {
229 return VERIFY_PART_POWERED_DOWN;
231 return VERIFY_PART_OK;
245 if(
wait_ready(flash_spi_configuration) ==
false) {
255 if(
spi_write_byte(flash_spi_configuration, cmd) != SPI_DEV_STATUS_OK) {
263 if(
verify_part(flash_spi_configuration) == VERIFY_PART_POWERED_DOWN) {
290 success = (
spi_write(flash_spi_configuration, &cmd,
sizeof(cmd)) == SPI_DEV_STATUS_OK);
293 success =
wait_ready(flash_spi_configuration) ==
true ? true :
false;
315 ret = (
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) == SPI_DEV_STATUS_OK);
336 if(
spi_acquire(flash_spi_configuration) != SPI_DEV_STATUS_OK) {
345 if(
verify_part(flash_spi_configuration) == VERIFY_PART_OK) {
366 if(
spi_release(flash_spi_configuration) != SPI_DEV_STATUS_OK) {
384 if(
wait_ready(flash_spi_configuration) ==
false) {
393 wbuf[1] = (offset >> 16) & 0xff;
394 wbuf[2] = (offset >> 8) & 0xff;
395 wbuf[3] = offset & 0xff;
401 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
407 ret = (
spi_read(flash_spi_configuration, buf, length) == SPI_DEV_STATUS_OK);
426 if(
wait_ready(flash_spi_configuration) ==
false) {
434 ilen = EXT_FLASH_PROGRAM_PAGE_SIZE - (offset % EXT_FLASH_PROGRAM_PAGE_SIZE);
440 wbuf[1] = (offset >> 16) & 0xff;
441 wbuf[2] = (offset >> 8) & 0xff;
442 wbuf[3] = offset & 0xff;
456 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
462 if(
spi_write(flash_spi_configuration, buf, ilen) != SPI_DEV_STATUS_OK) {
483 uint32_t i, numsectors;
484 uint32_t endoffset = offset + length - 1;
490 offset = (offset / EXT_FLASH_ERASE_SECTOR_SIZE) * EXT_FLASH_ERASE_SECTOR_SIZE;
491 numsectors = (endoffset - offset + EXT_FLASH_ERASE_SECTOR_SIZE - 1) / EXT_FLASH_ERASE_SECTOR_SIZE;
495 for(i = 0; i < numsectors; i++) {
497 if(
wait_ready(flash_spi_configuration) ==
false) {
505 wbuf[1] = (offset >> 16) & 0xff;
506 wbuf[2] = (offset >> 8) & 0xff;
507 wbuf[3] = offset & 0xff;
513 if(
spi_write(flash_spi_configuration, wbuf,
sizeof(wbuf)) != SPI_DEV_STATUS_OK) {
520 offset += EXT_FLASH_ERASE_SECTOR_SIZE;
537 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.