📄 w25x32_wr.c
字号:
/**------------------------------------------------------------------------------------------------------
** Created by:
** Created date:
** Version:
** Descriptions: 使用LPC2300系列ARM的SSP DMA,操作W25X32。
**
********************************************************************************************************/
#include "config.h"
/* 全局变量定义 */
//uint8 InitDatas[8] = {0x35, 0x45, 0x55, 0x36, 0x37, 0x38, 0x39, 0x30};
//uint8 RdCmdBuf[5] = {0x0B, 0x0, 0x20, 0x07, 0xFF}; // 该数组用于存放对FLASH的读操作初始化信息,仅由SSPDMA_Snd函数访问,发送完这组数据后,Flash进入读数据状态
//uint8 WaitCmdbuf[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // 每发送一个0xff到Flash,Flash会返回一个数据
//max add for extend flash r/w area
uint8 setup_sec=SETUP_PARAMS_SEC; //设定参数存放的起始扇区号
uint8 work_sec= WORK_PARAMS_SEC; //工作参数存放的起始扇区号
uint8 custom_sec=CUSTOM_PARAMS_SEC; //终端自用,无须上传,自定义参数存放的起始扇区号
uint8 mileage_sec=MILEAGE_ACC_SEC; //存储里程数及ACC开关状态的起始扇区号
uint8 Ini_Sec_counter(uint8* , uint8 , uint8);
uint8 Reset_All_Sec(void);
uint8 Test_Count_Sec(uint8, uint16, uint8);
uint8 Dump_Sec(uint8);
uint8 UART3_output_digit(uint16, uint8);
void DelayS(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
for(i=0; i<5000; i++);
}
uint8 W25X32_READ(uint32 Oid_Addr, uint32 Oid_Len, uint8 * Buff)
{
/* 中断方式下DMA发送和接收 */
// OS_ENTER_CRITICAL();
DelayS(20);
W25X32_RD(Oid_Addr,Oid_Len,Buff);
// OS_EXIT_CRITICAL();
return TRUE;
}
uint8 W25X32_READ_2(uint32 Oid_Addr, uint32 Oid_Len, uint8 * Buff)
{
// OS_ENTER_CRITICAL();
DelayS(20);
W25X32_RD_2(Oid_Addr,Oid_Len,Buff);
// OS_EXIT_CRITICAL();
return TRUE;
}
/********************************************************************************************************
** 函数名称:W25X32_INIT
** 函数功能:调用软件包,演示使用SSP DMA操作W25X32
** 入口参数:无
** 出口参数:返回0则表明出错
** 调试说明:在Flash中运行
********************************************************************************************************/
uint8 W25X32_INIT(void)
{
/* 完成SSP初始化 */
SSP_Init(); // 初始化SSP管脚以及SSP的工作参数
#if 1
//Reset_All_Sec(); //erase flash all sector
Ini_Sec_counter( &setup_sec, 'S', SETUP_PARAMS_SEC );
Ini_Sec_counter( &work_sec, 'W', WORK_PARAMS_SEC );
Ini_Sec_counter( &custom_sec, 'C', CUSTOM_PARAMS_SEC );
Ini_Sec_counter( &mileage_sec, 'M', MILEAGE_ACC_SEC );
#endif
return (TRUE);
}
// 将buff写入从地址Oid_Addr开始的Flash存储单元里
uint8 W25X32_WRITE(uint32 Oid_Addr, uint32 Oid_Len, uint8 * Buff, uint32 Data_Size)
{
const uint8 pageLen=0xff;
uint8 i=0;
//uint8 temp[SEC_SIZE];
uint8 * temp;
#if defined(SYSTEM_SEMCONTROL)
INT8U SysFlashErr;
OSSemPend(gw_pSysFlashSem, 0, &SysFlashErr);
#else
OSSchedLock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
OSMemQuery(IntBuffer_Big,&MemInfo);
if(MemInfo.OSNFree > (uint8)(Data_Size/BlockSize_Big))
{
temp=(INT8U *)OSMemGet(IntBuffer_Big,&err);
//使用获得的内存块
if( (Oid_Addr+Oid_Len)/SEC_SIZE > Oid_Addr/SEC_SIZE )
{
W25X32_READ(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
W25X32_READ(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase((Oid_Addr+Oid_Len)/SEC_SIZE, (Oid_Addr+Oid_Len)/SEC_SIZE);
memmove(temp,Buff+Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE,(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
else
{
W25X32_READ(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
//memset(temp,0,sizeof(temp));
//W25X32_READ(GetAddr(FIRSTSEC,Oid_Addr),Oid_Len,temp);
//释放获得的内存块
OSMemPut(IntBuffer_Big,temp);
}
else
{
#if defined(UART_SEMCONTROL)
OSSemPost(gw_pSysFlashSem);
#else
OSSchedUnlock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
return FALSE;
}
#if defined(UART_SEMCONTROL)
OSSemPost(gw_pSysFlashSem);
#else
OSSchedUnlock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
return TRUE;
}
uint8 W25X32_WRITE_2(uint32 Oid_Addr,uint32 Oid_Len,uint8 * Buff,uint32 Data_Size)
{
const uint8 pageLen=0xff;
uint8 i=0;
//uint8 temp[SEC_SIZE];
uint8 * temp;
#if defined(SYSTEM_SEMCONTROL)
INT8U SysFlashErr;
OSSemPend(gw_pSysFlashSem, 0, &SysFlashErr);
#else
OSSchedLock();
#endif // end of #if defined(SYSTEM_SEMCONTROL)
OSMemQuery(IntBuffer_Big,&MemInfo);
if(MemInfo.OSNFree > (uint8)(Data_Size/BlockSize_Big))
{
temp=(INT8U *)OSMemGet(IntBuffer_Big,&err);
//使用获得的内存块
if( ((Oid_Addr+Oid_Len)/SEC_SIZE) > (Oid_Addr/SEC_SIZE) )
{
W25X32_READ_2(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase_2(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
W25X32_READ_2(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase_2((Oid_Addr+Oid_Len)/SEC_SIZE, (Oid_Addr+Oid_Len)/SEC_SIZE);
memmove(temp,Buff+Oid_Len-(Oid_Addr+Oid_Len)%SEC_SIZE,(Oid_Addr+Oid_Len)%SEC_SIZE);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR_2(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR_2(GetAddr((Oid_Addr+Oid_Len)/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
else
{
W25X32_READ_2(GetAddr(Oid_Addr/SEC_SIZE,0),Data_Size,temp);
W25X32_Erase_2(Oid_Addr/SEC_SIZE, Oid_Addr/SEC_SIZE);
memmove(temp+Oid_Addr%SEC_SIZE,Buff,Oid_Len);
for(i=0;i<Data_Size/pageLen;i++)
{
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,pageLen);
OSTimeDly(3);
}
if(Data_Size%pageLen>0)
{
OSTimeDly(3);
W25X32_WR_2(GetAddr(Oid_Addr/SEC_SIZE,i*pageLen),temp+i*pageLen,Data_Size%pageLen);
}
}
//memset(temp,0,sizeof(temp));
//W25X32_READ(GetAddr(FIRSTSEC,Oid_Addr),Oid_Len,temp);
//释放获得的内存块
OSMemPut(IntBuffer_Big,temp);
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -