📄 flash.c
字号:
#include "config.h"
#include "RD_LPC2100.h"
#include <stdarg.h>
#include <stdio.h>
#include "flash.h"
//#include "dataret.h"
#include "ASCII.h"
#include "userlib.h"
/*
//应该继续添加的内容
1 写操作之前的WREN命令
2 命令序列中的Selection Enable操作
3 写操作之间的RDSR操作,判断WIP标志位
4 Sector Erase之前的保存机制
5
*/
// SSP作主机,当只和1个从机通信的时候,可以不用另外的IO口作从机选择线,直接用SSEL1即可。
//#define SLAVE_CS (1 << 29) // P0.29口为SSP为从机的选择控制引脚
volatile uint32 FlashCurrentWriteAddr = 0,FlashCurrentReadAddr=0;
volatile uint8 flash_buf[256] = {0};
volatile FlashRecord AlarmDataRecord;
volatile uint8 FlashCurrentSector = 0,FlashFormatEn =0;
/*
*********************************************************************************************************
** 函数名称:SSP_Init()
** 函数功能:将SSP控制器设置为主机SPI。
** 入口参数:无
** 出口参数:无
*********************************************************************************************************
*/
void SSP_Init(void)
{
PCONP |= 1<<10;
// PINSEL1 = 0x000002A8; // 设置SSP管脚连接
// PINSEL1 = 0xAA << 2;
PINSEL1 = (PINSEL1 & (~(0xFF << 2))) | (0xAA << 2);
// IO0DIR = SLAVE_CS;
// IO0SET = SLAVE_CS;
SE1_DISABLE;
SSPCR0 = (0x01 << 8) | // SCR 设置SPI时钟分频
(0x01 << 7) | // CPHA 时钟输出相位,仅SPI模式有效
(0x01 << 6) | // CPOL 时钟输出极性,仅SPI模式有效
(0x00 << 4) | // FRF 帧格式 00=SPI,01=SSI,10=Microwire,11=保留
(0x07 << 0); // DSS 数据长度,0000-0010=保留,0011=4位,0111=8位,1111=16位
SSPCR1 = (0x00 << 3) | // SOD 从机输出禁能,1=禁止,0=允许
(0x00 << 2) | // MS 主从选择,0=主机,1=从机
(0x01 << 1) | // SSE SSP使能,1=允许SSP与其它设备通信
(0x00 << 0); // LBM 回写模式
SSPCPSR = 0x52; // PCLK分频值
// SSPIMSC = 0x07; // 中断屏蔽寄存器
SSPICR = 0x03; // 中断清除寄存器
}
void SSP_Soft_Init(void)
{
SSP_SOFT;
IO0DIR |= (DO1|SCK1|SE1);
IO0DIR &= (~DI1);
IOSET|= (DO1|SCK1|SE1|DI1);
}
/*
*********************************************************************************************************
* 函数名称:SSP_SendData()
* 函数功能:SSP接口向SPI总线发送数据。
* 入口参数:data 待发送的数据
* 出口参数:返回值为读取的数据
*********************************************************************************************************
*/
uint8 SSP_SendData(uint8 data)
{
// IOCLR = SLAVE_CS; // 选择从机
uint8 i;
i = SSPDR;
i++;
SSPDR = data;
while( (SSPSR & 0x10) == 0x10 ); // 等待TFE置位,即发送FIFO空
// IOSET = SLAVE_CS;
i = SSPDR;
return(i);
}
uint SSPS_SendData(uint8 data,uint8 dataen)
{
volatile uint8 i,j=0;
for(i=0;i<8;i++)
{
SCK1L;
if (dataen == 1)
{
if (((data<<i)&0x80)== 0)
{
DO1L;
}
else
{
DO1H;
}
}
SCK1H;
if (DI1H)
{
j|=0x01;
j=j<<1;
}
}
return (j);
}
/*
*********************************************************************************************************
* 函数名称:FLASH_CMD()
* 函数功能:Flash 存储器读写函数
* 入口参数:cmd 读写命令
* 出口参数:返回值为读取的数据
*********************************************************************************************************
*/
uint8 FlashCmd(uint8 cmd)
{
return(1);
}
uint8 CMD_WREN(void)
{
volatile uint8 i;
SEL;
i = SSP_SendData(WREN);
SEH;
i = CMD_RDSR();
i = i;
//while ((i&0x01)==1)
//{
// i = CMD_RDSR();
//}
return (i);
}
uint8 CMD_WRDI(void)
{
volatile uint8 i;
SEL;
i = SSP_SendData(WRDI);
SEH;
// i = CMD_RDSR();
//while ((i&0x01)==1)
//{
// i = CMD_RDSR();
//}
return (i);
}
volatile uint8 ID[3]={0};
uint8 CMD_RDID(void)
{
volatile uint8 i;
uint16 j;
SEL;
for (j=0;j<50000;j++); //
//DO1_ENABLE;
i = SSP_SendData(RDID);
//DO1_DISABLE;
ID[0]=SSP_SendData(0xff);
ID[1]=SSP_SendData(0xff);
ID[2]=SSP_SendData(0xff);
//DO1_ENABLE;
SEH;
SEH;
i = ID[2];
return (i);
}
uint8 CMD_RDIDS(void)
{
volatile uint8 i;
uint16 j;
SEL;
for (j=0;j<50000;j++);
i = SSPS_SendData(RDID,1);
ID[0]= SSPS_SendData(0,0);
ID[1]= SSPS_SendData(0,0);
ID[2]= SSPS_SendData(0,0);
SEH;
return (0);
}
uint8 CMD_RES(void)
{
volatile uint8 i;
uint16 j;
SEL;
for (j=0;j<50000;j++);
//DO1_ENABLE;
i = SSP_SendData(RES);
ID[0]=SSP_SendData(0xff);
ID[1]=SSP_SendData(0xff);
ID[2]=SSP_SendData(0xff);
//DO1_DISABLE;
i = SSP_SendData(0xff);
//DO1_ENABLE;
SEH;
return (i);
}
uint8 CMD_RDSR(void)
{
volatile uint8 i;
uint16 j;
SEL;
for (j=0;j<50000;j++);
//DO1_ENABLE;
i = SSP_SendData(RDSR);
//DO1_DISABLE;
i = SSP_SendData(0xff);
//DO1_ENABLE;
SEH;
// i = CMD_RDSR();
//while ((i&0x01)==1)
//{
// i = CMD_RDSR();
//}
return (i);
}
uint8 CMD_WRSR(uint8 data)
{
volatile uint8 i;
uint16 j;
CMD_WREN();
i = Wait_For_WEL();
SEL;
for (j=0;j<50000;j++);
i = SSP_SendData(WRSR);
i = SSP_SendData(data);
SEH;
i = Wait_For_Status(WIP);
return (i);
}
uint8 CMD_READ(uint32 addr,uint8 *data,uint16 length)
{
volatile uint8 i;
uint16 j;
//DO1_ENABLE;
SEL;
for (j=0;j<50000;j++);
i = SSP_SendData(READ);
i = SSP_SendData((uint8)(addr>>16));
i = SSP_SendData((uint8)(addr>>8));
i = SSP_SendData((uint8)(addr&0xff));
//DO1_DISABLE;
for (j=0;j<length;j++)
{
*(data+j) = SSP_SendData(0xff);
//flash_buf[i] = SSP_SendData(0xff);
}
//DO1_ENABLE;
SEH;
return (*data);
}
uint8 CMD_FREAD(uint32 addr,uint8 length)
{
volatile uint8 i;
uint16 j;
SEL;
for (j=0;j<50000;j++);
i = SSP_SendData(FAST_READ);
i = SSP_SendData((uint8)(addr>>16));
i = SSP_SendData((uint8)(addr>>8));
i = SSP_SendData((uint8)(addr&0xff));
i = SSP_SendData(0xff);
//DO1_DISABLE;
for (i=0;i<length;i++)
{
flash_buf[i] = SSP_SendData(0xff);
}
//DO1_ENABLE;
SEH;
return (i);
}
uint8 CMD_PP(uint32 addr,uint8 *data,uint16 length)
{
volatile uint8 i;
uint16 k,j;
i = CMD_WREN();
i = Wait_For_WEL();
SEL;
for (k=0;k<50000;k++);
i = SSP_SendData(PP);
i = SSP_SendData((uint8)(addr>>16));
i = SSP_SendData((uint8)(addr>>8));
i = SSP_SendData((uint8)(addr&0xff));
for (j=0;j<length;j++)
{
i = SSP_SendData(*(data+j));
//j = SSP_SendData(flash_buf[i]);
}
SEH;
i = Wait_For_Status(WIP);
return (i);
}
uint8 CMD_SE(uint32 saddr)
{
volatile uint8 i;
uint16 j;
i = CMD_WREN();
i = Wait_For_WEL();
i = i;
SEL;
for (j=0;j<50000;j++);
i = SSP_SendData(SE);
i = SSP_SendData((uint8)(saddr>>16));
i = SSP_SendData((uint8)(saddr>>8));
i = SSP_SendData((uint8)(saddr&0xff));
SEH;
i = Wait_For_Status(WIP);
i = i;
return (i);
}
uint8 CMD_BE(void)
{
volatile uint8 i;
uint16 j;
i = CMD_WREN();
i = Wait_For_WEL();
SEL;
for (j=0;j<50000;j++);
i = SSP_SendData(BE);
SEH;
i = Wait_For_Status(WIP);
return (i);
}
uint8 Wait_For_WEL(void)
{
volatile uint32 n, i;
volatile uint8 status_register = 0;
volatile uint8 ErrorCode = 0; // tells us if there was an error erasing flash
for(i = 0; i < 35; i++)
{
status_register = CMD_RDSR();
if( (status_register & WEL)==WEL )
{
ErrorCode = 0; // tells us if there was an error erasing flash
break;
}
for(n=0; n<1000; n++)
n= n;
//asm("nop;");
ErrorCode = 1; // Time out error
};
return ErrorCode;
}
uint8 Wait_For_Status( uint8 Statusbit )
{
volatile uint32 n, i;
volatile uint8 status_register = 0xFF;
volatile uint8 ErrorCode = 0; // tells us if there was an error erasing flash
for(i = 0; i < TIMEOUT; i++)
{
status_register = CMD_RDSR();
if( !((status_register & Statusbit)==Statusbit) )
{
ErrorCode = 0; // tells us if there was an error erasing flash
break;
}
for(n=0; n<1000; n++)
n=n;
//asm("nop;");
ErrorCode = 1; // Time out error
};
return ErrorCode;
}
uint8 FlashRead(uint32 FlashAddr,uint8 *RamAddr,uint8 length)
{
uint8 i;
if (FLASHAUTO == FlashAddr)
{
FlashAddr = FlashCurrentReadAddr;
i = CMD_READ(FlashAddr,RamAddr,length);
}
else
{
i = CMD_READ(FlashAddr,RamAddr,length);
}
FlashCurrentReadAddr += length;
if (FLASH_AVAILABLE <= FlashCurrentReadAddr)
{
FlashCurrentReadAddr = 0;
}
return(i);
}
uint8 FlashWrite(uint32 FlashAddr,uint8 *RamAddr,uint8 length)
{
uint8 i;
if (FlashAddr == FLASHAUTO)
{
FlashAddr = FlashCurrentWriteAddr;
i = CMD_PP(FlashAddr,RamAddr,length);
}
else
{
i = CMD_PP(FlashAddr,RamAddr,length);
}
FlashCurrentWriteAddr += length;
if (FLASH_AVAILABLE <= FlashCurrentWriteAddr)
{
FlashCurrentWriteAddr = 0; //reserve the upper 2 page
}
return(i);
}
uint8 RecordPackage(LPFlashRecord RData,LPUART485 UData,LPMONITDATA AData)
{
RData->RecordID = 0;
RData->RecordTrain = UData->train; //*(2个字节)车次
RData->RecordDriver = UData->driver; //*(2个字节)司机号
RData->RecordCarriageNum = CarriageNum;
RData->RecordDistance = UData->distance;
RData->RecordSpeed = UData->speed;
RData->RecordSec = UData->sec;
RData->RecordMin = UData->min;
RData->RecordHour = UData->hour;
RData->RecordDate = UData->date;
RData->RecordMonth = UData->month;
RData->RecordHor1 = AData->Hor1;
RData->RecordVer1 = AData->Ver1;
RData->RecordHor2 = AData->Hor2;
RData->RecordVer2 = AData->Ver2;
RData->RecordHor3 = AData->Hor3;
RData->RecordVer3 = AData->Ver3;
RData->RecordHor4 = AData->Hor4;
RData->RecordVer4 = AData->Ver4;
RData->RecordForw = AData->Forw;
RData->RecordAlarmFlag = AData->AlarmFlag;
RData->RecordReserved0 = 0x55;
RData->RecordReserved1 = 0xaa;
return(0);
}
uint8 SearchRecordIndex(void)
{
uint8 i;
for (FlashCurrentReadAddr = 0;FlashCurrentReadAddr<FLASH_AVAILABLE;
FlashCurrentReadAddr+=32)
{
i = FlashRead(FlashCurrentReadAddr,(uint8 *)flash_buf,32);
if (0xff==i)
{
break;
}
}
if (FLASH_AVAILABLE <= FlashCurrentReadAddr)
{
FlashCurrentReadAddr = 0;
i = CMD_SE(FlashCurrentWriteAddr);
}
return(i);
}
uint8 ReadRecordFromFlash(LPFlashRecord RData)
{
uint8 i;
if ((FlashCurrentReadAddr&0x1f)==0)
{
//i = FlashRead(FlashCurrentReadAddr,(uint8 *)flash_buf,32);
i = FlashRead(FlashCurrentReadAddr,(uint8 *)RData,32);
}
else
{
i=0;
}
return(i);
}
uint8 WriteRecord2Flash(LPFlashRecord RData)
{
uint8 i;
if ((FlashCurrentWriteAddr&0xffff)==0)
{
i = FlashRead(FlashCurrentWriteAddr,(uint8 *)flash_buf,32);
if (0xff!=i)
{
i = CMD_SE(FlashCurrentWriteAddr);
}
}
FlashWrite(FlashCurrentWriteAddr,(uint8 *)RData,32);
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -