| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- /**
- * @file wm_fls_gd25qxx.c
- *
- * @brief gd25qxx flash Driver Module
- *
- * @author dave
- *
- * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include "wm_type_def.h"
- #include "wm_flash.h"
- #include "wm_hostspi.h"
- #include "wm_fls_gd25qxx.h"
- #include "wm_debug.h"
- #include "wm_gpio.h"
- static int tls_spifls_drv_read(u32 addr, u8 * buf, u32 len);
- static int tls_spifls_drv_fast_read(u32 addr, u8 * buf, u32 len);
- static int tls_spifls_drv_page_write(u32 page, u8 * buf);
- static int tls_spifls_drv_erase(u32 sector);
- static int tls_spifls_drv_chip_erase(void);
- static int tls_spifls_drv_probe(u32 id);
- static void tls_spifls_drv_remove(void);
- static struct tls_fls_drv exspi_fls = {
- .drv_list = {NULL, NULL},
- .clock = SPI_SCLK,
- .mode = TLS_SPI_MODE_0,
- .cs_active = TLS_SPI_CS_LOW,
- .flags = 0,
- .read = tls_spifls_drv_read,
- .fast_read = tls_spifls_drv_fast_read,
- .page_write = tls_spifls_drv_page_write,
- .erase = tls_spifls_drv_erase,
- .chip_erase = tls_spifls_drv_chip_erase,
- .probe = tls_spifls_drv_probe,
- .remove = tls_spifls_drv_remove
- };
- static struct tls_fls_drv *exspifls_drv = NULL;
- static unsigned int swap32(unsigned int v)
- {
- return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
- ((v & 0xff0000) >> 8) | (v >> 24);
- }
- static int tls_spifls_drv_write_enable(void)
- {
- u8 cmd;
- int err;
- cmd = EXSPIFLASH_WRITE_ENABLE;
- err = tls_spi_write((const u8 *) &cmd, 1);
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- return TLS_FLS_STATUS_OK;
- }
- static int tls_spifls_drv_wait_write_enable(void)
- {
- u8 cmd;
- u8 sr;
- int err;
- cmd = EXSPIFLASH_READ_SR1;
- sr = 0;
- do
- {
- err = tls_spi_read_with_cmd((const u8 *) &cmd, 1, &sr, 1);
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- if (sr & FLASH_STATUS_WEL)
- {
- break;
- }
- }
- while (1);
- return TLS_FLS_STATUS_OK;
- }
- static int tls_spifls_drv_wait_flash_ready(void)
- {
- u8 cmd;
- u8 sr;
- int err;
- cmd = EXSPIFLASH_READ_SR1;
- sr = 0;
- do
- {
- err = tls_spi_read_with_cmd((const u8 *) &cmd, 1, &sr, 1);
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- if ((sr & FLASH_STATUS_BUSY) == 0x00)
- {
- break;
- }
- }
- while (1);
- return TLS_FLS_STATUS_OK;
- }
- static int tls_spifls_drv_read(u32 addr, u8 * buf, u32 len)
- {
- u32 cmd;
- int err;
- cmd = 0;
- cmd |= EXSPIFLASH_DATA_READ;
- cmd |= swap32(addr) & 0xffffff00;
- err = tls_spi_read_with_cmd((const u8 *) &cmd, 4, buf, len);
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- return TLS_FLS_STATUS_OK;
- }
- static int tls_spifls_drv_fast_read(u32 addr, u8 * buf, u32 len)
- {
- return TLS_FLS_STATUS_ENOSUPPORT;
- }
- static int tls_spifls_drv_page_write(u32 page, u8 * buf)
- {
- u32 cmd;
- int err;
- err = tls_spifls_drv_write_enable();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- err = tls_spifls_drv_wait_write_enable();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- cmd = 0;
- cmd |= EXSPIFLASH_PAGE_PROGRAM;
- cmd |= swap32(page * exspifls_drv->page_size) & 0xffffff00;
- err = tls_spi_write_with_cmd((const u8 *) &cmd, 4, (const u8 *) buf,
- exspifls_drv->page_size);
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- err = tls_spifls_drv_wait_flash_ready();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- return TLS_FLS_STATUS_OK;
- }
- static int tls_spifls_drv_erase(u32 sector)
- {
- u32 cmd;
- int err;
- err = tls_spifls_drv_write_enable();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- err = tls_spifls_drv_wait_write_enable();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- cmd = 0;
- cmd |= EXSPIFLASH_SECTOR_ERASE;
- cmd |= swap32(sector * exspifls_drv->sector_size) & 0xffffff00;
- err = tls_spi_write((const u8 *) &cmd, 4);
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- tls_os_time_delay(6);
- err = tls_spifls_drv_wait_flash_ready();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- return TLS_FLS_STATUS_OK;
- }
- static int tls_spifls_drv_chip_erase(void)
- {
- u8 cmd;
- int err;
- err = tls_spifls_drv_write_enable();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- err = tls_spifls_drv_wait_write_enable();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- cmd = EXSPIFLASH_CHIP_ERASE;
- err = tls_spi_write((const u8 *) &cmd, 1);
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- err = tls_spifls_drv_wait_flash_ready();
- if (err != TLS_SPI_STATUS_OK)
- {
- return TLS_FLS_STATUS_EIO;
- }
- return TLS_FLS_STATUS_OK;
- }
- static int tls_spifls_drv_probe(u32 id)
- {
- // int i = 0;
- if (!id)
- {
- return TLS_FLS_STATUS_EINVAL;
- }
- exspi_fls.id = id;
- if ((id>>16)&0xFF)
- {
- exspi_fls.total_size = 1 << (id>>16);
- }else{
- exspi_fls.total_size = FLASH_TOTAL_SIZE; /*1MByte*/
- }
-
- exspi_fls.page_size = PAGE_SIZE;
- exspi_fls.program_size = PROGRAM_SIZE;
- exspi_fls.sector_size = SECTOR_SIZE;
-
-
- exspifls_drv = &exspi_fls;
- return TLS_FLS_STATUS_OK;
- }
- static void tls_spifls_drv_remove(void)
- {
- exspifls_drv = NULL;
- }
- /**
- * @brief This function is used to install gd25qxx driver.
- *
- * @param[in] None
- *
- * @retval TLS_FLS_STATUS_OK if write flash success
- * @retval TLS_FLS_STATUS_EPERM if flash struct point is null
- * @retval TLS_FLS_STATUS_ENODRV if flash driver is not installed
- * @retval TLS_FLS_STATUS_EINVAL if argument is invalid
- * @retval TLS_FLS_STATUS_EIO if io error
- * @retval TLS_FLS_STATUS_EEXIST if driver is already existed
- *
- * @note None
- */
- int tls_spifls_drv_install(void)
- {
- int err;
- extern int tls_spifls_probe(void);
- extern int tls_spifls_drv_register(struct tls_fls_drv *fls_drv);
- err = tls_spifls_drv_register((struct tls_fls_drv *) &exspi_fls);
- if (err == TLS_FLS_STATUS_EEXIST)
- {
- return err;
- }
- TLS_DBGPRT_INFO("register the spi flash driver - %d.\n", err);
- err = tls_spifls_probe();
- TLS_DBGPRT_INFO("probe spi flash - %d.\n", err);
- return err;
- }
|