Flash Bloques
Flash Bloques
******************************************************************************
* @file
stm32f4xx_spi.c
* @author VC
* @version V1.2.0
* @date
13-April-2015
* @brief This file provides the kernel rtc functions
******************************************************************************
* Use the following configuration settings in the middleware component
* to connect to this driver.
*
* Configuration Setting
Value
* ------------------------* Connect to hardware via Driver_Flash# = n (default: 0)
*
******************************************************************************
*/
#include "drv_sflash.h"
#include "drv_SPI.h"
#include <string.h>
#include "sst26vfx.h"
#include "drv_led.h"
#define EVENT_RTOS
#ifdef EVENT_RTOS
#include "cmsis_os.h"
#endif
/* User Configuration */
#define DRIVER_SPI
DRIVER_SPI2
33000000
/* Bus speed
((uint32_t)1000) /* 1s */
0x03 // 40MHz
0x0B // 104MHz
0x05
#define CMD_PAGE_PROGRAM
#define CMD_WRITE_ENABLE
#define CMD_WRITE_DISABLE
0x02
0x06
0x04
#define CMD_ERASE_BLOCK
#define CMD_ERASE_SECTOR
#define CMD_ERASE_CHIP
0xD8
0x20
0xC7
#define CMD_READ_ID
#define CMD_RESET_ENABLE
#define CMD_RESET
0x9F
0x66
0x99
*/
#define
#define
#define
#define
FLAG_ADDR_PRESENT
FLAG_TYPE_READ
FLAG_TYPE_WRITE
FLAG_TYPE_ONLY_CMD
(1<<0)
(1<<1)
(1<<2)
(1<<3)
(&DRIVER_SPI)
state;
block_protection[10];
uint16_t
uint32_t
uint8_t
sector_size;
nsector;
nsector_mem[SFLASH_SECTOR_SIZE];
}sflashInfo_str;
sflashInfo_str SflashInfo;
/* Flash Information */
//static SFLASH_INFO FlashInfo = {
// SFLASH_SECTOR_INFO,
// SFLASH_SECTOR_COUNT,
// SFLASH_SECTOR_SIZE,
//
SFLASH_PAGE_COUNT,
// SFLASH_PAGE_SIZE,
// SFLASH_PROGRAM_UNIT,
// SFLASH_ERASED_VALUE
//};
// command byte
// cont dummy bytes
// read/write & present addr
= {
,0
,0
,0
,0
,0
,
,
,
,
,
FLAG_TYPE_ONLY_CMD},
FLAG_TYPE_ONLY_CMD},
FLAG_TYPE_ONLY_CMD},
FLAG_TYPE_ONLY_CMD},
FLAG_TYPE_READ | FLAG_ADDR_PRES
,1 , FLAG_TYPE_READ | FLAG_ADDR_PRES
,0
,0
,0
,0
,0
,
,
,
,
,
FLAG_TYPE_READ},
FLAG_TYPE_READ},
FLAG_TYPE_READ},
FLAG_TYPE_WRITE},
FLAG_TYPE_WRITE | FLAG_ADDR_PRE
,0 , FLAG_TYPE_WRITE | FLAG_ADDR_PRE
,0 , FLAG_TYPE_WRITE | FLAG_ADDR_PRE
,0 , FLAG_TYPE_ONLY_CMD}
/* Select Slave */
ptrSPI->ActiveNSS();
cmd_str[n++] = command->cmd;
if (command->flag & FLAG_ADDR_PRESENT ){
cmd_str[n++] = (uint8_t)(addr >> 16);
cmd_str[n++] = (uint8_t)(addr >> 8);
cmd_str[n++] = (uint8_t)(addr >> 0);
}
/* Add dummy bytes */
n += command->dummy;
/* Send cmd + [addr] + [dummy] */
if (ptrSPI->Send(cmd_str, n) != SPI_STATE_OK){
goto transfer_error;
}
while (ptrSPI->GetState() == SPI_STATE_BUSY){}
if(command->flag & FLAG_TYPE_WRITE){
/* Send data n-byte */
if (ptrSPI->Send(data, cnt) != SPI_STATE_OK){
goto transfer_error;
}
while (ptrSPI->GetState() == SPI_STATE_BUSY){}
}
else if(command->flag & FLAG_TYPE_READ){
/* Recv data n-bytes */
if (ptrSPI->Receive(data, cnt) != SPI_STATE_OK) {
goto transfer_error;
}
while (ptrSPI->GetState() == SPI_STATE_BUSY){}
}
/* Deselect Slave */
ptrSPI->InactiveNSS();
return SFLASH_OK;
transfer_error:
/* Deselect Slave */
ptrSPI->InactiveNSS();
return SFLASH_ERROR;
}
/**
\fn
SFLASH_STATUS Write_Enable (void)
\brief
Enable write complete Flash.
\return
\ref execution_status
*/
static SFLASH_STATUS Write_Enable(void){
return Send_Command(CMD_WRITE_ENABLE,0,NULL,0);
}
/**
\fn
SFLASH_STATUS Write_Disable (void)
\brief
Disable write complete Flash.
\return
\ref execution_status
*/
//static SFLASH_STATUS Write_Disable(void){
//
//
return Send_Command(CMD_WRITE_DISABLE,0,NULL,0);
//}
/**
\fn
\brief
\return
*/
static SFLASH_STATUS Reset(void){
\return
*/
static SFLASH_STATUS Read_Block_Protection(void){
return Send_Command(CMD_RD_BLOCK_PROTECTION,0,SflashInfo.block_protection,10
);
}
/**
\fn
\brief
\return
*/
//static unsigned char SimmetryBytes[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0
x01};
static SFLASH_STATUS Write_Block_Protection(void){
//
);
memset(SflashInfo.block_protection, 0, sizeof(SflashInfo.block_protection)
//
for (int i = 0; i< sizeof(lock_Structure);i++) {
//
SflashInfo.block_protection[(9-lock_Structure[i]/8)] |= SimmetryBytes
[lock_Structure[i] % 8];
//
}
//memset(SflashInfo.block_protection, 0, sizeof(SflashInfo.block_protection)
);
Write_Enable();
return Send_Command(CMD_WR_BLOCK_PROTECTION,0,SflashInfo.block_protection,10
);
}
static SFLASH_STATUS Unlock_Block_Protection(void) {
sflashInfo_str temp_fInfo;
memset(temp_fInfo.block_protection, 0, sizeof(temp_fInfo.block_protection));
Write_Enable();
return Send_Command(CMD_WR_BLOCK_PROTECTION,0,temp_fInfo.block_protection,10
);
}
\fn
\brief
\param[in]
\return
*/
uint16_t code;
const SPI_ParamConfig_str SPI_Config = {
.mode
= SPI_CMODE_MASTER,
.fomat
= SPI_CPOL1_CPHA1,
.data_bits= SPI_DATA_BIT_8BIT,
.order
= SPI_MSB_LSB,
.speed
= BUS_SPEED
};
static SFLASH_STATUS sst26vfx_Initialize (ARM_Flash_SignalEvent_t cb_event) {
/* SPI Init */
ptrSPI->Initialize();
/* check serial flash*/
Reset();
Read_Block_Protection();
Protected_Blocks_Init();
if (sst26vfx_ReadID(&code) == SFLASH_ERROR)
return SFLASH_ERROR;
FlashInfo.sector_info = SFLASH_SECTOR_TABLE;
SflashInfo.nsector = SFLASH_MAX_ADDRESS + 1; //fuera de rango
Write_Block_Protection();
#ifdef EVENT_RTOS
mut_sflash_id = osMutexCreate(osMutex(mut_sflash));
#endif
return SFLASH_OK;
}
/**
\fn
int32_t ARM_Flash_Uninitialize (void)
\brief
De-initialize the Flash Interface.
\return
\ref execution_status
*/
static SFLASH_STATUS sst26vfx_Uninitialize (void) {
\brief
\param[in]
\return
*/
static SFLASH_STATUS sst26vfx_EraseSector (uint32_t addr) {
SFLASH_STATUS ret;
/* Init sector */
SflashInfo.nsector = SFLASH_MAX_ADDRESS + 1;
/* Check Status */
Wait_Ready();
Write_Enable();
ret = Send_Command(CMD_ERASE_SECTOR, addr, NULL, 0);
return ret;
}
/**
\fn
int32_t ARM_Flash_EraseBlock (uint32_t addr)
\brief
Erase Flash Block.
\param[in] addr Sector address
\return
\ref execution_status
*/
static SFLASH_STATUS sst26vfx_EraseBlock (uint32_t addr) {
/* Init sector */
SflashInfo.nsector = SFLASH_MAX_ADDRESS + 1;
/* Check Status */
Wait_Ready();
Write_Enable();
/* Borra el bloque (no los sectores asociados al bloque) */
return Send_Command(CMD_ERASE_BLOCK, addr, NULL, 0);
}
/**
\fn
t)
\brief
\param[in]
\param[out]
\param[in]
\return
*/
static int32_t
int i;
#ifdef EVENT_RTOS
osMutexWait(mut_sflash_id,osWaitForever);
#endif
/* check parameters 4Mbytes */
if( (addr + cnt) > SFLASH_MAX_ADDRESS || data == NULL){
#ifdef EVENT_RTOS
osMutexRelease(mut_sflash_id);
#endif
return ARM_DRIVER_ERROR_PARAMETER;
}
for (i=0;i<cnt/256;i++) {
/* Check Status */
Wait_Ready();
if (Send_Command(CMD_READ_DATA, addr, (uint8_t *)data + 256*i, 256) == S
FLASH_OK){
continue;
}
else {
#ifdef EVENT_RTOS
osMutexRelease(mut_sflash_id);
#endif
return SFLASH_ERROR;
}
}
for (int j=0;j<cnt%256;j++) {
/* Check Status */
Wait_Ready();
if (Send_Command(CMD_READ_DATA, addr, (uint8_t *)data + 256*i +j, cnt%25
6) == SFLASH_OK){
continue;
}
else {
#ifdef EVENT_RTOS
osMutexRelease(mut_sflash_id);
#endif
return SFLASH_ERROR;
}
}
#ifdef EVENT_RTOS
osMutexRelease(mut_sflash_id);
#endif
return cnt;
}
/**
\fn
int32_t cnt)
\brief
\param[in]
\param[in]
Flash.
\param[in]
\return
*/
#define SECTOR_SUBADDRESS(addr)
#define SECTOR_ADDRESS(addr)
16_t inc){
uint8_t result = 0;
uint32_t sector = ( addr & ~(SFLASH_SECTOR_SIZE-1));
uint32_t sub_addr = addr & (SFLASH_SECTOR_SIZE-1);
if(SflashInfo.nsector != sector){
// leemos el sector entero
sst26vfx_ReadData(sector, SflashInfo.nsector_mem, SFLASH_SECTOR_SIZE);
SflashInfo.nsector = sector;
}
for(uint32_t i=0; i< cnt; i++){
/* chech AND data, if (RAM &FLASH) != RAM -> erase Sector */
if((SflashInfo.nsector_mem[sub_addr+i] & *(data+(i*inc))) != *(data+
(i*inc)))
result = 1;
/* copy data in RAM */
SflashInfo.nsector_mem[sub_addr+i] = *(data+(i*inc));
}
return result;
}
static SFLASH_STATUS Sector_ProgramData(uint32_t addr, const void *data, uint32_
t cnt){
const uint8_t *buf;
uint32_t n;
SFLASH_STATUS result = SFLASH_OK;
buf = data;
while(cnt && result == SFLASH_OK)
{
n = SFLASH_PAGE_SIZE - (addr % SFLASH_PAGE_SIZE);
if (n > cnt) n = cnt;
/* Check Status */
Wait_Ready();
Write_Enable();
/* Send Command with Address */
result = Send_Command(CMD_PAGE_PROGRAM, addr, (void *)buf, n);
Wait_Ready();
/* Calculate next page to program */
addr += n;
buf += n;
cnt -= n;
}
return result;
}
static int32_t _ProgramData (uint32_t addr, const void *data, uint32_t cnt, uint
16_t inc) {
return SFLASH_ERROR;
}
static int32_t sst26vfx_ProgramData (uint32_t addr, const void *data, uint32_t c
nt) {
uint32_t ret;
int i;
/* Program data with increment 1 */
#ifdef EVENT_RTOS
osMutexWait(mut_sflash_id,osWaitForever);
#endif
for (i = 0;i<(cnt/256);i++) {
ret = _ProgramData(addr, (uint8_t *)data+256*i, 256, 1);
}
for (int j = 0;j < (cnt%256);j++) {
ret += _ProgramData(addr, (uint8_t *)data+256*i+j, cnt%256, 1);
}
#ifdef EVENT_RTOS
osMutexRelease(mut_sflash_id);
#endif
return ret;
}
static int32_t sst26vfx_FillData (uint32_t addr, const uint8_t data, uint32_t cn
t) {
/* Program Data with increment 0 */
return _ProgramData(addr, &data, cnt, 0);
}
/**
\fn
int32_t ARM_Flash_EraseSector (uint32_t addr)
\brief
Erase Flash Sector.
\param[in] addr Sector address
\return
\ref execution_status
*/
static SFLASH_STATUS sst26vfx_ErasePage (uint32_t addr) {
return SFLASH_ERROR_UNSUPPORTED;
}
/**
\fn
SFLASH_STATUS sst26vfx_ReadID (void)
\brief
Read ID chip.
\return
\ref execution_status
*/
static SFLASH_STATUS sst26vfx_ReadID(uint16_t *id_code){
uint8_t bufout[3];
if (Send_Command(CMD_READ_ID, 0, bufout, 3) == SFLASH_OK){
*id_code = *((uint16_t *)&bufout[1]);
return SFLASH_OK;
}
return SFLASH_ERROR;
}
/**
\fn
\brief
\return
*/
static SFLASH_STATUS sst26vfx_EraseChip (void) {
/* Init sector */
SflashInfo.nsector = SFLASH_MAX_ADDRESS + 1;
/* Check Status */
Wait_Ready();
Write_Enable();
/**
\fn
ARM_FLASH_STATUS ARM_Flash_GetStatus (void)
\brief
Get Flash status.
\return
Flash status \ref ARM_FLASH_STATUS
*/
static SFLASH_STATUS sst26vfx_GetStatus (void) {
return SFLASH_OK;
}
/**
\fn
ARM_FLASH_INFO * ARM_Flash_GetInfo (void)
\brief
Get Flash information.
\return
Pointer to Flash information \ref ARM_FLASH_INFO
*/
SFLASH_INFO * sst26vfx_GetInfo (void) {
return &FlashInfo;
}
/**
\fn
ARM_DRIVER_VERSION ARM_Flash_GetVersion (void)
\brief
Get driver version.
\return
\ref ARM_DRIVER_VERSION
*/
static uint16_t sst26vfx_GetVersion (void) {
return SFLASH_DRIVER_VERSION(1,0);
//DriverVersion;
}
/* Flash Driver Control Block */
SFLASH_DRIVER driver_sst26vfx = {
sst26vfx_GetVersion,
sst26vfx_Initialize,
sst26vfx_Uninitialize,
sst26vfx_ReadData,
sst26vfx_ProgramData,
sst26vfx_FillData,
sst26vfx_ErasePage,
sst26vfx_EraseSector,
sst26vfx_EraseBlock,
sst26vfx_EraseChip,
sst26vfx_GetStatus,
sst26vfx_ReadID,
sst26vfx_GetInfo,
Write_Block_Protection,
Unlock_Block_Protection,
};