324 lines
9.9 KiB
C
324 lines
9.9 KiB
C
/**
|
|
******************************************************************************
|
|
* @file stm3210e_eval_serialflash.c
|
|
* @author MCD Application Team
|
|
* @version V7.0.0
|
|
* @date 14-April-2017
|
|
* @brief This file provides a set of functions needed to manage the SPI M25Pxx
|
|
* FLASH memory mounted on STM3210E_EVAL board.
|
|
* It implements a high level communication layer for read and write
|
|
* from/to this memory. The needed STM32 hardware resources (SPI and
|
|
* GPIO) are defined in stm3210e_eval.h file, and the initialization is
|
|
* performed in FLASH_SPI_IO_Init() function declared in stm3210e_eval.c
|
|
* file.
|
|
* You can easily tailor this driver to any other development board,
|
|
* by just adapting the defines for hardware resources and
|
|
* FLASH_SPI_IO_Init() function.
|
|
*
|
|
* +---------------------------------------------------------------------+
|
|
* | Pin assignment |
|
|
* +---------------------------------------+---------------+-------------+
|
|
* | STM32 SPI Pins | BSP_FLASH | Pin |
|
|
* +---------------------------------------+---------------+-------------+
|
|
* | BSP_SERIAL_FLASH_CS_PIN | ChipSelect(/S)| 1 |
|
|
* | BSP_SERIAL_FLASH_SPI_MISO_PIN / MISO | DataOut(Q) | 2 |
|
|
* | | VCC | 3 (3.3 V)|
|
|
* | | GND | 4 (0 V) |
|
|
* | BSP_SERIAL_FLASH_SPI_MOSI_PIN / MOSI | DataIn(D) | 5 |
|
|
* | BSP_SERIAL_FLASH_SPI_SCK_PIN / SCLK | Clock(C) | 6 |
|
|
* | | VCC | 7 (3.3 V)|
|
|
* | | VCC | 8 (3.3 V)|
|
|
* +---------------------------------------+---------------+-------------+
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2016 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "stm3210e_eval_serialflash.h"
|
|
|
|
/** @addtogroup BSP
|
|
* @{
|
|
*/
|
|
|
|
/** @addtogroup STM3210E_EVAL
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup STM3210E_EVAL_SERIAL_FLASH STM3210E EVAL Serial FLASH
|
|
* @brief This file includes the M25Pxxx SPI FLASH driver of
|
|
* STM3210E-EVAL board.
|
|
* @{
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup STM3210E_EVAL_SERIAL_FLASH_Exported_Functions STM3210E EVAL SERIAL FLASH Exported Functions
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Initializes peripherals used by the Serial FLASH device.
|
|
* @retval FLASH_OK (0x00) if operation is correctly performed, else
|
|
* return FLASH_ERROR (0x01).
|
|
*/
|
|
uint8_t BSP_SERIAL_FLASH_Init(void)
|
|
{
|
|
if(FLASH_SPI_IO_Init() != HAL_OK)
|
|
{
|
|
return FLASH_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return FLASH_OK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Erases the specified FLASH sector.
|
|
* @param SectorAddr: address of the sector to erase.
|
|
* @retval FLASH_OK (0x00) if operation is correctly performed, else
|
|
* return FLASH_ERROR (0x01).
|
|
*/
|
|
uint8_t BSP_SERIAL_FLASH_EraseSector(uint32_t SectorAddr)
|
|
{
|
|
/*!< Sector Erase */
|
|
/*!< Select the FLASH and send "Write Enable" instruction */
|
|
FLASH_SPI_IO_WriteEnable();
|
|
|
|
/*!< Send Sector Erase instruction */
|
|
FLASH_SPI_IO_WriteByte(FLASH_SPI_CMD_SE);
|
|
/*!< Send SectorAddr high nibble address byte */
|
|
FLASH_SPI_IO_WriteByte((SectorAddr & 0xFF0000) >> 16);
|
|
/*!< Send SectorAddr medium nibble address byte */
|
|
FLASH_SPI_IO_WriteByte((SectorAddr & 0xFF00) >> 8);
|
|
/*!< Send SectorAddr low nibble address byte */
|
|
FLASH_SPI_IO_WriteByte(SectorAddr & 0xFF);
|
|
|
|
/*!< Wait the end of Flash writing and Deselect the FLASH*/
|
|
if(FLASH_SPI_IO_WaitForWriteEnd()!= HAL_OK)
|
|
{
|
|
return FLASH_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return FLASH_OK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Erases the entire FLASH.
|
|
* @retval FLASH_OK (0x00) if operation is correctly performed, else
|
|
* return FLASH_ERROR (0x01).
|
|
*/
|
|
uint8_t BSP_SERIAL_FLASH_EraseBulk(void)
|
|
{
|
|
/*!< Bulk Erase */
|
|
/*!< Select the FLASH and send "Write Enable" instruction */
|
|
FLASH_SPI_IO_WriteEnable();
|
|
|
|
/*!< Send Bulk Erase instruction */
|
|
FLASH_SPI_IO_WriteByte(FLASH_SPI_CMD_BE);
|
|
|
|
/*!< Wait the end of Flash writing and Deselect the FLASH*/
|
|
if(FLASH_SPI_IO_WaitForWriteEnd()!= HAL_OK)
|
|
{
|
|
return FLASH_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return FLASH_OK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Writes more than one byte to the FLASH with a single WRITE cycle
|
|
* (Page WRITE sequence).
|
|
* @note The number of byte can't exceed the FLASH page size (FLASH_SPI_PAGESIZE).
|
|
* @param pData: pointer to the buffer containing the data to be written
|
|
* to the FLASH.
|
|
* @param uwStartAddress: FLASH's internal address to write to.
|
|
* @param uwDataSize: number of bytes to write to the FLASH, must be equal
|
|
* or less than "FLASH_SPI_PAGESIZE" value.
|
|
* @retval FLASH_OK (0x00) if operation is correctly performed, else
|
|
* return FLASH_ERROR (0x01).
|
|
*/
|
|
uint8_t BSP_SERIAL_FLASH_WritePage(uint32_t uwStartAddress, uint8_t* pData, uint32_t uwDataSize)
|
|
{
|
|
/*!< Select the FLASH and send "Write Enable" instruction */
|
|
FLASH_SPI_IO_WriteEnable();
|
|
|
|
/*!< Send "Write to Memory " instruction */
|
|
FLASH_SPI_IO_WriteByte(FLASH_SPI_CMD_WRITE);
|
|
/*!< Send uwStartAddress high nibble address byte to write to */
|
|
FLASH_SPI_IO_WriteByte((uwStartAddress & 0xFF0000) >> 16);
|
|
/*!< Send uwStartAddress medium nibble address byte to write to */
|
|
FLASH_SPI_IO_WriteByte((uwStartAddress & 0xFF00) >> 8);
|
|
/*!< Send uwStartAddress low nibble address byte to write to */
|
|
FLASH_SPI_IO_WriteByte(uwStartAddress & 0xFF);
|
|
|
|
/*!< while there is data to be written on the FLASH */
|
|
while (uwDataSize--)
|
|
{
|
|
/*!< Send the current byte */
|
|
FLASH_SPI_IO_WriteByte(*pData);
|
|
/*!< Point on the next byte to be written */
|
|
pData++;
|
|
}
|
|
|
|
/*!< Wait the end of Flash writing */
|
|
if (FLASH_SPI_IO_WaitForWriteEnd()!= HAL_OK)
|
|
{
|
|
return FLASH_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return FLASH_OK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Writes block of data to the FLASH. In this function, the number of
|
|
* WRITE cycles are reduced, using Page WRITE sequence.
|
|
* @param pData: pointer to the buffer containing the data to be written
|
|
* to the FLASH.
|
|
* @param uwStartAddress: FLASH's internal address to write to.
|
|
* @param uwDataSize: number of bytes to write to the FLASH.
|
|
* @retval FLASH_OK (0x00) if operation is correctly performed, else
|
|
* return FLASH_ERROR (0x01).
|
|
*/
|
|
uint8_t BSP_SERIAL_FLASH_WriteData(uint32_t uwStartAddress, uint8_t* pData, uint32_t uwDataSize)
|
|
{
|
|
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0, status = 0;
|
|
|
|
Addr = uwStartAddress % FLASH_SPI_PAGESIZE;
|
|
count = FLASH_SPI_PAGESIZE - Addr;
|
|
NumOfPage = uwDataSize / FLASH_SPI_PAGESIZE;
|
|
NumOfSingle = uwDataSize % FLASH_SPI_PAGESIZE;
|
|
|
|
if (Addr == 0) /*!< uwStartAddress is FLASH_SPI_PAGESIZE aligned */
|
|
{
|
|
if (NumOfPage == 0) /*!< uwDataSize < FLASH_SPI_PAGESIZE */
|
|
{
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, uwDataSize);
|
|
}
|
|
else /*!< uwDataSize > FLASH_SPI_PAGESIZE */
|
|
{
|
|
while (NumOfPage--)
|
|
{
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, FLASH_SPI_PAGESIZE);
|
|
uwStartAddress += FLASH_SPI_PAGESIZE;
|
|
pData += FLASH_SPI_PAGESIZE;
|
|
}
|
|
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, NumOfSingle);
|
|
}
|
|
}
|
|
else /*!< uwStartAddress is not FLASH_SPI_PAGESIZE aligned */
|
|
{
|
|
if (NumOfPage == 0) /*!< uwDataSize < FLASH_SPI_PAGESIZE */
|
|
{
|
|
if (NumOfSingle > count) /*!< (uwDataSize + uwStartAddress) > FLASH_SPI_PAGESIZE */
|
|
{
|
|
temp = NumOfSingle - count;
|
|
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, count);
|
|
uwStartAddress += count;
|
|
pData += count;
|
|
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, temp);
|
|
}
|
|
else
|
|
{
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, uwDataSize);
|
|
}
|
|
}
|
|
else /*!< uwDataSize > BSP_SERIAL_FLASH_PAGESIZE */
|
|
{
|
|
uwDataSize -= count;
|
|
NumOfPage = uwDataSize / FLASH_SPI_PAGESIZE;
|
|
NumOfSingle = uwDataSize % FLASH_SPI_PAGESIZE;
|
|
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, count);
|
|
uwStartAddress += count;
|
|
pData += count;
|
|
|
|
while (NumOfPage--)
|
|
{
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, FLASH_SPI_PAGESIZE);
|
|
uwStartAddress += FLASH_SPI_PAGESIZE;
|
|
pData += FLASH_SPI_PAGESIZE;
|
|
}
|
|
|
|
if (NumOfSingle != 0)
|
|
{
|
|
status = BSP_SERIAL_FLASH_WritePage(uwStartAddress, pData, NumOfSingle);
|
|
}
|
|
}
|
|
}
|
|
if (status!= HAL_OK)
|
|
{
|
|
return FLASH_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return FLASH_OK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Reads a block of data from the FLASH.
|
|
* @param pData: pointer to the buffer that receives the data read from the FLASH.
|
|
* @param uwStartAddress: FLASH's internal address to read from.
|
|
* @param uwDataSize: number of bytes to read from the FLASH.
|
|
* @retval FLASH_OK (0x00) if operation is correctly performed, else
|
|
* return FLASH_ERROR (0x01).
|
|
*/
|
|
uint8_t BSP_SERIAL_FLASH_ReadData(uint32_t uwStartAddress, uint8_t* pData, uint32_t uwDataSize)
|
|
{
|
|
if(FLASH_SPI_IO_ReadData(uwStartAddress, pData, uwDataSize)!= HAL_OK)
|
|
{
|
|
return FLASH_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return FLASH_OK;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Reads FLASH identification.
|
|
* @retval FLASH identification
|
|
*/
|
|
uint32_t BSP_SERIAL_FLASH_ReadID(void)
|
|
{
|
|
return(FLASH_SPI_IO_ReadID());
|
|
}
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|