STM32CubeWL/Projects/B-WL5M-SUBG1/Examples/BSP/BSP_Example/Src/flash.c

435 lines
11 KiB
C

/**
******************************************************************************
* @file flash.c
* @author MCD Application Team
* @brief This example code shows how to use the Flash supported by the
* B-WL5M-SUBG board
******************************************************************************
* @attention
*
* Copyright (c) 2022 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 "main.h"
#include "b_wl5m_subg_bus.h"
#include "string.h"
/** @addtogroup B_WL5M_SUBG_HAL_Examples
* @{
*/
/** @addtogroup BSP
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void printSector(uint8_t idxSector);
void printSector2(uint32_t address, uint16_t size);
void printBlock(uint8_t idxBlock);
int32_t checkSectorErased(uint32_t sectorAddress);
int32_t checkBlockErased(uint32_t blockAddress);
/**
* @brief demo of External Flash.
*/
void Flash_demo(void)
{
/* Init the LEDs */
BSP_LED_Init(LED_RED);
BSP_LED_Init(LED_GREEN);
/* Initialize the External Flash */
if (BSP_FLASH_Init(0) != BSP_ERROR_NONE)
{
printf("Error to initialize BSP Flash !!\n");
return;
}
/* 1 - Read Identification (RDID) */
uint8_t RDID[3] = {0U, 0U, 0U};
printf("1 - Read Device IDs: ");
if (BSP_FLASH_ReadID(0, RDID) != BSP_ERROR_NONE)
{
printf("Failed\n");
BSP_LED_On(LED_RED);
}
else
{
printf("0x%02x | 0x%02x | 0x%02x ", RDID[0], RDID[1], RDID[2]);
if ((RDID[0] != 0xC2) || (RDID[1] != 0x20) || (RDID[2] != 0x13))
{
printf("Failed");
BSP_LED_On(LED_RED);
}
printf("\n");
}
/* 2 - Read SFDP parameters */
uint8_t SFDP[4] = {0U, 0U, 0U, 0U};
printf("2 - Read SFDP Parameters\n");
printf("\t2.1 - Read SFDP Signature: ");
if (BSP_FLASH_ReadSFDP(0, SFDP, 0x00, 4) != BSP_ERROR_NONE)
{
printf("BSP_FLASH_ReadSFDP error\n");
}
else
{
printf("\t%x%x%x%x\n", SFDP[3], SFDP[2], SFDP[1], SFDP[0]);
if ((SFDP[3] != 0x50) || (SFDP[2] != 0x44) || (SFDP[1] != 0x46) || (SFDP[0] != 0x53))
{
printf("Failed\n");
BSP_LED_On(LED_RED);
}
}
printf("\t2.2 - Read SFDP revision: ");
if (BSP_FLASH_ReadSFDP(0, SFDP, 0x04, 2) != BSP_ERROR_NONE)
{
printf("BSP_FLASH_ReadSFDP error\n");
}
else
{
printf("\tv%x.%x\n", SFDP[1], SFDP[0]);
if ((SFDP[1] != 0x01) || (SFDP[0] != 0x00))
{
printf("Failed\n");
BSP_LED_On(LED_RED);
}
}
/* 3 - Read Status */
printf("3 - Read Status");
if (BSP_FLASH_GetStatus(0) == BSP_ERROR_NONE)
{
printf("\tGet Status is OK\n");
}
else
{
printf("\tGet Status error\n");
BSP_LED_On(LED_RED);
}
/* 4 - Check Memory configuration */
uint8_t statusRegister = 0xFF;
printf("4 - Test to configure Memory Block Protection: ");
printf("\t- Initial Status Register value: ");
if (BSP_FLASH_ReadStatusRegister(0, &statusRegister) != BSP_ERROR_NONE)
{
printf("Failed\n");
BSP_LED_On(LED_RED);
}
else
{
printf("0x%02x\n", statusRegister);
}
if (BSP_FLASH_GetStatus(0) == BSP_ERROR_NONE)
{
printf("Get Status is OK\n");
}
else
{
printf("Get Status error\n");
}
printf("\t- Tests all Block Protection configurations:\n");
for (uint8_t i = 1; i < 8; i++)
{
uint8_t BPbits = i << 2;
printf("\t\t-> BP bits: 0x%02x", BPbits);
if (BSP_FLASH_BlockProtectConfig(0U, BPbits) != BSP_ERROR_NONE)
{
printf("Failed\n");
BSP_LED_On(LED_RED);
}
else
{
if (BSP_FLASH_ReadStatusRegister(0U, &statusRegister) != BSP_ERROR_NONE)
{
printf("Failed\n");
BSP_LED_On(LED_RED);
}
else if ((statusRegister & MX25L4006_SR_BLOCKPR) == BPbits)
{
printf(" 0x%02x\n", statusRegister);
}
else
{
printf("Failed\n");
BSP_LED_On(LED_RED);
}
}
}
/* Reset Block Protection bits */
if (BSP_FLASH_BlockProtectConfig(0U, 0U) != BSP_ERROR_NONE)
{
printf("Failed to reset Block Protection Configuration !!\n");
BSP_LED_On(LED_RED);
}
/* Erase Block */
if (BSP_FLASH_Erase_Chip(0) != BSP_ERROR_NONE)
{
printf("Failed to erase whole chip !!\n");
BSP_LED_On(LED_RED);
}
printf("5 - Read/Write to Memory\n");
/* Write data in block 0 with granularity of 64B */
uint8_t data[256] = {0};
uint8_t data2[256] = {0};
uint32_t sizeBlock = 256;
for (uint32_t i = 0; i < sizeBlock; i++)
{
data[i] = (uint8_t)(0xFE - i);
}
uint32_t nbBlockPerSector = MX25L4006_SECTOR_SIZE / sizeBlock;
for (uint32_t idSector = 0; idSector < 128; idSector++)
{
uint32_t sectorAddress = idSector * MX25L4006_SECTOR_SIZE;
for (uint32_t idxBlock = 0; idxBlock < nbBlockPerSector; idxBlock++)
{
if (BSP_FLASH_Write(0, data, sectorAddress, sizeBlock) != BSP_ERROR_NONE)
{
printf("Write error at sector[0x%06x]\n", sectorAddress);
BSP_LED_On(LED_RED);
}
sectorAddress += sizeBlock;
BSP_LED_Toggle(LED_BLUE);
}
/* Read memory with classic function BSP_FLASH_Read */
sectorAddress = idSector * MX25L4006_SECTOR_SIZE;
for (uint32_t idxBlock = 0; idxBlock < nbBlockPerSector; idxBlock++)
{
memset(data2, 0xAA, sizeBlock);
if (BSP_FLASH_Read(0, data2, sectorAddress, sizeBlock) != BSP_ERROR_NONE)
{
printf("Read error at sector[0x%06x]\n", sectorAddress);
BSP_LED_On(LED_RED);
}
else
{
if (memcmp(data, data2, sizeBlock) != 0)
{
printf("Error diff at sector[0x%06x]\n", sectorAddress);
BSP_LED_On(LED_RED);
}
}
sectorAddress += sizeBlock;
BSP_LED_Toggle(LED_GREEN);
}
/* Quickly Read memory with specific function BSP_FLASH_FastRead */
sectorAddress = idSector * MX25L4006_SECTOR_SIZE;
for (uint32_t idxBlock = 0; idxBlock < nbBlockPerSector; idxBlock++)
{
memset(data2, 0xAA, sizeBlock);
if (BSP_FLASH_FastRead(0, data2, sectorAddress, sizeBlock) != BSP_ERROR_NONE)
{
printf("Read error at sector[0x%06x]\n", sectorAddress);
BSP_LED_On(LED_RED);
}
else
{
if (memcmp(data, data2, sizeBlock) != 0)
{
printf("Error diff at sector[0x%06x]\n", sectorAddress);
BSP_LED_On(LED_RED);
}
}
sectorAddress += sizeBlock;
BSP_LED_Toggle(LED_GREEN);
}
}
printf("6 - Checking Erase sector at 0x000000\n");
if (BSP_FLASH_Erase_Sector(0, 0x000000) != BSP_ERROR_NONE)
{
printf("failed\n");
BSP_LED_On(LED_RED);
}
if (checkSectorErased(0) != 0)
{
BSP_LED_On(LED_RED);
}
printf("7 - Checking Erase block at 0x01CA32\n");
uint32_t blockAddress = 0x01CA32;
if (BSP_FLASH_Erase_Block(0, blockAddress, MX25L4006_ERASE_64K) != BSP_ERROR_NONE)
{
printf("failed\n");
BSP_LED_On(LED_RED);
}
if (checkBlockErased(blockAddress & ~0xFFFF) != 0)
{
printf("failed\n");
BSP_LED_On(LED_RED);
}
printf("8 - Checking Erase whole Chip\n");
/* Erase full chip */
if (BSP_FLASH_Erase_Chip(0) != BSP_ERROR_NONE)
{
printf("failed\n");
BSP_LED_On(LED_RED);
}
for (uint32_t blockAddress = 0x00000000; blockAddress < 0x00080000; blockAddress += MX25L4006_BLOCK_SIZE)
{
if (checkBlockErased(blockAddress) != 0)
{
printf("failed\n");
BSP_LED_On(LED_RED);
break;
}
BSP_LED_Toggle(LED_BLUE);
HAL_Delay(1);
}
/* DeInit the Flash */
BSP_FLASH_DeInit(0);
/* DeInit the LEDs */
BSP_LED_DeInit(LED_RED);
BSP_LED_DeInit(LED_GREEN);
}
void printSector(uint8_t idxSector)
{
uint8_t datasRead[64];
uint32_t idx = 0;
uint32_t addressSector = idxSector * MX25L4006_SECTOR_SIZE; /* Sector of 4KB */
memset(datasRead, 0, 64 * sizeof(uint8_t));
printf("\t- Sector %02i [0x%06x] ", idxSector, addressSector);
fflush(stdout);
for (uint32_t idxBlock64 = 0; idxBlock64 < 64; idxBlock64++)
{
if (BSP_FLASH_Read(0, datasRead, addressSector, 64) != BSP_ERROR_NONE)
{
BSP_LED_On(LED_RED);
}
for (idx = 0; idx < 64; idx++)
{
printf("%02x ", datasRead[idx]);
fflush(stdout);
}
printf("\n\t\t\t\t");
addressSector += 64;
}
printf("\n");
}
void printSector2(uint32_t address, uint16_t size)
{
uint8_t datasRead[64];
uint32_t idx = 0;
uint32_t addressSector = address; /* Sector of 4KB */
memset(datasRead, 0, 64 * sizeof(uint8_t));
printf("\t- Sector [0x%06x] %02i ", address, size);
fflush(stdout);
if (BSP_FLASH_Read(0, datasRead, addressSector, size) != BSP_ERROR_NONE)
{
BSP_LED_On(LED_RED);
}
for (idx = 0; idx < size; idx++)
{
printf("%02x ", datasRead[idx]);
fflush(stdout);
}
printf("\n");
}
void printBlock(uint8_t idxBlock)
{
uint32_t addressBlock = idxBlock * MX25L4006_BLOCK_SIZE; /* Block of 64KB */
printf("\t- Block %i [0x%06x\n", idxBlock, addressBlock);
for (uint8_t idxSector = 0; idxSector < 16; idxSector++)
{
printSector(idxBlock * 16 + idxSector);
}
}
int32_t checkSectorErased(uint32_t sectorAddress)
{
int32_t ret = 0;
uint8_t dataRead[MX25L4006_PAGE_SIZE];
uint32_t endSectorAddress = sectorAddress + MX25L4006_SECTOR_SIZE;
for (uint32_t memoryAddress = sectorAddress; (ret == 0) && (memoryAddress < endSectorAddress); memoryAddress += MX25L4006_PAGE_SIZE)
{
memset(dataRead, 0x00, MX25L4006_PAGE_SIZE);
if (BSP_FLASH_Read(0, dataRead, memoryAddress, MX25L4006_PAGE_SIZE) != BSP_ERROR_NONE)
{
ret = -1;
break;
}
for (uint32_t i = 0; i < MX25L4006_PAGE_SIZE; i++)
{
if (dataRead[ i ] != 0xFF)
{
ret = -2;
break;
}
}
}
return ret;
}
int32_t checkBlockErased(uint32_t blockAddress)
{
int32_t ret = 0;
uint32_t endBlockAddress = blockAddress + MX25L4006_BLOCK_SIZE;
for (uint32_t memoryAddress = blockAddress; (ret == 0) && (memoryAddress < endBlockAddress); memoryAddress += MX25L4006_SECTOR_SIZE)
{
ret = checkSectorErased(memoryAddress);
}
return ret;
}
/**
* @}
*/
/**
* @}
*/