mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-12-26 17:18:24 +00:00
Re-normalizing the repo
This commit is contained in:
@@ -1,411 +1,411 @@
|
||||
/***************************************************************************//**
|
||||
* @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) */
|
||||
|
||||
/******************************************************************//**
|
||||
* @}
|
||||
*********************************************************************/
|
||||
/***************************************************************************//**
|
||||
* @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) */
|
||||
|
||||
/******************************************************************//**
|
||||
* @}
|
||||
*********************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user