STM32之SPI驱动外部Flash
来源:互联网 发布:嫁コレ数据提取资料 编辑:程序博客网 时间:2024/05/20 20:18
MCU为STM32F030C8T6,Nor Flash为IS25LQ010B。
spi.h源代码
#ifndef __spi_H#define __spi_H#ifdef __cplusplusextern "C" {#endif/* Includes ------------------------------------------------------------------*/#include "stm32f0xx_hal.h"#define SPI2_NSS GPIO_PIN_12 /* PB12 */#define SPI2_SCLK GPIO_PIN_13 /* PB13 */#define SPI2_MISO GPIO_PIN_14 /* PB14 */#define SPI2_MOSI GPIO_PIN_15 /* PB15 *//* Variables */extern SPI_HandleTypeDef hspi2;/* Function prototype */extern void _Error_Handler(char *, int);void MX_SPI2_Init(void);#ifdef __cplusplus}#endif#endif /*__ spi_H */
spi.c源代码:
#include "spi.h"SPI_HandleTypeDef hspi2;/* SPI2 init function */void MX_SPI2_Init(void){ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 7; hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; if (HAL_SPI_Init(&hspi2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}/* Init SPI GPIO pins */void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle){ GPIO_InitTypeDef GPIO_InitStruct; if(spiHandle->Instance==SPI2) { /* SPI2 clock enable */ __HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**SPI2 GPIO Configuration PB12 ------> SPI2_NSS PB13 ------> SPI2_SCK PB14 ------> SPI2_MISO PB15 ------> SPI2_MOSI */ GPIO_InitStruct.Pin = SPI2_NSS; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = SPI2_SCLK | SPI2_MISO | SPI2_MOSI; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF0_SPI2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure SPI2_NSS default output level */ HAL_GPIO_WritePin(GPIOB, SPI2_NSS, GPIO_PIN_SET); }}void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle){ if(spiHandle->Instance==SPI2) { /* Peripheral clock disable */ __HAL_RCC_SPI2_CLK_DISABLE(); __HAL_RCC_GPIOB_CLK_DISABLE(); /**SPI2 GPIO Configuration PB12 ------> SPI2_NSS PB13 ------> SPI2_SCK PB14 ------> SPI2_MISO PB15 ------> SPI2_MOSI */ HAL_GPIO_DeInit(GPIOB, SPI2_NSS | SPI2_SCLK | SPI2_MISO | SPI2_MOSI); }}
flash.h源代码:
#ifndef __FLASH_IS25LQ010B_H__#define __FLASH_IS25LQ010B_H__ /* Define macro __FLASH_IS25LQ010B_H__ */#ifdef __cplusplusextern "C"{#endif#include <stdint.h>#include <stdbool.h>#define IS25LQ010B /* Define NOR Flash type */#define MAX_COMMAND_SIZE (256+3+1)#define DUMMY_BYTE (0x00)#define SPI2_TIMEOUT (1000)#define SPI2_WAITING_FOREVER (0xFFFFFFFF)#define IS25LQ010B_FLASH_BASE_ADDRESS (0x000000)#define IS25LQ010B_FLASH_SECTOR_SIZE (0x1000) /* 4Kb */#define IS25LQ010B_FLASH_BLOCK_SIZE (IS25LQ010B_FLASH_SECTOR_SIZE*8) /* 32Kb */#define IS25LQ010B_FLASH_SIZE (IS25LQ010B_FLASH_BLOCK_SIZE*4) /* 128Kb *//* Device Operation Instruction Set */#define RD 0x03 /* Read Data Bytes from Memory at Normal Read Mode, SPI mode, Maximum frequency 33MHz */#define FR 0x0B /* Read Data Bytes from Memory at Fast Read Mode, SPI mode, Maximum frequency 104MHz */#define FRDIO 0xBB /* Fast Read Dual I/O, SPI mode, Maximum frequency 104MHz */#define FRDO 0x3B /* Fast Read Dual Output, SPI mode, Maximum frequency 104MHz */#define FRQIO 0xEB /* Fast Read Quad I/O, SPI mode, Maximum frequency 104MHz */#define FRQO 0x6B /* Fast Read Quad Output, SPI mode, Maximum frequency 104MHz *//* Follow instructions must be preceded by the WREN instruction */ /************************** Start *********************************/ #define PP 0x02 /* Page Program Data Bytes into Memory, SPI mode, Maximum frequency 104MHz */#define PPQ 0x32 /* Page Program Data Bytes into Memory with Quad Interface, SPI mode, Maximum frequency 104MHz *///#define PPQ 0x38 /* Page Program Data Bytes into Memory with Quad Interface, SPI mode, Maximum frequency 104MHz */#define SER 0xD7 /* Sector Erase 4KB, SPI mode, Maximum frequency 104MHz *///#define SER 0x20 /* Sector Erase 4KB, SPI mode, Maximum frequency 104MHz */#if defined(IS25LQ040B) || defined(IS25LQ020B) || defined(IS25LQ010B) #define BER32 0x52 /* Block Erase 32KB, SPI mode, Maximum frequency 104MHz */ #define BER64 0xD8 /* Block Erase 64KB, SPI mode, Maximum frequency 104MHz */#elif defined(IS25LQ512B) || defined(IS25LQ025B) #define BER32 0x52 /* Block Erase 32KB, SPI mode, Maximum frequency 104MHz */ //#define BER32 0xD8 /* Block Erase 32KB, SPI mode, Maximum frequency 104MHz */ #define BER64 /* Unsupported instruction */#endif#if defined(IS25LQ040B) || defined(IS25LQ020B) || defined(IS25LQ010B) || defined(IS25LQ512B) #define CER 0xC7 /* Chip Erase, SPI mode, Maximum frequency 104MHz */ //#define CER 0x60 /* Chip Erase, SPI mode, Maximum frequency 104MHz */#endif#define WRSR 0x01 /* Write Status Register, SPI mode, Maximum frequency 104MHz */#define WRFR 0x42 /* Write Function Register, SPI mode, Maximum frequency 104MHz */#define IRP 0x62 /* Program Information Row, SPI mode, Maximum frequency 104MHz *//************************** End *********************************/#define WREN 0x06 /* Write Enable, SPI mode, Maximum frequency 104MHz */#define WRDI 0x04 /* Write Disable, SPI mode, Maximum frequency 104MHz */#define RDSR 0x05 /* Read Status Register, SPI mode, Maximum frequency 104MHz */#define RDFR 0x48 /* Read Function Register, SPI mode, Maximum frequency 104MHz */#define PERSUS 0x75 /* Suspend during the Program/Erase, SPI mode, Maximum frequency 104MHz */ //#define PERSUS 0xB0 /* Suspend during the Program/Erase, SPI mode, Maximum frequency 104MHz */#define PERRSM 0x7A /* Resume Program/Erase, SPI mode, Maximum frequency 104MHz */ //#define PERRSM 0x30 /* Resume Program/Erase, SPI mode, Maximum frequency 104MHz */#define DP 0xB9 /* Deep Power Down Mode, SPI mode, Maximum frequency 104MHz */#define RDID 0xAB /* Read Manufacturer and Product ID/Release Deep Power Down, SPI mode, Maximum frequency 104MHz */#define RDPD 0xAB /* Read Manufacturer and Product ID/Release Deep Power Down, SPI mode, Maximum frequency 104MHz */#define RDUID 0x4B /* Read Unique ID Number, SPI mode, Maximum frequency 104MHz */#define RDJDID 0x9F /* Read Manufacturer and Product ID by JEDEC ID Command, SPI mode, Maximum frequency 104MHz */#define RDMDID 0x90 /* Read Manufacturer and Device ID, SPI mode, Maximum frequency 104MHz */#define RDSFDP 0x5A /* SFDP Read, SPI mode, Maximum frequency 104MHz */#define RSTEN 0x66 /* Software Reset Enable, SPI mode, Maximum frequency 104MHz */#define RST 0x99 /* Reset, SPI mode, Maximum frequency 104MHz */#define IRRD 0x68 /* Read Information Row, SPI mode, Maximum frequency 104MHz */#define SECUNLOCK 0x26 /* Sector Unlock, SPI mode, Maximum frequency 104MHz */#define SECLOCK 0x24 /* Sector Lock, SPI mode, Maximum frequency 104MHz *//* Function Prototype */void IS25LQ010B_NORFlashInit(void);void IS25LQ010B_NSSEnable(void);void IS25LQ010B_NSSDisable(void);bool IS25LQ010B_WriteEnable(void);bool IS25LQ010B_WriteDisable(void);int32_t IS25LQ010B_ReadStatusRegister(uint8_t* StatusRegister);int32_t IS25LQ010B_WriteSatusRegister(uint8_t SatusRegister);int32_t IS25LQ010B_ReadFunctionRegister(uint8_t* FunctionRegister);int32_t IS25LQ010B_WriteFunctionRegister(uint8_t FunctionRegister);bool IS25LQ010B_DeviceIsBusy(void);int32_t IS25LQ010B_WritePage(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_WriteNoCheck(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_Write(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_SectorErase(uint32_t Address);int32_t IS25LQ010B_BlockErase32KB(uint32_t Address);int32_t IS25LQ010B_BlockErase64KB(uint32_t Address);int32_t IS25LQ010B_EraseChip(void);int32_t IS25LQ010B_Read(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_FastRead(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_DeepPowerDown(void);int32_t IS25LQ010B_ReleaseDeepPowerDown(void);int32_t IS25LQ010B_ReadDeviceID(uint8_t* DeviceID);int32_t IS25LQ010B_ReadManufacturerProductCapacity(uint8_t* ManufacturerID, uint8_t* DeviceType, uint8_t* Capacity);int32_t IS25LQ010B_ReadManufacturerIDDeviceID(uint32_t Address, uint8_t* ManufacturerID, uint8_t* DeviceID);int32_t IS25LQ010B_ReadUID(uint32_t Address, uint8_t* UID, uint16_t* UIDSize);int32_t IS25LQ010B_ReadSerialFlashDiscoverableParameter(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_SoftwareReset(void);int32_t IS25LQ010B_WritRowPage(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_WriteRowNoCheck(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_WriteRow(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_ReadRow(uint32_t Address, uint8_t* Data, uint16_t Size);int32_t IS25LQ010B_SectorLock(void);int32_t IS25LQ010B_SectorUnlock(uint32_t Address);#ifdef __cplusplus}#endif#endif /* End define macro __FLASH_IS25LQ010B_H__ */
flash.c源代码:
#include "flash_is25lq010b.h"#include "spi.h"#include <string.h>/*** @Brief: Init flash spi driver** @Parameter: None** @Return: None**/void IS25LQ010B_NORFlashInit(void){ MX_SPI2_Init();}/*** @Brief: Spi Chip Select Pin pull down and enable spi** @Parameter: None** @Return: None**/void IS25LQ010B_NSSEnable(void){ HAL_GPIO_WritePin(GPIOB, SPI2_NSS, GPIO_PIN_RESET);}/*** @Brief: Spi Chip Select Pin up down and disable spi** @Parameter: None** @Return: None**/void IS25LQ010B_NSSDisable(void){ HAL_GPIO_WritePin(GPIOB, SPI2_NSS, GPIO_PIN_SET);}/*** @Brief: Enable flash write function** @Parameter: None** @Return: 1) true, Enable OK 2) false, Enable failed**/bool IS25LQ010B_WriteEnable(void){ uint8_t Command = WREN; IS25LQ010B_NSSEnable(); HAL_StatusTypeDef State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return false; } IS25LQ010B_NSSDisable(); return true;}/*** @Brief: Disable flash write function** @Parameter: None** @Return: 1) true, Disable OK 2) false, Disable failed**/bool IS25LQ010B_WriteDisable(void){ uint8_t Command = WRDI; IS25LQ010B_NSSEnable(); HAL_StatusTypeDef State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return false; } IS25LQ010B_NSSDisable(); return true;}/*** @Brief: Read status register value** @Parameter: StatusRegister, Status Register value** @Return: 1) 0, get Status Register OK 2) -1, get Status Register failed**/int32_t IS25LQ010B_ReadStatusRegister(uint8_t* StatusRegister){ uint8_t Command = RDSR; HAL_StatusTypeDef State = HAL_OK; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); StatusRegister = NULL; return -1; } State = HAL_SPI_Receive(&hspi2, StatusRegister, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); StatusRegister = NULL; return -2; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Write status register value** @Parameter: SatusRegister, status register value** @Return: 1) -1, transmit command data failed 2) 0, set status register value successful**/int32_t IS25LQ010B_WriteSatusRegister(uint8_t SatusRegister){ uint8_t Command[2] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; Command[CommandSize++] = WRSR; Command[CommandSize++] = SatusRegister; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -1; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Read function register value** @Parameter: FunctionRegister, Function Register** @Return: 1) 0, get Function Register value 2) -1, get Function Register failed**/int32_t IS25LQ010B_ReadFunctionRegister(uint8_t* FunctionRegister){ uint8_t Command = RDFR; HAL_StatusTypeDef State = HAL_OK; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); FunctionRegister = NULL; return -1; } State = HAL_SPI_Receive(&hspi2, FunctionRegister, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); FunctionRegister = NULL; return -2; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Write function register value** @Parameter: FunctionRegister, function register value** @Return: 1) -1, transmit command failed 2) 0, set function register value successful**/int32_t IS25LQ010B_WriteFunctionRegister(uint8_t FunctionRegister){ uint8_t Command[2] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; Command[CommandSize++] = WRFR; Command[CommandSize++] = FunctionRegister; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -1; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Check device is busy** @Parameter: None** @Return: 1) true, device is busy 2) false, device ready**/bool IS25LQ010B_DeviceIsBusy(void){ uint8_t StatusRegister = 0; int32_t Result = 0; Result = IS25LQ010B_ReadStatusRegister(&StatusRegister); if(Result < 0) { /* Device busy, get status register failed */ return true; } if(StatusRegister & 0x01) { /* Device busy */ return true; } /* Device ready */ return false;}/*** @Brief: Write data to flash page** @Parameter: 1) Address, flash address 2) Data, write data 3) Size, write data size** @Return: 1) -1, enable write failed 2) -2, write data to flash failed 3) 0, write data to flash successful**/int32_t IS25LQ010B_WritePage(uint32_t Address, uint8_t* Data, uint16_t Size){ uint8_t Command[MAX_COMMAND_SIZE] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; if(!IS25LQ010B_WriteEnable()) { return -1; } Command[CommandSize++] = PP; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; memcpy(&Command[CommandSize], Data, Size); CommandSize = Size + 4; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { return -2; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Write data to flash** @Parameter: 1) Address, flash address 2) Data, write data 3) Size, write data size** @Return: 1) -1, write data to flash page failed 2) 0, write data to flash successful**/int32_t IS25LQ010B_WriteNoCheck(uint32_t Address, uint8_t* Data, uint16_t Size){ uint16_t PageRemain = 256 - Address % 256; int32_t Result = 0; if(PageRemain >= Size) { PageRemain = Size; } while(1) { Result = IS25LQ010B_WritePage(Address, Data, PageRemain); if(Result != 0) { return -1; } if(Size == PageRemain) { break; } else { Data += PageRemain; Address += PageRemain; Size -= PageRemain; if(Size > 256) { PageRemain = 256; } else { PageRemain = Size; } } } return 0;}/*** @Brief: Write data to flash** @Parameter: 1) Address, flash address 2) Data, write data 3) Size, write data size** @Return: 1) -1, read flash data failed 2) -2, erase sector failed 3) -3, write date to flash failed 4) -4, write data to flash failed 5) 0, write data to flash successful**/int32_t IS25LQ010B_Write(uint32_t Address, uint8_t* Data, uint16_t Size){ uint16_t SectorPosition = Address / IS25LQ010B_FLASH_SECTOR_SIZE; uint16_t SectorOffset = Address % IS25LQ010B_FLASH_SECTOR_SIZE; uint16_t SectorRemain = IS25LQ010B_FLASH_SECTOR_SIZE - SectorOffset; uint8_t TempBuffer[IS25LQ010B_FLASH_SECTOR_SIZE] = {0}; int32_t Result = 0; int32_t Index = 0; if(SectorRemain >= Size) { SectorRemain = Size; } while(1) { Result = IS25LQ010B_Read(SectorPosition*IS25LQ010B_FLASH_SECTOR_SIZE, TempBuffer, IS25LQ010B_FLASH_SECTOR_SIZE); if(Result != 0) { return -1; } for(Index = 0; Index < SectorRemain; Index++) { if(TempBuffer[SectorOffset + Index] != 0xFF) { break; } } if(Index < SectorRemain) { Result = IS25LQ010B_SectorErase(SectorPosition); if(Result != 0) { return -2; } memcpy(&TempBuffer[SectorOffset], Data, SectorRemain); Result = IS25LQ010B_WriteNoCheck(SectorPosition*IS25LQ010B_FLASH_SECTOR_SIZE, TempBuffer, IS25LQ010B_FLASH_SECTOR_SIZE); if(Result != 0) { return -3; } } else { Result = IS25LQ010B_WriteNoCheck(Address, Data, SectorRemain); if(Result != 0) { return -4; } } if(SectorRemain == Size) { break; } else { SectorPosition++; SectorOffset = 0; Data += SectorRemain; Address += SectorRemain; Size -= SectorRemain; if(Size > IS25LQ010B_FLASH_SECTOR_SIZE) { SectorRemain = IS25LQ010B_FLASH_SECTOR_SIZE; } else { SectorRemain = Size; } } } return 0;}/*** @Brief: Erase a sector** @Parameter: Address, sector address** @Return: 1) -1, sector address illegal 2) -2, write enable failed 3) -3, sector erase failed 4) 0, sector erase successfil**/int32_t IS25LQ010B_SectorErase(uint32_t Address){ uint8_t Command[4] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; /* Check whether address is legal */ if(Address > (IS25LQ010B_FLASH_SIZE - IS25LQ010B_FLASH_SECTOR_SIZE)) { return -1; } if(!IS25LQ010B_WriteEnable()) { return -2; } while(IS25LQ010B_DeviceIsBusy()); Command[CommandSize++] = SER; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -3; } IS25LQ010B_NSSDisable(); while(IS25LQ010B_DeviceIsBusy()); return 0;}/*** @Brief: Erase a block** @Parameter: Address, block address** @Return: 1) -1, block address illegal 2) -2, write enable failed 3) -3, block erase failed 4) 0, block erase successfil**/int32_t IS25LQ010B_BlockErase32KB(uint32_t Address){ uint8_t Command[4] = {0}; uint16_t CommandSize = 0; /* Check whether address is legal */ if(Address > (IS25LQ010B_FLASH_SIZE - IS25LQ010B_FLASH_BLOCK_SIZE)) { return -1; } if(!IS25LQ010B_WriteEnable()) { return -2; } while(IS25LQ010B_DeviceIsBusy()); Command[CommandSize++] = BER32; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; IS25LQ010B_NSSEnable(); /* Transmit erase sector command */ HAL_StatusTypeDef TransmitState = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(TransmitState != HAL_OK) { IS25LQ010B_NSSDisable(); return -3; } IS25LQ010B_NSSDisable(); while(IS25LQ010B_DeviceIsBusy()); return 0;}/*** @Brief: Erase a block** @Parameter: Address, block address** @Return: 1) -1, block address illegal 2) -2, write enable failed 3) -3, erase 64 Kb failed 4) 0, erase 64Kb successfil**/int32_t IS25LQ010B_BlockErase64KB(uint32_t Address){ uint8_t Command[4] = {0}; uint16_t CommandSize = 0; /* Check whether address is legal */ if(Address > (IS25LQ010B_FLASH_SIZE - 2 * IS25LQ010B_FLASH_BLOCK_SIZE)) { return -1; } if(!IS25LQ010B_WriteEnable()) { return -2; } while(IS25LQ010B_DeviceIsBusy()); Command[CommandSize++] = BER64; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; IS25LQ010B_NSSEnable(); /* Transmit erase sector command */ HAL_StatusTypeDef TransmitState = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(TransmitState != HAL_OK) { IS25LQ010B_NSSDisable(); return -3; } IS25LQ010B_NSSDisable(); while(IS25LQ010B_DeviceIsBusy()); return 0;}/*** @Brief: Erase flash chip** @Parameter: None** @Return: 1) -1, write enable failed 2) -2, erase flash chip failed 0) 0, erase flash chip successful**/int32_t IS25LQ010B_EraseChip(void){ uint8_t EraseChipCommand = CER; if(!IS25LQ010B_WriteEnable()) { return -1; } while(IS25LQ010B_DeviceIsBusy()); IS25LQ010B_NSSEnable(); /* Transmit erase sector command */ HAL_StatusTypeDef TransmitState = HAL_SPI_Transmit(&hspi2, &EraseChipCommand, 1, SPI2_TIMEOUT); if(TransmitState != HAL_OK) { IS25LQ010B_NSSDisable(); return -2; } IS25LQ010B_NSSDisable(); while(IS25LQ010B_DeviceIsBusy()); return 0;}/*** @Brief: Read memory contents of the device at a maximum frequency of 33MHz** @Parameter: 1) Address, flash address 2) Data, read data 3) Size, read data size** @Return: 1) -1, Address illegal 2) -2, transmit read command failed 3) -3, receive read data failed 4) 0, read data from flash successful**/int32_t IS25LQ010B_Read(uint32_t Address, uint8_t* Data, uint16_t Size){ uint8_t Command[4] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; /* Check whether parameters is legal */ if((0 == Size) || (Address >= IS25LQ010B_FLASH_SIZE)) { return -1; } Command[CommandSize++] = RD; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -2; } State = HAL_SPI_Receive(&hspi2, Data, Size, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -3; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Read memory data at up to a 104MHZ clock** @Parameter: 1) Address, flash address 2) Data, read data 3) Size, read data size** @Return: 1) -1, Address illegal 2) -2, transmit read command failed 3) -3, receive read data failed 4) 0, read data from flash successful**/int32_t IS25LQ010B_FastRead(uint32_t Address, uint8_t* Data, uint16_t Size){ uint8_t Command[5] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef ReceiveState = HAL_OK; /* Check whether parameters is legal */ if((0 == Size) || (Address >= IS25LQ010B_FLASH_SIZE)) { return -1; } Command[CommandSize++] = FR; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; Command[CommandSize++] = DUMMY_BYTE; IS25LQ010B_NSSEnable(); /* Transmit read data instrction */ ReceiveState = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(ReceiveState != HAL_OK) { IS25LQ010B_NSSDisable(); return -2; } ReceiveState = HAL_SPI_Receive(&hspi2, Data, Size, SPI2_TIMEOUT); if(ReceiveState != HAL_OK) { IS25LQ010B_NSSDisable(); return -3; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Enter device minimizing the power comsumption** @Parameter: None** @Return: 1) -1, transmit command failed 2) 0, operate execute successful**/int32_t IS25LQ010B_DeepPowerDown(void){ uint8_t Command = DP; HAL_StatusTypeDef State = HAL_OK; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -1; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Release device minimizing the power comsumption** @Parameter: None** @Return: 1) -1, transmit command failed 2) 0, operate execute successful**/int32_t IS25LQ010B_ReleaseDeepPowerDown(void){ uint8_t Command = RDPD; HAL_StatusTypeDef State = HAL_OK; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -1; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Read a byte device ID** @Parameter: DeviceID, device ID** @Return: 1) -1, transmit command failed 2) -2, receive device ID failed 3) 0, get a byte device ID successful**/int32_t IS25LQ010B_ReadDeviceID(uint8_t* DeviceID){ uint8_t Command[4] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; Command[CommandSize++] = RDID; Command[CommandSize++] = DUMMY_BYTE; Command[CommandSize++] = DUMMY_BYTE; Command[CommandSize++] = DUMMY_BYTE; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); DeviceID = NULL; return -1; } State = HAL_SPI_Receive(&hspi2, DeviceID, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); DeviceID = NULL; return -2; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Read Manufacturer ID, Device type and Capacity** @Parameter: 1) ManufacturerID 2) DeviceType 3) Capacity** @Return: 1) -1, command transmit failed 2) -2, recive Manufacturer ID, Device Type and Capacity data failed 3) 0, operate successful**/int32_t IS25LQ010B_ReadManufacturerProductCapacity(uint8_t* ManufacturerID, uint8_t* DeviceType, uint8_t* Capacity){ HAL_StatusTypeDef State = HAL_OK; uint8_t Command = RDJDID; uint8_t TmpData[3] = {0}; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); ManufacturerID = NULL; DeviceType = NULL; Capacity = NULL; return -1; } State = HAL_SPI_Receive(&hspi2, TmpData, 3, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); ManufacturerID = NULL; DeviceType = NULL; Capacity = NULL; return -2; } IS25LQ010B_NSSDisable(); *ManufacturerID = TmpData[0]; *DeviceType = TmpData[1]; *Capacity = TmpData[2]; return 0;}/*** @Brief: Read Manufacturer ID and Device ID** @Parameter: 1) Address, flash address 2) ManufacturerID, need return Manufacturer ID 3) DeviceID, need return Device ID** @Return: 1) -1, Address illegal 2) -2, command transmit failed 3) -3, receive data failed 0) 0, operate successful**/int32_t IS25LQ010B_ReadManufacturerIDDeviceID(uint32_t Address, uint8_t* ManufacturerID, uint8_t* DeviceID){ uint8_t Command[4] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; uint8_t TmpData[2] = {0}; /* Check whether parameters is legal */ if(Address >= IS25LQ010B_FLASH_SIZE) { ManufacturerID = NULL; DeviceID = NULL; return -1; } Command[CommandSize++] = RDMDID; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSEnable(); ManufacturerID = NULL; DeviceID = NULL; return -2; } State = HAL_SPI_Receive(&hspi2, TmpData, 2, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSEnable(); ManufacturerID = NULL; DeviceID = NULL; return -3; } IS25LQ010B_NSSEnable(); *ManufacturerID = TmpData[0]; *DeviceID = TmpData[1]; return 0;}/*** @Brief: Get 16 bytes unique ID number** @Parameter: 1) Address, flash address 2) UID, need return UID 3) UIDSize, UID size** @Return: 1) -1, parameter illegal 2) -2,command transmit failed 3) -3, receive UID data failed 4) 0, operate successful**/int32_t IS25LQ010B_ReadUID(uint32_t Address, uint8_t* UID, uint16_t* UIDSize){ uint8_t Command[5] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; uint8_t TmpUID[16] = {0}; if(Address > IS25LQ010B_FLASH_SIZE) { return -1; } Command[CommandSize++] = RDUID; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; Command[CommandSize++] = DUMMY_BYTE; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -2; } State = HAL_SPI_Receive(&hspi2, TmpUID, 16, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -3; } IS25LQ010B_NSSDisable(); /* return 16-byte device unique number */ *UIDSize = 16; memcpy(UID, TmpUID, *UIDSize); return 0;}/*** @Brief: Read Serial Flash Discoverable Parameter(SFDP)** @Parameter: 1) Address, flash address 2) Data, SFDP data 3) Size, SFDP data size** @Return: 1) -1, address illegal 2) -2, command transmit failed 3) -3, receive SFDP data failed 4) 0, operate successful**/int32_t IS25LQ010B_ReadSerialFlashDiscoverableParameter(uint32_t Address, uint8_t* Data, uint16_t Size){ uint8_t Command[5] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; if(Address > IS25LQ010B_FLASH_SIZE) { memset(Data, 0, Size); return -1; } Command[CommandSize++] = RDSFDP; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; Command[CommandSize++] = DUMMY_BYTE; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); memset(Data, 0, Size); return -2; } State = HAL_SPI_Receive(&hspi2, Data, Size, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); memset(Data, 0, Size); return -3; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: software reset operation** @Parameter: None** @Return: 1) -1, transmit reset enable command failed 2) -2, transmit reset command failed 0) 0, operate successful**/int32_t IS25LQ010B_SoftwareReset(void){ uint8_t ResetEnableCommand = RSTEN; uint8_t ResetCommand = RST; HAL_StatusTypeDef State = HAL_OK; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &ResetEnableCommand, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -1; } IS25LQ010B_NSSDisable(); IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &ResetCommand, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -2; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Write data to flash page** @Parameter: 1) Address, flash address 2) Data, write data 3) Size, write data size** @Return: 1) -1, enable write failed 2) -2, write data to flash failed 3) 0, write data to flash successful**/int32_t IS25LQ010B_WritRowPage(uint32_t Address, uint8_t* Data, uint16_t Size){ uint8_t Command[MAX_COMMAND_SIZE] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; if(!IS25LQ010B_WriteEnable()) { return -1; } Command[CommandSize++] = IRP; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; memcpy(&Command[CommandSize], Data, Size); CommandSize = Size + 4; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { return -2; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Write data to flash** @Parameter: 1) Address, flash address 2) Data, write data 3) Size, write data size** @Return: 1) -1, write data to flash page failed 2) 0, write data to flash successful**/int32_t IS25LQ010B_WriteRowNoCheck(uint32_t Address, uint8_t* Data, uint16_t Size){ uint16_t PageRemain = 256 - Address % 256; int32_t Result = 0; if(PageRemain >= Size) { PageRemain = Size; } while(1) { Result = IS25LQ010B_WritRowPage(Address, Data, PageRemain); if(Result != 0) { return -1; } if(Size == PageRemain) { break; } else { Data += PageRemain; Address += PageRemain; Size -= PageRemain; if(Size > 256) { PageRemain = 256; } else { PageRemain = Size; } } } return 0;}/*** @Brief: Write data to flash** @Parameter: 1) Address, flash address 2) Data, write data 3) Size, write data size** @Return: 1) 0, write data to flash successful 2) -1, parameter illegal 3) -2, write enable failed 4) -3, write data to flash failed 5) -4, write data to flash failed**/int32_t IS25LQ010B_WriteRow(uint32_t Address, uint8_t* Data, uint16_t Size){ uint16_t SectorPosition = Address / IS25LQ010B_FLASH_SECTOR_SIZE; uint16_t SectorOffset = Address % IS25LQ010B_FLASH_SECTOR_SIZE; uint16_t SectorRemain = IS25LQ010B_FLASH_SECTOR_SIZE - SectorOffset; uint8_t TempBuffer[IS25LQ010B_FLASH_SECTOR_SIZE] = {0}; int32_t Result = 0; int32_t Index = 0; if(SectorRemain >= Size) { SectorRemain = Size; } while(1) { Result = IS25LQ010B_ReadRow(SectorPosition*IS25LQ010B_FLASH_SECTOR_SIZE, TempBuffer, IS25LQ010B_FLASH_SECTOR_SIZE); if(Result != 0) { return -1; } for(Index = 0; Index < SectorRemain; Index++) { if(TempBuffer[SectorOffset + Index] != 0xFF) { break; } } if(Index < SectorRemain) { Result = IS25LQ010B_SectorErase(SectorPosition); if(Result != 0) { return -2; } memcpy(&TempBuffer[SectorOffset], Data, SectorRemain); Result = IS25LQ010B_WriteRowNoCheck(SectorPosition*IS25LQ010B_FLASH_SECTOR_SIZE, TempBuffer, IS25LQ010B_FLASH_SECTOR_SIZE); if(Result != 0) { return -3; } } else { Result = IS25LQ010B_WriteRowNoCheck(Address, Data, SectorRemain); if(Result != 0) { return -4; } } if(SectorRemain == Size) { break; } else { SectorPosition++; SectorOffset = 0; Data += SectorRemain; Address += SectorRemain; Size -= SectorRemain; if(Size > IS25LQ010B_FLASH_SECTOR_SIZE) { SectorRemain = IS25LQ010B_FLASH_SECTOR_SIZE; } else { SectorRemain = Size; } } } return 0;}/*** @Brief: Read memory data at up to a 104MHZ clock** @Parameter: 1) Address, flash address 2) Data, read data 3) Size, read data size** @Return: 1) -1, parameter illegal 2) -2, command transmit failed 3) -3, receive data failed 4) 0, read data from falsh successful**/int32_t IS25LQ010B_ReadRow(uint32_t Address, uint8_t* Data, uint16_t Size){ uint8_t Command[5] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; if((0 == Size) || ((Address + Size/256 * IS25LQ010B_FLASH_SECTOR_SIZE) > IS25LQ010B_FLASH_SIZE)) { return -1; } Command[CommandSize++] = IRRD; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; Command[CommandSize++] = DUMMY_BYTE; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); memset(Data, 0, Size); return -2; } State = HAL_SPI_Receive(&hspi2, Data, Size, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); memset(Data, 0, Size); return -3; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: The Sector Lock command relocks a sector that was previously unlocked by the Sector Unlock command** @Parameter: None** @Return: 1) -1, command transmit failed 2) 0, operate successful**/int32_t IS25LQ010B_SectorLock(void){ uint8_t Command = SECLOCK; HAL_StatusTypeDef State = HAL_OK; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, &Command, 1, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -1; } IS25LQ010B_NSSDisable(); return 0;}/*** @Brief: Unlock sector** @Parameter: Address, flash address** @Return: 1) -1, parameter illegal 2) -2, command transmit failed 3) 0, operate successful**/int32_t IS25LQ010B_SectorUnlock(uint32_t Address){ uint8_t Command[4] = {0}; uint16_t CommandSize = 0; HAL_StatusTypeDef State = HAL_OK; if(Address > IS25LQ010B_FLASH_SIZE) { return -1; } Command[CommandSize++] = SECUNLOCK; Command[CommandSize++] = (Address >> 16) & 0xFF; Command[CommandSize++] = (Address >> 8) & 0xFF; Command[CommandSize++] = Address & 0xFF; IS25LQ010B_NSSEnable(); State = HAL_SPI_Transmit(&hspi2, Command, CommandSize, SPI2_TIMEOUT); if(State != HAL_OK) { IS25LQ010B_NSSDisable(); return -2; } IS25LQ010B_NSSDisable(); return 0;}
阅读全文
0 0
- STM32之SPI驱动外部Flash
- SST25VF080B SPI接口FLASH STM32驱动
- STM32 SPI对外部FLASH的访问(转载)
- SPI专题(二)——STM32驱动FLASH(W25Q64)
- STM32 SPI Flash DFU
- stm32 SPI-FLASH W25Q64
- spi flash 驱动
- spi flash控制驱动
- SPI FLASH 驱动
- SPI Flash驱动目录
- spi nor flash驱动
- spi flash驱动
- STM32 SPI接口读写SPI flash实验
- stm32 spi flash u盘
- STM32之SPI驱动液晶屏的一个问题
- STM32 SPI驱动TFT LCD
- 【STM32】STM32之flash
- STM32之SPI
- windows、解决管理员权限
- mico 物联网开发平台学习资料
- jQuery显示与隐藏效果
- 语义角色标注
- 修改desktop.ini 自定义文件夹[高级篇]
- STM32之SPI驱动外部Flash
- 分割java字符串,工具类
- leetcode---permutations---dfs
- html禁用文本位11位数为电话号码
- C#.Net中ADO.net数据增删查改操作
- MIB 浏览器的使用指导
- Core Java Volume I 读书笔记---第六章 接口与内部类
- CSS position属性的实际应用
- java的日期的比较