📄 sharpflash.c
字号:
/*****************************************************************************
FILE NAME: sharpflash.c
DESCRIPTION:
Sharp flash driver.
Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/
#include "fsmdefs.h"
#include "FsmFlash.h"
#include "sharpflash.h"
#include "ostype.h"
#define FSM_DATA_START_ADDR 0x07300000 /* Address at which data volume begins. */
#define FSM_DATA_BLOCK_COUNT 8
#define FSM_DATA_BLOCK_SIZE 0x10000 /* Number of bytes in each block of
* the data volume. */
#define BUFFER_SIZE 16
#define ALIGN_ADDRESS(addr) \
((uint32) ((addr) & ((uint32) ~(sizeof(FLASH_DATA) - 1))))
#define UNALIGNED_BYTES(addr) \
((uint32) ((addr) & ((uint32) (sizeof(FLASH_DATA) - 1))))
#define GET_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define LOCK_BLOCK(addr) \
do \
{ \
*(addr) = FLASH_COMMAND_LOCK; \
*(addr) = FLASH_COMMAND_LOCK_CONFIRM; \
} while(0)
#define UNLOCK_BLOCK(addr) \
do \
{ \
*(addr) = FLASH_COMMAND_LOCK; \
*(addr) = FLASH_COMMAND_UNLOCK_CONFIRM; \
} while(0)
/* Function prototypes. */
uint32 FsmSharpFlashInit(FsmDevObjHdrT *DevObjP);
uint32 FsmSharpFlashWrite(FsmDevObjHdrT *DevObjP, uint8 *buf, uint32 addr, uint32 len);
uint32 FsmSharpFlashErase(FsmDevObjHdrT *DevObjP, uint32 addr);
uint32 FsmSharpFlashCopy(FsmDevObjHdrT *DevObjP, uint32 DstAddr, uint32 SrcAddr, uint32 len);
uint32 FsmSharpFlashRead(FsmDevObjHdrT *DevObjP, uint8 *buf, uint32 addr, uint32 len);
uint32 FsmSharpFlashCtrl(FsmDevObjHdrT *DevObjP, uint32 CtrlCode, void *arg);
/* global variables */
const FsmDevDrvT SharpFlashDrv =
{
FsmSharpFlashRead,
FsmSharpFlashWrite,
FsmSharpFlashCopy,
FsmSharpFlashErase,
FsmSharpFlashCtrl,
FsmSharpFlashInit
};
FsmFlashDevT FlashDev =
{
{ (FsmDevDrvT *)&SharpFlashDrv, DEV_TYPE_FLASH, NULL },
NULL,
NULL,
FSM_DATA_BLOCK_SIZE,
FSM_DATA_BLOCK_COUNT,
FSM_DATA_START_ADDR
};
volatile uint8 FsmStarting = FALSE;
/**********************************************
* FUNCTIONS *
**********************************************/
/******************************************************************************
* WriteToFlash()
*
* descriptions:
* Writes data to flash.
*
* parameters:
* FLASH_DATA_PTR flash_ptr - A pointer to the data destination.
* FLASH_DATA_PTR ram_ptr - A pointer to the data source.
* uint32 size - The number of FLASH_DATA units to write.
*
* return:
* If any portion of the data is not written successfully, the function
* returns HW_ERR_WRITE; otherwise, the function returns HW_ERR_NONE.
*
*****************************************************************************/
static uint32
WriteToFlash(
volatile FLASH_DATA *flash_ptr,
const FLASH_DATA *ram_ptr,
uint32 size
)
{
FLASH_DATA buffer_size;
uint32 size_to_write;
uint32 i;
uint32 status = HW_ERR_NONE;
while (size > 0)
{
/* no enough data, use single data program */
if (size == 1)
{
DISABLE_INTERRUPTS();
UNLOCK_BLOCK(flash_ptr);
*flash_ptr = FLASH_COMMAND_WRITE;
*flash_ptr = *ram_ptr;
ENABLE_INTERRUPTS();
ram_ptr++;
size--;
}
else
{
/* determine the size of the buffer */
size_to_write = GET_MIN(size, BUFFER_SIZE / sizeof(FLASH_DATA));
buffer_size = (uint32)(size_to_write - 1);
/* wait until buffer is ready */
DISABLE_INTERRUPTS();
UNLOCK_BLOCK(flash_ptr);
do
{
*flash_ptr = FLASH_COMMAND_WRITE_BUFFER;
} while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY);
/* send size of data and fill buffer */
*flash_ptr = buffer_size;
for (i = 0; i < size_to_write; i++)
{
*flash_ptr = *ram_ptr;
flash_ptr++;
ram_ptr++;
}
/* make sure pointer is in the same block and commit buffer */
flash_ptr--;
*flash_ptr = FLASH_COMMAND_CONFIRM;
ENABLE_INTERRUPTS();
size -= size_to_write;
}
/* wait until flash is done */
while ((*flash_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
/* Lock the block */
DISABLE_INTERRUPTS();
LOCK_BLOCK(flash_ptr);
ENABLE_INTERRUPTS();
/* check for errors */
if (*flash_ptr & FLASH_STATUS_ERROR)
{
*flash_ptr = FLASH_COMMAND_CLEAR;
status = HW_ERR_WRITE;
break;
}
/* increment flash pointer */
flash_ptr++;
}
return status;
}
/******************************************************************************
* FsmSharpFlashInit()
*
* descriptions:
* reset flash device to read-mode.
*
* parameters:
* FsmDevObjHdrT * DevObjP - device object
*
* return:
* HW_ERR_NONE.
*
*****************************************************************************/
uint32 FsmSharpFlashInit(FsmDevObjHdrT *DevObjP)
{
volatile FLASH_DATA_PTR flash_ptr;
FsmFlashDevT * pDev;
pDev = (FsmFlashDevT *)DevObjP;
flash_ptr = (volatile FLASH_DATA_PTR)(pDev->DevStartAddr);
/* Place flash into read state. */
*flash_ptr = FLASH_COMMAND_READ;
return HW_ERR_NONE;
}
/******************************************************************************
* FsmSharpFlashRead()
*
* descriptions:
* reset flash device to read-mode.
*
* parameters:
* FsmDevObjHdrT * DevObjP - device object
* uint8 * buf - buffer to receive the returned data
* uint32 Addr - where to read from within flash.
* uint32 length - number of bytes to read.
*
* return:
* HW_ERR_NONE.
*
*****************************************************************************/
uint32 FsmSharpFlashRead(FsmDevObjHdrT *DevObjP, uint8 *buf, uint32 addr, uint32 len)
{
volatile FLASH_DATA_PTR flash_data_ptr;
volatile uint8 *flash_byte_ptr;
FLASH_DATA_PTR ram_data_ptr;
uint8 *ram_byte_ptr;
uint32 flash_offset, ram_offset;
uint8 suspended = (uint8)FALSE;
FsmFlashDevT *pDev;
pDev = (FsmFlashDevT *)DevObjP;
/* Validate address. */
#ifdef VALIDATE_ADDRESS
if ((addr + len) > (pDev->BlockSize * pDev->Blocks))
{
return HW_ERR_PARAM;
}
#endif /* VALIDATE_ADDRESS */
addr += pDev->DevStartAddr;
/* Return if nothing to read. */
if (len == 0)
{
return HW_ERR_NONE;
}
/* Set up pointers. */
flash_data_ptr = (FLASH_DATA_PTR)ALIGN_ADDRESS(addr);
flash_byte_ptr = (uint8 *)addr;
ram_byte_ptr = buf;
/* calculate alignment offsets */
flash_offset = UNALIGNED_BYTES(addr);
ram_offset = UNALIGNED_BYTES((uint32)buf);
*flash_data_ptr = FLASH_COMMAND_STATUS;
/* Partition ready? */
if ((*flash_data_ptr & FLASH_STATUS_PARTITION_READY) == 0)
{
*flash_data_ptr = FLASH_COMMAND_SUSPEND;
*flash_data_ptr = FLASH_COMMAND_STATUS;
while ((*flash_data_ptr & FLASH_STATUS_READY) != FLASH_STATUS_READY)
{
}
if (*flash_data_ptr &
(FLASH_STATUS_WRITE_SUSPENDED | FLASH_STATUS_ERASE_SUSPENDED))
{
suspended = (uint8)TRUE;
}
}
/*
* determine if source and destination addresses allow the reading on
* aligned addresses
*/
*flash_data_ptr = FLASH_COMMAND_READ;
if ((flash_offset == ram_offset) && (len > sizeof(FLASH_DATA)))
{
/* Read the initial unaligned bytes. */
if (flash_offset != 0)
{
while (flash_offset < sizeof(FLASH_DATA))
{
*ram_byte_ptr = *flash_byte_ptr;
ram_byte_ptr++;
flash_byte_ptr++;
len--;
flash_offset++;
}
}
/* Read aligned data. */
ram_data_ptr = (FLASH_DATA_PTR)ram_byte_ptr;
flash_data_ptr = (FLASH_DATA_PTR)flash_byte_ptr;
while (len >= sizeof(FLASH_DATA))
{
*ram_data_ptr = *flash_data_ptr;
ram_data_ptr++;
flash_data_ptr++;
len -= sizeof(FLASH_DATA);
}
/* Read the remaining unaligned bytes. */
if (len > 0)
{
ram_byte_ptr = (uint8 *)ram_data_ptr;
flash_byte_ptr = (uint8 *)flash_data_ptr;
while (len > 0)
{
*ram_byte_ptr = *flash_byte_ptr;
ram_byte_ptr++;
flash_byte_ptr++;
len--;
}
}
}
else /* We have to read byte by byte if the source and destination addresses
* do not allow the reading on aligned addresses.
*/
{
while (len > 0)
{
*ram_byte_ptr = *flash_byte_ptr;
ram_byte_ptr++;
flash_byte_ptr++;
len--;
}
}
/* if suspended, resume */
if (suspended)
{
*flash_data_ptr = FLASH_COMMAND_STATUS;
if (*flash_data_ptr & FLASH_STATUS_WRITE_SUSPENDED)
{
/* Resume write suspended flash. */
*flash_data_ptr = FLASH_COMMAND_RESUME;
*flash_data_ptr = FLASH_COMMAND_STATUS;
}
else
{
*flash_data_ptr = FLASH_COMMAND_RESUME;
}
}
return HW_ERR_NONE;
}
/******************************************************************************
* FsmSharpFlashWrite()
*
* descriptions:
* write data to flash.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -