M25PXX FLASH 驱动程序

FLASH驱动程序,做个备份以后用着方便


//*****************************************************************************
//
//! \file hw_M25Pxx.h
//! \brief header file of Driver for M25Pxx
//! \version V2.1.1.0
//! \date 9/6/2011
//! \author CooCoX
//! \copy
//!
//! Copyright (c)  2011, CooCoX All rights reserved.
//! 
//! Redistribution and use in source and binary forms, with or without 
//! modification, are permitted provided that the following conditions 
//! are met: 
//! 
//!     * Redistributions of source code must retain the above copyright 
//! notice, this list of conditions and the following disclaimer. 
//!     * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution. 
//!     * Neither the name of the <ORGANIZATION> nor the names of its 
//! contributors may be used to endorse or promote products derived 
//! from this software without specific prior written permission. 
//! 
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************



#ifndef __HW_M25PXX_H__
#define __HW_M25PXX_H__

//*****************************************************************************
//
//! \addtogroup CoX_Driver_Lib 
//! @{
//! \addtogroup Memory
//! @{
//! \addtogroup SPI_Flash
//! @{
//! \addtogroup M25Pxx
//! @{
//! \addtogroup M25Pxx_Driver_Single
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! \addtogroup M25Pxx_CMD
//! M25Pxx SPI Flash CMD.
//! @{
//
//*****************************************************************************
  
//
//! Write Enable 
//
#define M25Pxx_CMD_WREN         0x06     
   
//
//! Write Disable
// 
#define M25Pxx_CMD_WRDI         0x04     
     
//
//! Read Identification 
// 
#define M25Pxx_CMD_RDID         0x9F     
       
//
//! Read Status Register 
// 
#define M25Pxx_CMD_RDSR         0x05     
         
//
//! Write Status Register 
// 
#define M25Pxx_CMD_WRSR         0x01     
           
//
//! Read Data Bytes 
// 
#define M25Pxx_CMD_READ         0x03     
             
//
//! Read Data Bytes at Higher Speed 
// 
#define M25Pxx_CMD_FAST_READ    0x0B     
               
//
//! Page Program 
// 
#define M25Pxx_CMD_PP           0x02     
                 
//
//! Sector Erase
// 
#define M25Pxx_CMD_SE           0xD8    
                   
//
//! Bulk Erase
// 
#define M25Pxx_CMD_BE           0xC7     
                     
//
//! Read Electronic Signature
// 
#define M25Pxx_CMD_RES          0xAB     
  

//*****************************************************************************
//
//! @}
//
//*****************************************************************************    

//*****************************************************************************
//
//! \addtogroup M25Pxx_Attribute
//! M25Pxx SPI Flash attribute.
//! @{
//
//*****************************************************************************

//
//! M25P10 SIZE
//
#define M25P10_PAGE_SIZE        256UL
#define M25P10_PAGES_PER_SECTORS                                              \
                                256UL
#define M25P10_SECTORS          2UL
#define M25P10_PAGES            (M25P10_SECTORS * M25P10_PAGES_PER_SECTORS)
#define M25P10_SIZE             (M25P10_SECTORS * M25P10_PAGES_PER_SECTORS *  \
                                M25P10_PAGE_SIZE)
//
//! M25P20 SIZE
//
#define M25P20_PAGE_SIZE        256UL
#define M25P20_PAGES_PER_SECTORS                                              \
                                256UL
#define M25P20_SECTORS          4UL
#define M25P20_PAGES            (M25P20_SECTORS * M25P20_PAGES_PER_SECTORS)
#define M25P20_SIZE             (M25P20_SECTORS * M25P20_PAGES_PER_SECTORS *  \
                                M25P20_PAGE_SIZE)

//
//! M25P40 SIZE
//
#define M25P40_PAGE_SIZE        256UL
#define M25P40_PAGES_PER_SECTORS                                              \
                                256UL
#define M25P40_SECTORS          8UL
#define M25P40_PAGES            (M25P40_SECTORS * M25P40_PAGES_PER_SECTORS)
#define M25P40_SIZE             (M25P40_SECTORS * M25P40_PAGES_PER_SECTORS *  \
                                M25P40_PAGE_SIZE)

//
//! M25P80 SIZE
//
#define M25P80_PAGE_SIZE        256UL
#define M25P80_PAGES_PER_SECTORS                                              \
                                256UL
#define M25P80_SECTORS          16UL
#define M25P80_PAGES            (M25P80_SECTORS * M25P80_PAGES_PER_SECTORS)
#define M25P80_SIZE             (M25P80_SECTORS * M25P80_PAGES_PER_SECTORS *  \
                                M25P80_PAGE_SIZE)

//
//! M25P16 SIZE
//
#define M25P16_PAGE_SIZE        256UL
#define M25P16_PAGES_PER_SECTORS                                              \
                                256UL
#define M25P16_SECTORS          32UL
#define M25P16_PAGES            (M25P16_SECTORS * M25P16_PAGES_PER_SECTORS)
#define M25P16_SIZE             (M25P16_SECTORS * M25P16_PAGES_PER_SECTORS *  \
                                M25P16_PAGE_SIZE)

//
//! M25P32 SIZE
//
#define M25P32_PAGE_SIZE        256UL
#define M25P32_PAGES_PER_SECTORS                                              \
                                256UL
#define M25P32_SECTORS          64UL
#define M25P32_PAGES            (M25P32_SECTORS * M25P32_PAGES_PER_SECTORS)
#define M25P32_SIZE             (M25P32_SECTORS * M25P32_PAGES_PER_SECTORS *  \
                                M25P32_PAGE_SIZE)

//
//! M25P64 SIZE
//
#define M25P64_PAGE_SIZE        256UL
#define M25P64_PAGES_PER_SECTORS                                              \
                                256UL
#define M25P64_SECTORS          128UL
#define M25P64_PAGES            (M25P64_SECTORS * M25P64_PAGES_PER_SECTORS)       
#define M25P64_SIZE             (M25P64_SECTORS * M25P64_PAGES_PER_SECTORS *  \
                                M25P64_PAGE_SIZE)

//
//! M25P128 SIZE
//
#define M25P128_PAGE_SIZE       256UL
#define M25P128_PAGES_PER_SECTORS                                             \
                                256UL
#define M25P128_SECTORS         256UL
#define M25P128_PAGES           (M25P128_SECTORS * M25P128_PAGES_PER_SECTORS)
#define M25P128_SIZE            (M25P128_SECTORS * M25P128_PAGES_PER_SECTORS  \
                                * M25P128_PAGE_SIZE)

#define M25P10                    0
#define M25P20                    1
#define M25P40                    2
#define M25P80                    3
#define M25P16                    4
#define M25P32                    5
#define M25P64                    6
#define M25P128                   7

//*****************************************************************************
//
//! @}
//
//*****************************************************************************    

//*****************************************************************************
//
//! @}
//! @}
//! @}
//! @}
//! @}
//
//*****************************************************************************      



#endif // __HW_M25PXX_H__


//*****************************************************************************
//
//! \file M25Pxx.c
//! \brief the M25Pxx Driver.
//! \version V2.1.1.0
//! \date 9/1/2011
//! \author CooCox
//! \copy
//!
//! Copyright (c)  2011, CooCox 
//! All rights reserved.
//! 
//! Redistribution and use in source and binary forms, with or without 
//! modification, are permitted provided that the following conditions 
//! are met: 
//! 
//!     * Redistributions of source code must retain the above copyright 
//! notice, this list of conditions and the following disclaimer. 
//!     * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution. 
//!     * Neither the name of the <ORGANIZATION> nor the names of its 
//! contributors may be used to endorse or promote products derived 
//! from this software without specific prior written permission. 
//! 
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
//! THE POSSIBILITY OF SUCH DAMAGE.
//*****************************************************************************
#include "xhw_types.h"
#include "xsysctl.h"
#include "xdebug.h"
#include "xhw_memmap.h"
#include "xspi.h"
#include "Xhw_spi.h"
#include "xgpio.h"
#include "M25Pxx.h"
#include "hw_M25Pxx.h"

#if (M25Pxx_Device == M25P10)
#define M25Pxx_MAX_CLOCK        20000000

#define M25PxxPAGE_SIZE         M25P10_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P10_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P10_SECTORS
#define M25Pxx_PAGES            M25P10_PAGES
#define M25Pxx_SIZE             M25P10_SIZE

#elif (M25Pxx_Device == M25P20)
#define M25Pxx_MAX_CLOCK        25000000

#define M25PxxPAGE_SIZE         M25P20_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P20_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P20_SECTORS
#define M25Pxx_PAGES            M25P20_PAGES
#define M25Pxx_SIZE             M25P20_SIZE

#elif (M25Pxx_Device == M25P40)

#define M25Pxx_MAX_CLOCK        25000000

#define M25PxxPAGE_SIZE         M25P40_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P40_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P40_SECTORS
#define M25Pxx_PAGES            M25P40_PAGES
#define M25Pxx_SIZE             M25P40_SIZE

#elif (M25Pxx_Device == M25P80)

#define M25Pxx_MAX_CLOCK        25000000

#define M25PxxPAGE_SIZE         M25P80_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P80_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P80_SECTORS
#define M25Pxx_PAGES            M25P80_PAGES
#define M25Pxx_SIZE             M25P80_SIZE

#elif (M25Pxx_Device == M25P16)

#define M25Pxx_MAX_CLOCK        50000000

#define M25PxxPAGE_SIZE         M25P16_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P16_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P16_SECTORS
#define M25Pxx_PAGES            M25P16_PAGES
#define M25Pxx_SIZE             M25P16_SIZE

#elif (M25Pxx_Device == M25P32)

#define M25Pxx_MAX_CLOCK        50000000

#define M25PxxPAGE_SIZE         M25P32_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P32_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P32_SECTORS
#define M25Pxx_PAGES            M25P32_PAGES
#define M25Pxx_SIZE             M25P32_SIZE

#elif (M25Pxx_Device == M25P64)

#define M25Pxx_MAX_CLOCK        50000000

#define M25PxxPAGE_SIZE         M25P64_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P64_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P64_SECTORS
#define M25Pxx_PAGES            M25P64_PAGES
#define M25Pxx_SIZE             M25P64_SIZE

#elif (M25Pxx_Device == M25P128)

#define M25Pxx_MAX_CLOCK        50000000

#define M25PxxPAGE_SIZE         M25P128_PAGE_SIZE
#define M25PxxPAGES_PER_SECTORS M25P128_PAGES_PER_SECTORS
#define M25Pxx_SECTORS          M25P128_SECTORS
#define M25Pxx_PAGES            M25P128_PAGES
#define M25Pxx_SIZE             M25P128_SIZE

#endif


//*****************************************************************************
//
//! \brief Initialize M25Pxx and SPI  
//!
//! \param ulClock specifies the SPI Clock Rate
//!
//! This function initialize the mcu SPI as master and specified SPI port.Set 
//! PD0->CS PD1->CLK PD2->MISO and PD3->MOSI,most of all it check the first
//! convert is finished or not in order to execute the following operation
//! 
//! \return None.
//
//*****************************************************************************
void M25PxxInit(unsigned long ulSpiClock)
{
    //
    // The max clock rate of M25Pxx is 20M to 50M Hz acoording to Datasheet
    //
    xASSERT((ulSpiClock > 0) && (ulSpiClock < M25Pxx_MAX_CLOCK));
    //
    // Enable the GPIOx port which is connected with M25Pxx 
    //
    xSysCtlPeripheralEnable(xGPIOSPinToPeripheralId(FLASH_PIN_SPI_CLK));
    xSysCtlPeripheralEnable(xGPIOSPinToPeripheralId(FLASH_PIN_SPI_CS));
    xSysCtlPeripheralEnable(xGPIOSPinToPeripheralId(FLASH_PIN_SPI_MISO));
    xSysCtlPeripheralEnable(xGPIOSPinToPeripheralId(FLASH_PIN_SPI_MOSI));
    //
    // Enable the SPIx which is connected with M25Pxx
    //
    xSysCtlPeripheralEnable2(FLASH_PIN_SPI_PORT);
    //
    // Set GPIOD0 as a chip select pin and set it as OUT_MODE
    //
    xGPIOSPinDirModeSet(FLASH_PIN_SPI_CS, xGPIO_DIR_MODE_OUT);
    
#if (M25Pxx_HOLD > 0)
    xGPIOSPinDirModeSet(FLASH_PIN_HOLD, xGPIO_DIR_MODE_OUT);
    xGPIOSPinWrite(FLASH_PIN_HOLD, 1);
#endif
 
#if (M25Pxx_WRITE_PROTECT > 0)
    xGPIOSPinDirModeSet(FLASH_PIN_WRITE_PROTECT, xGPIO_DIR_MODE_OUT);
    xGPIOSPinWrite(FLASH_PIN_WRITE_PROTECT, 1);
#endif
     
    //
    // PD1 as SPI2.CLK
    //
    xSPinTypeSPI(SPI_CLK, FLASH_PIN_SPI_CLK);
    //
    // PD2 as SPI2.MISO
    // MISO20 => SPI0MISO
    //
    xSPinTypeSPI(SPI_MISO, FLASH_PIN_SPI_MISO);
    //
    // PD3 as SPI2.MOSI
    // MOSI20 => SPI0MISO
    //
    xSPinTypeSPI(SPI_MOSI, FLASH_PIN_SPI_MOSI); 
    //
    // Configure MCU as a master device , 16 bits data width ,MSB first,Mode_0
    //
    xSPIConfigSet(FLASH_PIN_SPI_PORT, ulSpiClock, xSPI_MOTO_FORMAT_MODE_0 |
                                                  xSPI_MODE_MASTER | 
                                                  xSPI_MSB_FIRST |
                                                  xSPI_DATA_WIDTH8);
    //
    // Disable M25Pxx when Power up
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
	
	
}

//*****************************************************************************
//
//! \brief Read M25Pxx ID
//! 
//! \param None
//!
//! This function is to Read ID
//! 
//! \return M25Pxx ID in Hexadecimal
//
//*****************************************************************************
unsigned long M25PxxIDcodeGet(void)
{
    unsigned long ulIDcode;
    unsigned char ucInstruction;
    unsigned char ucManuID;
    unsigned char ucHighDeviID;
    unsigned char ucLowDeviID;
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer intruction of "get ID"
    //
    ucInstruction = M25Pxx_CMD_RDID;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucInstruction, 1);
    
    //
    // Get Manufacture ID
    //
    xSPIDataRead(FLASH_PIN_SPI_PORT, &ucManuID, 1);
    //
    // Get Devidce ID
    //
    xSPIDataRead(FLASH_PIN_SPI_PORT, &ucHighDeviID, 1);
    xSPIDataRead(FLASH_PIN_SPI_PORT, &ucLowDeviID, 1);
    xSPIDataRead(FLASH_PIN_SPI_PORT, &ucLowDeviID, 1);
    //
    //Step 3 Disable chip select
    //    
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);

    ulIDcode = ucManuID << 16;
    ulIDcode |= ucHighDeviID << 8;
    ulIDcode |= ucLowDeviID;
    return ulIDcode;
}

//*****************************************************************************
//
//! \brief Read M25Pxx Status Register
//! 
//! \param None
//!
//! This function is to Read M25Pxx Status Register:the bit field follows:
//! BIT7  6   5   4   3   2   1   0 
//!SRWD  0   0  BP2 BP1 BP0 WEL WIP 
//! 
//! \return the value of status
//!
//*****************************************************************************
unsigned char M25PxxStatusRegRead(void)    
{   
    unsigned char ucStatus=0;
    unsigned char ucCommand;
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer the command Read Status Register 
    //
    ucCommand = M25Pxx_CMD_RDSR;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 3 Read status Register
    //
    xSPIDataRead(FLASH_PIN_SPI_PORT, &ucStatus, 1);
    //
    //Step 4 Disable chip select 
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    
    return ucStatus;    
}

//*****************************************************************************
//
//! \brief Wait for M25Pxx is not busy
//! 
//! \param None
//!
//! This function is to Wait for M25Pxx is not busy
//! 
//! \return None
//
//*****************************************************************************
void M25PxxWaitNotBusy(void)    
{    
    //
    //Wait the bit of busy is clear
    //
    while((M25PxxStatusRegRead() & 0x01) == 0x01); 
}
//*****************************************************************************
//
//! \brief M25Pxx write enable
//! 
//! \param None
//!
//! This function is to enable the function 0f writing
//! 
//! \return none
//
//*****************************************************************************
void M25PxxWriteEnable(void)
{
    unsigned char ucCommand;
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer the command Write Enable
    // 
    ucCommand = M25Pxx_CMD_WREN;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 3 Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
}

//*****************************************************************************
//
//! \brief M25Pxx write disable
//! 
//! \param None
//!
//! This function is to disable the function 0f writing
//! 
//! \return none
//
//*****************************************************************************
void M25PxxWriteDisable(void)
{
    unsigned char ucCommand;
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer the command Write Disable
    // 
    ucCommand = M25Pxx_CMD_WRDI;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 3 Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
}

//*****************************************************************************
//
//! \brief  write a page(1~256byte) data to M25Pxx
//!
//! \param ucBuffer specifies the location data which will be .
//! \param ulWriteAddr specifies the address which data will be written 
//! \param usNumByteToWrite specifies the length of data will be write.
//!
//! This function is to write a page(1~256byte) data to M25Pxx, The appointed
//! byte length data will be writen in appointed address.
//!
//! \return None
//!  
//*****************************************************************************
void M25PxxPageWrite(unsigned char* ucBuffer, unsigned long  ulWriteAddr,
                     unsigned short usNumByteToWrite)
{
    unsigned char ucCommand; 
    unsigned char ucAddr;
    xASSERT((usNumByteToWrite > 0) && (usNumByteToWrite <= 256));
    //
    //Step 1 Set write enable
    //
    M25PxxWriteEnable();
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 2  Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 3 Transfer the command page program
    // 
    ucCommand = M25Pxx_CMD_PP;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 4 Transfer the address(24bit) which data will be written
    //
    ucAddr = (unsigned char)(ulWriteAddr >> 16);
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucAddr, 1);
    ucAddr = (unsigned char)(ulWriteAddr >> 8);
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucAddr, 1);
    ucAddr = (unsigned char)(ulWriteAddr);
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucAddr, 1);
    //
    //Step 5 Write Data
    //

    xSPIDataWrite(FLASH_PIN_SPI_PORT, ucBuffer, usNumByteToWrite); 

    //
    //Step 6  Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 7  wait for the operation is over
    //
    M25PxxWaitNotBusy();       
}

//*****************************************************************************
//
//! \brief  Writes more than one byte to the FLASH M25Pxx
//!
//! \param ucBuffer specifies the location data which will be .
//! \param ulWriteAddr specifies the address which data will be written 
//! \param usNumByteToWrite specifies the length of data will be write.
//!
//! This function is to Writes more than one byte to the FLASH M25Pxx, The 
//! appointed byte length data will be writen in appointed address.
//!
//! \return None
//!  
//*****************************************************************************
void M25PxxWrite(unsigned char* pucBuffer, unsigned long  ulWriteAddr,
                 unsigned short usNumByteToWrite)
{
    const unsigned char *pucWriteBuf;
    unsigned short usFirstSize, usLastSize, usPageNum, i;
    unsigned long ulWriteAdrTemp;

    usFirstSize = ulWriteAddr % M25PxxPAGE_SIZE;

    ulWriteAdrTemp = ulWriteAddr - usFirstSize;
    usFirstSize = M25PxxPAGE_SIZE - usFirstSize;
    pucWriteBuf = pucBuffer;

    if(usFirstSize < usNumByteToWrite) 
    {
        usPageNum  = (usNumByteToWrite - usFirstSize) / M25PxxPAGE_SIZE;
        usLastSize = (usNumByteToWrite - usFirstSize) % M25PxxPAGE_SIZE;
    } 
    else 
    {
        usFirstSize = usNumByteToWrite;
        usPageNum = 0;
    }
    
    //
    //Write First Page
    //
    if(usFirstSize != 0)
    {
        M25PxxPageWrite (pucBuffer, ulWriteAddr, usFirstSize);
        ulWriteAdrTemp += M25PxxPAGE_SIZE;
        pucWriteBuf += usFirstSize;

        M25PxxWaitNotBusy();
    }

    for(i=0; i<usPageNum; i++) 
    {
        M25PxxPageWrite (pucBuffer, ulWriteAddr, M25PxxPAGE_SIZE);
        ulWriteAdrTemp += M25PxxPAGE_SIZE;
        pucWriteBuf += M25PxxPAGE_SIZE;

        M25PxxWaitNotBusy();
    }
    
    //
    //Write Last Page
    //
    if(usLastSize) 
    {
        M25PxxPageWrite(pucBuffer, ulWriteAddr, usLastSize);
    }

    return;
}

//*****************************************************************************
//
//! \brief  Read data from M25Pxx
//!
//! \param ucBuffer specifies the location data which will be store.
//! \param ulWriteAddr specifies the address which data will be read 
//! \param usNumByteToWrite specifies the length of data will be read.
//!
//! This function is to read data from M25Pxx, The appointed byte length data will
//! be read in appointed address.
//!
//! \return None
//!  
//*****************************************************************************
void M25PxxDataRead(unsigned char* ucBuffer, unsigned long  ulReadAddr,
                    unsigned long ulNumByteToRead)
{
    unsigned char ucCommand; 
    unsigned char ucAddrBuffer[3];
    ucAddrBuffer[0] = (unsigned char)(ulReadAddr >> 16);
    ucAddrBuffer[1] = (unsigned char)(ulReadAddr >> 8);
    ucAddrBuffer[2] = (unsigned char)(ulReadAddr >> 0);
//    xASSERT((usNumByteToRead > 0) && (usNumByteToRead <= 2097152));
    
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1  Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer the command page program
    // 
    ucCommand = M25Pxx_CMD_READ;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 3 Transfer the address(24bit) which data will be read
    //
    xSPIDataWrite(FLASH_PIN_SPI_PORT, ucAddrBuffer, 3);
    //
    //Step 4 read Data
    //

    xSPIDataRead(FLASH_PIN_SPI_PORT, ucBuffer, ulNumByteToRead); 

    //
    //Step 5  Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1); 
}

//*****************************************************************************
//
//! \brief  Read data from M25Pxx at Higher Speed
//!
//! \param ucBuffer specifies the location data which will be store.
//! \param ulWriteAddr specifies the address which data will be read 
//! \param usNumByteToWrite specifies the length of data will be read.
//!
//! This function is to read data from M25Pxx, The appointed byte length data will
//! be read in appointed address.
//!
//! \return None
//!  
//*****************************************************************************
void M25PxxDataFastRead(unsigned char* ucBuffer, unsigned long  ulReadAddr,
                        unsigned long ulNumByteToRead)
{
    unsigned char ucCommand; 
    unsigned char ucDummy; 
    unsigned char ucAddrBuffer[3];
    ucAddrBuffer[0] = (unsigned char)(ulReadAddr >> 16);
    ucAddrBuffer[1] = (unsigned char)(ulReadAddr >> 8);
    ucAddrBuffer[2] = (unsigned char)(ulReadAddr >> 0);
//    xASSERT((usNumByteToRead > 0) && (usNumByteToRead <= 2097152));
    
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1  Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer the command page program
    // 
    ucCommand = M25Pxx_CMD_READ;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 3 Transfer the address(24bit) which data will be read
    //
    xSPIDataWrite(FLASH_PIN_SPI_PORT, ucAddrBuffer, 3);
    
    //
    //Step 3 Write Dummy Byte
    //
    ucDummy = 0xFF;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucDummy, 1); 
    //
    //Step 4 read Data
    //
    xSPIDataRead(FLASH_PIN_SPI_PORT, ucBuffer, ulNumByteToRead); 

    //
    //Step 3  Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1); 
}

//*****************************************************************************
//
//! \brief Erase all chip
//! 
//! \param None
//!
//! This function is to Erase all chip
//! 
//! \return none
//
//*****************************************************************************
void M25PxxChipErase(void)
{
    unsigned char ucCommand;
    //
    //Step 1 Set write enable
    //
    M25PxxWriteEnable();
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 2 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 3 Transfer the command Chip Erase
    // 
    ucCommand = M25Pxx_CMD_BE;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 4 Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 5  wait for the operation is over
    //
    M25PxxWaitNotBusy(); 
}

//*****************************************************************************
//
//! \brief Erase a sector
//! 
//! \param ulDstAddr specifies the sector address which will be erased.and for
//! W25X16,it must be smaller than 512
//! This function is to Erase a sector
//! 
//! \return none
//
//*****************************************************************************
void M25PxxSectorErase(unsigned long ulDstAddr)
{
    unsigned char ucCommand;
    unsigned char ucAddrBuffer[3];
    ulDstAddr = ulDstAddr * 4096;
    ucAddrBuffer[0] = (unsigned char)(ulDstAddr >> 16);
    ucAddrBuffer[1] = (unsigned char)(ulDstAddr >> 8);
    ucAddrBuffer[2] = (unsigned char)(ulDstAddr >> 0);
    //
    //Step 1 Set write enable
    //
    M25PxxWriteEnable();
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 2 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 3 Transfer the command Sector Erase
    // 
    ucCommand = M25Pxx_CMD_SE;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 4 Transfer the address which will be erased
    //
    xSPIDataWrite(FLASH_PIN_SPI_PORT, ucAddrBuffer, 3);
    //
    //Step 5 Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 6  wait for the operation is over
    //
    M25PxxWaitNotBusy(); 
}

//*****************************************************************************
//
//! \brief M25Pxx write status register
//! 
//! \param ulDstAddr specifies the status value which will be writen
//!
//! This function is to write status value to status register
//! 
//! \return none
//
//*****************************************************************************
void M25PxxStatusRegWrite(unsigned char ucStatusVal)
{
    unsigned char ucCommand;
    unsigned char ucStatus;
    ucStatus = ucStatusVal;
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer the command Write Status Value
    // 
    ucCommand = M25Pxx_CMD_WRSR;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucCommand, 1);
    //
    //Step 3 Write your status value that you need
    //
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucStatus, 1);
    //
    //Step 4 Disable chip select
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
}

