Skip to content

Instantly share code, notes, and snippets.

@nickfox-taterli
Created June 24, 2022 03:11
Show Gist options
  • Save nickfox-taterli/c933e2969b637e0fd4ecc2d437436783 to your computer and use it in GitHub Desktop.
Save nickfox-taterli/c933e2969b637e0fd4ecc2d437436783 to your computer and use it in GitHub Desktop.
MT29F2G01ABAGDWB BSP @ STM32 HAL
#include "mt29f2g01abagdwb.h"
QSPI_HandleTypeDef QSPIHandle;
static uint8_t QSPI_ResetMemory(void);
static uint8_t QSPI_WriteEnable(void);
static uint8_t QSPI_AutoPollingMemReady(void);
static uint8_t QSPI_GetStatusRegister(void);
uint8_t BSP_QSPI_Init(void)
{
QSPIHandle.Instance = QUADSPI;
/* Call the DeInit function to reset the driver */
if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
{
return MT29F2G_ERROR;
}
/* QSPI initialization */
QSPIHandle.Init.ClockPrescaler = 255; /* QSPI freq = 216 MHz/(1+1) = 108 Mhz */
QSPIHandle.Init.FifoThreshold = 4;
QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
QSPIHandle.Init.FlashSize = 31;
QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE; /* Min 50ns for nonRead */
QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1;
QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
{
return MT29F2G_ERROR;
}
if (QSPI_ResetMemory() != MT29F2G_OK)
{
return MT29F2G_ERROR;
}
return MT29F2G_OK;
}
/**
* @brief De-Initializes the QSPI interface.
* @retval QSPI memory status
*/
uint8_t BSP_QSPI_DeInit(void)
{
if (QSPI_ResetMemory() != MT29F2G_OK)
{
return MT29F2G_ERROR;
}
HAL_QSPI_DeInit(&QSPIHandle);
return MT29F2G_OK;
}
/**
* @brief Reads an amount of data from the QSPI memory.
* @param pData: Pointer to data to be read
* @param ReadAddr: Read start address
* @param Size: Size of data to read
* @retval QSPI memory status
*/
uint8_t BSP_QSPI_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
{
QSPI_CommandTypeDef s_command;
QSPI_AutoPollingTypeDef s_config;
// Address = RA[16:6] (Block) + RA[5:0] (Pages) + CA[11:0] Bytes
/* Initialize the reset enable command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x13;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = ReadAddr >> 12;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Send the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
/* Configure automatic polling mode to wait for Cache read ready */
s_command.Instruction = 0x0F;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
s_command.Address = 0xC0;
s_command.DataMode = QSPI_DATA_1_LINE;
s_config.Match = 0;
s_config.Mask = MT29F2G_SR_CRBSY;
s_config.MatchMode = QSPI_MATCH_MODE_AND;
s_config.StatusBytesSize = 1;
s_config.Interval = 0x1;
s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
if (HAL_QSPI_AutoPolling(&QSPIHandle, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
#if MT29F2G_READ_MODE == 1
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x03;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_16_BITS;
s_command.Address = ReadAddr & 0x1FFF;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 8;
s_command.NbData = Size;
#elif MT29F2G_READ_MODE == 2
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0xbb;
s_command.AddressMode = QSPI_ADDRESS_2_LINES;
s_command.AddressSize = QSPI_ADDRESS_16_BITS;
s_command.Address = ReadAddr & 0x1FFF;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_2_LINES;
s_command.DummyCycles = 4;
s_command.NbData = Size;
#elif MT29F2G_READ_MODE == 4
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0xeb;
s_command.AddressMode = QSPI_ADDRESS_4_LINES;
s_command.AddressSize = QSPI_ADDRESS_16_BITS;
s_command.Address = ReadAddr & 0x1FFF;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_4_LINES;
s_command.DummyCycles = 4;
s_command.NbData = Size;
#elif
#error "MT29F2G_READ_MODE Only support define to 1,2,4."
#endif
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
switch (QSPI_GetStatusRegister() & MT29F2G_SR_ECC)
{
case 0:
return MT29F2G_OK;
break;
case 0X10:
return MT29F2G_ECC_CORRECT_1_3;
break;
case 0X30:
return MT29F2G_ECC_CORRECT_4_6;
break;
case 0X50:
return MT29F2G_ECC_CORRECT_7_8;
break;
case 0X20:
return MT29F2G_ECC_FAIL;
break;
}
return MT29F2G_OK;
}
/**
* @brief Writes an amount of data to the QSPI memory.
* @param pData: Pointer to data to be written
* @param WriteAddr: Write start address
* @param Size: Size of data to write
* @retval QSPI memory status
*/
uint8_t BSP_QSPI_Write(uint8_t *pData, uint32_t WriteAddr, uint32_t Size)
{
QSPI_CommandTypeDef s_command;
QSPI_WriteEnable();
#if MT29F2G_WRITE_MODE == 1
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x02;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_16_BITS;
s_command.Address = WriteAddr & 0x1FFF;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.NbData = Size;
#elif MT29F2G_WRITE_MODE == 4
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x32;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_16_BITS;
s_command.Address = WriteAddr & 0x1FFF;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_4_LINES;
s_command.DummyCycles = 0;
s_command.NbData = Size;
#elif
#error "MT29F2G_WRITE_MODE Only support define to 1,4."
#endif
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x10;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = WriteAddr >> 12;
s_command.DataMode = QSPI_DATA_NONE;
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
QSPI_AutoPollingMemReady();
if (QSPI_GetStatusRegister() & MT29F2G_SR_PFAIL)
{
return MT29F2G_PFAIL;
}
return MT29F2G_OK;
}
/**
* @brief Erases the specified block of the QSPI memory.
* @param BlockAddress: Block address to erase
* @retval QSPI memory status
*/
uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
{
QSPI_CommandTypeDef s_command;
QSPI_WriteEnable();
/* Initialize the reset enable command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0xd8;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = BlockAddress >> 12;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Send the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
QSPI_AutoPollingMemReady();
if (QSPI_GetStatusRegister() & MT29F2G_SR_EFAIL)
{
return MT29F2G_EFAIL;
}
return MT29F2G_OK;
}
/**
* @brief Erases the entire QSPI memory.
* @retval QSPI memory status
*/
uint8_t BSP_QSPI_Erase_Chip(void)
{
return MT29F2G_OK;
}
/**
* @brief Return the configuration of the QSPI memory.
* @param pInfo: pointer on the configuration structure
* @retval QSPI memory status
*/
uint8_t BSP_QSPI_GetInfo(QSPI_Info *pInfo)
{
QSPI_CommandTypeDef s_command;
uint8_t status;
uint8_t status_tmp;
QSPI_GetStatusRegister();
QSPI_GetStatusRegister();
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x0F;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
s_command.Address = 0xB0;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.NbData = 1;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
if (HAL_QSPI_Receive(&QSPIHandle, &status, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
status_tmp = status;
CLEAR_BIT(status_tmp, 0xC2);
SET_BIT(status_tmp, 0x40);
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x1F;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
s_command.Address = 0xB0;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.NbData = 1;
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
if (HAL_QSPI_Transmit(&QSPIHandle, &status_tmp, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
BSP_QSPI_Read((uint8_t *)pInfo, 0x1000, sizeof(*pInfo) / sizeof(uint8_t));
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x1F;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
s_command.Address = 0xB0;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.NbData = 1;
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
if (HAL_QSPI_Transmit(&QSPIHandle, &status, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
return MT29F2G_OK;
}
/**
* @brief Configure the QSPI in memory-mapped mode
* @retval QSPI memory status
*/
uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
{
return MT29F2G_OK;
}
/**
* @brief This function reset the QSPI memory.
* @param hqspi: QSPI handle
* @retval None
*/
static uint8_t QSPI_ResetMemory(void)
{
QSPI_CommandTypeDef s_command;
/* Initialize the reset enable command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0xFF;
s_command.AddressMode = QSPI_ADDRESS_NONE;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Send the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
/* Configure automatic polling mode to wait the memory is ready */
if (QSPI_AutoPollingMemReady() != MT29F2G_OK)
{
return MT29F2G_ERROR;
}
return MT29F2G_OK;
}
/**
* @brief This function send a Write Enable and wait it is effective.
* @param hqspi: QSPI handle
* @retval None
*/
static uint8_t QSPI_WriteEnable(void)
{
QSPI_CommandTypeDef s_command;
QSPI_AutoPollingTypeDef s_config;
/* Initialize the reset enable command */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x06;
s_command.AddressMode = QSPI_ADDRESS_NONE;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_NONE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Send the command */
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
/* Configure automatic polling mode to wait for write enabling */
s_command.Instruction = 0x0F;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
s_command.Address = 0xC0;
s_command.DataMode = QSPI_DATA_1_LINE;
s_config.Match = MT29F2G_SR_WREN;
s_config.Mask = MT29F2G_SR_WREN;
s_config.MatchMode = QSPI_MATCH_MODE_AND;
s_config.StatusBytesSize = 1;
s_config.Interval = 0x1;
s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
if (HAL_QSPI_AutoPolling(&QSPIHandle, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
return MT29F2G_OK;
}
/**
* @brief This function read the SR of the memory and wait the EOP.
* @retval None
*/
static uint8_t QSPI_AutoPollingMemReady(void)
{
QSPI_CommandTypeDef s_command;
QSPI_AutoPollingTypeDef s_config;
/* Configure automatic polling mode to wait for memory ready */
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x0F;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
s_command.Address = 0xC0;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
s_config.Match = 0;
s_config.Mask = MT29F2G_SR_WIP;
s_config.MatchMode = QSPI_MATCH_MODE_AND;
s_config.StatusBytesSize = 1;
s_config.Interval = 1;
s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
if (HAL_QSPI_AutoPolling(&QSPIHandle, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
return MT29F2G_OK;
}
/**
* @brief Reads current status of the QSPI memory.
* @retval QSPI memory status
*/
static uint8_t QSPI_GetStatusRegister(void)
{
QSPI_CommandTypeDef s_command;
uint8_t status;
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = 0x0F;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_8_BITS;
s_command.Address = 0xC0;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.NbData = 1;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
if (HAL_QSPI_Receive(&QSPIHandle, &status, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return MT29F2G_ERROR;
}
return status;
}
#ifndef __MT29F2G01ABAGDWB_H
#define __MT29F2G01ABAGDWB_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "stm32h7xx_hal.h"
/* Status Register */
#define MT29F2G_SR_WIP ((uint8_t)0x01) /*!< Write in progress */
#define MT29F2G_SR_WREN ((uint8_t)0x02) /*!< Write enable latch */
#define MT29F2G_SR_EFAIL ((uint8_t)0x04) /*!< Erase fail */
#define MT29F2G_SR_PFAIL ((uint8_t)0x08) /*!< Program fail */
#define MT29F2G_SR_ECC ((uint8_t)0x70) /*!< ECC status */
#define MT29F2G_SR_CRBSY ((uint8_t)0x70) /*!< Cache read busy */
#define MT29F2G_READ_MODE 1
#define MT29F2G_WRITE_MODE 1
#define MT29F2G_OK ((uint8_t)0x00)
#define MT29F2G_ERROR ((uint8_t)0x01)
#define MT29F2G_PFAIL ((uint8_t)0x02)
#define MT29F2G_EFAIL ((uint8_t)0x04)
#define MT29F2G_ECC_CORRECT_1_3 ((uint8_t)0x08)
#define MT29F2G_ECC_CORRECT_4_6 ((uint8_t)0x10)
#define MT29F2G_ECC_CORRECT_7_8 ((uint8_t)0x20)
#define MT29F2G_ECC_FAIL ((uint8_t)0x40)
/* QSPI Info */
typedef struct
{
uint32_t Signature; /*!< Parameter page signature */
uint16_t Revision; /*!< Revision number */
uint16_t Feature; /*!< Feature support */
uint16_t OptionalCommands; /*!< Optional commands support */
uint8_t Reserved1[22]; /*!< Reserved */
uint8_t DeviceManufacturer[12]; /*!< Device manufacturer */
uint8_t DeviceModel[20]; /*!< Device model */
uint8_t ManufacturerID; /*!< Manufacturer ID */
uint16_t DateCode; /*!< Date code */
uint8_t Reserved2[12]; /*!< Reserved */
uint32_t PageSize; /*!< Number of data bytes per page */
uint16_t SpareSize; /*!< Number of spare bytes per page */
uint16_t PartialPageSize; /*!< Number of data bytes per partial page */
uint8_t Reserved3[2]; /*!< Reserved */
uint16_t PartialSpareSize; /*!< Number of spare bytes per partial page */
uint8_t BlockSize[4]; /*!< Number of pages per block */
uint8_t UnitSize[4]; /*!< Number of blocks per unit */
uint8_t LogicalUnit; /*!< Number of logical units */
uint8_t AddressCycles; /*!< Number of address cycles */
uint8_t BitsPerCell; /*!< Number of bits per cell */
uint8_t BadBlocksMaximumPerUnit; /*!< Bad blocks maximum per unit */
uint8_t Reserved4; /*!< Reserved */
uint8_t BlockEndurance[2]; /*!< Block endurance */
uint8_t GuaranteedBlock; /*!< Guaranteed valid blocks at beginning of target */
uint16_t BlockEnduranceGuaranteed; /*!< Block endurance for guaranteed valid blocks */
uint8_t ProgramsPerPage; /*!< Number of programs per page */
uint8_t PartialProgrammingAttributes; /*!< Partial programming attributes */
uint8_t ECCBits; /*!< Number of ECC bits */
uint8_t InterleavedAddressBits; /*!< Number of interleaved address bits */
uint8_t InterleavedOperationAttributes; /*!< Interleaved operation attributes */
uint8_t Reserved5[13]; /*!< Reserved */
uint8_t PinCapacitance; /*!< I/O pin capacitance */
uint8_t TimingModeSupport; /*!< Timing mode support */
uint16_t ProgramCacheTiming; /*!< Program cache timing */
uint8_t Reserved6; /*!< Reserved */
uint8_t tPROG[2]; /*!< tPROG maximum page program time */
uint8_t tERS[2]; /*!< tERS maximum block erase time */
uint8_t tR[2]; /*!< tR maximum page read time */
uint8_t tCCS[2]; /*!< tCCS minimum */
uint8_t Reserved7[23]; /*!< Reserved */
uint16_t VendorSpecificRevision; /*!< Vendor-specific revision number */
uint8_t VendorSpecific[14]; /*!< Vendor specific */
uint8_t Reserved8[68]; /*!< Reserved */
uint8_t ECCCorrectAbility; /*!< ECC maximum correct ability */
uint8_t DieSelectFeature; /*!< Die select feature */
uint8_t Reserved9[4]; /*!< Reserved */
uint8_t IntegrityCRC[2]; /*!< Integrity CRC */
} QSPI_Info;
uint8_t BSP_QSPI_Init(void);
uint8_t BSP_QSPI_DeInit(void);
uint8_t BSP_QSPI_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size);
uint8_t BSP_QSPI_Write(uint8_t *pData, uint32_t WriteAddr, uint32_t Size);
uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress);
uint8_t BSP_QSPI_Erase_Chip(void);
uint8_t BSP_QSPI_GetStatus(void);
uint8_t BSP_QSPI_GetInfo(QSPI_Info *pInfo);
uint8_t BSP_QSPI_EnableMemoryMappedMode(void);
#ifdef __cplusplus
}
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment