Files
HBshuiwuConcentrator/shuangjia/hal_GDflash.c
2025-12-15 16:07:49 +08:00

370 lines
8.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
}
}