//*****************************************************************************
//
//! \brief Disable M25Pxx 
//!
//! \param None
//!
//! This function is to Disable M25Pxx
//! 
//! \return None.
//
//*****************************************************************************
void M25PxxDisable(void)
{
    //xSysCtlPeripheralDisable(FLASH_PIN_SPI_PORT);
}

//*****************************************************************************
//
//! \brief Read M25Pxx Electronic Signature
//! 
//! \param None
//!
//! This function is to Read Electronic Signature
//! 
//! \return M25Pxx Electronic Signature in Hexadecimal
//
//*****************************************************************************
unsigned short M25PxxEScodeGet(void)
{
    unsigned char usEScode;
    unsigned char usDummy;
    unsigned char ucInstruction;

    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    //
    //Step 1 Select Chip
    //
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 0);
    //
    //Step 2 Transfer intruction of "get ID"
    //
    ucInstruction = M25Pxx_CMD_RES;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &ucInstruction, 1);
    //
    //Step 3 Transfer 3 Dummy Bytes
    //
    usDummy = 0xFF;
    xSPIDataWrite(FLASH_PIN_SPI_PORT, &usDummy, 3);
    //
    // Get Electronic Signature 
    //
    xSPIDataRead(FLASH_PIN_SPI_PORT, &usEScode, 1);
    
    //
    //Step 4 Disable chip select
    //    
    xGPIOSPinWrite(FLASH_PIN_SPI_CS, 1);
    return usEScode;
}

//*****************************************************************************
//
//! \brief Get M25Pxx Page Size
//! 
//! \param None
//!
//! This function is to get M25Pxx Page Size
//! 
//! \return M25Pxx Page Size
//
//*****************************************************************************
unsigned long M25PxxPageSizeGet(void)
{
    return M25PxxPAGE_SIZE;
}

//*****************************************************************************
//
//! \brief Get M25Pxx Sector Size
//! 
//! \param None
//!
//! This function is to get M25Pxx Sector Size
//! 
//! \return M25Pxx Sector Size
//
//*****************************************************************************
unsigned long M25PxxSectorSizeGet(void)
{
    return (M25PxxPAGE_SIZE * M25PxxPAGES_PER_SECTORS);
}

//*****************************************************************************
//
//! \brief Get M25Pxx Chip Size
//! 
//! \param None
//!
//! This function is to get M25Pxx Chip Size
//! 
//! \return M25Pxx Chip Size
//
//*****************************************************************************
unsigned long M25PxxChipSizeGet(void)
{
    return M25Pxx_SIZE;
}

#if (M25Pxx_HOLD > 0)

//*****************************************************************************
//
//! \brief Enable M25Pxx hold input
//! 
//! \param None
//!
//! This function is to enable M25Pxx hold input.
//! 
//! \return None.
//
//*****************************************************************************
void M25PxxHoldEnable(void)
{
    xGPIOSPinWrite(FLASH_PIN_HOLD, 0);
}

//*****************************************************************************
//
//! \brief Disable M25Pxx hold input
//! 
//! \param None
//!
//! This function is to disable M25Pxx hold input.
//! 
//! \return None.
//
//*****************************************************************************
void M25PxxHoldDisable(void)
{
    xGPIOSPinWrite(FLASH_PIN_HOLD, 1);
}
#endif
 
#if (M25Pxx_WRITE_PROTECT > 0)

//*****************************************************************************
//
//! \brief Enable M25Pxx write protect .
//! 
//! \param None
//!
//! This function is to enable M25Pxx write protect .
//! 
//! \return None.
//
//*****************************************************************************
void M25PxxWriteProtectEnable(void)
{
    xGPIOSPinWrite(FLASH_PIN_WRITE_PROTECT, 0);
}

//*****************************************************************************
//
//! \brief Disable M25Pxx write protect .
//! 
//! \param None
//!
//! This function is to disable M25Pxx write protect .
//! 
//! \return None.
//
//*****************************************************************************
void M25PxxWriteProtectDisable(void)
{
    xGPIOSPinWrite(FLASH_PIN_WRITE_PROTECT, 1);
}
#endif


//*****************************************************************************
//
//! \file M25Pxx.h
//! \brief Prototypes for the M25Pxx Driver.
//! \version V2.1.1.0
//! \date 9/22/2011
//! \author CooCoX
//! \copy
//!
//! Copyright (c)  2011, CooCoX 
//! All rights reserved.
//! 
//! Redistribution and use in source and binary forms, with or without 
//! modification, are permitted provided that the following conditions 
//! are met: 
//! 
//!     * Redistributions of source code must retain the above copyright 
//! notice, this list of conditions and the following disclaimer. 
//!     * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution. 
//!     * Neither the name of the <ORGANIZATION> nor the names of its 
//! contributors may be used to endorse or promote products derived 
//! from this software without specific prior written permission. 
//! 
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
//! THE POSSIBILITY OF SUCH DAMAGE.
//!
//*****************************************************************************
#ifndef __M25PXX_H__
#define __M25PXX_H__

