直接上代码:
cycx3_M25P40.h
/*
* 保存imu数据到flash(M25P40)中
*/
#ifndef _INCLUDED_CYCX3_M25P40_H_
#define _INCLUDED_CYCX3_M25P40_H_
#include "cyu3types.h"
#include "cyu3usbconst.h"
#include "cyu3os.h"
#include "cyu3utils.h"
#include "cyu3mipicsi.h"
#include "cyu3externcstart.h"
#include "cyu3spi.h"
//uint16_t glSpiPageSize = 0x100; /* SPI Page size to be used for transfers. */
#define glSpiPageSize 0x100
CyU3PReturnStatus_t CyFxSpiInit (uint16_t pageLen);
CyU3PReturnStatus_t CyFxSpiWaitForStatus (void);
CyU3PReturnStatus_t CyFxSpiTransfer (
uint16_t pageAddress,
uint16_t byteCount,
uint8_t *buffer,
CyBool_t isRead);
CyU3PReturnStatus_t //static
CyFxSpiEraseSector (
CyBool_t isErase,
uint8_t sector,
uint8_t *wip);
#endif
cycx3_M25P40.c
#include "cyu3system.h"
#include "cyu3os.h"
#include "cyu3dma.h"
#include "cyu3error.h"
#include "cyu3i2c.h"
#include "cyu3uart.h"
#include "cyu3gpio.h"
#include "cyu3utils.h"
#include "cycx3_M25P40.h"
/* SPI initialization for application. */
CyU3PReturnStatus_t
CyFxSpiInit (uint16_t pageLen)
{
CyU3PSpiConfig_t spiConfig;
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
/* Start the SPI module and configure the master. */
status = CyU3PSpiInit();
if (status != CY_U3P_SUCCESS)
{
return status;
}
/* Start the SPI master block. Run the SPI clock at 8MHz
* and configure the word length to 8 bits. Also configure
* the slave select using FW. */
CyU3PMemSet ((uint8_t *)&spiConfig, 0, sizeof(spiConfig));
spiConfig.isLsbFirst = CyFalse;
spiConfig.cpol = CyTrue;
spiConfig.ssnPol = CyFalse;
spiConfig.cpha = CyTrue;
spiConfig.leadTime = CY_U3P_SPI_SSN_LAG_LEAD_HALF_CLK;
spiConfig.lagTime = CY_U3P_SPI_SSN_LAG_LEAD_HALF_CLK;
spiConfig.ssnCtrl = CY_U3P_SPI_SSN_CTRL_FW;
spiConfig.clock = 8000000;
spiConfig.wordLen = 8;
status = CyU3PSpiSetConfig (&spiConfig, NULL);
return status;
}
/* Wait for the status response from the SPI flash. */
CyU3PReturnStatus_t
CyFxSpiWaitForStatus (
void)
{
uint8_t buf[2], rd_buf[2];
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
//uint8_t cnt = 0;
/* Wait for status response from SPI flash device. */
do
{
buf[0] = 0x06; /* Write enable command. */
CyU3PSpiSetSsnLine (CyFalse);
status = CyU3PSpiTransmitWords (buf, 1);
CyU3PSpiSetSsnLine (CyTrue);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (2, "SPI WR_ENABLE command failed\n\r");
return status;
}
buf[0] = 0x05; /* Read status command */
CyU3PSpiSetSsnLine (CyFalse);
status = CyU3PSpiTransmitWords (buf, 1);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (2, "SPI READ_STATUS command failed\n\r");
CyU3PSpiSetSsnLine (CyTrue);
return status;
}
status = CyU3PSpiReceiveWords (rd_buf, 2);
CyU3PSpiSetSsnLine (CyTrue);
if(status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (2, "SPI status read failed\n\r");
return status;
}
// CyU3PDebugPrint (2, "CyFxSpiWaitForStatus(),cnt = %d\n\r",++cnt);
} while ((rd_buf[0] & 1)|| (!(rd_buf[0] & 0x2)));
return CY_U3P_SUCCESS;
}
/* SPI read / write for programmer application. */
CyU3PReturnStatus_t
CyFxSpiTransfer (
uint16_t pageAddress,
uint16_t byteCount,
uint8_t *buffer,
CyBool_t isRead)
{
uint8_t location[4];
uint32_t byteAddress = 0;
uint16_t pageCount = (byteCount / glSpiPageSize);
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
if (byteCount == 0)
{
return CY_U3P_SUCCESS;
}
if ((byteCount % glSpiPageSize) != 0)
{
pageCount ++;
}
byteAddress = pageAddress * glSpiPageSize;
CyU3PDebugPrint (2, "SPI access - addr: 0x%x, size: 0x%x, pages: 0x%x.\r\n",
byteAddress, byteCount, pageCount);
while (pageCount != 0)
{
location[1] = (byteAddress >> 16) & 0xFF; /* MS byte */
location[2] = (byteAddress >> 8) & 0xFF;
location[3] = byteAddress & 0xFF; /* LS byte */
if (isRead)
{
location[0] = 0x03; /* Read command. */
status = CyFxSpiWaitForStatus ();
if (status != CY_U3P_SUCCESS)
return status;
CyU3PSpiSetSsnLine (CyFalse);
status = CyU3PSpiTransmitWords (location, 4);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (2, "SPI READ command failed\r\n");
CyU3PSpiSetSsnLine (CyTrue);
return status;
}
status = CyU3PSpiReceiveWords (buffer, glSpiPageSize);
if (status != CY_U3P_SUCCESS)
{
CyU3PSpiSetSsnLine (CyTrue);
CyU3PDebugPrint (2, "Read: CyU3PSpiReceiveWords err,status =0x%x.\r\n",status);
return status;
}
CyU3PSpiSetSsnLine (CyTrue);
}
else /* Write */
{
location[0] = 0x02; /* Write command */
status = CyFxSpiWaitForStatus ();
if (status != CY_U3P_SUCCESS)
return status;
CyU3PSpiSetSsnLine (CyFalse);
status = CyU3PSpiTransmitWords (location, 4);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (2, "SPI WRITE command failed\r\n");
CyU3PSpiSetSsnLine (CyTrue);
return status;
}
status = CyU3PSpiTransmitWords (buffer, glSpiPageSize);
if (status != CY_U3P_SUCCESS)
{
CyU3PSpiSetSsnLine (CyTrue);
return status;
}
CyU3PSpiSetSsnLine (CyTrue);
}
/* Update the parameters */
byteAddress += glSpiPageSize;
buffer += glSpiPageSize;
pageCount --;
CyU3PThreadSleep (10);
}
return CY_U3P_SUCCESS;
}
/* Function to erase SPI flash sectors. */
CyU3PReturnStatus_t
CyFxSpiEraseSector (
CyBool_t isErase,
uint8_t sector,
uint8_t *wip)
{
uint32_t temp = 0;
uint8_t location[4], rdBuf[2];
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
if ((!isErase) && (wip == NULL))
{
return CY_U3P_ERROR_BAD_ARGUMENT;
}
location[0] = 0x06; /* Write enable. */
CyU3PSpiSetSsnLine (CyFalse);
status = CyU3PSpiTransmitWords (location, 1);
CyU3PSpiSetSsnLine (CyTrue);
if (status != CY_U3P_SUCCESS)
return status;
if (isErase)
{
location[0] = 0xD8; /* Sector erase. */
temp = sector * 0x10000;
location[1] = (temp >> 16) & 0xFF;
location[2] = (temp >> 8) & 0xFF;
location[3] = temp & 0xFF;
CyU3PSpiSetSsnLine (CyFalse);
status = CyU3PSpiTransmitWords (location, 4);
CyU3PSpiSetSsnLine (CyTrue);
}
else
{
location[0] = 0x05; /* Read status */
CyU3PSpiSetSsnLine (CyFalse);
status = CyU3PSpiTransmitWords (location, 1);
if (status != CY_U3P_SUCCESS)
{
CyU3PSpiSetSsnLine (CyTrue);
return status;
}
status = CyU3PSpiReceiveWords (rdBuf, 2);
CyU3PSpiSetSsnLine (CyTrue);
*wip = rdBuf[0] & 0x1;
}
return status;
}
测试代码:
#define TEST_FLASH
#ifdef TEST_FLASH
//test flash rw.
#define len 270 //270 err 255 ok
uint16_t i = 0;
uint8_t buf_wr[len] = {0},buf_WIP[10]={0x01},buf_rd[len] = {0};
for(i=0;i<len;i++){
buf_wr[i] = i;
}
buf_wr[len-4] = 0x11;buf_wr[len-3] = 0x22;buf_wr[len-2] = 0x33;buf_wr[len-1] = 0x44;
const uint8_t Sector_Num = 7;
status = CyFxSpiEraseSector(CyTrue,Sector_Num,buf_WIP);
if(status != CY_U3P_SUCCESS){
CyU3PDebugPrint (4, "Erase Error: %x\r\n",status);
}
do{//wait until wip is 0
CyU3PThreadSleep (50);
CyFxSpiEraseSector(CyFalse,Sector_Num,buf_WIP);
CyU3PDebugPrint (4, "111 RDSR: %x\r\n",buf_WIP[0]);//3
}while((buf_WIP[0] & 0x01) == 1);
status = CyFxSpiTransfer (Sector_Num*glSpiPageSize, len,buf_wr, CyFalse);//write
if(status != CY_U3P_SUCCESS){
CyU3PDebugPrint (4, "Write Error: %x\r\n",status);
}//*/
do{//wait until wip is 0
CyU3PThreadSleep (50);
CyFxSpiEraseSector(CyFalse,Sector_Num,buf_WIP);
CyU3PDebugPrint (4, "111 RDSR: %x\r\n",buf_WIP[0]);//3
}while((buf_WIP[0] & 0x01) == 1);
status = CyFxSpiTransfer (Sector_Num*glSpiPageSize, len,buf_rd, CyTrue);//read
if(status != CY_U3P_SUCCESS){
CyU3PDebugPrint (4, "\r\nRead Error: %x\r\n",status);
}
CyU3PDebugPrint (4, "\r\nReadPage:%d,data:%x %x %x %x %x %x %x %x %x %x\r\n",
Sector_Num*glSpiPageSize,
buf_rd[len-4], buf_rd[len-3], buf_rd[len-2], buf_rd[len-1],buf_rd[4],
buf_rd[5], buf_rd[6], buf_rd[7], buf_rd[8], buf_rd[9]);
#endif