123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- /***************************************************************************//**
- * @file dev_sflash.c
- * @brief SPI Flash driver of RT-Thread RTOS for EFM32 by using USART module
- * COPYRIGHT (C) 2012, RT-Thread Development Team
- * @author onelife
- * @version 1.0
- *******************************************************************************
- * @section License
- * The license and distribution terms for this file may be found in the file
- * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE
- *******************************************************************************
- * @section Change Logs
- * Date Author Notes
- * 2011-05-06 onelife Initial creation by using USART module
- ******************************************************************************/
- /***************************************************************************//**
- * @addtogroup efm32
- * @{
- ******************************************************************************/
- /* Includes ------------------------------------------------------------------*/
- #include "board.h"
- #include "drv_usart.h"
- #include "dev_sflash.h"
- #if defined(EFM32_USING_SFLASH)
- /* Private typedef -------------------------------------------------------------*/
- typedef struct
- {
- rt_uint8_t code;
- rt_uint32_t address:24;
- rt_uint32_t dummy:8;
- } sflash_instruction;
- /* Private define --------------------------------------------------------------*/
- /* Private macro --------------------------------------------------------------*/
- #ifdef EFM32_SFLASH_DEBUG
- #define sflash_debug(format,args...) rt_kprintf(format, ##args)
- #else
- #define sflash_debug(format,args...)
- #endif
- /* Private constants -----------------------------------------------------------*/
- static rt_uint8_t sflash_inst_code_tbl[] =
- {
- /* Instruction only */
- SFLASH_INST_CODE_WREN,
- SFLASH_INST_CODE_WRDI,
- SFLASH_INST_CODE_RDID_L,
- SFLASH_INST_CODE_RDID_S,
- SFLASH_INST_CODE_RDSR,
- SFLASH_INST_CODE_WRSR,
- SFLASH_INST_CODE_BE,
- SFLASH_INST_CODE_DP,
- SFLASH_INST_CODE_RDP,
- /* Instruction and address */
- SFLASH_INST_CODE_WRLR,
- SFLASH_INST_CODE_RDLR,
- SFLASH_INST_CODE_READ,
- SFLASH_INST_CODE_POTP,
- SFLASH_INST_CODE_PP,
- SFLASH_INST_CODE_DIFP,
- SFLASH_INST_CODE_SSE,
- SFLASH_INST_CODE_SE,
- /* Instruction, address and dummy read */
- SFLASH_INST_CODE_READ_F,
- SFLASH_INST_CODE_DOFR,
- SFLASH_INST_CODE_ROTP
- };
- static rt_uint16_t sflash_data_len_tbl[] =
- {
- /* Instruction only */
- SFLASH_REPLY_LEN_WREN,
- SFLASH_REPLY_LEN_WRDI,
- SFLASH_REPLY_LEN_RDID_L,
- SFLASH_REPLY_LEN_RDID_S,
- SFLASH_REPLY_LEN_RDSR,
- SFLASH_REPLY_LEN_WRSR,
- SFLASH_REPLY_LEN_BE,
- SFLASH_REPLY_LEN_DP,
- SFLASH_REPLY_LEN_RDP,
- /* Instruction and address */
- SFLASH_REPLY_LEN_WRLR,
- SFLASH_REPLY_LEN_RDLR,
- SFLASH_REPLY_LEN_READ,
- SFLASH_REPLY_LEN_POTP,
- SFLASH_REPLY_LEN_PP,
- SFLASH_REPLY_LEN_DIFP,
- SFLASH_REPLY_LEN_SSE,
- SFLASH_REPLY_LEN_SE,
- /* Instruction, address and dummy read */
- SFLASH_REPLY_LEN_READ_F,
- SFLASH_REPLY_LEN_DOFR,
- SFLASH_REPLY_LEN_ROTP
- };
- static rt_bool_t sflash_read_inst_tbl[] =
- {
- /* Instruction only */
- false,
- false,
- true,
- true,
- true,
- false,
- false,
- false,
- false,
- /* Instruction and address */
- false,
- true,
- true,
- false,
- false,
- false,
- false,
- false,
- /* Instruction, address and dummy read */
- true,
- true,
- true
- };
- /* Private variables ------------------------------------------------------------*/
- static rt_device_t sFlash = RT_NULL;
- static rt_bool_t sFlashAutoCs = true;
- /* Private function prototypes ---------------------------------------------------*/
- /* Private functions ------------------------------------------------------------*/
- /******************************************************************//**
- * @brief
- * Initialize the SPI Flash
- *
- * @details
- *
- * @note
- *
- * @return
- * Error code
- *********************************************************************/
- rt_err_t efm_spiFlash_init(void)
- {
- struct efm32_usart_device_t *usart;
- usart = (struct efm32_usart_device_t *)(sFlash->user_data);
- #if defined(EFM32_GXXX_DK)
- /* Enable SPI access to Flash */
- DVK_writeRegister(BC_SPI_CFG, 0);
- #endif
- do
- {
- /* Find SPI device */
- sFlash = rt_device_find(SFLASH_USING_DEVICE_NAME);
- if (sFlash == RT_NULL)
- {
- sflash_debug("SFLASH: Can't find device %s!\n",
- SFLASH_USING_DEVICE_NAME);
- break;
- }
- sflash_debug("SFLASH: Find device %s\n", SFLASH_USING_DEVICE_NAME);
- /* Config chip slect pin */
- if (!(usart->state & USART_STATE_AUTOCS))
- {
- GPIO_PinModeSet(SFLASH_CS_PORT, SFLASH_CS_PIN, gpioModePushPull, 1);
- sFlashAutoCs = false;
- }
- /* Open SPI device */
- if (sFlash->open(sFlash, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
- {
- break;
- }
- return RT_EOK;
- } while(0);
- sflash_debug("SFLASH: Init failed!\n");
- return -RT_ERROR;
- }
- /******************************************************************//**
- * @brief
- * De-initialize the SPI Flash
- *
- * @details
- *
- * @note
- *
- * @return
- * Error code
- *********************************************************************/
- rt_err_t efm_spiFlash_deinit(void)
- {
- do
- {
- if (sFlash == RT_NULL)
- {
- sflash_debug("SFLASH: Already deinit!\n");
- break;
- }
- /* Close SPI device */
- if (sFlash->close(sFlash) != RT_EOK)
- {
- break;
- }
- sFlash = RT_NULL;
- sflash_debug("SFLASH: Close device %s\n", SFLASH_USING_DEVICE_NAME);
- return RT_EOK;
- } while(0);
- sflash_debug("SFLASH: Deinit failed!\n");
- return -RT_ERROR;
- }
- /******************************************************************//**
- * @brief
- * Set/Clear chip select
- *
- * @details
- *
- * @note
- *
- * @param[in] enable
- * Chip select pin setting
- *********************************************************************/
- static void efm_spiFlash_cs(rt_uint8_t enable)
- {
- if (!sFlashAutoCs)
- {
- if (enable)
- {
- GPIO_PinOutClear(SFLASH_CS_PORT, SFLASH_CS_PIN);
- }
- else
- {
- GPIO_PinOutSet(SFLASH_CS_PORT, SFLASH_CS_PIN);
- }
- }
- }
- /******************************************************************//**
- * @brief
- * Execute a command
- *
- * @details
- *
- * @note
- *
- * @param[in] command
- * SPI Flash instruction
- *
- * @param[in] address
- * Memory address
- *
- * @param[in] buffer
- * Poniter to the read/write buffer
- *
- * @param[in] size
- * Buffer size in byte
- *
- * @return
- * Number of read/written bytes
- *********************************************************************/
- rt_uint32_t efm_spiFlash_cmd(
- enum sflash_inst_type_t command,
- rt_uint32_t address,
- rt_uint8_t *buffer,
- rt_uint32_t size)
- {
- RT_ASSERT(sFlash != RT_NULL);
- sflash_instruction *inst;
- rt_uint8_t *inst_buf;
- rt_uint8_t inst_len, head_len;
- rt_uint32_t data_len;
- sflash_debug("SFLASH: Inst %x\n", sflash_inst_code_tbl[command]);
- if (sflash_data_len_tbl[command] && !size)
- {
- sflash_debug("SFLASH: No data!\n");
- return 0x00;
- }
- data_len = (sflash_data_len_tbl[command] < size)? \
- sflash_data_len_tbl[command] : size;
- if (data_len && (buffer == RT_NULL))
- {
- sflash_debug("SFLASH: No buffer specified!\n");
- return 0x00;
- }
- /* Allocate memory for write buffer */
- if (sflash_read_inst_tbl[command])
- {
- inst_buf = rt_malloc(6 + 4);
- inst = (sflash_instruction *)(inst_buf + 1);
- head_len = 1;
- }
- else
- {
- inst_buf = rt_malloc(5 + data_len);
- inst = (sflash_instruction *)inst_buf;
- head_len = 0;
- }
- /* Fill in instruction */
- inst->code = sflash_inst_code_tbl[command];
- if (command >= sflash_inst_wrlr)
- {
- /* MSB first */
- inst->address = ((address & 0x000000FF) << 16) | \
- (address & 0x0000FF00) | \
- ((address & 0x00FF0000) >> 16);
- if (command >= sflash_inst_read_f)
- {
- inst->dummy = 0x00;
- inst_len = 5;
- }
- else
- {
- inst_len = 4;
- }
- }
- else
- {
- inst_len = 1;
- }
- head_len += inst_len;
- /* Fill in data and send the buffer */
- if (sflash_read_inst_tbl[command])
- {
- rt_off_t skip;
- inst_buf[0] = inst_len;
- *(rt_uint8_t **)(inst_buf + head_len) = buffer;
- if (command == sflash_inst_read)
- {
- skip = SFLASH_SPI_READ_SKIP;
- }
- else
- {
- skip = SFLASH_SPI_COMMAND_SKIP;
- }
- efm_spiFlash_cs(1);
- if (sFlash->read(sFlash, skip, inst_buf, \
- (data_len == size)? data_len - 1 : data_len) == 0)
- {
- sflash_debug("SFLASH: Read failed!\n");
- return 0x00;
- }
- efm_spiFlash_cs(0);
- buffer[data_len] = 0x00;
- sflash_debug("SFLASH: Read %d bytes data to 0x%x\n", data_len, buffer);
- }
- else
- {
- if (data_len)
- {
- rt_memcpy((inst_buf + head_len), buffer, data_len);
- }
- efm_spiFlash_cs(1);
- if (sFlash->write(sFlash, EFM32_NO_DATA, inst_buf, \
- head_len + data_len) == 0)
- {
- sflash_debug("SFLASH: Write failed!\n");
- return 0x00;
- }
- efm_spiFlash_cs(0);
- sflash_debug("SFLASH: Write %d/%d bytes data\n", data_len, \
- head_len + data_len);
- }
- /* Free the buffer */
- rt_free(inst_buf);
- return data_len;
- }
- /*********************************************************************
- * Export to FINSH
- *********************************************************************/
- #ifdef RT_USING_FINSH
- #include <finsh.h>
- void list_sflash(void)
- {
- rt_uint8_t buf[4];
- efm_spiFlash_cmd(sflash_inst_rdid_s, EFM32_NO_DATA, buf, sizeof(buf));
- rt_kprintf(" spi flash on %s\n", SFLASH_USING_DEVICE_NAME);
- rt_kprintf(" ------------------------------\n");
- rt_kprintf(" Manufacturer ID:\t%x\n", buf[0]);
- rt_kprintf(" Memory type:\t\t%x\n", buf[1]);
- rt_kprintf(" Memory capacity:\t%x\n", buf[2]);
- }
- FINSH_FUNCTION_EXPORT(list_sflash, list the SPI Flash.)
- #endif
- #endif /* defined(EFM32_USING_SFLASH) */
- /******************************************************************//**
- * @}
- *********************************************************************/
|