370 lines
8.1 KiB
C
370 lines
8.1 KiB
C
#include "hal_gdflash.h"
|
||
#include "stm32f10x.h"
|
||
#include "FRAM.h"
|
||
|
||
/*****************************************************************************
|
||
Prototype : hal_sRF_SPI_Config
|
||
Description : none
|
||
Input : void
|
||
Output : None
|
||
Return Value :
|
||
Date : 2014/3/15
|
||
Author : Barry
|
||
*****************************************************************************/
|
||
void GDflash_init(void)
|
||
{
|
||
spiFlash_FRAMFlash_init();
|
||
}
|
||
/*****************************************************************************
|
||
Prototype : spiReadWriteByte
|
||
Description : spi basic function
|
||
Input : u8 data
|
||
Output : None
|
||
Return Value :
|
||
Date : 2014/3/15
|
||
Author : Barry
|
||
*****************************************************************************/
|
||
u8 GDflash_ReadWriteByte(u8 data)
|
||
{
|
||
return FRAMReadWriteByte(data);
|
||
|
||
}
|
||
|
||
void GDflash_write_enable(bool enable)
|
||
{
|
||
DGFLASH_CS_LOW();
|
||
|
||
if (enable)
|
||
{
|
||
GDflash_ReadWriteByte(GDFLASH_WRITE_ENABLE);
|
||
}
|
||
else
|
||
{
|
||
GDflash_ReadWriteByte(GDFLASH_WRITE_DISABLE);
|
||
}
|
||
|
||
DGFLASH_CS_HIGH();
|
||
}
|
||
|
||
|
||
u8 GDflash_read_status_reg(void)
|
||
{
|
||
u8 status_value;
|
||
|
||
DGFLASH_CS_LOW();
|
||
GDflash_ReadWriteByte(GDFLASH_READ_STATUS_REG);
|
||
status_value = GDflash_ReadWriteByte(DGFLASH_DUMMY_BYTE);
|
||
DGFLASH_CS_HIGH();
|
||
|
||
return status_value;
|
||
}
|
||
|
||
void GDflash_write_status_reg(u8 value)
|
||
{
|
||
DGFLASH_CS_LOW();
|
||
GDflash_ReadWriteByte(GDFLASH_WRITE_STATUS_REG);
|
||
GDflash_ReadWriteByte(value);
|
||
DGFLASH_CS_HIGH();
|
||
}
|
||
|
||
void GDflash_read_datas(u32 startAddr, u8 *buf, u32 length, bool fastRead)
|
||
{
|
||
while ((GDflash_read_status_reg() & 0x01) == 1 );
|
||
|
||
DGFLASH_CS_LOW();
|
||
|
||
if (fastRead)
|
||
{
|
||
GDflash_ReadWriteByte(GDFLASH_FAST_READ);
|
||
}
|
||
else
|
||
{
|
||
GDflash_ReadWriteByte(GDFLASH_READ_DATA);
|
||
}
|
||
|
||
GDflash_ReadWriteByte( (u8)((startAddr>> 16) &0xFF));
|
||
GDflash_ReadWriteByte( (u8)((startAddr>> 8) &0xFF));
|
||
GDflash_ReadWriteByte( (u8)(startAddr &0xFF));
|
||
|
||
if (fastRead)
|
||
{
|
||
GDflash_ReadWriteByte(DGFLASH_DUMMY_BYTE);
|
||
}
|
||
|
||
for (u32 i = 0; i < length; i++)
|
||
{
|
||
buf[i] = GDflash_ReadWriteByte(DGFLASH_DUMMY_BYTE);
|
||
}
|
||
|
||
DGFLASH_CS_HIGH();
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
Prototype : spiReadWriteByte
|
||
Description : spi basic function
|
||
Input : u8 data
|
||
Output : None
|
||
Return Value :
|
||
Date : 2014/3/15
|
||
Author : Barry
|
||
当写入地址不是每页的开头时,若此页的剩余空间小于要写入的内容大小,那么数据将会重当前
|
||
地址开始填充完此页后,从此页的开始处,再继续填充,直到完成
|
||
写入内容不能超出每页的大小256字节,超出的部分自能保证最后256字节的内容被写入flash
|
||
*****************************************************************************/
|
||
void GDflash_page_program(u32 startAddr, u8 *buf, u16 length, bool fastWrite)
|
||
{
|
||
while ((GDflash_read_status_reg() & 0x01) == 1 );
|
||
|
||
GDflash_write_enable(TRUE);
|
||
|
||
|
||
DGFLASH_CS_LOW();
|
||
|
||
if (fastWrite)
|
||
{
|
||
GDflash_ReadWriteByte(GDFLASH_PAGE_PROGRAM_F2);
|
||
}
|
||
else
|
||
{
|
||
GDflash_ReadWriteByte(GDFLASH_PAGE_PROGRAM_02);
|
||
}
|
||
|
||
GDflash_ReadWriteByte( (u8)((startAddr>> 16) &0xFF));
|
||
GDflash_ReadWriteByte( (u8)((startAddr>> 8) &0xFF));
|
||
GDflash_ReadWriteByte( (u8)(startAddr &0xFF));
|
||
|
||
for (u16 i = 0; i < length; i++)
|
||
{
|
||
GDflash_ReadWriteByte( buf[i]);
|
||
}
|
||
|
||
DGFLASH_CS_HIGH();
|
||
}
|
||
|
||
|
||
/*
|
||
Any address inside the sector is a valid
|
||
address for the Sector Erase (SE) command
|
||
*/
|
||
void GDflash_erase(u32 startAddr, GDFLASH_ERASE_TYPE erase_type)
|
||
{
|
||
while ((GDflash_read_status_reg() & 0x01) == 1 );
|
||
|
||
GDflash_write_enable(TRUE);
|
||
|
||
DGFLASH_CS_LOW();
|
||
|
||
switch (erase_type)
|
||
{
|
||
case SECTOR_ERASE:
|
||
GDflash_ReadWriteByte(GDFLASH_SECTOR_ERASE);
|
||
break;
|
||
|
||
case BLOCK_ERASE_32K:
|
||
GDflash_ReadWriteByte(GDFLASH_BLOCK_ERASE_32);
|
||
break;
|
||
|
||
case BLOCK_ERASE_64K:
|
||
GDflash_ReadWriteByte(GDFLASH_BLOCK_ERASE_64);
|
||
break;
|
||
|
||
case CHIP_ERASE:
|
||
GDflash_ReadWriteByte(GDFLASH_CHIP_ERASE);
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (erase_type != CHIP_ERASE)
|
||
{
|
||
GDflash_ReadWriteByte( (u8)((startAddr>> 16) &0xFF));
|
||
GDflash_ReadWriteByte( (u8)((startAddr>> 8) &0xFF));
|
||
GDflash_ReadWriteByte( (u8)(startAddr &0xFF));
|
||
}
|
||
|
||
DGFLASH_CS_HIGH();
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
*
|
||
|
||
*
|
||
*
|
||
*
|
||
*
|
||
*
|
||
当写入地址不是每页的开头时,若此页的剩余空间小于要写入的内容大小,那么数据将会重当前
|
||
地址开始填充完此页后,从此页的开始处,再继续填充,直到完成
|
||
写入内容不能超出每页的大小256字节,超出的部分自能保证最后256字节的内容被写入flash
|
||
|
||
这种写入方法,只管写,不管擦除,在第一个升级包的时候就全片擦除
|
||
*****************************************************************************/
|
||
#define GDFLASH_PAGE_SIZE 256
|
||
|
||
void GDflash_write(u32 startAddr, u8 *buf, u32 length)
|
||
{
|
||
u32 current_startAddr = startAddr;
|
||
u8 first_page_byte = GDFLASH_PAGE_SIZE - (startAddr % GDFLASH_PAGE_SIZE);
|
||
u8 * current_data_ptr = buf;
|
||
u32 left_length = length;
|
||
u16 integrated_Pages;
|
||
u16 end_page_byte;
|
||
|
||
if (length > first_page_byte)
|
||
{
|
||
GDflash_page_program( current_startAddr, current_data_ptr, first_page_byte, FALSE);
|
||
|
||
current_startAddr = current_startAddr + first_page_byte;
|
||
current_data_ptr += first_page_byte;
|
||
left_length = length - first_page_byte;
|
||
integrated_Pages = left_length / GDFLASH_PAGE_SIZE;
|
||
end_page_byte = left_length % GDFLASH_PAGE_SIZE;
|
||
|
||
|
||
for (u16 i = 0; i < integrated_Pages; i++)
|
||
{
|
||
GDflash_page_program( current_startAddr, current_data_ptr, GDFLASH_PAGE_SIZE, FALSE);
|
||
current_startAddr += GDFLASH_PAGE_SIZE;
|
||
current_data_ptr += GDFLASH_PAGE_SIZE;
|
||
}
|
||
|
||
if (end_page_byte > 0)
|
||
{
|
||
GDflash_page_program( current_startAddr, current_data_ptr, end_page_byte, FALSE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
GDflash_page_program( current_startAddr, current_data_ptr, length, FALSE);
|
||
}
|
||
}
|
||
|
||
void GDflash_read_next(u32 startAddr, u8 *buf, u32 length)
|
||
{
|
||
u32 current_startAddr = startAddr;
|
||
u8 first_page_byte = GDFLASH_PAGE_SIZE - (startAddr % GDFLASH_PAGE_SIZE);
|
||
u8 * current_data_ptr = buf;
|
||
u32 left_length = length;
|
||
u16 integrated_Pages;
|
||
u16 end_page_byte;
|
||
|
||
if (length > first_page_byte)
|
||
{
|
||
GDflash_read_datas( current_startAddr, current_data_ptr, first_page_byte, FALSE);
|
||
|
||
current_startAddr = current_startAddr + first_page_byte;
|
||
current_data_ptr += first_page_byte;
|
||
left_length = length - first_page_byte;
|
||
integrated_Pages = left_length / GDFLASH_PAGE_SIZE;
|
||
end_page_byte = left_length % GDFLASH_PAGE_SIZE;
|
||
|
||
|
||
for (u16 i = 0; i < integrated_Pages; i++)
|
||
{
|
||
GDflash_read_datas( current_startAddr, current_data_ptr, GDFLASH_PAGE_SIZE, FALSE);
|
||
current_startAddr += GDFLASH_PAGE_SIZE;
|
||
current_data_ptr += GDFLASH_PAGE_SIZE;
|
||
}
|
||
|
||
if (end_page_byte > 0)
|
||
{
|
||
GDflash_read_datas( current_startAddr, current_data_ptr, end_page_byte, FALSE);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
GDflash_read_datas( current_startAddr, current_data_ptr, length, FALSE);
|
||
}
|
||
}
|
||
|
||
|
||
void GDfalsh_read_identification(u8 *buf)
|
||
{
|
||
DGFLASH_CS_LOW();
|
||
|
||
GDflash_ReadWriteByte(0x9F);
|
||
|
||
buf[0] = GDflash_ReadWriteByte(0xAA);
|
||
buf[1] = GDflash_ReadWriteByte(0xAA);
|
||
buf[2] = GDflash_ReadWriteByte(0xAA);
|
||
|
||
DGFLASH_CS_HIGH();
|
||
}
|
||
|
||
|
||
|
||
void GDflash_128KByte_erase(void)
|
||
{
|
||
GDflash_erase(0, BLOCK_ERASE_64K);
|
||
GDflash_erase(65536, BLOCK_ERASE_64K);
|
||
}
|
||
|
||
void GDflash_read(u32 startAddr, u8 *buf, u32 length)
|
||
{
|
||
GDflash_read_datas(startAddr, buf, length, FALSE);
|
||
}
|
||
|
||
|
||
|
||
void GDflash_test(void)
|
||
{
|
||
u8 buf[] = "hello,world!";
|
||
u8 buf1[20];
|
||
u8 buf2[20];
|
||
|
||
GDflash_init();
|
||
|
||
GDflash_erase(0,BLOCK_ERASE_64K);
|
||
GDflash_read_datas(0 , buf1, sizeof(buf), FALSE);
|
||
GDflash_page_program(0 , buf, sizeof(buf),TRUE);
|
||
GDflash_read_datas(0 , buf2, sizeof(buf), FALSE);
|
||
}
|
||
|
||
void flash_onepage_write(u32 addr,u8 * val,u16 len)
|
||
{
|
||
GDflash_erase(addr,SECTOR_ERASE);
|
||
GDflash_page_program(addr , val, len,TRUE);
|
||
|
||
}
|
||
|
||
void flash_onepage_read(u32 addr,u8 * val,u16 len)
|
||
{
|
||
GDflash_read_datas(addr , val, len, FALSE);
|
||
}
|
||
|
||
|
||
void flash_doc_write(u32 addr,u8 * val,u16 len)
|
||
{
|
||
GDflash_erase(addr,SECTOR_ERASE);
|
||
GDflash_erase(addr+4096,SECTOR_ERASE);
|
||
GDflash_erase(addr+4096*2,SECTOR_ERASE);
|
||
GDflash_erase(addr+4096*3,SECTOR_ERASE);
|
||
GDflash_erase(addr+4096*4,SECTOR_ERASE);
|
||
// GDflash_page_program(addr , val, len,TRUE);
|
||
|
||
GDflash_write(addr , val, len);
|
||
|
||
|
||
}
|
||
|
||
void flash_doc_read(u32 addr,u8 * val,u16 len)
|
||
{
|
||
GDflash_read_next(addr , val, len);
|
||
|
||
}
|
||
|
||
void update_clear()
|
||
{
|
||
|
||
for(u16 i = 26;i<200;i++)
|
||
{
|
||
GDflash_erase(i*4096 ,SECTOR_ERASE);
|
||
}
|
||
|
||
}
|
||
|