#include #include #define SPI_FLASHx SPI1 #define SPI_FLASH_APBxClock_FUN RCC_APB2PeriphClockCmd #define SPI_FLASH_CLK RCC_APB2Periph_SPI1 //GPIO #define SPI_FLASH_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd #define SPI_FLASH_GPIO_CLK RCC_APB2Periph_GPIOA #define SPI_FLASH_GPIO_PORT GPIOA //CS(NSS) #define SPI_FLASH_CS_PIN GPIO_Pin_4 //SCK #define SPI_FLASH_SCK_PIN GPIO_Pin_5 //MISO #define SPI_FLASH_MISO_PIN GPIO_Pin_6 //MOSI #define SPI_FLASH_MOSI_PIN GPIO_Pin_7 #define SPI_FLASH_CS_LOW() GPIO_ResetBits(SPI_FLASH_GPIO_PORT, SPI_FLASH_CS_PIN) #define SPI_FLASH_CS_HIGH() GPIO_SetBits(SPI_FLASH_GPIO_PORT, SPI_FLASH_CS_PIN) #define SPI_FLASH_DUMMY_BYTE (0xFF) #define SPIT_FLAG_TIMEOUT ((uint32_t)0x1000) #define SPIT_LONG_TIMEOUT ((uint32_t)(10 * SPIT_FLAG_TIMEOUT)) static __IO uint32_t SPITimeout = SPIT_LONG_TIMEOUT; static uint32_t SPI_TIMEOUT_UserCallback(uint8_t errorCode); #define FLASH_INFO(fmt,arg...) printf("<<-FLASH-INFO->> "fmt"\n",##arg) #define FLASH_ERROR(fmt,arg...) printf("<<-FLASH-ERROR->> "fmt"\n",##arg) void SPI_FLASH_Initialize(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; SPI_FLASH_APBxClock_FUN(SPI_FLASH_CLK, ENABLE); SPI_FLASH_GPIO_APBxClock_FUN(SPI_FLASH_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = SPI_FLASH_CS_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(SPI_FLASH_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = SPI_FLASH_SCK_PIN|SPI_FLASH_MISO_PIN|SPI_FLASH_MOSI_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(SPI_FLASH_GPIO_PORT, &GPIO_InitStructure); SPI_FLASH_CS_HIGH(); 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; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI_FLASHx, &SPI_InitStructure); SPI_Cmd(SPI_FLASHx, ENABLE); } uint8_t SPI_FLASH_TransferByte(uint8_t uiByte) { SPITimeout = SPIT_FLAG_TIMEOUT; while (SPI_I2S_GetFlagStatus(SPI_FLASHx, SPI_I2S_FLAG_TXE) == RESET) { if ((SPITimeout--) == 0) { return SPI_TIMEOUT_UserCallback(0); } } SPI_I2S_SendData(SPI_FLASHx, uiByte); SPITimeout = SPIT_FLAG_TIMEOUT; while (SPI_I2S_GetFlagStatus(SPI_FLASHx, SPI_I2S_FLAG_RXNE) == RESET) { if ((SPITimeout--) == 0) { return SPI_TIMEOUT_UserCallback(1); } } return SPI_I2S_ReceiveData(SPI_FLASHx); } uint32_t SPI_FLASH_ReadID(void) { uint32_t uiID = 0x00; SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_JedecDeviceID); uiID = SPI_FLASH_TransferByte(SPI_FLASH_DUMMY_BYTE); uiID <<= 8; uiID |= SPI_FLASH_TransferByte(SPI_FLASH_DUMMY_BYTE); uiID <<= 8; uiID |= SPI_FLASH_TransferByte(SPI_FLASH_DUMMY_BYTE); SPI_FLASH_CS_HIGH(); return uiID; } void SPI_FLASH_Erase_Sector(uint32_t uiAddr) { SPI_FLASH_WriteEnable(); SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_SectorErase); SPI_FLASH_TransferByte((uiAddr>>16)&0xff); SPI_FLASH_TransferByte((uiAddr>>8)&0xff); SPI_FLASH_TransferByte(uiAddr&0xff); SPI_FLASH_CS_HIGH(); SPI_FLASH_WaitBusy(); } void SPI_FLASH_WaitBusy(void) { uint8_t uiStatusReg = 0; SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_ReadStatusReg); do { uiStatusReg = SPI_FLASH_TransferByte(SPI_FLASH_DUMMY_BYTE); } while((uiStatusReg & 0x01) == 1); SPI_FLASH_CS_HIGH(); } void SPI_FLASH_WriteEnable(void) { SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_WriteEnable); SPI_FLASH_CS_HIGH(); } void SPI_FLASH_ReadData(uint32_t uiAddr,uint8_t *readBuff,uint32_t numByteToRead) { SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_ReadData); (void)SPI_FLASH_TransferByte((uiAddr>>16)&0xff); (void)SPI_FLASH_TransferByte((uiAddr>>8)&0xff); (void)SPI_FLASH_TransferByte(uiAddr&0xff); while(numByteToRead--) { *readBuff = SPI_FLASH_TransferByte(SPI_FLASH_DUMMY_BYTE); readBuff++; } SPI_FLASH_CS_HIGH(); } void SPI_FLASH_WriteData(uint32_t uiAddr,uint8_t *writeBuff,uint32_t numByteToWrite) { SPI_FLASH_WriteEnable(); SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_PageProgram); (void)SPI_FLASH_TransferByte((uiAddr>>16)&0xff); (void)SPI_FLASH_TransferByte((uiAddr>>8)&0xff); (void)SPI_FLASH_TransferByte(uiAddr&0xff); while(numByteToWrite--) { (void)SPI_FLASH_TransferByte(*writeBuff); writeBuff++; } SPI_FLASH_CS_HIGH(); SPI_FLASH_WaitBusy(); } static uint32_t SPI_TIMEOUT_UserCallback(uint8_t errorCode) { /* Block communication and all processes */ FLASH_ERROR("SPI waiting timeout! error code is %d",errorCode); return 0; } uint8_t SPI_FLASH_ReadStatusReg(void) { uint8_t uiStatusRegVal = 0; SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_ReadStatusReg); uiStatusRegVal = SPI_FLASH_TransferByte(SPI_FLASH_DUMMY_BYTE); SPI_FLASH_CS_HIGH(); return uiStatusRegVal; } void SPI_FLASH_EraseChip(void) { SPI_FLASH_WriteEnable(); SPI_FLASH_WaitBusy(); SPI_FLASH_CS_LOW(); (void)SPI_FLASH_TransferByte(W25X_ChipErase); SPI_FLASH_CS_HIGH(); SPI_FLASH_WaitBusy(); }