//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! \addtogroup CoX_Driver_Lib
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! \addtogroup Memory
//! @{
//
//*****************************************************************************
  
//*****************************************************************************
//
//! \addtogroup SPI_Flash
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! \addtogroup M25Pxx
//! @{
//
//*****************************************************************************
//*****************************************************************************

//*****************************************************************************
//! \addtogroup M25Pxx_Driver_Single
//! @{
//
//*****************************************************************************
  
//*****************************************************************************
//! \addtogroup M25Pxx_User_Config
//! @{
//
//*****************************************************************************
  
//
//! User write protect config,it can be 0 or 1
//
#define M25Pxx_WRITE_PROTECT    0 
  
//
//! User hold input config,it can be 0 or 1
//
#define M25Pxx_HOLD             0 

//
//! User device config,it can only be M25P10 M25P20 M25P40 M25P80 M25P16 M25P32
//! M25P64 M25P128
// 
#define M25Pxx_Device           M25P64 
  
//*****************************************************************************
//
//! @}
//
//*****************************************************************************

//*****************************************************************************
//! \addtogroup M25Pxx_Hardware_Config
//! @{
//
//*****************************************************************************

//
//! Define SPIx as a port connecting M25Pxx which can be configured
//
#define FLASH_PIN_SPI_CLK       PC9
#define SPI_CLK                 SPI1CLK  
#define FLASH_PIN_SPI_MISO      PC10
#define SPI_MISO                SPI1MISO
#define FLASH_PIN_SPI_MOSI      PC11
#define SPI_MOSI                SPI1MOSI
#define FLASH_PIN_SPI_PORT      SPI1_BASE
  
//
//! Configure GPIOC.0 as chip Select
//
#define FLASH_PIN_SPI_CS        PC8

#if (M25Pxx_HOLD > 0)
//
//! Configure GPIOA.1 as hold in
//
#define FLASH_PIN_HOLD          PA1
  
#endif
 

#if (M25Pxx_WRITE_PROTECT > 0)
//
//! Configure GPIOA.2 as hold in
//
#define FLASH_PIN_WRITE_PROTECT PA2 
  
#endif
  
//*****************************************************************************
//
//! @}
//
//*****************************************************************************
  
//*****************************************************************************
//
//! \addtogroup CoX_M25Pxx_Exported_APIs
//! @{
//
//*****************************************************************************
extern void M25PxxInit(unsigned long ulSpiClock);
extern unsigned long M25PxxIDcodeGet(void);
extern unsigned char M25PxxStatusRegRead(void);
extern void M25PxxWaitNotBusy(void);
extern void M25PxxWriteEnable(void);
extern void M25PxxWriteDisable(void);
extern void M25PxxPageWrite(unsigned char* ucBuffer, unsigned long ulWriteAddr,
                            unsigned short usNumByteToWrite);
extern void M25PxxWrite(unsigned char* pucBuffer, unsigned long  ulWriteAddr,
                        unsigned short usNumByteToWrite);
extern void M25PxxDataRead(unsigned char* ucBuffer, unsigned long ulReadAddr,
                           unsigned long ulNumByteToRead);
extern void M25PxxDataFastRead(unsigned char* ucBuffer, unsigned long ulReadAddr,
                               unsigned long ulNumByteToRead);
extern void M25PxxChipErase(void);
extern void M25PxxSectorErase(unsigned long ulDstAddr);
extern void M25PxxStatusRegWrite(unsigned char ucStatusVal);
extern void M25PxxDisable(void);
extern unsigned short M25PxxEScodeGet(void);
extern unsigned long M25PxxPageSizeGet(void);
extern unsigned long M25PxxSectorSizeGet(void);
extern unsigned long M25PxxChipSizeGet(void);

#if (M25Pxx_HOLD > 0)
extern void M25PxxHoldEnable(void);
extern void M25PxxHoldDisable(void);  
#endif
 
#if (M25Pxx_WRITE_PROTECT > 0)
extern void M25PxxWriteProtectEnable(void);
extern void M25PxxWriteProtectDisable(void);   
#endif


//*****************************************************************************
//
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
//! Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif

#endif //__M25PXX_H__


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值