MX25L51245G 支持SPI的MODE0/MODE3,一般都选择mode3
#define FLASH_SECTOR_SIZE (4*1024)
#define FLASH_PAGE_SIZE 256
引脚定义
/*
* SPI1
* @SCK : PA5
* @MISO : PA6
* @MOSI : PA7
*
* @CS : PA0
*/
读写接口
static u8 SPI_Write(u8 byte)
{
u32 timeout = 0xFFFF;
while(!(SPI1->SR & SPI_I2S_FLAG_TXE))
{
if(--timeout == 0)
{
printf("TX timeout ! \r\n");
return 0;
}
}
SPI1->DR = byte;
timeout = 0xFFFF;
while(!(SPI1->SR & SPI_I2S_FLAG_RXNE))
if(--timeout == 0)
{
printf("RX timeout ! \r\n");
return 0;
}
return SPI1->DR;
}
static u8 SPI_Read(void)
{
return (SPI_Write(DUMMY_BYTE));
}
初始化函数
void SPI1_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure SPI1 pins: NSS, SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PA.0 as Output push-pull, used as Chip select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Deselect the FLASH: Chip Select high */
SPI_CS_Low();
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; /* mode 3 */
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 NSS output for master mode */
//SPI_SSOutputCmd(SPI1, DISABLE);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
SPI_Write(0xFF); //start transport
}
等待忙
/*
* @return : none-zero idle, else busy
*/
static u8 SPI_WaitBusy(void)
{
u32 timeout = 0xFFFF;
while( SET==SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)) /* SPI_SR */
{
if(--timeout == 0)
return 1;
}
return 0;
}
Flash 等待WIP信号
#define FLASH_WIP_MASK (1 << 0)
/*
* @return : none-zero timeout
*/
static u8 FlashWait_Busy(void)
{
u8 FLASH_Status;
u32 retry=0;
FLASH_CS_Low();
/*
* bit 0: WIP (=1 busy, else free)
* bit 1: WEL (=1 write enable)
*/
SPI_Write(RDSD_CMD); /* read status register */
do{
FLASH_Status=SPI_Read();
if(retry++ > FLASH_BUSY_TIMEOUT)
return FLASH_Status;
}while((FLASH_Status & FLASH_WIP_MASK) == FLASH_WIP_MASK); /* fix : not bit 7 !!! */
//printf("status register : 0x%x \r\n", FLASH_Status);
SPI_CS_High();
return 0;
}
获取flash信息
static void FlashGet_Info(flashInfoTypedef * pFlashInfo)
{
// FlashWait_Busy();
FLASH_CS_Low();
SPI_Write(RDID_CMD);
pFlashInfo->ManufacturerID=SPI_Read();
pFlashInfo->DeviceID[0]=SPI_Read();
pFlashInfo->DeviceID[1]=SPI_Read();
SPI_CS_High();
}
static void FlashGet_ElectronicInfo(flashInfoTypedef * pFlashInfo)
{
FLASH_CS_Low();
SPI_Write(REMS_CMD);
SPI_Write(DUMMY_BYTE);
SPI_Write(DUMMY_BYTE);
SPI_Write(0x00); //manufacturer's ID first
pFlashInfo->ManufacturerID=SPI_Read();
pFlashInfo->DeviceID[0]=SPI_Read();
SPI_CS_High();
}
写使能
static void FlashWriteEnable(void)
{
FLASH_CS_Low();
SPI_Write(WREN_CMD);
SPI_CS_High();
}
spi flash初始化
void SpiFlash_Init(void)
{
flashInfoTypedef flashInfo;
//SPI1_Configuration();
#if 1
FlashGet_ElectronicInfo(&flashInfo);
if((flashInfo.ManufacturerID==0xc2)&&(flashInfo.DeviceID[0]==0x20))
{
printf("Flash Info: MXIC(Macronix International Co.,Ltd\r\n");
}
#endif
FlashGet_Info(&flashInfo);
printf("ManufacturerID = 0x%02X \r\n",flashInfo.ManufacturerID);
printf("DeviceID = 0x%02X%02X \r\n",flashInfo.DeviceID[0],flashInfo.DeviceID[1]);
}
获取ID的接口
static void Flash_ReadID(void)
{
flashInfoTypedef flashInfo;
FlashGet_ElectronicInfo(&flashInfo);
if((flashInfo.ManufacturerID==0xc2)&&(flashInfo.DeviceID[0]==0x20))
{
printf("Flash Info: MXIC(Macronix International Co.,Ltd\r\n");
}
FlashGet_Info(&flashInfo);
printf("ManufacturerID = 0x%02X \r\n",flashInfo.ManufacturerID);
printf("DeviceID = 0x%02X%02X \r\n",flashInfo.DeviceID[0],flashInfo.DeviceID[1]);
}