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;}
原创粉丝点击