/******************************************************************************
|
* Copyright (C) 2014-2015 HangZhou SiZhu Co.,LTD.
|
*
|
*-----------------------------------------------------------------------------
|
* File: out_flash.c
|
* Description: FLASH operation code
|
* Author: jinlicong
|
* Date: 2023.10
|
*****************************************************************************/
|
|
/* ----------------------- Platform includes --------------------------------*/
|
#include "off_chip_flash.h"
|
#include "spi.h"
|
#include "uart.h"
|
#include "main.h"
|
|
typedef union
|
{
|
double doul;
|
uint8 data[8];
|
}double_union;
|
|
typedef union
|
{
|
float fl;
|
uint8 data[4];
|
}float_union;
|
|
|
typedef union
|
{
|
uint32 ui;
|
uint8 data[4];
|
}u32_union;
|
|
typedef union
|
{
|
uint16 us;
|
uint8 data[2];
|
}u16_union;
|
|
|
/******************************************
|
* func: Flash_ReadSR
|
* desc: read 1 byte status data from flash
|
* input: none
|
* output: none
|
* return: 1 byte status data read from flash
|
*****************************************/
|
uint8_t Flash_ReadSR(void)
|
{
|
uint8_t byte=0;
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_RDSR); //send read status register instructon
|
byte=FLASH_ReadWriteByte(0Xff);
|
FLASH_CS_DISABLE;
|
return byte;
|
}
|
|
/******************************************
|
* func: FLASH_Write_SR
|
* desc: write 1 byte status data to flash
|
* input:
|
* data - 1 byte state data to fram status register
|
* output: none
|
* return: none
|
*****************************************/
|
void FLASH_Write_SR(uint8_t sr)
|
{
|
FLASH_Write_Enable();
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_WRSR); //send write status register instructon
|
FLASH_ReadWriteByte(sr);
|
FLASH_CS_DISABLE;
|
}
|
|
/******************************************
|
* func: FLASH_Write_Enable
|
* desc: write enable flash.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void FLASH_Write_Enable(void)
|
{
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_WREN); //send write enable instruction
|
FLASH_CS_DISABLE;
|
}
|
|
/******************************************
|
* func: FLASH_Write_Disable
|
* desc: write disable flash
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void FLASH_Write_Disable(void)
|
{
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_WRDI); //send write disable instruction
|
FLASH_CS_DISABLE;
|
}
|
|
/******************************************
|
* func: Flash_ReadID
|
* desc: read 16bit ID from flash
|
* input: none
|
* output: none
|
* return: ID - 16bit Manufacturer ID/Device ID
|
*****************************************/
|
u16 Flash_ReadID(void)
|
{
|
u16 ID = 0;
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_RDID);//send
|
FLASH_ReadWriteByte(0x00);
|
FLASH_ReadWriteByte(0x00);
|
FLASH_ReadWriteByte(0x00);
|
ID|=FLASH_ReadWriteByte(0xFF)<<8;
|
ID|=FLASH_ReadWriteByte(0xFF);
|
FLASH_CS_DISABLE;
|
return ID;
|
}
|
|
/******************************************
|
* func: Flash_Read
|
* desc: read one or one more data bytes from flash
|
* input: pBuffer-data read from flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to read
|
* output: none
|
* return: none
|
*****************************************/
|
void Out_Flash_MultipleRead(uint8* pBuffer,uint32 ReadAddr,uint16 NumByteToRead)
|
{
|
u16 i;
|
|
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_READ); //send read command
|
FLASH_ReadWriteByte((uint8_t)((ReadAddr)>>16)); //send 24bit address
|
FLASH_ReadWriteByte((uint8_t)((ReadAddr)>>8));
|
FLASH_ReadWriteByte((uint8_t)ReadAddr);
|
for(i=0;i<NumByteToRead;i++)
|
{
|
pBuffer[i]=FLASH_ReadWriteByte(0XFF);
|
}
|
FLASH_CS_DISABLE;
|
}
|
|
|
/******************************************
|
* func: Flash_Write_NoCheck
|
* desc: write data into flash,can write more than 256 bytes.(we must delete the precious data before write)
|
* input: pBuffer-data write into flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to write
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Write_NoCheck(uint8_t* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
|
{
|
u16 pageremain;
|
pageremain=256-WriteAddr%256; //µ¥Ò³Ê£ÓàÊý×Ö
|
if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//²»´óÓÚ256×Ö½Ú
|
while(1)
|
{
|
|
Flash_Write_Page(pBuffer,WriteAddr,pageremain);
|
|
|
if(NumByteToWrite==pageremain)break; //дÈë½áÊø
|
else //NumByteToWrite>pageremain
|
{
|
pBuffer+=pageremain;
|
WriteAddr+=pageremain;
|
|
NumByteToWrite-=pageremain;
|
if(NumByteToWrite>256)pageremain=256; //Ò»´Î¿ÉÒÔдÈë256¸ö×Ö½Ú
|
else pageremain=NumByteToWrite; //²»¹»256¸ö×Ö½Ú
|
}
|
}
|
}
|
|
/******************************************
|
* func: Flash_Write
|
* desc: write data into flash,can write more than 256 bytes,and can executed sector erase operation.
|
* input: pBuffer-data write into flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to write
|
* output: none
|
* return: none
|
*****************************************/
|
|
void Out_Flash_MultipleWrite(uint8* pBuffer,uint32 WriteAddr,uint16 NumByteToWrite)
|
{
|
u32 secpos;
|
u16 secoff;
|
u16 secremain;
|
u16 i;
|
uint8_t FLASH_BUF[OUT_FLASH_SECTOR_SIZE] = {0};
|
|
if((WriteAddr + NumByteToWrite ) >OUT_FLASH_ALL_SIZE) //³¬¹ý×ÜÈÝÁ¿²»ÔÊÐí²Ù×÷
|
return;
|
|
|
secpos=WriteAddr/OUT_FLASH_SECTOR_SIZE; //ÉÈÇøµØÖ·
|
secoff=WriteAddr%OUT_FLASH_SECTOR_SIZE; //ÔÚ¸ÃÉÈÇøÄ򵀮«ÒÆÁ¿
|
secremain=OUT_FLASH_SECTOR_SIZE-secoff; //ÉÈÇøÊ£Óà¿Õ¼ä´óС
|
|
if(NumByteToWrite<=secremain)
|
{//²»´óÓÚOUT_FLASH_SECTOR_SIZE¸ö×Ö½Ú
|
secremain=NumByteToWrite;
|
}
|
|
while(1)
|
{
|
Out_Flash_MultipleRead(FLASH_BUF,secpos*OUT_FLASH_SECTOR_SIZE,OUT_FLASH_SECTOR_SIZE); //¶ÁÈ¡¸ÃµØÖ·¿ªÊ¼µÄÕû¸öÉÈÇøµÄÊý¾Ý
|
|
for(i=0;i<secremain;i++)
|
{//УÑéÊý¾Ý
|
if(FLASH_BUF[secoff+i]!=0XFF) //²é¿´ÉÈÇøÊÇ·ñ±»²Á³ý£¬Èç¹ûÓв»µÈÓÚ0xFFµÄÊý¾Ý£¬¾ÍÐèÒª²Á³ý
|
{
|
break;
|
}
|
}
|
|
if( i<secremain) //ÐèÒª²Á³ý
|
{
|
Flash_OUT_Erase_Sector(secpos); //²Á³ýÕâ¸öÉÈÇø
|
for(i=0;i<secremain;i++)
|
{
|
FLASH_BUF[i+secoff]=pBuffer[i]; //½«ÒªÐ´ÈëµÄÊý¾ÝдÈëµ½»º³åÖУ¬ÕâÀïµÄpBufferÖÐÊÇÎÒÃÇҪдµÄÊý¾Ý£¬°ÑÕâЩÊý¾Ý¸üе½»º´æÖжÔÓ¦µÄλÖÃ
|
}
|
|
Flash_Write_NoCheck(FLASH_BUF,secpos*OUT_FLASH_SECTOR_SIZE,OUT_FLASH_SECTOR_SIZE); ///½«»º³åÖеÄÊý¾ÝÖØÐÂдÈëÕû¸öÉÈÇø
|
|
}
|
else
|
{
|
// GPIO_SetBits(GPIOE, GPIO_Pin_3);
|
Flash_Write_NoCheck(pBuffer,WriteAddr,secremain); //Èç¹ûû±ØÒª²Á³ý²Ù×÷£¬ÄÇôֱ½ÓдÈëÉÈÇøÊ£ÓàÇø¼ä
|
// GPIO_ResetBits(GPIOE, GPIO_Pin_3);
|
}
|
|
|
if(NumByteToWrite==secremain) //Íê³ÉÁËҪдÈëµÄÊý¾Ý³¤¶È£¬Ôò½áÊø
|
{//дÈë½áÊø
|
break;
|
}
|
else //Èç¹ûҪдÈëµÄÊý¾Ý±ÈÊ£Óà¿Õ¼ä´ó£¬ÄÇôִÐÐÒÔϲÙ×÷
|
{//дÈëδ½áÊø
|
secpos++; //ÉÈÇøµØÖ·+1£¬¿ªÊ¼ÏÂÒ»¸öÉÈÇøµÄдÊý¾Ý
|
secoff=0; //ϸöÉÈÇøµÄÆ«ÒÆÁ¿Îª0
|
|
pBuffer+=secremain; //Êý¾ÝÖ¸Ïò+secremainµÄÊý¾ÝµØÖ·£¬´ÓÕâ¸öµØÖ·¿ªÊ¼¶ÁÊý¾Ý
|
WriteAddr+=secremain; //µØÖ·Ò²ÏàÓ¦µÄ+Êý¾Ý´óС
|
NumByteToWrite-=secremain; //ҪдÈëµÄ³¤¶È¼õȥ֮ǰµÄÒѾдÈëµÄsecremain³¤¶È
|
if(NumByteToWrite>OUT_FLASH_SECTOR_SIZE)
|
{//ÏÂÒ»¸öÉÈÇø»¹ÊÇд²»Íê
|
secremain=OUT_FLASH_SECTOR_SIZE; //ÅжϽÓÏÂÀ´ÒªÐ´ÈëµÄ³¤¶È£¬ÊÇ·ñÊÇ´óÓÚÕû¸öÉÈÇøµÄ´óС£¬Èç¹û»¹ÊÇÒ»¸öÉÈÇø»¹ÊDz»¹»£¬ÄÇôÏÈдÈëÒ»¸öÉÈÇøµÄ³¤¶È
|
}
|
else
|
{ //ÏÂÒ»¸öÉÈÇø¿ÉÒÔдÍêÁË
|
secremain=NumByteToWrite; //Èç¹û²»´óÓÚ£¬ÄÇôֱ½Ó½«Ê£Ó೤¶ÈдÈë¼´¿É
|
}
|
}
|
}
|
FLASH_CS_DISABLE;
|
}
|
|
|
/******************************************
|
* func: Flash_Write_Page
|
* desc: write data less than 256 bytes into flash.(we must delete the precious data before write)
|
* input: pBuffer-data write into flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to write
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Write_Page(uint8_t* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
|
{
|
u16 i;
|
FLASH_Write_Enable(); //write enable
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_WRITE); //send write command
|
FLASH_ReadWriteByte((uint8_t)((WriteAddr)>>16)); //send 24bit address
|
FLASH_ReadWriteByte((uint8_t)((WriteAddr)>>8));
|
FLASH_ReadWriteByte((uint8_t)WriteAddr);
|
for(i=0;i<NumByteToWrite;i++)
|
FLASH_ReadWriteByte(pBuffer[i]);
|
FLASH_CS_DISABLE;
|
Flash_Wait_Busy(); //wait write finish
|
}
|
|
|
//¶ÁÒ»¸ö×Ö½Ú
|
uint8 Flash_data_read(uint32 ReadAddr)
|
{
|
uint8 data;
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_READ); //send read command
|
FLASH_ReadWriteByte((uint8_t)((ReadAddr)>>16)); //send 24bit address
|
FLASH_ReadWriteByte((uint8_t)((ReadAddr)>>8));
|
FLASH_ReadWriteByte((uint8_t)ReadAddr);
|
|
data=FLASH_ReadWriteByte(0XFF);
|
|
FLASH_CS_DISABLE;
|
return data;
|
}
|
|
|
/******************************************
|
* func: Flash_Erase_Chip
|
* desc: erase all data.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Erase_Chip(void)
|
{
|
FLASH_Write_Enable();
|
Flash_Wait_Busy();
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_ChipErase); //send chip erase instruction
|
FLASH_CS_DISABLE;
|
Flash_Wait_Busy(); //wait erase finish
|
}
|
|
|
/******************************************
|
* func: Flash_OUT_Erase_Sector
|
* desc: sector erase operation.
|
* input: Dst_Addr - sector address.
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_OUT_Erase_Sector(u32 Dst_Addr)
|
{
|
Dst_Addr*=OUT_FLASH_SECTOR_SIZE;
|
FLASH_Write_Enable(); //write enable
|
Flash_Wait_Busy();
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_SectorErase); //send sector erase instruction
|
FLASH_ReadWriteByte((uint8_t)((Dst_Addr)>>16));
|
FLASH_ReadWriteByte((uint8_t)((Dst_Addr)>>8));
|
FLASH_ReadWriteByte((uint8_t)Dst_Addr);
|
FLASH_CS_DISABLE;
|
Flash_Wait_Busy();
|
}
|
|
|
/******************************************
|
* func: Flash_Wait_Busy
|
* desc: wait write or erase operation finish.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Wait_Busy(void)
|
{
|
while ((Flash_ReadSR()&0x01)==0x01); //wait BUSY=0
|
}
|
|
|
/******************************************
|
* func: Flash_PowerDown
|
* desc: take flash into power-down mode.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_PowerDown(void)
|
{
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_POWERDOWN); //send power-down instruction
|
FLASH_CS_DISABLE;
|
delay_us(3); //wait TPD
|
}
|
|
|
/******************************************
|
* func: Flash_WAKEUP
|
* desc: release flash from power-down mode.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_WAKEUP(void)
|
{
|
FLASH_CS_ENABLE;
|
FLASH_ReadWriteByte(FLASH_WKUP); //send wake up command 0xAB
|
FLASH_CS_DISABLE;
|
delay_us(3); //wait TRES1
|
}
|
|
|
//////------------------------------------------------------------------------------------------------------------------------
|
|
///******************************************
|
// * func: Flash_data_read_float
|
// * desc: read float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//float Flash_data_read_float(uint32 addr16)
|
//{
|
|
// float_union k;
|
// k.data[0] = Flash_data_read(addr16);
|
// k.data[1] = Flash_data_read(addr16+1);
|
// k.data[2] = Flash_data_read(addr16+2);
|
// k.data[3] = Flash_data_read(addr16+3);
|
// return (k.fl);
|
//}
|
|
///******************************************
|
// * func: Flash_data_write_float
|
// * desc: write float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//void Flash_data_write_float(uint32 addr16, float data)
|
//{
|
// float_union f;
|
// f.fl = data;
|
//
|
// Out_Flash_MultipleWrite(f.data,addr16,4);
|
|
//}
|
|
|
///******************************************
|
// * func: Flash_data_read_float
|
// * desc: read float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//double Flash_data_read_double(uint32 addr16)
|
//{
|
// double_union d;
|
// d.data[0] = Flash_data_read(addr16);
|
// d.data[1] = Flash_data_read(addr16+1);
|
// d.data[2] = Flash_data_read(addr16+2);
|
// d.data[3] = Flash_data_read(addr16+3);
|
// d.data[4] = Flash_data_read(addr16+4);
|
// d.data[5] = Flash_data_read(addr16+5);
|
// d.data[6] = Flash_data_read(addr16+6);
|
// d.data[7] = Flash_data_read(addr16+7);
|
// if( (d.data[0]==0xff) && (d.data[1]==0xff)&&(d.data[2]==0xff) && (d.data[3]==0xff)&&(d.data[4]==0xff) && (d.data[5]==0xff)&&(d.data[6]==0xff) && (d.data[7]==0xff))
|
// d.doul=0;
|
// return (d.doul);
|
//}
|
|
///******************************************
|
// * func: Flash_data_read_float
|
// * desc: read float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//void Flash_data_write_double(uint32 addr16, double data)
|
//{
|
// double_union d;
|
// d.doul = data;
|
|
//
|
// Out_Flash_MultipleWrite(d.data,addr16,8);
|
//
|
//}
|
|
|
///******************************************
|
// * func: Flash_data_read_float
|
// * desc: read float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//u32 Flash_data_read_uint32(uint32 addr16)
|
//{
|
|
// u32_union t;
|
// t.data[0] = Flash_data_read(addr16);
|
// t.data[1] = Flash_data_read(addr16+1);
|
// t.data[2] = Flash_data_read(addr16+2);
|
// t.data[3] = Flash_data_read(addr16+3);
|
// return (t.ui);
|
//}
|
|
///******************************************
|
// * func: Flash_data_write_float
|
// * desc: write float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//void Flash_data_write_uint32(uint32 addr16, uint32 data)
|
//{
|
// u32_union t;
|
// t.ui = data;
|
//
|
// Out_Flash_MultipleWrite(t.data,addr16,4);
|
|
//
|
//}
|
|
|
///******************************************
|
// * func: Flash_data_read_float
|
// * desc: read float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//u16 Flash_data_read_uint16(uint32 addr16)
|
//{
|
|
// u16_union t;
|
// t.data[0] = Flash_data_read(addr16);
|
// t.data[1] = Flash_data_read(addr16+1);
|
// return (t.us);
|
//}
|
|
///******************************************
|
// * func: Flash_data_write_float
|
// * desc: write float data from fram
|
// * input:
|
// * addr16 - destination address for read 1byte data
|
// * output: none
|
// * return:
|
// *****************************************/
|
//void Flash_data_write_uint16(uint32 addr16, uint16 data)
|
//{
|
// u16_union t;
|
// t.us = data;
|
|
// Out_Flash_MultipleWrite(t.data,addr16,2);
|
|
//}
|
|
|
void OUT_FLASH_test(void)
|
{
|
uint8_t u8_temp_s[512];
|
uint8_t u8_temp_s2[512];
|
u32 addr1;
|
u16 count_i = 0;
|
|
for(count_i=0;count_i<512;count_i++)
|
{
|
u8_temp_s[count_i] =(uint8_t)count_i;
|
u8_temp_s2[count_i] = 0;
|
}
|
|
addr1 = 0x1000+100;
|
Out_Flash_MultipleWrite(&u8_temp_s[addr1&0xff],addr1,1);
|
|
Out_Flash_MultipleRead(&u8_temp_s2[addr1&0xff],addr1,1);
|
|
#ifdef RS232_PRINTF
|
printf("outFLASH--WD=%d;RD=%d;\r\n",u8_temp_s[addr1&0xff],u8_temp_s2[addr1&0xff]);
|
#endif
|
|
// Out_Flash_MultipleWrite(&u8_temp_s[0],BOOTLOAD_DIFF_PROG_START_ADDRESS+512,512);
|
//
|
// Out_Flash_MultipleRead(&u8_temp_s2[0],BOOTLOAD_DIFF_PROG_START_ADDRESS+512,512);
|
// sprintf((char *)debug_send_buf,"senddata000000000");
|
// uart_send_data(UART0,(char *)debug_send_buf,strlen((char *)debug_send_buf));
|
//// for(count_i=0;count_i<256;count_i++)
|
//// {
|
// uart_send_data(UART0,(char *)u8_temp_s2,512);
|
//// }
|
// sprintf((char *)debug_send_buf,"000000000\r\n");
|
// uart_send_data(UART0,(char *)debug_send_buf,strlen((char *)debug_send_buf));
|
|
|
// while(WR_times <1024)
|
// {
|
//
|
// EEPROM_MultipleWrite_CS_2(u8_temp_s,(WR_times * 256),256);
|
// delay_ms(1);
|
// for(count_i=0;count_i<256;count_i++)
|
// {
|
// u8_temp_s2[count_i] = 0;
|
// }
|
// EEPROM_MultipleRead_CS_2(u8_temp_s2,(WR_times * 256),256);
|
// WR_times ++;
|
//
|
// for(count_i=0;count_i<256;count_i++)
|
// {
|
// if(u8_temp_s[count_i] != u8_temp_s2[count_i])
|
// {
|
// break;
|
// }
|
// }
|
//
|
// if(count_i == 256)
|
// {
|
// WR_times_suc++;
|
// }
|
// delay_ms(998);
|
//
|
//
|
// }
|
|
// EEPROM_MultipleRead_CS_2(u8_temp_s2,(1000 * 256+9),256);
|
|
|
|
// while(1);
|
|
|
|
}
|