/**--------------File Info-------------------------------------------------------------------------------
** File name: M25P64Drv.c
** Descriptions: SPI下M25P64操作函数库
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "drivehead.h"
#include "ssi.h"
#include "gpio.h"
#include "sysctl.h"
#include "includes.h"
#include "NetInclude.h"
#include "m25p64.h"
#include "audio.h"
#include "netserver.h"
#include "flash.h"
#include "process.h"
#include "protocol.h"
#define Dummy_Byte 0xA5
#define SDC_SSI_BASE SSI0_BASE
#define SDC_SSI_SYSCTL_PERIPH SYSCTL_PERIPH_SSI0
// GPIO for SSI pins
#define SDC_GPIO_PORT_BASE GPIO_PORTA_BASE
#define SDC_GPIO_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOA
#define SDC_SSI_CLK GPIO_PIN_2
#define SDC_SSI_TX GPIO_PIN_5
#define SDC_SSI_RX GPIO_PIN_4
#define SDC_SSI_PINS (SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK)
// GPIO for M25P64 chip select
#define MP_CS_PORT_BASE GPIO_PORTA_BASE
#define MP_CS_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOA
#define MP_CS GPIO_PIN_3
#define MPCE_Low() GPIOPinWrite(MP_CS_PORT_BASE,MP_CS,0)
#define MPCE_High() GPIOPinWrite(MP_CS_PORT_BASE,MP_CS,MP_CS)
// GPIO for FM25CL64 chip select
#define FM_CS_PORT_BASE GPIO_PORTF_BASE
#define FM_CS_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOF
#define FM_CS GPIO_PIN_0
#define FMCE_Low() GPIOPinWrite(FM_CS_PORT_BASE,FM_CS,0)
#define FMCE_High() GPIOPinWrite(FM_CS_PORT_BASE,FM_CS,FM_CS)
FIL Filefops;
/* 移植本软件包时需要修改以下的函数或宏 */
static void Send_Byte(INT8U data);
static INT8U Get_Byte(void);
static void MP_WaitForWriteEnd(void);
static void MP_FLASH_PageWrite(INT8U* pBuffer, INT32U WriteAddr, INT16U NumByteToWrite);
static void Init_RecordPt(void);
void PutRecordInfo(RecordSaveStruct_t *PRecord);
int GetRecordInfo(RecordSaveStruct_t *PRecord);
/*******************************************************************************
* Function Name : M25P64_RD
* Description : Reads a block of data from the MP FLASH.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the FLASH.
* - ReadAddr : FLASH's internal address to read from.
* - NumByteToRead : number of bytes to read from the FLASH.
* Output : None
* Return : if(OK) return 0;
* else return -1;
*******************************************************************************/
int M25P64_RD(INT32U ReadAddr, INT32U NumByteToRead, void * pBuffer)
{
INT8U *RcvBufPt = (INT8U *)pBuffer;
INT8U err;
if ((ReadAddr + NumByteToRead > MAX_ADDR)||(NumByteToRead == 0))
{ return (-1); }
OSSemPend(SemSPI,0,&err);
/* Select the FLASH: Chip Select low */
MPCE_Low();
/* Send "Read from Memory " instruction */
Send_Byte(FCMD_READ);
/* Send ReadAddr high nibble address byte to read from */
Send_Byte((ReadAddr & 0xFF0000) >> 16);
/* Send ReadAddr medium nibble address byte to read from */
Send_Byte((ReadAddr & 0xFF00) >> 8);
/* Send ReadAddr low nibble address byte to read from */
Send_Byte(ReadAddr & 0xFF);
while(NumByteToRead--) /* while there is data to be read */
{
/* Read a byte from the FLASH */
*RcvBufPt = Get_Byte();
/* Point to the next location where the byte read will be saved */
RcvBufPt++;
}
/* Deselect the FLASH: Chip Select high */
MPCE_High();
OSSemPost(SemSPI);
return (0);
}
/************************************************************************
** 函数名称:M25P64_RdID
** 函数功能:M25P64的读ID函数,可选择读ID和读数据操作
** 入口参数:
** type: 读取的数据的类型
** INT32U* RcvbufPt:存储ID变量的指针
** 出口参数:
** 操作成功则返回0
** 失败则返回 -1
************************************************************************/
int M25P64_RdID(INT32U type,INT32U* RcvbufPt)
{
INT32U temp = 0;
MPCE_Low();
switch(type)
{
case FLASH_RDID:
Send_Byte(FCMD_RDID); /* 发送读JEDEC */
temp = (temp | Get_Byte()) << 8;/* 接收数据*/
temp = (temp | Get_Byte()) << 8;
temp = (temp | Get_Byte()); /* 在本例中,temp的值应为0xBF2541 */
break;
case FLASH_RDSR:
Send_Byte(FCMD_RDSR);
temp = Get_Byte();
break;
case FLASH_RES:
Send_Byte(FCMD_RES);
Send_Byte(0xff); //Send 3 dump.
Send_Byte(0xff);
Send_Byte(0xff);
temp = Get_Byte();
break;
default:
MPCE_High();
*RcvbufPt = 0;
return -1;
}
MPCE_High();
*RcvbufPt = temp;
return (0);
}
/************************************************************************
** 函数名称:M25P64_WR
** 函数功能:M25P64的写函数,可写1个和多个数据到指定地址
** 入口参数:
** INT32U Dst:目标地址,范围 0x0 - MAX_ADDR(MAX_ADDR = 0x7FFFFF)
** INT32U SndBytes:发送数据字节数
** INT8U *buff:发送的数据
** 出口参数:操作成功则返回写入的字节数,失败则返回 -1;
** 注 意:若某功能下,某一入口参数无效,可在该入口参数处填Invalid,该参数将被忽略
************************************************************************/
int M25P64_WR(INT32U Dst,INT32U SndBytes,const void *wbuff)
{
int i;
const INT8U *buff = (const INT8U *)wbuff;
if(SndBytes > 0x100 || SndBytes == 0)
return -1;
if(Dst > MAX_ADDR)
return -1;
MPCE_Low();
Send_Byte(FCMD_READ); // 发送读命令
Send_Byte(((Dst & 0xFF0000) >> 16)); // 发送地址信息:该地址由3个字节组成
Send_Byte(((Dst & 0xFF00) >> 8));
Send_Byte(Dst & 0xFF);
for(i = Dst; i< Dst + SndBytes; i++)
{
if(0xff != Get_Byte())
{
DiagPrintf(Uart0Dsc,"Read add=%d_%derror\r\n",Dst,i);
MPCE_High();
return -1;
}
}
MPCE_High();
i = 0;
MPCE_Low();
Send_Byte(FCMD_WREN); /* 发送写使能命令 */
MPCE_High();
MPCE_Low();
Send_Byte(FCMD_PP); /* 发送字节数据烧写命令 */
Send_Byte(((Dst & 0xFF0000) >> 16)); /* 发送3个字节的地址信息 */
Send_Byte(((Dst & 0xFF00) >> 8));
Send_Byte(Dst & 0xFF);
while(i < SndBytes)
{
Send_Byte(buff[i]); /* 发送被烧写的数据 */
i++;
if(0 == ((Dst + i) & 0xff)) /*只能在同一页内写,如果超出,返回实际写入的字节数*/
{
break;
}
}
SndBytes = i;
MPCE_High();
MP_WaitForWriteEnd(); /* 一直等待,直到芯片空闲 */
MPCE_Low();
Send_Byte(FCMD_READ); // 发送读命令
Send_Byte(((Dst & 0xFF0000) >> 16)); // 发送地址信息:该地址由3个字节组成
Send_Byte(((Dst & 0xFF00) >> 8));
Send_Byte(Dst & 0xFF);
for (i = 0; i < SndBytes; i++)
{
if(buff[i] != Get_Byte())
{
MPCE_High();
DiagPrintf(Uart0Dsc,"write add=%d_%derror\r\n",Dst,i);
return -1;
}
}
MPCE_High();
return (i);
}
/************************************************************************
** 函数名称:M25P64_Erase
** 函数功能:根据指定的扇区号选取最高效的算法擦除
** 入口参数:
** INT32U sec1:起始族号,范围(0 ~ 128)
** INT32U sec2:终止族号,范围(0 ~ 128)
** 出口参数:
** 操作成功则返回0
** 失败则返回-1
************************************************************************/
int M25P64_Erase(INT32U sec1, INT32U sec2)
{
INT32U SecnHdAddr;
/* 检查入口参数 */
if ((sec1 > SECTOR_MAX)||(sec2 > SECTOR_MAX))
{
return (-1);
}
#if 0
MPCE_Low();
Send_Byte(FCMD_RDSR); /* 发送读状态寄存器命令 */
temp1 = Get_Byte(); /* 保存读得的状态寄存器值 */
MPCE_High();
#endif
MPCE_Low();
Send_Byte(FCMD_WREN); /* 使状态寄存器可写 */
MPCE_High();
MPCE_Low();
Send_Byte(FCMD_WRSR); /* 发送写状态寄存器指令 */
Send_Byte(0x00); /* 清0BPx位,使Flash芯片全区可写 */
MPCE_High();
MP_WaitForWriteEnd();
/* 如果用户输入的起始扇区号大于终止扇区号,则在内部作
评论0