From 94ec36d62ffa25a0075ecdf38334550a483b2191 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Thu, 3 Sep 2020 15:13:36 +0200 Subject: [PATCH 1/5] [B_L4S5I_IOT01A] update to support OCTOSPI L4S5 IOT kit has octospi feature to access the hw mx2556435f the 64-Mbit Quad-SPI Flash memory from Macronix Signed-off-by: Francois Ramu --- src/mx25r6435f_driver.c | 859 +++++++++++++++++++++++++++++++++++++++- src/mx25r6435f_driver.h | 8 +- 2 files changed, 853 insertions(+), 14 deletions(-) diff --git a/src/mx25r6435f_driver.c b/src/mx25r6435f_driver.c index e083e6a..4c4fd7d 100644 --- a/src/mx25r6435f_driver.c +++ b/src/mx25r6435f_driver.c @@ -111,8 +111,15 @@ /** @defgroup STM32L475E_IOT01_QSPI_Private_Variables QSPI Private Variables * @{ */ +#ifdef OCTOSPI +OSPI_HandleTypeDef OSPIHandle; +#define XSPI_HandleTypeDef OSPI_HandleTypeDef +#define hxspi hospi +#else QSPI_HandleTypeDef QSPIHandle; - +#define XSPI_HandleTypeDef QSPI_HandleTypeDef +#define hxspi hqspi +#endif /* OCTOSPI */ /** * @} */ @@ -123,11 +130,11 @@ QSPI_HandleTypeDef QSPIHandle; /** @defgroup STM32L475E_IOT01_QSPI_Private_Functions QSPI Private Functions * @{ */ -static uint8_t QSPI_ResetMemory (QSPI_HandleTypeDef *hqspi); -static uint8_t QSPI_WriteEnable (QSPI_HandleTypeDef *hqspi); -static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout); -static uint8_t QSPI_QuadMode (QSPI_HandleTypeDef *hqspi, uint8_t Operation); -static uint8_t QSPI_HighPerfMode (QSPI_HandleTypeDef *hqspi, uint8_t Operation); +static uint8_t QSPI_ResetMemory (XSPI_HandleTypeDef *hxspi); +static uint8_t QSPI_WriteEnable (XSPI_HandleTypeDef *hxspi); +static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Timeout); +static uint8_t QSPI_QuadMode (XSPI_HandleTypeDef *hxspi, uint8_t Operation); +static uint8_t QSPI_HighPerfMode (XSPI_HandleTypeDef *hxspi, uint8_t Operation); static uint8_t qspi_setClockPrescaler (void); /** @@ -163,10 +170,17 @@ static uint8_t qspi_setClockPrescaler(void) { */ uint8_t BSP_QSPI_Init(void) { +#ifdef OCTOSPI + OSPIHandle.Instance = OCTOSPI; + + /* Call the DeInit function to reset the driver */ + if (HAL_OSPI_DeInit(&OSPIHandle) != HAL_OK) +#else QSPIHandle.Instance = QUADSPI; /* Call the DeInit function to reset the driver */ if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) +#endif /* OCTOSPI */ { return QSPI_ERROR; } @@ -174,7 +188,53 @@ uint8_t BSP_QSPI_Init(void) /* System level initialization */ BSP_QSPI_MspInit(); - /* QSPI initialization */ +#ifdef OCTOSPI + /* OSPI initialization */ + OSPIHandle.Init.FifoThreshold = 4; + OSPIHandle.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + OSPIHandle.Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX; + OSPIHandle.Init.DeviceSize = POSITION_VAL(MX25R6435F_FLASH_SIZE); + OSPIHandle.Init.ChipSelectHighTime = 1; + OSPIHandle.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; + OSPIHandle.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; + OSPIHandle.Init.ClockPrescaler = 4; /* QSPI clock = 110MHz / ClockPrescaler = 27.5 MHz */ + OSPIHandle.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE; + OSPIHandle.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; + OSPIHandle.Init.ChipSelectBoundary = 0; + OSPIHandle.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED; + + if (HAL_OSPI_Init(&OSPIHandle) != HAL_OK) + { + return QSPI_ERROR; + } + + /* QSPI memory reset */ + if (QSPI_ResetMemory(&OSPIHandle) != QSPI_OK) + { + return QSPI_NOT_SUPPORTED; + } + + /* QSPI quad enable */ + if (QSPI_QuadMode(&OSPIHandle, QSPI_QUAD_ENABLE) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* High performance mode enable */ + if (QSPI_HighPerfMode(&OSPIHandle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Re-configure the clock for the high performance mode */ + OSPIHandle.Init.ClockPrescaler = 2; /* QSPI clock = 110MHz / ClockPrescaler = 55 MHz */ + + if (HAL_OSPI_Init(&OSPIHandle) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ + /* QSPI initialization */ /* High performance mode clock is limited to 80 MHz */ QSPIHandle.Init.ClockPrescaler = qspi_setClockPrescaler() + 1; /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ QSPIHandle.Init.FifoThreshold = 4; @@ -214,6 +274,7 @@ uint8_t BSP_QSPI_Init(void) { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -224,10 +285,17 @@ uint8_t BSP_QSPI_Init(void) */ uint8_t BSP_QSPI_DeInit(void) { +#ifdef OCTOSPI + OSPIHandle.Instance = OCTOSPI; + + /* Call the DeInit function to reset the driver */ + if (HAL_OSPI_DeInit(&OSPIHandle) != HAL_OK) +#else /* OCTOSPI */ QSPIHandle.Instance = QUADSPI; /* Call the DeInit function to reset the driver */ if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) +#endif /* OCTOSPI */ { return QSPI_ERROR; } @@ -247,6 +315,43 @@ uint8_t BSP_QSPI_DeInit(void) */ uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the read command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = QUAD_INOUT_READ_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Address = ReadAddr; + sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES; + sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS; + sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; + sCommand.DataMode = HAL_OSPI_DATA_4_LINES; + sCommand.NbData = Size; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_OSPI_Receive(&OSPIHandle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Initialize the read command */ @@ -276,6 +381,7 @@ uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -289,7 +395,11 @@ 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) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; +#endif /* OCTOSPI */ uint32_t end_addr, current_size, current_addr; /* Calculation of the size between the write address and the end of the page */ @@ -305,6 +415,55 @@ uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) current_addr = WriteAddr; end_addr = WriteAddr + Size; +#ifdef OCTOSPI + /* Initialize the program command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = QUAD_PAGE_PROG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_4_LINES; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Perform the write page by page */ + do + { + sCommand.Address = current_addr; + sCommand.NbData = current_size; + + /* Enable write operations */ + if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Configure the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Transmission of the data */ + if (HAL_OSPI_Transmit(&OSPIHandle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of program */ + if (QSPI_AutoPollingMemReady(&OSPIHandle, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + { + return QSPI_ERROR; + } + +#else /* OCTOSPI */ /* Initialize the program command */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; sCommand.Instruction = QUAD_PAGE_PROG_CMD; @@ -346,6 +505,7 @@ uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) { return QSPI_ERROR; } +#endif /* OCTOSPI */ /* Update the address and size variables for next page programming */ current_addr += current_size; @@ -363,6 +523,45 @@ uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) */ uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = BLOCK_ERASE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Address = BlockAddress; + sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(&OSPIHandle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) + { + return QSPI_ERROR; + } + +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Initialize the erase command */ @@ -396,6 +595,7 @@ uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -411,6 +611,43 @@ uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) */ uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE)) + { + return QSPI_ERROR; + } + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = SECTOR_ERASE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Address = (Sector * MX25R6435F_SECTOR_SIZE); + sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE)) @@ -442,6 +679,7 @@ uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -452,6 +690,42 @@ uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) */ uint8_t BSP_QSPI_Erase_Chip(void) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = CHIP_ERASE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Enable write operations */ + if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(&OSPIHandle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) + { + return QSPI_ERROR; + } + +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Initialize the erase command */ @@ -482,6 +756,7 @@ uint8_t BSP_QSPI_Erase_Chip(void) { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -492,8 +767,64 @@ uint8_t BSP_QSPI_Erase_Chip(void) */ uint8_t BSP_QSPI_GetStatus(void) { - QSPI_CommandTypeDef sCommand; uint8_t reg; +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the read security register command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_SEC_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.NbData = 1; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_OSPI_Receive(&OSPIHandle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Check the value of the register */ + if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) + { + return QSPI_ERROR; + } + else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0) + { + return QSPI_SUSPENDED; + } + + /* Initialize the read status register command */ + sCommand.Instruction = READ_STATUS_REG_CMD; + + /* Configure the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_OSPI_Receive(&OSPIHandle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; /* Initialize the read security register command */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; @@ -543,6 +874,7 @@ uint8_t BSP_QSPI_GetStatus(void) { return QSPI_ERROR; } +#endif /* OCTOSPI */ /* Check the value of the register */ if ((reg & MX25R6435F_SR_WIP) != 0) @@ -578,6 +910,56 @@ uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo) */ uint8_t BSP_QSPI_EnableMemoryMappedMode(void) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + OSPI_MemoryMappedTypeDef sMemMappedCfg; + + /* Configure the command for the read instruction */ + sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = QUAD_INOUT_READ_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES; + sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS; + sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; + sCommand.DataMode = HAL_OSPI_DATA_4_LINES; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure the command for the program instruction */ + sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG; + sCommand.Instruction = QUAD_PAGE_PROG_CMD; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DummyCycles = 0; + + /* Configure the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure the memory mapped mode */ + sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE; + + if (HAL_OSPI_MemoryMapped(&OSPIHandle, &sMemMappedCfg) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; QSPI_MemoryMappedTypeDef sMemMappedCfg; @@ -602,6 +984,7 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(void) { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -612,6 +995,34 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(void) */ uint8_t BSP_QSPI_SuspendErase(void) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Check whether the device is busy (erase operation is + in progress). + */ + if (BSP_QSPI_GetStatus() == QSPI_BUSY) + { + /* Initialize the suspend command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Send the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Check whether the device is busy (erase operation is @@ -635,6 +1046,7 @@ uint8_t BSP_QSPI_SuspendErase(void) { return QSPI_ERROR; } +#endif /* OCTOSPI */ if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) { @@ -653,6 +1065,33 @@ uint8_t BSP_QSPI_SuspendErase(void) */ uint8_t BSP_QSPI_ResumeErase(void) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Check whether the device is in suspended state */ + if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) + { + /* Initialize the resume command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = PROG_ERASE_RESUME_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Send the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Check whether the device is in suspended state */ @@ -675,6 +1114,8 @@ uint8_t BSP_QSPI_ResumeErase(void) return QSPI_ERROR; } +#endif /* OCTOSPI */ + /* When this command is executed, the status register write in progress bit is set to 1, and the flag status register program erase controller bit is set to 0. This command is ignored @@ -698,6 +1139,29 @@ uint8_t BSP_QSPI_ResumeErase(void) */ uint8_t BSP_QSPI_EnterDeepPowerDown(void) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the deep power down command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = DEEP_POWER_DOWN_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Send the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Initialize the deep power down command */ @@ -716,6 +1180,7 @@ uint8_t BSP_QSPI_EnterDeepPowerDown(void) { return QSPI_ERROR; } +#endif /* OCTOSPI */ /* --- Memory takes 10us max to enter deep power down --- */ /* --- At least 30us should be respected before leaving deep power down --- */ @@ -729,6 +1194,30 @@ uint8_t BSP_QSPI_EnterDeepPowerDown(void) */ uint8_t BSP_QSPI_LeaveDeepPowerDown(void) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = NO_OPERATION_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Send the command */ + if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Initialize the erase command */ @@ -747,6 +1236,7 @@ uint8_t BSP_QSPI_LeaveDeepPowerDown(void) { return QSPI_ERROR; } +#endif /* OCTOSPI */ /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */ /* --- Memory takes 35us min to leave deep power down --- */ @@ -765,6 +1255,35 @@ __weak void BSP_QSPI_MspInit(void) uint8_t idx = 0; PinName pin; +#ifdef OCTOSPI + /* Enable the OctoSPI memory interface clock */ + __HAL_RCC_OSPI1_CLK_ENABLE(); + + /* Reset the OctoSPI memory interface */ + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + + /* Enable GPIO clocks */ + __HAL_RCC_GPIOE_CLK_ENABLE(); + + /* OCTOSPI CLK, CS, D0, D1, D2 and D3 GPIO pins configuration */ + pin = PinMap_OCTOSPI[idx].pin; + while(pin != NC) + { + /* Enable GPIO clocks */ + port = set_GPIO_Port_Clock(STM_PORT(pin)); + + /* Pin configuration */ + GPIO_InitStruct.Pin = STM_GPIO_PIN(pin); + GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(pin, PinMap_OCTOSPI)); + GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(pin, PinMap_OCTOSPI)); + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(pin, PinMap_OCTOSPI)); + HAL_GPIO_Init(port, &GPIO_InitStruct); + + pin = PinMap_OCTOSPI[idx++].pin; + } + #else /* OCTOSPI */ /* Enable the QuadSPI memory interface clock */ __HAL_RCC_QSPI_CLK_ENABLE(); @@ -789,6 +1308,7 @@ __weak void BSP_QSPI_MspInit(void) pin = PinMap_QUADSPI[idx++].pin; } +#endif /* OCTOSPI */ } /** @@ -802,6 +1322,25 @@ __weak void BSP_QSPI_MspDeInit(void) uint8_t idx = 0; PinName pin; +#ifdef OCTOSPI + /* OSPI CLK, CS, D0-D3 GPIO pins de-configuration */ + pin = PinMap_OCTOSPI[idx].pin; + while(pin != NC) + { + port = get_GPIO_Port(STM_PORT(pin)); + GPIO_InitStruct.Pin = STM_GPIO_PIN(pin); + HAL_GPIO_DeInit(port, GPIO_InitStruct.Pin); + + pin = PinMap_OCTOSPI[idx++].pin; + } + + /* Reset the OctoSPI memory interface */ + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + + /* Disable the OctoSPI memory interface clock */ + __HAL_RCC_OSPI1_CLK_DISABLE(); +#else /* OCTOSPI */ /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration */ pin = PinMap_QUADSPI[idx].pin; while(pin != NC) @@ -819,6 +1358,7 @@ __weak void BSP_QSPI_MspDeInit(void) /* Disable the QuadSPI memory interface clock */ __HAL_RCC_QSPI_CLK_DISABLE(); +#endif /* OCTOSPI */ } /** @@ -834,8 +1374,45 @@ __weak void BSP_QSPI_MspDeInit(void) * @param hqspi : QSPI handle * @retval None */ -static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) +static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the reset enable command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = RESET_ENABLE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Send the command */ + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Send the reset memory command */ + sCommand.Instruction = RESET_MEMORY_CMD; + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait the memory is ready */ + if (QSPI_AutoPollingMemReady(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + { + return QSPI_ERROR; + } + +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; /* Initialize the reset enable command */ @@ -867,6 +1444,7 @@ static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -876,8 +1454,53 @@ static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) * @param hqspi : QSPI handle * @retval None */ -static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi) +static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + OSPI_AutoPollingTypeDef sConfig; + + /* Enable write operations */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = WRITE_ENABLE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for write enabling */ + sConfig.Match = MX25R6435F_SR_WEL; + sConfig.Mask = MX25R6435F_SR_WEL; + sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; + + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.NbData = 1; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; QSPI_AutoPollingTypeDef sConfig; @@ -912,6 +1535,7 @@ static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi) { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -922,8 +1546,44 @@ static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi) * @param Timeout : Timeout for auto-polling * @retval None */ -static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) +static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Timeout) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + OSPI_AutoPollingTypeDef sConfig; + + /* Configure automatic polling mode to wait for memory ready */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.NbData = 1; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + sConfig.Match = 0; + sConfig.Mask = MX25R6435F_SR_WIP; + sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_AutoPolling(hospi, &sConfig, Timeout) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; QSPI_AutoPollingTypeDef sConfig; @@ -949,6 +1609,7 @@ static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Time { return QSPI_ERROR; } +#endif /* OCTOSPI */ return QSPI_OK; } @@ -959,8 +1620,85 @@ static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Time * @param Operation : QSPI_QUAD_ENABLE or QSPI_QUAD_DISABLE mode * @retval None */ -static uint8_t QSPI_QuadMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation) +static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + uint8_t reg; + + /* Read status register */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_Receive(hospi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Enable write operations */ + if (QSPI_WriteEnable(hospi) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Activate/deactivate the Quad mode */ + if (Operation == QSPI_QUAD_ENABLE) + { + SET_BIT(reg, MX25R6435F_SR_QE); + } + else + { + CLEAR_BIT(reg, MX25R6435F_SR_QE); + } + + sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_Transmit(hospi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Wait that memory is ready */ + if (QSPI_AutoPollingMemReady(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Check the configuration has been correctly done */ + sCommand.Instruction = READ_STATUS_REG_CMD; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_Receive(hospi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; uint8_t reg; @@ -1032,6 +1770,7 @@ static uint8_t QSPI_QuadMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation) { return QSPI_ERROR; } +#endif /* OCTOSPI */ if ((((reg & MX25R6435F_SR_QE) == 0) && (Operation == QSPI_QUAD_ENABLE)) || (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE))) @@ -1048,8 +1787,101 @@ static uint8_t QSPI_QuadMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation) * @param Operation : QSPI_HIGH_PERF_ENABLE or QSPI_HIGH_PERF_DISABLE high performance mode * @retval None */ -static uint8_t QSPI_HighPerfMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation) +static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + uint8_t reg[3]; + + /* Read status register */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_Receive(hospi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Read configuration registers */ + sCommand.Instruction = READ_CFG_REG_CMD; + sCommand.NbData = 2; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_Receive(hospi, &(reg[1]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Enable write operations */ + if (QSPI_WriteEnable(hospi) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Activate/deactivate the Quad mode */ + if (Operation == QSPI_HIGH_PERF_ENABLE) + { + SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); + } + else + { + CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); + } + + sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; + sCommand.NbData = 3; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_Transmit(hospi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + /* Wait that memory is ready */ + if (QSPI_AutoPollingMemReady(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + { + return QSPI_ERROR; + } + + /* Check the configuration has been correctly done */ + sCommand.Instruction = READ_CFG_REG_CMD; + sCommand.NbData = 2; + + if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } + + if (HAL_OSPI_Receive(hospi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return QSPI_ERROR; + } +#else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; uint8_t reg[3]; @@ -1137,6 +1969,7 @@ static uint8_t QSPI_HighPerfMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation) { return QSPI_ERROR; } +#endif /* OCTOSPI */ if ((((reg[1] & MX25R6435F_CR2_LH_SWITCH) == 0) && (Operation == QSPI_HIGH_PERF_ENABLE)) || (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE))) diff --git a/src/mx25r6435f_driver.h b/src/mx25r6435f_driver.h index 8a16c9d..5381568 100644 --- a/src/mx25r6435f_driver.h +++ b/src/mx25r6435f_driver.h @@ -48,10 +48,16 @@ #include "stm32_def.h" #include "mx25r6435f_desc.h" +#if defined(OCTOSPI1) +#define OCTOSPI OCTOSPI1 +#elif defined(OCTOSPI2) +#define OCTOSPI OCTOSPI2 +#else /* Checks if QSPI available */ #ifndef QUADSPI #error "QSPI not available. MX25R6435F library compilation failed." -#endif +#endif /* QSPI */ +#endif /* OSPI */ /** @addtogroup BSP * @{ From 3112b29a0d5db08e6ed0f1a8f92e7d3b590cdcd3 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 8 Sep 2020 12:02:36 +0200 Subject: [PATCH 2/5] Add capabilities to redefine QSPI pins Signed-off-by: Frederic Pillon --- README.md | 77 +++-- keywords.txt | 3 + src/MX25R6435F.cpp | 36 ++- src/MX25R6435F.h | 56 +++- src/mx25r6435f_driver.c | 624 +++++++++++++++++++--------------------- src/mx25r6435f_driver.h | 83 ++++-- 6 files changed, 496 insertions(+), 383 deletions(-) diff --git a/README.md b/README.md index b882c37..563d82f 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,69 @@ # MX25R6435F -Arduino library to support the Quad-SPI NOR Flash memory MX25R6435F +Arduino library to support the Quad-SPI NOR Flash memory MX25R6435F using the Quad SPI flash memories interface. Since library version 2.0.0 and [STM32 core](https://github.com/stm32duino/Arduino_Core_STM32) version 2.0.0 the OctoSPI Flash memories interface can also be used. ## API The library provides the following API: -* begin() -* end() -* write() -* read() -* mapped() -* erase() -* eraseChip() -* eraseSector() -* suspendErase() -* resumeErase() -* sleep() -* wakeup() -* status() -* info() -* length() +* `begin()` +* `end()` +* `write()` +* `read()` +* `mapped()` +* `erase()` +* `eraseChip()` +* `eraseSector()` +* `suspendErase()` +* `resumeErase()` +* `sleep()` +* `wakeup()` +* `status()` +* `info()` +* `length()` + +Since library version 2.0.0, xSPI pins can be defined at sketch level, using: + +* To redefine the default one before call of `begin()`: + + * `setDx(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3)` + * `setDx(PinName data0, PinName data1, PinName data2, PinName data3)` + * `setSSEL(uint32_t ssel)` + * `setSSEL(PinName ssel)` + * `setSCLK(uint32_t sclk)` + * `setSCLK(PinName sclk)` + + *Code snippet:* +```C++ + MX25R6435F.setDx(PE12, PE13, PE14, PE15); // using pin number + MX25R6435F.setSCLK(PE10); + MX25R6435F.setSSEL(PE_11); // using PinName + MX25R6435F.begin(); +``` + +* or using the `begin()` method: + + * `MX25R6435FClass(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t clk, uint8_t ssel)` + + *Code snippet:* +```C++ + MX25R6435F.begin(PE12, PE13, PE14, PE15, PE10, PE11); +``` + +* or by redefining the default pins definition (using [build_opt.h](https://github.com/stm32duino/wiki/wiki/Customize-build-options-using-build_opt.h) or [hal_conf_extra.h](https://github.com/stm32duino/wiki/wiki/HAL-configuration#customize-hal-or-variant-definition)): + + * `MX25R6435F_D0` + * `MX25R6435F_D1` + * `MX25R6435F_D2` + * `MX25R6435F_D3` + * `MX25R6435F_SCLK` + * `MX25R6435F_SSEL` ## Examples -3 sketches provide basic examples to show how to use the library API. -demo.ino uses basic read/write functions. -eraseChip.ino erases all data present in the memory. -memoryMappedMode.ino shows how to use the mapped mode. +3 sketches provide basic examples to show how to use the library API: +* `demo.ino` uses basic read/write functions. +* `eraseChip.ino` erases all data present in the memory. +* `memoryMappedMode.ino` shows how to use the mapped mode. ## Documentation diff --git a/keywords.txt b/keywords.txt index 9472dfa..67bee68 100644 --- a/keywords.txt +++ b/keywords.txt @@ -26,6 +26,9 @@ wakeup KEYWORD2 status KEYWORD2 info KEYWORD2 length KEYWORD2 +setDx KEYWORD2 +setSCLK KEYWORD2 +setSSEL KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/src/MX25R6435F.cpp b/src/MX25R6435F.cpp index 02e2948..0e01559 100644 --- a/src/MX25R6435F.cpp +++ b/src/MX25R6435F.cpp @@ -42,18 +42,24 @@ MX25R6435FClass MX25R6435F; MX25R6435FClass::MX25R6435FClass(): initDone(0) { - } -void MX25R6435FClass::begin(void) +void MX25R6435FClass::begin(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t sclk, uint8_t ssel) { - if(BSP_QSPI_Init() == MEMORY_OK) + _qspi.pin_d0 = digitalPinToPinName(data0); + _qspi.pin_d1 = digitalPinToPinName(data1); + _qspi.pin_d2 = digitalPinToPinName(data2); + _qspi.pin_d3 = digitalPinToPinName(data3); + _qspi.pin_sclk = digitalPinToPinName(sclk); + _qspi.pin_ssel = digitalPinToPinName(ssel); + + if (BSP_QSPI_Init(&_qspi) == MEMORY_OK) { initDone = 1; } void MX25R6435FClass::end(void) { - BSP_QSPI_DeInit(); + BSP_QSPI_DeInit(&_qspi); initDone = 0; } @@ -67,7 +73,7 @@ uint32_t MX25R6435FClass::write(uint8_t *pData, uint32_t addr, uint32_t size) if((pData == NULL) || (initDone == 0)) return 0; - if(BSP_QSPI_Write(pData, addr, size) != MEMORY_OK) + if(BSP_QSPI_Write(&_qspi, pData, addr, size) != MEMORY_OK) return 0; return size; @@ -85,12 +91,12 @@ uint8_t MX25R6435FClass::read(uint32_t addr) void MX25R6435FClass::read(uint8_t *pData, uint32_t addr, uint32_t size) { if((pData != NULL) && (initDone == 1)) - BSP_QSPI_Read(pData, addr, size); + BSP_QSPI_Read(&_qspi, pData, addr, size); } uint8_t *MX25R6435FClass::mapped(void) { - if(BSP_QSPI_EnableMemoryMappedMode() != MEMORY_OK) + if(BSP_QSPI_EnableMemoryMappedMode(&_qspi) != MEMORY_OK) return NULL; return (uint8_t *)MEMORY_MAPPED_ADDRESS; @@ -101,7 +107,7 @@ uint8_t MX25R6435FClass::erase(uint32_t addr) if(initDone == 0) return MEMORY_ERROR; - return BSP_QSPI_Erase_Block(addr); + return BSP_QSPI_Erase_Block(&_qspi, addr); } uint8_t MX25R6435FClass::eraseChip(void) @@ -109,7 +115,7 @@ uint8_t MX25R6435FClass::eraseChip(void) if(initDone == 0) return MEMORY_ERROR; - return BSP_QSPI_Erase_Chip(); + return BSP_QSPI_Erase_Chip(&_qspi); } uint8_t MX25R6435FClass::eraseSector(uint32_t sector) @@ -117,7 +123,7 @@ uint8_t MX25R6435FClass::eraseSector(uint32_t sector) if(initDone == 0) return MEMORY_ERROR; - return BSP_QSPI_Erase_Sector(sector); + return BSP_QSPI_Erase_Sector(&_qspi, sector); } uint8_t MX25R6435FClass::suspendErase(void) @@ -125,7 +131,7 @@ uint8_t MX25R6435FClass::suspendErase(void) if(initDone == 0) return MEMORY_ERROR; - return BSP_QSPI_SuspendErase(); + return BSP_QSPI_SuspendErase(&_qspi); } uint8_t MX25R6435FClass::resumeErase(void) @@ -133,7 +139,7 @@ uint8_t MX25R6435FClass::resumeErase(void) if(initDone == 0) return MEMORY_ERROR; - return BSP_QSPI_ResumeErase(); + return BSP_QSPI_ResumeErase(&_qspi); } uint8_t MX25R6435FClass::sleep(void) @@ -141,7 +147,7 @@ uint8_t MX25R6435FClass::sleep(void) if(initDone == 0) return MEMORY_ERROR; - return BSP_QSPI_EnterDeepPowerDown(); + return BSP_QSPI_EnterDeepPowerDown(&_qspi); } uint8_t MX25R6435FClass::wakeup(void) @@ -149,12 +155,12 @@ uint8_t MX25R6435FClass::wakeup(void) if(initDone == 0) return MEMORY_ERROR; - return BSP_QSPI_LeaveDeepPowerDown(); + return BSP_QSPI_LeaveDeepPowerDown(&_qspi); } uint8_t MX25R6435FClass::status(void) { - return BSP_QSPI_GetStatus(); + return BSP_QSPI_GetStatus(&_qspi); } uint32_t MX25R6435FClass::info(memory_info_t info) diff --git a/src/MX25R6435F.h b/src/MX25R6435F.h index 1386210..9536547 100644 --- a/src/MX25R6435F.h +++ b/src/MX25R6435F.h @@ -39,8 +39,28 @@ #ifndef _MX25R6435F_H_ #define _MX25R6435F_H_ +#include "Arduino.h" #include "mx25r6435f_driver.h" +#ifndef MX25R6435F_D0 +#define MX25R6435F_D0 NC +#endif +#ifndef MX25R6435F_D1 +#define MX25R6435F_D1 NC +#endif +#ifndef MX25R6435F_D2 +#define MX25R6435F_D2 NC +#endif +#ifndef MX25R6435F_D3 +#define MX25R6435F_D3 NC +#endif +#ifndef MX25R6435F_SCLK +#define MX25R6435F_SCLK NC +#endif +#ifndef MX25R6435F_SSEL +#define MX25R6435F_SSEL NC +#endif + /* Memory configuration paremeters */ typedef enum { MEMORY_SIZE, @@ -65,8 +85,41 @@ class MX25R6435FClass public: MX25R6435FClass(); + // setDx/SCLK/SSEL have to be called before begin() + void setDx(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3) + { + _qspi.pin_d0 = digitalPinToPinName(data0); + _qspi.pin_d1 = digitalPinToPinName(data1); + _qspi.pin_d2 = digitalPinToPinName(data2); + _qspi.pin_d3 = digitalPinToPinName(data3); + }; + void setSCLK(uint32_t sclk) + { + _qspi.pin_sclk = digitalPinToPinName(sclk); + }; + void setSSEL(uint32_t ssel) + { + _qspi.pin_ssel = digitalPinToPinName(ssel); + }; + + void setDx(PinName data0, PinName data1, PinName data2, PinName data3) + { + _qspi.pin_d0 = (data0); + _qspi.pin_d1 = (data1); + _qspi.pin_d2 = (data2); + _qspi.pin_d3 = (data3); + }; + void setSCLK(PinName sclk) + { + _qspi.pin_sclk = (sclk); + }; + void setSSEL(PinName ssel) + { + _qspi.pin_ssel = (ssel); + }; + /* Initializes the memory interface. */ - void begin(void); + void begin(uint8_t data0 = MX25R6435F_D0, uint8_t data1 = MX25R6435F_D1, uint8_t data2 = MX25R6435F_D2, uint8_t data3 = MX25R6435F_D3, uint8_t sclk = MX25R6435F_SCLK, uint8_t ssel = MX25R6435F_SSEL); /* De-Initializes the memory interface. */ void end(void); @@ -174,6 +227,7 @@ class MX25R6435FClass private: uint8_t initDone; + QSPI_t _qspi; }; extern MX25R6435FClass MX25R6435F; diff --git a/src/mx25r6435f_driver.c b/src/mx25r6435f_driver.c index 4c4fd7d..5c7ad07 100644 --- a/src/mx25r6435f_driver.c +++ b/src/mx25r6435f_driver.c @@ -79,8 +79,8 @@ #endif /* Includes ------------------------------------------------------------------*/ +#include "core_debug.h" #include "mx25r6435f_driver.h" -#include "PeripheralPins.h" /** @addtogroup BSP * @{ @@ -111,15 +111,7 @@ /** @defgroup STM32L475E_IOT01_QSPI_Private_Variables QSPI Private Variables * @{ */ -#ifdef OCTOSPI -OSPI_HandleTypeDef OSPIHandle; -#define XSPI_HandleTypeDef OSPI_HandleTypeDef -#define hxspi hospi -#else -QSPI_HandleTypeDef QSPIHandle; -#define XSPI_HandleTypeDef QSPI_HandleTypeDef -#define hxspi hqspi -#endif /* OCTOSPI */ + /** * @} */ @@ -166,155 +158,145 @@ static uint8_t qspi_setClockPrescaler(void) { /** * @brief Initializes the QSPI interface. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_Init(void) +uint8_t BSP_QSPI_Init(QSPI_t *obj) { -#ifdef OCTOSPI - OSPIHandle.Instance = OCTOSPI; - - /* Call the DeInit function to reset the driver */ - if (HAL_OSPI_DeInit(&OSPIHandle) != HAL_OK) -#else - QSPIHandle.Instance = QUADSPI; - - /* Call the DeInit function to reset the driver */ - if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) -#endif /* OCTOSPI */ - { + if (obj == NULL) { return QSPI_ERROR; } + XSPI_HandleTypeDef *handle = &(obj->handle); - /* System level initialization */ - BSP_QSPI_MspInit(); + /* Determine the XSPI to use */ + XSPI_TypeDef *xspi_d0 = pinmap_peripheral(obj->pin_d0, PinMap_XSPI_DATA0); + XSPI_TypeDef *xspi_d1 = pinmap_peripheral(obj->pin_d1, PinMap_XSPI_DATA1); + XSPI_TypeDef *xspi_d2 = pinmap_peripheral(obj->pin_d2, PinMap_XSPI_DATA2); + XSPI_TypeDef *xspi_d3 = pinmap_peripheral(obj->pin_d3, PinMap_XSPI_DATA3); -#ifdef OCTOSPI - /* OSPI initialization */ - OSPIHandle.Init.FifoThreshold = 4; - OSPIHandle.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; - OSPIHandle.Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX; - OSPIHandle.Init.DeviceSize = POSITION_VAL(MX25R6435F_FLASH_SIZE); - OSPIHandle.Init.ChipSelectHighTime = 1; - OSPIHandle.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; - OSPIHandle.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; - OSPIHandle.Init.ClockPrescaler = 4; /* QSPI clock = 110MHz / ClockPrescaler = 27.5 MHz */ - OSPIHandle.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE; - OSPIHandle.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; - OSPIHandle.Init.ChipSelectBoundary = 0; - OSPIHandle.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED; + XSPI_TypeDef *xspi_sclk = pinmap_peripheral(obj->pin_sclk, PinMap_XSPI_SCLK); + XSPI_TypeDef *xspi_ssel = pinmap_peripheral(obj->pin_ssel, PinMap_XSPI_SSEL); - if (HAL_OSPI_Init(&OSPIHandle) != HAL_OK) - { + /* Pins Dx/SSEL/SCLK must not be NP. */ + if (xspi_d0 == NP || xspi_d1 == NP || xspi_d2 == NP || xspi_sclk == NP || xspi_ssel == NP) { + core_debug("ERROR: at least one QSPI pin has no peripheral\n"); return QSPI_ERROR; } - /* QSPI memory reset */ - if (QSPI_ResetMemory(&OSPIHandle) != QSPI_OK) - { - return QSPI_NOT_SUPPORTED; - } + XSPI_TypeDef *spi_d01 = pinmap_merge_peripheral(xspi_d0, xspi_d1); + XSPI_TypeDef *spi_d23 = pinmap_merge_peripheral(xspi_d2, xspi_d3); + XSPI_TypeDef *spi_dx = pinmap_merge_peripheral(spi_d01, spi_d23); + XSPI_TypeDef *spi_sxxx = pinmap_merge_peripheral(xspi_sclk, xspi_ssel); - /* QSPI quad enable */ - if (QSPI_QuadMode(&OSPIHandle, QSPI_QUAD_ENABLE) != QSPI_OK) - { - return QSPI_ERROR; - } + obj->qspi = pinmap_merge_peripheral(spi_dx, spi_sxxx); - /* High performance mode enable */ - if (QSPI_HighPerfMode(&OSPIHandle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK) - { + /* Are all pins connected to the same SPI instance? */ + if (obj->qspi == NP) { + core_debug("ERROR: QSPI pins mismatch\n"); return QSPI_ERROR; } - /* Re-configure the clock for the high performance mode */ - OSPIHandle.Init.ClockPrescaler = 2; /* QSPI clock = 110MHz / ClockPrescaler = 55 MHz */ - if (HAL_OSPI_Init(&OSPIHandle) != HAL_OK) - { + handle->Instance = obj->qspi; + + /* Call the DeInit function to reset the driver */ + if (HAL_XSPI_DeInit(handle) != HAL_OK) { return QSPI_ERROR; } + + /* System level initialization */ + BSP_QSPI_MspInit(obj); + +#ifdef OCTOSPI + /* OSPI initialization */ + handle->Init.FifoThreshold = 4; + handle->Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + handle->Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX; + handle->Init.DeviceSize = POSITION_VAL(MX25R6435F_FLASH_SIZE); + handle->Init.ChipSelectHighTime = 1; + handle->Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; + handle->Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; + handle->Init.ClockPrescaler = 4; /* QSPI clock = 110MHz / ClockPrescaler = 27.5 MHz */ + handle->Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE; + handle->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; + handle->Init.ChipSelectBoundary = 0; + handle->Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED; #else /* OCTOSPI */ - /* QSPI initialization */ + /* QSPI initialization */ /* High performance mode clock is limited to 80 MHz */ - QSPIHandle.Init.ClockPrescaler = qspi_setClockPrescaler() + 1; /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ - QSPIHandle.Init.FifoThreshold = 4; - QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; - QSPIHandle.Init.FlashSize = POSITION_VAL(MX25R6435F_FLASH_SIZE) - 1; - QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; - QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; + handle->Init.ClockPrescaler = qspi_setClockPrescaler() + 1; /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ + handle->Init.FifoThreshold = 4; + handle->Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; + handle->Init.FlashSize = POSITION_VAL(MX25R6435F_FLASH_SIZE) - 1; + handle->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; + handle->Init.ClockMode = QSPI_CLOCK_MODE_0; +#endif - if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) - { + if (HAL_XSPI_Init(handle) != HAL_OK) { return QSPI_ERROR; } /* QSPI memory reset */ - if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK) - { + if (QSPI_ResetMemory(handle) != QSPI_OK) { return QSPI_NOT_SUPPORTED; } /* QSPI quad enable */ - if (QSPI_QuadMode(&QSPIHandle, QSPI_QUAD_ENABLE) != QSPI_OK) - { + if (QSPI_QuadMode(handle, QSPI_QUAD_ENABLE) != QSPI_OK) { return QSPI_ERROR; } /* High performance mode enable */ - if (QSPI_HighPerfMode(&QSPIHandle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK) - { + if (QSPI_HighPerfMode(handle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK) { return QSPI_ERROR; } /* Re-configure the clock for the high performance mode */ /* High performance mode clock is limited to 80 MHz */ - QSPIHandle.Init.ClockPrescaler = qspi_setClockPrescaler(); /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ + handle->Init.ClockPrescaler = qspi_setClockPrescaler(); /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ - if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) - { + if (HAL_XSPI_Init(handle) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Init(handle) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ return QSPI_OK; } /** * @brief De-Initializes the QSPI interface. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_DeInit(void) +uint8_t BSP_QSPI_DeInit(QSPI_t *obj) { -#ifdef OCTOSPI - OSPIHandle.Instance = OCTOSPI; - - /* Call the DeInit function to reset the driver */ - if (HAL_OSPI_DeInit(&OSPIHandle) != HAL_OK) -#else /* OCTOSPI */ - QSPIHandle.Instance = QUADSPI; + XSPI_HandleTypeDef *handle = &(obj->handle); /* Call the DeInit function to reset the driver */ - if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) -#endif /* OCTOSPI */ - { + if (HAL_XSPI_DeInit(handle) != HAL_OK) { return QSPI_ERROR; } /* System level De-initialization */ - BSP_QSPI_MspDeInit(); + BSP_QSPI_MspDeInit(obj); return QSPI_OK; } /** * @brief Reads an amount of data from the QSPI memory. + * @param obj : pointer to QSPI_t structure * @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) +uint8_t BSP_QSPI_Read(QSPI_t *obj, uint8_t* pData, uint32_t ReadAddr, uint32_t Size) { + XSPI_HandleTypeDef *handle = &(obj->handle); #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; @@ -339,15 +321,15 @@ uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Configure the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - + /* Reception of the data */ - if (HAL_OSPI_Receive(&OSPIHandle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(handle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -371,13 +353,13 @@ uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Configure the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(handle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -388,13 +370,15 @@ uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) /** * @brief Writes an amount of data to the QSPI memory. + * @param obj : pointer to QSPI_t structure * @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) +uint8_t BSP_QSPI_Write(QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t Size) { + XSPI_HandleTypeDef *handle = &(obj->handle); #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; #else /* OCTOSPI */ @@ -432,7 +416,7 @@ uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Perform the write page by page */ do { @@ -440,25 +424,25 @@ uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) sCommand.NbData = current_size; /* Enable write operations */ - if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } - + /* Configure the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - + /* Transmission of the data */ - if (HAL_OSPI_Transmit(&OSPIHandle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Transmit(handle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait for end of program */ - if (QSPI_AutoPollingMemReady(&OSPIHandle, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + if (QSPI_AutoPollingMemReady(handle, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } @@ -483,25 +467,25 @@ uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) sCommand.NbData = current_size; /* Enable write operations */ - if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Configure the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Transmission of the data */ - if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Transmit(handle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait for end of program */ - if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + if (QSPI_AutoPollingMemReady(handle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } @@ -518,11 +502,13 @@ uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size) /** * @brief Erases the specified block of the QSPI memory. + * @param obj : pointer to QSPI_t structure * @param BlockAddress : Block address to erase * @retval QSPI memory status */ -uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) +uint8_t BSP_QSPI_Erase_Block(QSPI_t *obj, uint32_t BlockAddress) { + XSPI_HandleTypeDef *handle = &(obj->handle); #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; @@ -544,19 +530,19 @@ uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; /* Enable write operations */ - if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - - /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(&OSPIHandle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) { return QSPI_ERROR; } @@ -578,19 +564,19 @@ uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Enable write operations */ - if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) { return QSPI_ERROR; } @@ -601,6 +587,7 @@ uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) /** * @brief Erases the specified sector of the QSPI memory. + * @param obj : pointer to QSPI_t structure * @param Sector : Sector address to erase (0 to 255) * @retval QSPI memory status * @note This function is non blocking meaning that sector erase @@ -609,16 +596,18 @@ uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress) * to know when the device is available again (i.e. erase operation * completed). */ -uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) +uint8_t BSP_QSPI_Erase_Sector(QSPI_t *obj, uint32_t Sector) { + XSPI_HandleTypeDef *handle = &(obj->handle); + #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; - + if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE)) { return QSPI_ERROR; } - + /* Initialize the erase command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; @@ -635,15 +624,15 @@ uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Enable write operations */ - if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } - + /* Send the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -669,13 +658,13 @@ uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Enable write operations */ - if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -686,10 +675,13 @@ uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector) /** * @brief Erases the entire QSPI memory. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_Erase_Chip(void) +uint8_t BSP_QSPI_Erase_Chip(QSPI_t *obj) { + XSPI_HandleTypeDef *handle = &(obj->handle); + #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; @@ -708,19 +700,19 @@ uint8_t BSP_QSPI_Erase_Chip(void) sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; /* Enable write operations */ - if (QSPI_WriteEnable(&OSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - - /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(&OSPIHandle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) { return QSPI_ERROR; } @@ -740,19 +732,19 @@ uint8_t BSP_QSPI_Erase_Chip(void) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Enable write operations */ - if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK) + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) { return QSPI_ERROR; } @@ -763,10 +755,12 @@ uint8_t BSP_QSPI_Erase_Chip(void) /** * @brief Reads current status of the QSPI memory. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_GetStatus(void) +uint8_t BSP_QSPI_GetStatus(QSPI_t *obj) { + XSPI_HandleTypeDef *handle = &(obj->handle); uint8_t reg; #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; @@ -788,17 +782,17 @@ uint8_t BSP_QSPI_GetStatus(void) sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; /* Configure the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_OSPI_Receive(&OSPIHandle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(handle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - + /* Check the value of the register */ if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) { @@ -813,13 +807,13 @@ uint8_t BSP_QSPI_GetStatus(void) sCommand.Instruction = READ_STATUS_REG_CMD; /* Configure the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_OSPI_Receive(&OSPIHandle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(handle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -839,13 +833,13 @@ uint8_t BSP_QSPI_GetStatus(void) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Configure the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(handle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -864,13 +858,13 @@ uint8_t BSP_QSPI_GetStatus(void) sCommand.Instruction = READ_STATUS_REG_CMD; /* Configure the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_QSPI_Receive(&QSPIHandle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(handle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -906,10 +900,13 @@ uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo) /** * @brief Configure the QSPI in memory-mapped mode + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_EnableMemoryMappedMode(void) +uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj) { + XSPI_HandleTypeDef *handle = &(obj->handle); + #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; OSPI_MemoryMappedTypeDef sMemMappedCfg; @@ -933,9 +930,9 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(void) sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Configure the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -945,17 +942,17 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(void) sCommand.Instruction = QUAD_PAGE_PROG_CMD; sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; sCommand.DummyCycles = 0; - + /* Configure the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure the memory mapped mode */ sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE; - - if (HAL_OSPI_MemoryMapped(&OSPIHandle, &sMemMappedCfg) != HAL_OK) + + if (HAL_OSPI_MemoryMapped(handle, &sMemMappedCfg) != HAL_OK) { return QSPI_ERROR; } @@ -980,7 +977,7 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(void) /* Configure the memory mapped mode */ sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; - if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK) + if (HAL_QSPI_MemoryMapped(handle, &sCommand, &sMemMappedCfg) != HAL_OK) { return QSPI_ERROR; } @@ -991,17 +988,20 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(void) /** * @brief This function suspends an ongoing erase command. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_SuspendErase(void) +uint8_t BSP_QSPI_SuspendErase(QSPI_t *obj) { + XSPI_HandleTypeDef *handle = &(obj->handle); + #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; - - /* Check whether the device is busy (erase operation is + + /* Check whether the device is busy (erase operation is in progress). */ - if (BSP_QSPI_GetStatus() == QSPI_BUSY) + if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) { /* Initialize the suspend command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; @@ -1016,9 +1016,9 @@ uint8_t BSP_QSPI_SuspendErase(void) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Send the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1042,13 +1042,13 @@ uint8_t BSP_QSPI_SuspendErase(void) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Send the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } #endif /* OCTOSPI */ - if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) + if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) { return QSPI_OK; } @@ -1061,15 +1061,18 @@ uint8_t BSP_QSPI_SuspendErase(void) /** * @brief This function resumes a paused erase command. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_ResumeErase(void) +uint8_t BSP_QSPI_ResumeErase(QSPI_t *obj) { + XSPI_HandleTypeDef *handle = &(obj->handle); + #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; - + /* Check whether the device is in suspended state */ - if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) + if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) { /* Initialize the resume command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; @@ -1084,9 +1087,9 @@ uint8_t BSP_QSPI_ResumeErase(void) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Send the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1109,7 +1112,7 @@ uint8_t BSP_QSPI_ResumeErase(void) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Send the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1122,7 +1125,7 @@ uint8_t BSP_QSPI_ResumeErase(void) if the device is not in a suspended state. */ - if (BSP_QSPI_GetStatus() == QSPI_BUSY) + if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) { return QSPI_OK; } @@ -1135,13 +1138,16 @@ uint8_t BSP_QSPI_ResumeErase(void) /** * @brief This function enter the QSPI memory in deep power down mode. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_EnterDeepPowerDown(void) +uint8_t BSP_QSPI_EnterDeepPowerDown(QSPI_t *obj) { + XSPI_HandleTypeDef *handle = &(obj->handle); + #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; - + /* Initialize the deep power down command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; @@ -1155,9 +1161,9 @@ uint8_t BSP_QSPI_EnterDeepPowerDown(void) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Send the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1176,7 +1182,7 @@ uint8_t BSP_QSPI_EnterDeepPowerDown(void) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Send the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1190,13 +1196,16 @@ uint8_t BSP_QSPI_EnterDeepPowerDown(void) /** * @brief This function leave the QSPI memory from deep power down mode. + * @param obj : pointer to QSPI_t structure * @retval QSPI memory status */ -uint8_t BSP_QSPI_LeaveDeepPowerDown(void) +uint8_t BSP_QSPI_LeaveDeepPowerDown(QSPI_t *obj) { + XSPI_HandleTypeDef *handle = &(obj->handle); + #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; - + /* Initialize the erase command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; @@ -1210,9 +1219,9 @@ uint8_t BSP_QSPI_LeaveDeepPowerDown(void) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - + /* Send the command */ - if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1232,7 +1241,7 @@ uint8_t BSP_QSPI_LeaveDeepPowerDown(void) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Send the command */ - if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1246,112 +1255,85 @@ uint8_t BSP_QSPI_LeaveDeepPowerDown(void) /** * @brief Initializes the QSPI MSP. + * @param obj : pointer to QSPI_t structure * @retval None */ -__weak void BSP_QSPI_MspInit(void) +__weak void BSP_QSPI_MspInit(QSPI_t *obj) { - GPIO_InitTypeDef GPIO_InitStruct; - GPIO_TypeDef *port; - uint8_t idx = 0; - PinName pin; - #ifdef OCTOSPI - /* Enable the OctoSPI memory interface clock */ - __HAL_RCC_OSPI1_CLK_ENABLE(); - /* Reset the OctoSPI memory interface */ - __HAL_RCC_OSPI1_FORCE_RESET(); - __HAL_RCC_OSPI1_RELEASE_RESET(); + /* Enable the OctoSPI memory interface clock */ + /* Reset the OctoSPI memory interface */ +#if defined(OCTOSPI1) + if (obj->qspi == OCTOSPI1) { + __HAL_RCC_OSPI1_CLK_ENABLE(); - /* Enable GPIO clocks */ - __HAL_RCC_GPIOE_CLK_ENABLE(); - - /* OCTOSPI CLK, CS, D0, D1, D2 and D3 GPIO pins configuration */ - pin = PinMap_OCTOSPI[idx].pin; - while(pin != NC) - { - /* Enable GPIO clocks */ - port = set_GPIO_Port_Clock(STM_PORT(pin)); - - /* Pin configuration */ - GPIO_InitStruct.Pin = STM_GPIO_PIN(pin); - GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(pin, PinMap_OCTOSPI)); - GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(pin, PinMap_OCTOSPI)); - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(pin, PinMap_OCTOSPI)); - HAL_GPIO_Init(port, &GPIO_InitStruct); + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + } +#endif +#if defined(OCTOSPI2) + if (obj->qspi == OCTOSPI2) { + __HAL_RCC_OSPI2_CLK_ENABLE(); - pin = PinMap_OCTOSPI[idx++].pin; + __HAL_RCC_OSPI2_FORCE_RESET(); + __HAL_RCC_OSPI2_RELEASE_RESET(); } - #else /* OCTOSPI */ +#endif +#else /* OCTOSPI */ /* Enable the QuadSPI memory interface clock */ __HAL_RCC_QSPI_CLK_ENABLE(); /* Reset the QuadSPI memory interface */ __HAL_RCC_QSPI_FORCE_RESET(); __HAL_RCC_QSPI_RELEASE_RESET(); - - /* QSPI CLK, CS, D0, D1, D2 and D3 GPIO pins configuration */ - pin = PinMap_QUADSPI[idx].pin; - while(pin != NC) - { - /* Enable GPIO clocks */ - port = set_GPIO_Port_Clock(STM_PORT(pin)); - - /* Pin configuration */ - GPIO_InitStruct.Pin = STM_GPIO_PIN(pin); - GPIO_InitStruct.Mode = STM_PIN_MODE(pinmap_function(pin, PinMap_QUADSPI)); - GPIO_InitStruct.Pull = STM_PIN_PUPD(pinmap_function(pin, PinMap_QUADSPI)); - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = STM_PIN_AFNUM(pinmap_function(pin, PinMap_QUADSPI)); - HAL_GPIO_Init(port, &GPIO_InitStruct); - - pin = PinMap_QUADSPI[idx++].pin; - } #endif /* OCTOSPI */ + + /* Configure QSPI GPIO pins */ + pinmap_pinout(obj->pin_d0, PinMap_XSPI_DATA0); + pinmap_pinout(obj->pin_d1, PinMap_XSPI_DATA1); + pinmap_pinout(obj->pin_d2, PinMap_XSPI_DATA2); + pinmap_pinout(obj->pin_d3, PinMap_XSPI_DATA3); + pinmap_pinout(obj->pin_sclk, PinMap_XSPI_SCLK); + pinmap_pinout(obj->pin_ssel, PinMap_XSPI_SSEL); } /** * @brief De-Initializes the QSPI MSP. + * @param obj : pointer to QSPI_t structure * @retval None */ -__weak void BSP_QSPI_MspDeInit(void) +__weak void BSP_QSPI_MspDeInit(QSPI_t *obj) { - GPIO_InitTypeDef GPIO_InitStruct; - GPIO_TypeDef *port; - uint8_t idx = 0; - PinName pin; - -#ifdef OCTOSPI - /* OSPI CLK, CS, D0-D3 GPIO pins de-configuration */ - pin = PinMap_OCTOSPI[idx].pin; - while(pin != NC) - { - port = get_GPIO_Port(STM_PORT(pin)); - GPIO_InitStruct.Pin = STM_GPIO_PIN(pin); - HAL_GPIO_DeInit(port, GPIO_InitStruct.Pin); + /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration */ - pin = PinMap_OCTOSPI[idx++].pin; - } + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d0), STM_GPIO_PIN(obj->pin_d0)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d1), STM_GPIO_PIN(obj->pin_d1)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d2), STM_GPIO_PIN(obj->pin_d2)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d3), STM_GPIO_PIN(obj->pin_d3)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_sclk), STM_GPIO_PIN(obj->pin_sclk)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_ssel), STM_GPIO_PIN(obj->pin_ssel)); +#ifdef OCTOSPI +#if defined(OCTOSPI1) /* Reset the OctoSPI memory interface */ - __HAL_RCC_OSPI1_FORCE_RESET(); - __HAL_RCC_OSPI1_RELEASE_RESET(); - /* Disable the OctoSPI memory interface clock */ - __HAL_RCC_OSPI1_CLK_DISABLE(); -#else /* OCTOSPI */ - /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration */ - pin = PinMap_QUADSPI[idx].pin; - while(pin != NC) - { - port = get_GPIO_Port(STM_PORT(pin)); - GPIO_InitStruct.Pin = STM_GPIO_PIN(pin); - HAL_GPIO_DeInit(port, GPIO_InitStruct.Pin); + if (obj->qspi == OCTOSPI1) { + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); - pin = PinMap_QUADSPI[idx++].pin; + __HAL_RCC_OSPI1_CLK_DISABLE(); } +#endif +#if defined(OCTOSPI2) + if (obj->qspi == OCTOSPI2) { + __HAL_RCC_OSPI2_FORCE_RESET(); + __HAL_RCC_OSPI2_RELEASE_RESET(); + __HAL_RCC_OSPI2_CLK_DISABLE(); + } +#endif +#else /* OCTOSPI */ /* Reset the QuadSPI memory interface */ __HAL_RCC_QSPI_FORCE_RESET(); __HAL_RCC_QSPI_RELEASE_RESET(); @@ -1371,7 +1353,7 @@ __weak void BSP_QSPI_MspDeInit(void) /** * @brief This function reset the QSPI memory. - * @param hqspi : QSPI handle + * @param hxspi : QSPI handle * @retval None */ static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) @@ -1394,20 +1376,20 @@ static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; /* Send the command */ - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Send the reset memory command */ sCommand.Instruction = RESET_MEMORY_CMD; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - /* Configure automatic polling mode to wait the memory is ready */ - if (QSPI_AutoPollingMemReady(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + /* Configure automatic polling mode to wait the memory is ready */ + if (QSPI_AutoPollingMemReady(hxspi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } @@ -1427,20 +1409,20 @@ static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; /* Send the command */ - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Send the reset memory command */ sCommand.Instruction = RESET_MEMORY_CMD; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait the memory is ready */ - if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + if (QSPI_AutoPollingMemReady(hxspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } @@ -1451,7 +1433,7 @@ static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) /** * @brief This function send a Write Enable and wait it is effective. - * @param hqspi : QSPI handle + * @param hxspi : QSPI handle * @retval None */ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) @@ -1474,12 +1456,12 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - - /* Configure automatic polling mode to wait for write enabling */ + + /* Configure automatic polling mode to wait for write enabling */ sConfig.Match = MX25R6435F_SR_WEL; sConfig.Mask = MX25R6435F_SR_WEL; sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND; @@ -1491,12 +1473,12 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.NbData = 1; sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_AutoPolling(hxspi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1515,7 +1497,7 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1531,7 +1513,7 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.Instruction = READ_STATUS_REG_CMD; sCommand.DataMode = QSPI_DATA_1_LINE; - if (HAL_QSPI_AutoPolling(hqspi, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1542,7 +1524,7 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) /** * @brief This function read the SR of the memory and wait the EOP. - * @param hqspi : QSPI handle + * @param hxspi : QSPI handle * @param Timeout : Timeout for auto-polling * @retval None */ @@ -1552,7 +1534,7 @@ static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Time OSPI_RegularCmdTypeDef sCommand; OSPI_AutoPollingTypeDef sConfig; - /* Configure automatic polling mode to wait for memory ready */ + /* Configure automatic polling mode to wait for memory ready */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; sCommand.Instruction = READ_STATUS_REG_CMD; @@ -1574,12 +1556,12 @@ static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Time sConfig.Interval = 0x10; sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_AutoPolling(hospi, &sConfig, Timeout) != HAL_OK) + if (HAL_OSPI_AutoPolling(hxspi, &sConfig, Timeout) != HAL_OK) { return QSPI_ERROR; } @@ -1605,7 +1587,7 @@ static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Time sConfig.Interval = 0x10; sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; - if (HAL_QSPI_AutoPolling(hqspi, &sCommand, &sConfig, Timeout) != HAL_OK) + if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, Timeout) != HAL_OK) { return QSPI_ERROR; } @@ -1616,14 +1598,14 @@ static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Time /** * @brief This function enables/disables the Quad mode of the memory. - * @param hqspi : QSPI handle + * @param hxspi : QSPI handle * @param Operation : QSPI_QUAD_ENABLE or QSPI_QUAD_DISABLE mode * @retval None */ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) { #ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; + OSPI_RegularCmdTypeDef sCommand; uint8_t reg; /* Read status register */ @@ -1642,22 +1624,22 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_Receive(hospi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(hxspi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Enable write operations */ - if (QSPI_WriteEnable(hospi) != QSPI_OK) + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { return QSPI_ERROR; } - + /* Activate/deactivate the Quad mode */ if (Operation == QSPI_QUAD_ENABLE) { @@ -1670,31 +1652,31 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_Transmit(hospi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Transmit(hxspi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + /* Wait that memory is ready */ + if (QSPI_AutoPollingMemReady(hxspi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } - + /* Check the configuration has been correctly done */ sCommand.Instruction = READ_STATUS_REG_CMD; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_Receive(hospi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(hxspi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1714,18 +1696,18 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hqspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(hxspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Enable write operations */ - if (QSPI_WriteEnable(hqspi) != QSPI_OK) + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { return QSPI_ERROR; } @@ -1742,18 +1724,18 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Transmit(hqspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Transmit(hxspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + if (QSPI_AutoPollingMemReady(hxspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } @@ -1761,12 +1743,12 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) /* Check the configuration has been correctly done */ sCommand.Instruction = READ_STATUS_REG_CMD; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hqspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(hxspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1783,7 +1765,7 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) /** * @brief This function enables/disables the high performance mode of the memory. - * @param hqspi : QSPI handle + * @param hxspi : QSPI handle * @param Operation : QSPI_HIGH_PERF_ENABLE or QSPI_HIGH_PERF_DISABLE high performance mode * @retval None */ @@ -1809,12 +1791,12 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_Receive(hospi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(hxspi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1823,22 +1805,22 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = READ_CFG_REG_CMD; sCommand.NbData = 2; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_Receive(hospi, &(reg[1]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(hxspi, &(reg[1]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Enable write operations */ - if (QSPI_WriteEnable(hospi) != QSPI_OK) + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { return QSPI_ERROR; } - + /* Activate/deactivate the Quad mode */ if (Operation == QSPI_HIGH_PERF_ENABLE) { @@ -1852,32 +1834,32 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; sCommand.NbData = 3; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_Transmit(hospi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Transmit(hxspi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hospi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + /* Wait that memory is ready */ + if (QSPI_AutoPollingMemReady(hxspi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } - + /* Check the configuration has been correctly done */ sCommand.Instruction = READ_CFG_REG_CMD; sCommand.NbData = 2; - if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_Receive(hospi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_OSPI_Receive(hxspi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1897,12 +1879,12 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(hxspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1911,18 +1893,18 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = READ_CFG_REG_CMD; sCommand.NbData = 2; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hqspi, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(hxspi, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Enable write operations */ - if (QSPI_WriteEnable(hqspi) != QSPI_OK) + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { return QSPI_ERROR; } @@ -1940,18 +1922,18 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; sCommand.NbData = 3; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Transmit(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Transmit(hxspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) + if (QSPI_AutoPollingMemReady(hxspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } @@ -1960,12 +1942,12 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = READ_CFG_REG_CMD; sCommand.NbData = 2; - if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + if (HAL_QSPI_Receive(hxspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } diff --git a/src/mx25r6435f_driver.h b/src/mx25r6435f_driver.h index 5381568..ee3ff49 100644 --- a/src/mx25r6435f_driver.h +++ b/src/mx25r6435f_driver.h @@ -46,18 +46,9 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32_def.h" +#include "PeripheralPins.h" #include "mx25r6435f_desc.h" -#if defined(OCTOSPI1) -#define OCTOSPI OCTOSPI1 -#elif defined(OCTOSPI2) -#define OCTOSPI OCTOSPI2 -#else -/* Checks if QSPI available */ -#ifndef QUADSPI -#error "QSPI not available. MX25R6435F library compilation failed." -#endif /* QSPI */ -#endif /* OSPI */ /** @addtogroup BSP * @{ @@ -75,6 +66,34 @@ /** @defgroup STM32L475E_IOT01_QSPI_Exported_Constants QSPI Exported Constants * @{ */ + +#if defined(OCTOSPI1) || defined(OCTOSPI2) +#define OCTOSPI +#define XSPI_HandleTypeDef OSPI_HandleTypeDef +#define XSPI_TypeDef OCTOSPI_TypeDef +#define PinMap_XSPI_DATA0 PinMap_OCTOSPI_DATA0 +#define PinMap_XSPI_DATA1 PinMap_OCTOSPI_DATA1 +#define PinMap_XSPI_DATA2 PinMap_OCTOSPI_DATA2 +#define PinMap_XSPI_DATA3 PinMap_OCTOSPI_DATA3 +#define PinMap_XSPI_SCLK PinMap_OCTOSPI_SCLK +#define PinMap_XSPI_SSEL PinMap_OCTOSPI_SSEL +#define HAL_XSPI_Init HAL_OSPI_Init +#define HAL_XSPI_DeInit HAL_OSPI_DeInit +#elif defined(QUADSPI) +#define XSPI_HandleTypeDef QSPI_HandleTypeDef +#define XSPI_TypeDef QUADSPI_TypeDef +#define PinMap_XSPI_DATA0 PinMap_QUADSPI_DATA0 +#define PinMap_XSPI_DATA1 PinMap_QUADSPI_DATA1 +#define PinMap_XSPI_DATA2 PinMap_QUADSPI_DATA2 +#define PinMap_XSPI_DATA3 PinMap_QUADSPI_DATA3 +#define PinMap_XSPI_SCLK PinMap_QUADSPI_SCLK +#define PinMap_XSPI_SSEL PinMap_QUADSPI_SSEL +#define HAL_XSPI_Init HAL_QSPI_Init +#define HAL_XSPI_DeInit HAL_QSPI_DeInit +#else +#error "QSPI feature not available. MX25R6435F library compilation failed." +#endif /* OCTOSPIx */ + /* QSPI Error codes */ #define QSPI_OK ((uint8_t)0x00) #define QSPI_ERROR ((uint8_t)0x01) @@ -99,6 +118,18 @@ typedef struct { uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */ } QSPI_Info; + +typedef struct { + XSPI_HandleTypeDef handle; + XSPI_TypeDef *qspi; + PinName pin_d0; + PinName pin_d1; + PinName pin_d2; + PinName pin_d3; + PinName pin_sclk; + PinName pin_ssel; +} QSPI_t; + /** * @} */ @@ -107,23 +138,23 @@ typedef struct { /** @defgroup STM32L475E_IOT01_QSPI_Exported_Functions QSPI Exported Functions * @{ */ -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_Sector (uint32_t Sector); -uint8_t BSP_QSPI_Erase_Chip (void); -uint8_t BSP_QSPI_GetStatus (void); +uint8_t BSP_QSPI_Init (QSPI_t *obj); +uint8_t BSP_QSPI_DeInit (QSPI_t *obj); +uint8_t BSP_QSPI_Read (QSPI_t *obj, uint8_t* pData, uint32_t ReadAddr, uint32_t Size); +uint8_t BSP_QSPI_Write (QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t Size); +uint8_t BSP_QSPI_Erase_Block (QSPI_t *obj, uint32_t BlockAddress); +uint8_t BSP_QSPI_Erase_Sector (QSPI_t *obj, uint32_t Sector); +uint8_t BSP_QSPI_Erase_Chip (QSPI_t *obj); +uint8_t BSP_QSPI_GetStatus (QSPI_t *obj); uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo); -uint8_t BSP_QSPI_EnableMemoryMappedMode(void); -uint8_t BSP_QSPI_SuspendErase (void); -uint8_t BSP_QSPI_ResumeErase (void); -uint8_t BSP_QSPI_EnterDeepPowerDown (void); -uint8_t BSP_QSPI_LeaveDeepPowerDown (void); - -void BSP_QSPI_MspInit(void); -void BSP_QSPI_MspDeInit(void); +uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj); +uint8_t BSP_QSPI_SuspendErase (QSPI_t *obj); +uint8_t BSP_QSPI_ResumeErase (QSPI_t *obj); +uint8_t BSP_QSPI_EnterDeepPowerDown (QSPI_t *obj); +uint8_t BSP_QSPI_LeaveDeepPowerDown (QSPI_t *obj); + +void BSP_QSPI_MspInit(QSPI_t *obj); +void BSP_QSPI_MspDeInit(QSPI_t *obj); /** * @} */ From b938d4837900ac23a0d5a7781c74982ae8e41247 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 9 Sep 2020 18:20:38 +0200 Subject: [PATCH 3/5] Code factorization Several part of code are the same except HAL API name. Create generic function names to map on the correct one. Signed-off-by: Frederic Pillon --- src/mx25r6435f_driver.c | 595 +++++++--------------------------------- src/mx25r6435f_driver.h | 8 + 2 files changed, 107 insertions(+), 496 deletions(-) diff --git a/src/mx25r6435f_driver.c b/src/mx25r6435f_driver.c index 5c7ad07..ba79415 100644 --- a/src/mx25r6435f_driver.c +++ b/src/mx25r6435f_driver.c @@ -196,7 +196,6 @@ uint8_t BSP_QSPI_Init(QSPI_t *obj) return QSPI_ERROR; } - handle->Instance = obj->qspi; /* Call the DeInit function to reset the driver */ @@ -322,17 +321,6 @@ uint8_t BSP_QSPI_Read(QSPI_t *obj, uint8_t* pData, uint32_t ReadAddr, uint32_t S sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Reception of the data */ - if (HAL_OSPI_Receive(handle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; @@ -351,19 +339,17 @@ uint8_t BSP_QSPI_Read(QSPI_t *obj, uint8_t* pData, uint32_t ReadAddr, uint32_t S sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Configure the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_QSPI_Receive(handle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(handle, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ return QSPI_OK; } @@ -379,11 +365,6 @@ uint8_t BSP_QSPI_Read(QSPI_t *obj, uint8_t* pData, uint32_t ReadAddr, uint32_t S uint8_t BSP_QSPI_Write(QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t Size) { XSPI_HandleTypeDef *handle = &(obj->handle); -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; -#endif /* OCTOSPI */ uint32_t end_addr, current_size, current_addr; /* Calculation of the size between the write address and the end of the page */ @@ -400,6 +381,8 @@ uint8_t BSP_QSPI_Write(QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t end_addr = WriteAddr + Size; #ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + /* Initialize the program command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; @@ -416,38 +399,9 @@ uint8_t BSP_QSPI_Write(QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Perform the write page by page */ - do - { - sCommand.Address = current_addr; - sCommand.NbData = current_size; - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Transmission of the data */ - if (HAL_OSPI_Transmit(handle, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for end of program */ - if (QSPI_AutoPollingMemReady(handle, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { - return QSPI_ERROR; - } - #else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + /* Initialize the program command */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; sCommand.Instruction = QUAD_PAGE_PROG_CMD; @@ -459,6 +413,7 @@ uint8_t BSP_QSPI_Write(QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Perform the write page by page */ do @@ -467,29 +422,24 @@ uint8_t BSP_QSPI_Write(QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t sCommand.NbData = current_size; /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Configure the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Transmission of the data */ - if (HAL_QSPI_Transmit(handle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Transmit(handle, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait for end of program */ - if (QSPI_AutoPollingMemReady(handle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { + if (QSPI_AutoPollingMemReady(handle, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ /* Update the address and size variables for next page programming */ current_addr += current_size; @@ -528,25 +478,6 @@ uint8_t BSP_QSPI_Erase_Block(QSPI_t *obj, uint32_t BlockAddress) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Send the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(handle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) - { - return QSPI_ERROR; - } - #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; @@ -562,26 +493,22 @@ uint8_t BSP_QSPI_Erase_Block(QSPI_t *obj, uint32_t BlockAddress) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(handle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) - { + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) { return QSPI_ERROR; } - -#endif /* OCTOSPI */ return QSPI_OK; } @@ -600,14 +527,14 @@ uint8_t BSP_QSPI_Erase_Sector(QSPI_t *obj, uint32_t Sector) { XSPI_HandleTypeDef *handle = &(obj->handle); -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE)) { return QSPI_ERROR; } +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + /* Initialize the erase command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; @@ -624,26 +551,9 @@ uint8_t BSP_QSPI_Erase_Sector(QSPI_t *obj, uint32_t Sector) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Send the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; - if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE)) - { - return QSPI_ERROR; - } - /* Initialize the erase command */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; sCommand.Instruction = SECTOR_ERASE_CMD; @@ -656,19 +566,17 @@ uint8_t BSP_QSPI_Erase_Sector(QSPI_t *obj, uint32_t Sector) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ return QSPI_OK; } @@ -698,25 +606,6 @@ uint8_t BSP_QSPI_Erase_Chip(QSPI_t *obj) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Send the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(handle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) - { - return QSPI_ERROR; - } - #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; @@ -730,25 +619,22 @@ uint8_t BSP_QSPI_Erase_Chip(QSPI_t *obj) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) - { + if (QSPI_WriteEnable(handle) != QSPI_OK) { return QSPI_ERROR; } /* Send the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(handle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) - { + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ return QSPI_OK; } @@ -780,43 +666,6 @@ uint8_t BSP_QSPI_GetStatus(QSPI_t *obj) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Reception of the data */ - if (HAL_OSPI_Receive(handle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Check the value of the register */ - if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) - { - return QSPI_ERROR; - } - else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0) - { - return QSPI_SUSPENDED; - } - - /* Initialize the read status register command */ - sCommand.Instruction = READ_STATUS_REG_CMD; - - /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Reception of the data */ - if (HAL_OSPI_Receive(handle, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; @@ -831,52 +680,43 @@ uint8_t BSP_QSPI_GetStatus(QSPI_t *obj) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Configure the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_QSPI_Receive(handle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(handle, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Check the value of the register */ - if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) - { + if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) { return QSPI_ERROR; } - else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0) - { + else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0) { return QSPI_SUSPENDED; } /* Initialize the read status register command */ - sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.Instruction = READ_STATUS_REG_CMD; /* Configure the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Reception of the data */ - if (HAL_QSPI_Receive(handle, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(handle, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ /* Check the value of the register */ - if ((reg & MX25R6435F_SR_WIP) != 0) - { + if ((reg & MX25R6435F_SR_WIP) != 0) { return QSPI_BUSY; - } - else - { + } else { return QSPI_OK; } } @@ -932,8 +772,7 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj) sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -944,16 +783,14 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj) sCommand.DummyCycles = 0; /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure the memory mapped mode */ sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE; - if (HAL_OSPI_MemoryMapped(handle, &sMemMappedCfg) != HAL_OK) - { + if (HAL_OSPI_MemoryMapped(handle, &sMemMappedCfg) != HAL_OK) { return QSPI_ERROR; } #else /* OCTOSPI */ @@ -977,8 +814,7 @@ uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj) /* Configure the memory mapped mode */ sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; - if (HAL_QSPI_MemoryMapped(handle, &sCommand, &sMemMappedCfg) != HAL_OK) - { + if (HAL_QSPI_MemoryMapped(handle, &sCommand, &sMemMappedCfg) != HAL_OK) { return QSPI_ERROR; } #endif /* OCTOSPI */ @@ -995,14 +831,14 @@ uint8_t BSP_QSPI_SuspendErase(QSPI_t *obj) { XSPI_HandleTypeDef *handle = &(obj->handle); -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - /* Check whether the device is busy (erase operation is in progress). */ if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + /* Initialize the suspend command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; @@ -1016,20 +852,9 @@ uint8_t BSP_QSPI_SuspendErase(QSPI_t *obj) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; - /* Send the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - #else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Check whether the device is busy (erase operation is - in progress). - */ - if (BSP_QSPI_GetStatus() == QSPI_BUSY) - { /* Initialize the erase command */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; @@ -1040,16 +865,13 @@ uint8_t BSP_QSPI_SuspendErase(QSPI_t *obj) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - +#endif /* OCTOSPI */ /* Send the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ - if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) - { + if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) { return QSPI_OK; } @@ -1068,12 +890,12 @@ uint8_t BSP_QSPI_ResumeErase(QSPI_t *obj) { XSPI_HandleTypeDef *handle = &(obj->handle); -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - /* Check whether the device is in suspended state */ if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + /* Initialize the resume command */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; sCommand.FlashId = HAL_OSPI_FLASH_ID_1; @@ -1087,19 +909,9 @@ uint8_t BSP_QSPI_ResumeErase(QSPI_t *obj) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Send the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - #else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; + QSPI_CommandTypeDef sCommand; - /* Check whether the device is in suspended state */ - if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED) - { /* Initialize the erase command */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; sCommand.Instruction = PROG_ERASE_RESUME_CMD; @@ -1110,23 +922,18 @@ uint8_t BSP_QSPI_ResumeErase(QSPI_t *obj) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - +#endif /* OCTOSPI */ /* Send the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - -#endif /* OCTOSPI */ - /* When this command is executed, the status register write in progress bit is set to 1, and the flag status register program erase controller bit is set to 0. This command is ignored if the device is not in a suspended state. */ - if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) - { + if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) { return QSPI_OK; } @@ -1161,12 +968,6 @@ uint8_t BSP_QSPI_EnterDeepPowerDown(QSPI_t *obj) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Send the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; @@ -1180,13 +981,12 @@ uint8_t BSP_QSPI_EnterDeepPowerDown(QSPI_t *obj) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Send the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ /* --- Memory takes 10us max to enter deep power down --- */ /* --- At least 30us should be respected before leaving deep power down --- */ @@ -1219,13 +1019,6 @@ uint8_t BSP_QSPI_LeaveDeepPowerDown(QSPI_t *obj) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Send the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; @@ -1239,13 +1032,12 @@ uint8_t BSP_QSPI_LeaveDeepPowerDown(QSPI_t *obj) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Send the command */ - if (HAL_QSPI_Command(handle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */ /* --- Memory takes 35us min to leave deep power down --- */ @@ -1374,26 +1166,6 @@ static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) sCommand.DummyCycles = 0; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Send the command */ - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Send the reset memory command */ - sCommand.Instruction = RESET_MEMORY_CMD; - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait the memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { - return QSPI_ERROR; - } - #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; @@ -1407,26 +1179,23 @@ static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ /* Send the command */ - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Send the reset memory command */ sCommand.Instruction = RESET_MEMORY_CMD; - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Configure automatic polling mode to wait the memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { + if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ return QSPI_OK; } @@ -1456,8 +1225,7 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1473,13 +1241,11 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.NbData = 1; sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_AutoPolling(hxspi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_OSPI_AutoPolling(hxspi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } #else /* OCTOSPI */ @@ -1497,8 +1263,7 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1513,8 +1278,7 @@ static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) sCommand.Instruction = READ_STATUS_REG_CMD; sCommand.DataMode = QSPI_DATA_1_LINE; - if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } #endif /* OCTOSPI */ @@ -1556,13 +1320,11 @@ static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Time sConfig.Interval = 0x10; sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_OSPI_AutoPolling(hxspi, &sConfig, Timeout) != HAL_OK) - { + if (HAL_OSPI_AutoPolling(hxspi, &sConfig, Timeout) != HAL_OK) { return QSPI_ERROR; } #else /* OCTOSPI */ @@ -1587,8 +1349,7 @@ static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Time sConfig.Interval = 0x10; sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; - if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, Timeout) != HAL_OK) - { + if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, Timeout) != HAL_OK) { return QSPI_ERROR; } #endif /* OCTOSPI */ @@ -1604,9 +1365,9 @@ static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Time */ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) { + uint8_t reg; #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; - uint8_t reg; /* Read status register */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; @@ -1623,66 +1384,8 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.NbData = 1; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - if (HAL_OSPI_Receive(hxspi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Enable write operations */ - if (QSPI_WriteEnable(hxspi) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Activate/deactivate the Quad mode */ - if (Operation == QSPI_QUAD_ENABLE) - { - SET_BIT(reg, MX25R6435F_SR_QE); - } - else - { - CLEAR_BIT(reg, MX25R6435F_SR_QE); - } - - sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - if (HAL_OSPI_Transmit(hxspi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Check the configuration has been correctly done */ - sCommand.Instruction = READ_STATUS_REG_CMD; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - if (HAL_OSPI_Receive(hxspi, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; - uint8_t reg; /* Read status register */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; @@ -1695,68 +1398,56 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hxspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Enable write operations */ - if (QSPI_WriteEnable(hxspi) != QSPI_OK) - { + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { return QSPI_ERROR; } /* Activate/deactivate the Quad mode */ - if (Operation == QSPI_QUAD_ENABLE) - { + if (Operation == QSPI_QUAD_ENABLE) { SET_BIT(reg, MX25R6435F_SR_QE); - } - else - { + } else { CLEAR_BIT(reg, MX25R6435F_SR_QE); } sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Transmit(hxspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Transmit(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { + if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } /* Check the configuration has been correctly done */ sCommand.Instruction = READ_STATUS_REG_CMD; - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hxspi, ®, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ if ((((reg & MX25R6435F_SR_QE) == 0) && (Operation == QSPI_QUAD_ENABLE)) || - (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE))) - { + (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE))) { return QSPI_ERROR; } @@ -1771,9 +1462,9 @@ static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) */ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) { + uint8_t reg[3]; #ifdef OCTOSPI OSPI_RegularCmdTypeDef sCommand; - uint8_t reg[3]; /* Read status register */ sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; @@ -1790,82 +1481,8 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.NbData = 1; sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - if (HAL_OSPI_Receive(hxspi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Read configuration registers */ - sCommand.Instruction = READ_CFG_REG_CMD; - sCommand.NbData = 2; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - if (HAL_OSPI_Receive(hxspi, &(reg[1]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Enable write operations */ - if (QSPI_WriteEnable(hxspi) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Activate/deactivate the Quad mode */ - if (Operation == QSPI_HIGH_PERF_ENABLE) - { - SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); - } - else - { - CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); - } - - sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; - sCommand.NbData = 3; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - if (HAL_OSPI_Transmit(hxspi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { - return QSPI_ERROR; - } - - /* Check the configuration has been correctly done */ - sCommand.Instruction = READ_CFG_REG_CMD; - sCommand.NbData = 2; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } - - if (HAL_OSPI_Receive(hxspi, &(reg[0]), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { - return QSPI_ERROR; - } #else /* OCTOSPI */ QSPI_CommandTypeDef sCommand; - uint8_t reg[3]; /* Read status register */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; @@ -1878,14 +1495,13 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hxspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } @@ -1893,48 +1509,39 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = READ_CFG_REG_CMD; sCommand.NbData = 2; - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hxspi, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(hxspi, &(reg[1]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Enable write operations */ - if (QSPI_WriteEnable(hxspi) != QSPI_OK) - { + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { return QSPI_ERROR; } /* Activate/deactivate the Quad mode */ - if (Operation == QSPI_HIGH_PERF_ENABLE) - { + if (Operation == QSPI_HIGH_PERF_ENABLE) { SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); - } - else - { + } else { CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); } sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; sCommand.NbData = 3; - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Transmit(hxspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Transmit(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) - { + if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { return QSPI_ERROR; } @@ -1942,20 +1549,16 @@ static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) sCommand.Instruction = READ_CFG_REG_CMD; sCommand.NbData = 2; - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } - if (HAL_QSPI_Receive(hxspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) - { + if (HAL_XSPI_Receive(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return QSPI_ERROR; } -#endif /* OCTOSPI */ if ((((reg[1] & MX25R6435F_CR2_LH_SWITCH) == 0) && (Operation == QSPI_HIGH_PERF_ENABLE)) || - (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE))) - { + (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE))) { return QSPI_ERROR; } diff --git a/src/mx25r6435f_driver.h b/src/mx25r6435f_driver.h index ee3ff49..95a2e93 100644 --- a/src/mx25r6435f_driver.h +++ b/src/mx25r6435f_driver.h @@ -79,6 +79,10 @@ #define PinMap_XSPI_SSEL PinMap_OCTOSPI_SSEL #define HAL_XSPI_Init HAL_OSPI_Init #define HAL_XSPI_DeInit HAL_OSPI_DeInit +#define HAL_XSPI_TIMEOUT_DEFAULT_VALUE HAL_OSPI_TIMEOUT_DEFAULT_VALUE +#define HAL_XSPI_Command HAL_OSPI_Command +#define HAL_XSPI_Transmit HAL_OSPI_Transmit +#define HAL_XSPI_Receive HAL_OSPI_Receive #elif defined(QUADSPI) #define XSPI_HandleTypeDef QSPI_HandleTypeDef #define XSPI_TypeDef QUADSPI_TypeDef @@ -90,6 +94,10 @@ #define PinMap_XSPI_SSEL PinMap_QUADSPI_SSEL #define HAL_XSPI_Init HAL_QSPI_Init #define HAL_XSPI_DeInit HAL_QSPI_DeInit +#define HAL_XSPI_TIMEOUT_DEFAULT_VALUE HAL_QPSI_TIMEOUT_DEFAULT_VALUE +#define HAL_XSPI_Command HAL_QSPI_Command +#define HAL_XSPI_Transmit HAL_QSPI_Transmit +#define HAL_XSPI_Receive HAL_QSPI_Receive #else #error "QSPI feature not available. MX25R6435F library compilation failed." #endif /* OCTOSPIx */ From ff9ce881c433ddd343bc32a0774bf68b64a17222 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 9 Sep 2020 18:44:24 +0200 Subject: [PATCH 4/5] Clean up code - Remove useless comments - Apply Astyle Signed-off-by: Frederic Pillon --- src/MX25R6435F.cpp | 76 +- src/MX25R6435F.h | 46 +- src/mx25r6435f_desc.h | 356 ++--- src/mx25r6435f_driver.c | 3050 +++++++++++++++++++-------------------- src/mx25r6435f_driver.h | 311 ++-- 5 files changed, 1779 insertions(+), 2060 deletions(-) diff --git a/src/MX25R6435F.cpp b/src/MX25R6435F.cpp index 0e01559..0d22a20 100644 --- a/src/MX25R6435F.cpp +++ b/src/MX25R6435F.cpp @@ -9,29 +9,13 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2017 STMicroelectronics

+ *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of STMicroelectronics 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 HOLDER 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. + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ @@ -55,6 +39,7 @@ void MX25R6435FClass::begin(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t if (BSP_QSPI_Init(&_qspi) == MEMORY_OK) { initDone = 1; + } } void MX25R6435FClass::end(void) @@ -70,11 +55,13 @@ uint32_t MX25R6435FClass::write(uint8_t data, uint32_t addr) uint32_t MX25R6435FClass::write(uint8_t *pData, uint32_t addr, uint32_t size) { - if((pData == NULL) || (initDone == 0)) + if ((pData == NULL) || (initDone == 0)) { return 0; + } - if(BSP_QSPI_Write(&_qspi, pData, addr, size) != MEMORY_OK) + if (BSP_QSPI_Write(&_qspi, pData, addr, size) != MEMORY_OK) { return 0; + } return size; } @@ -90,70 +77,79 @@ uint8_t MX25R6435FClass::read(uint32_t addr) void MX25R6435FClass::read(uint8_t *pData, uint32_t addr, uint32_t size) { - if((pData != NULL) && (initDone == 1)) + if ((pData != NULL) && (initDone == 1)) { BSP_QSPI_Read(&_qspi, pData, addr, size); + } } uint8_t *MX25R6435FClass::mapped(void) { - if(BSP_QSPI_EnableMemoryMappedMode(&_qspi) != MEMORY_OK) + if (BSP_QSPI_EnableMemoryMappedMode(&_qspi) != MEMORY_OK) { return NULL; + } return (uint8_t *)MEMORY_MAPPED_ADDRESS; } uint8_t MX25R6435FClass::erase(uint32_t addr) { - if(initDone == 0) + if (initDone == 0) { return MEMORY_ERROR; + } return BSP_QSPI_Erase_Block(&_qspi, addr); } uint8_t MX25R6435FClass::eraseChip(void) { - if(initDone == 0) + if (initDone == 0) { return MEMORY_ERROR; + } return BSP_QSPI_Erase_Chip(&_qspi); } uint8_t MX25R6435FClass::eraseSector(uint32_t sector) { - if(initDone == 0) + if (initDone == 0) { return MEMORY_ERROR; + } return BSP_QSPI_Erase_Sector(&_qspi, sector); } uint8_t MX25R6435FClass::suspendErase(void) { - if(initDone == 0) + if (initDone == 0) { return MEMORY_ERROR; + } return BSP_QSPI_SuspendErase(&_qspi); } uint8_t MX25R6435FClass::resumeErase(void) { - if(initDone == 0) + if (initDone == 0) { return MEMORY_ERROR; + } return BSP_QSPI_ResumeErase(&_qspi); } uint8_t MX25R6435FClass::sleep(void) { - if(initDone == 0) + if (initDone == 0) { return MEMORY_ERROR; + } return BSP_QSPI_EnterDeepPowerDown(&_qspi); } uint8_t MX25R6435FClass::wakeup(void) { - if(initDone == 0) + if (initDone == 0) { return MEMORY_ERROR; + } return BSP_QSPI_LeaveDeepPowerDown(&_qspi); } @@ -170,30 +166,30 @@ uint32_t MX25R6435FClass::info(memory_info_t info) BSP_QSPI_GetInfo(&pInfo); - switch(info){ + switch (info) { case MEMORY_SIZE: res = pInfo.FlashSize; - break; + break; case MEMORY_SECTOR_SIZE: res = pInfo.EraseSectorSize; - break; + break; case MEMORY_SECTOR_NUMBER: res = pInfo.EraseSectorsNumber; - break; + break; case MEMORY_PAGE_SIZE: res = pInfo.ProgPageSize; - break; + break; case MEMORY_PAGE_NUMBER: res = pInfo.ProgPagesNumber; - break; + break; default: res = 0; - break; + break; } return res; diff --git a/src/MX25R6435F.h b/src/MX25R6435F.h index 9536547..8ad12da 100644 --- a/src/MX25R6435F.h +++ b/src/MX25R6435F.h @@ -1,37 +1,18 @@ /** ****************************************************************************** * @file MX25R6435F.h - * @author WI6LABS - * @version V1.0.0 - * @date 19-July-2017 * @brief MX25R6435F library for STM32 Arduino * ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2017 STMicroelectronics

+ *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of STMicroelectronics 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 HOLDER 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. + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ @@ -43,22 +24,22 @@ #include "mx25r6435f_driver.h" #ifndef MX25R6435F_D0 -#define MX25R6435F_D0 NC + #define MX25R6435F_D0 NC #endif #ifndef MX25R6435F_D1 -#define MX25R6435F_D1 NC + #define MX25R6435F_D1 NC #endif #ifndef MX25R6435F_D2 -#define MX25R6435F_D2 NC + #define MX25R6435F_D2 NC #endif #ifndef MX25R6435F_D3 -#define MX25R6435F_D3 NC + #define MX25R6435F_D3 NC #endif #ifndef MX25R6435F_SCLK -#define MX25R6435F_SCLK NC + #define MX25R6435F_SCLK NC #endif #ifndef MX25R6435F_SSEL -#define MX25R6435F_SSEL NC + #define MX25R6435F_SSEL NC #endif /* Memory configuration paremeters */ @@ -80,8 +61,7 @@ typedef enum { /* Base address of the memory in mapped mode */ #define MEMORY_MAPPED_ADDRESS ((uint32_t)0x90000000) -class MX25R6435FClass -{ +class MX25R6435FClass { public: MX25R6435FClass(); diff --git a/src/mx25r6435f_desc.h b/src/mx25r6435f_desc.h index ccdc384..76a869d 100644 --- a/src/mx25r6435f_desc.h +++ b/src/mx25r6435f_desc.h @@ -1,211 +1,145 @@ -/** - ****************************************************************************** - * @file mx25r6435f.h - * @author MCD Application Team - * @version V1.0.0 - * @date 17-February-2017 - * @brief This file contains all the description of the MX25R6435F QSPI memory. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of STMicroelectronics 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 HOLDER 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. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MX25R6435F_H -#define __MX25R6435F_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup Components - * @{ - */ - -/** @addtogroup mx25r6435f - * @{ - */ - -/** @defgroup MX25R6435F_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup MX25R6435F_Exported_Constants - * @{ - */ - -/** - * @brief MX25R6435F Configuration - */ -#define MX25R6435F_FLASH_SIZE 0x800000 /* 64 MBits => 8MBytes */ -#define MX25R6435F_BLOCK_SIZE 0x10000 /* 128 blocks of 64KBytes */ -#define MX25R6435F_SUBBLOCK_SIZE 0x8000 /* 256 blocks of 32KBytes */ -#define MX25R6435F_SECTOR_SIZE 0x1000 /* 2048 sectors of 4kBytes */ -#define MX25R6435F_PAGE_SIZE 0x100 /* 32768 pages of 256 bytes */ - -#define MX25R6435F_DUMMY_CYCLES_READ 8 -#define MX25R6435F_DUMMY_CYCLES_READ_DUAL 4 -#define MX25R6435F_DUMMY_CYCLES_READ_QUAD 4 -#define MX25R6435F_DUMMY_CYCLES_2READ 2 -#define MX25R6435F_DUMMY_CYCLES_4READ 4 - -#define MX25R6435F_ALT_BYTES_PE_MODE 0xA5 -#define MX25R6435F_ALT_BYTES_NO_PE_MODE 0xAA - -#define MX25R6435F_CHIP_ERASE_MAX_TIME 240000 -#define MX25R6435F_BLOCK_ERASE_MAX_TIME 3500 -#define MX25R6435F_SUBBLOCK_ERASE_MAX_TIME 3000 -#define MX25R6435F_SECTOR_ERASE_MAX_TIME 240 - -/** - * @brief MX25R6435F Commands - */ -/* Read Operations */ -#define READ_CMD 0x03 -#define FAST_READ_CMD 0x0B -#define DUAL_OUT_READ_CMD 0x3B -#define DUAL_INOUT_READ_CMD 0xBB -#define QUAD_OUT_READ_CMD 0x6B -#define QUAD_INOUT_READ_CMD 0xEB - -/* Program Operations */ -#define PAGE_PROG_CMD 0x02 -#define QUAD_PAGE_PROG_CMD 0x38 - -/* Erase Operations */ -#define SECTOR_ERASE_CMD 0x20 -#define SUBBLOCK_ERASE_CMD 0x52 -#define BLOCK_ERASE_CMD 0xD8 -#define CHIP_ERASE_CMD 0x60 -#define CHIP_ERASE_CMD_2 0xC7 - -#define PROG_ERASE_RESUME_CMD 0x7A -#define PROG_ERASE_RESUME_CMD_2 0x30 -#define PROG_ERASE_SUSPEND_CMD 0x75 -#define PROG_ERASE_SUSPEND_CMD_2 0xB0 - -/* Identification Operations */ -#define READ_ID_CMD 0x9F -#define READ_ELECTRONIC_ID_CMD 0xAB -#define READ_ELEC_MANUFACTURER_DEVICE_ID_CMD 0x90 -#define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A - -/* Write Operations */ -#define WRITE_ENABLE_CMD 0x06 -#define WRITE_DISABLE_CMD 0x04 - -/* Register Operations */ -#define READ_STATUS_REG_CMD 0x05 -#define READ_CFG_REG_CMD 0x15 -#define WRITE_STATUS_CFG_REG_CMD 0x01 - -#define READ_SEC_REG_CMD 0x2B -#define WRITE_SEC_REG_CMD 0x2F - -/* Power Down Operations */ -#define DEEP_POWER_DOWN_CMD 0xB9 - -/* Burst Operations */ -#define SET_BURST_LENGTH_CMD 0xC0 - -/* One-Time Programmable Operations */ -#define ENTER_SECURED_OTP_CMD 0xB1 -#define EXIT_SECURED_OTP_CMD 0xC1 - -/* No Operation */ -#define NO_OPERATION_CMD 0x00 - -/* Reset Operations */ -#define RESET_ENABLE_CMD 0x66 -#define RESET_MEMORY_CMD 0x99 -#define RELEASE_READ_ENHANCED_CMD 0xFF - -/** - * @brief MX25R6435F Registers - */ -/* Status Register */ -#define MX25R6435F_SR_WIP ((uint8_t)0x01) /*!< Write in progress */ -#define MX25R6435F_SR_WEL ((uint8_t)0x02) /*!< Write enable latch */ -#define MX25R6435F_SR_BP ((uint8_t)0x3C) /*!< Block protect */ -#define MX25R6435F_SR_QE ((uint8_t)0x40) /*!< Quad enable */ -#define MX25R6435F_SR_SRWD ((uint8_t)0x80) /*!< Status register write disable */ - -/* Configuration Register 1 */ -#define MX25R6435F_CR1_TB ((uint8_t)0x08) /*!< Top / bottom */ - -/* Configuration Register 2 */ -#define MX25R6435F_CR2_LH_SWITCH ((uint8_t)0x02) /*!< Low power / high performance switch */ - -/* Security Register */ -#define MX25R6435F_SECR_SOI ((uint8_t)0x01) /*!< Secured OTP indicator */ -#define MX25R6435F_SECR_LDSO ((uint8_t)0x02) /*!< Lock-down secured OTP */ -#define MX25R6435F_SECR_PSB ((uint8_t)0x04) /*!< Program suspend bit */ -#define MX25R6435F_SECR_ESB ((uint8_t)0x08) /*!< Erase suspend bit */ -#define MX25R6435F_SECR_P_FAIL ((uint8_t)0x20) /*!< Program fail flag */ -#define MX25R6435F_SECR_E_FAIL ((uint8_t)0x40) /*!< Erase fail flag */ - -/** - * @} - */ - -/** @defgroup MX25R6435F_Exported_Functions - * @{ - */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MX25R6435F_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file mx25r6435f.h + * @brief This file contains all the description of the MX25R6435F QSPI memory. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MX25R6435F_H +#define __MX25R6435F_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/** + * @brief MX25R6435F Configuration + */ +#define MX25R6435F_FLASH_SIZE 0x800000 /* 64 MBits => 8MBytes */ +#define MX25R6435F_BLOCK_SIZE 0x10000 /* 128 blocks of 64KBytes */ +#define MX25R6435F_SUBBLOCK_SIZE 0x8000 /* 256 blocks of 32KBytes */ +#define MX25R6435F_SECTOR_SIZE 0x1000 /* 2048 sectors of 4kBytes */ +#define MX25R6435F_PAGE_SIZE 0x100 /* 32768 pages of 256 bytes */ + +#define MX25R6435F_DUMMY_CYCLES_READ 8 +#define MX25R6435F_DUMMY_CYCLES_READ_DUAL 4 +#define MX25R6435F_DUMMY_CYCLES_READ_QUAD 4 +#define MX25R6435F_DUMMY_CYCLES_2READ 2 +#define MX25R6435F_DUMMY_CYCLES_4READ 4 + +#define MX25R6435F_ALT_BYTES_PE_MODE 0xA5 +#define MX25R6435F_ALT_BYTES_NO_PE_MODE 0xAA + +#define MX25R6435F_CHIP_ERASE_MAX_TIME 240000 +#define MX25R6435F_BLOCK_ERASE_MAX_TIME 3500 +#define MX25R6435F_SUBBLOCK_ERASE_MAX_TIME 3000 +#define MX25R6435F_SECTOR_ERASE_MAX_TIME 240 + +/** + * @brief MX25R6435F Commands + */ +/* Read Operations */ +#define READ_CMD 0x03 +#define FAST_READ_CMD 0x0B +#define DUAL_OUT_READ_CMD 0x3B +#define DUAL_INOUT_READ_CMD 0xBB +#define QUAD_OUT_READ_CMD 0x6B +#define QUAD_INOUT_READ_CMD 0xEB + +/* Program Operations */ +#define PAGE_PROG_CMD 0x02 +#define QUAD_PAGE_PROG_CMD 0x38 + +/* Erase Operations */ +#define SECTOR_ERASE_CMD 0x20 +#define SUBBLOCK_ERASE_CMD 0x52 +#define BLOCK_ERASE_CMD 0xD8 +#define CHIP_ERASE_CMD 0x60 +#define CHIP_ERASE_CMD_2 0xC7 + +#define PROG_ERASE_RESUME_CMD 0x7A +#define PROG_ERASE_RESUME_CMD_2 0x30 +#define PROG_ERASE_SUSPEND_CMD 0x75 +#define PROG_ERASE_SUSPEND_CMD_2 0xB0 + +/* Identification Operations */ +#define READ_ID_CMD 0x9F +#define READ_ELECTRONIC_ID_CMD 0xAB +#define READ_ELEC_MANUFACTURER_DEVICE_ID_CMD 0x90 +#define READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5A + +/* Write Operations */ +#define WRITE_ENABLE_CMD 0x06 +#define WRITE_DISABLE_CMD 0x04 + +/* Register Operations */ +#define READ_STATUS_REG_CMD 0x05 +#define READ_CFG_REG_CMD 0x15 +#define WRITE_STATUS_CFG_REG_CMD 0x01 + +#define READ_SEC_REG_CMD 0x2B +#define WRITE_SEC_REG_CMD 0x2F + +/* Power Down Operations */ +#define DEEP_POWER_DOWN_CMD 0xB9 + +/* Burst Operations */ +#define SET_BURST_LENGTH_CMD 0xC0 + +/* One-Time Programmable Operations */ +#define ENTER_SECURED_OTP_CMD 0xB1 +#define EXIT_SECURED_OTP_CMD 0xC1 + +/* No Operation */ +#define NO_OPERATION_CMD 0x00 + +/* Reset Operations */ +#define RESET_ENABLE_CMD 0x66 +#define RESET_MEMORY_CMD 0x99 +#define RELEASE_READ_ENHANCED_CMD 0xFF + +/** + * @brief MX25R6435F Registers + */ +/* Status Register */ +#define MX25R6435F_SR_WIP ((uint8_t)0x01) /*!< Write in progress */ +#define MX25R6435F_SR_WEL ((uint8_t)0x02) /*!< Write enable latch */ +#define MX25R6435F_SR_BP ((uint8_t)0x3C) /*!< Block protect */ +#define MX25R6435F_SR_QE ((uint8_t)0x40) /*!< Quad enable */ +#define MX25R6435F_SR_SRWD ((uint8_t)0x80) /*!< Status register write disable */ + +/* Configuration Register 1 */ +#define MX25R6435F_CR1_TB ((uint8_t)0x08) /*!< Top / bottom */ + +/* Configuration Register 2 */ +#define MX25R6435F_CR2_LH_SWITCH ((uint8_t)0x02) /*!< Low power / high performance switch */ + +/* Security Register */ +#define MX25R6435F_SECR_SOI ((uint8_t)0x01) /*!< Secured OTP indicator */ +#define MX25R6435F_SECR_LDSO ((uint8_t)0x02) /*!< Lock-down secured OTP */ +#define MX25R6435F_SECR_PSB ((uint8_t)0x04) /*!< Program suspend bit */ +#define MX25R6435F_SECR_ESB ((uint8_t)0x08) /*!< Erase suspend bit */ +#define MX25R6435F_SECR_P_FAIL ((uint8_t)0x20) /*!< Program fail flag */ +#define MX25R6435F_SECR_E_FAIL ((uint8_t)0x40) /*!< Erase fail flag */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MX25R6435F_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/mx25r6435f_driver.c b/src/mx25r6435f_driver.c index ba79415..0398342 100644 --- a/src/mx25r6435f_driver.c +++ b/src/mx25r6435f_driver.c @@ -1,1588 +1,1462 @@ -/** - ****************************************************************************** - * @file mx25r6435f_driver.c - * @author MCD Application Team - * @version V1.1.0 - * @date 21-April-2017 - * @brief This file includes a standard driver for the MX25R6435F QSPI - * memory. - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - (#) This driver is used to drive the MX25R6435F QSPI external - memory mounted on STM32L475E IOT01 board. - - (#) This driver need a specific component driver (MX25R6435F) to be included with. - - (#) Initialization steps: - (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This - function includes the MSP layer hardware resources initialization and the - QSPI interface with the external memory. The BSP_QSPI_DeInit() can be used - to deactivate the QSPI interface. - - (#) QSPI memory operations - (++) QSPI memory can be accessed with read/write operations once it is - initialized. - Read/write operation can be performed with AHB access using the functions - BSP_QSPI_Read()/BSP_QSPI_Write(). - (++) The function to the QSPI memory in memory-mapped mode is possible after - the call of the function BSP_QSPI_EnableMemoryMappedMode(). - (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. - (see the QSPI memory data sheet) - (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by - specifying the block address. You can perform an erase operation of the whole - chip by calling the function BSP_QSPI_Erase_Chip(). - (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. - (see the QSPI memory data sheet) - (++) Perform erase sector operation using the function BSP_QSPI_Erase_Sector() - which is not blocking. So the function BSP_QSPI_GetStatus() should be used - to check if the memory is busy, and the functions BSP_QSPI_SuspendErase()/ - BSP_QSPI_ResumeErase() can be used to perform other operations during the - sector erase. - (++) Deep power down of the QSPI memory is managed with the call of the functions - BSP_QSPI_EnterDeepPowerDown()/BSP_QSPI_LeaveDeepPowerDown() - @endverbatim - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of STMicroelectronics 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 HOLDER 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. - * - ****************************************************************************** - */ - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "core_debug.h" -#include "mx25r6435f_driver.h" - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup STM32L475E_IOT01 - * @{ - */ - -/** @defgroup STM32L475E_IOT01_QSPI QSPI - * @{ - */ - -/* Private constants --------------------------------------------------------*/ -/** @defgroup STM32L475E_IOT01_QSPI_Private_Constants QSPI Private Constants - * @{ - */ -#define QSPI_QUAD_DISABLE 0x0 -#define QSPI_QUAD_ENABLE 0x1 - -#define QSPI_HIGH_PERF_DISABLE 0x0 -#define QSPI_HIGH_PERF_ENABLE 0x1 -/** - * @} - */ -/* Private variables ---------------------------------------------------------*/ - -/** @defgroup STM32L475E_IOT01_QSPI_Private_Variables QSPI Private Variables - * @{ - */ - -/** - * @} - */ - - -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup STM32L475E_IOT01_QSPI_Private_Functions QSPI Private Functions - * @{ - */ -static uint8_t QSPI_ResetMemory (XSPI_HandleTypeDef *hxspi); -static uint8_t QSPI_WriteEnable (XSPI_HandleTypeDef *hxspi); -static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Timeout); -static uint8_t QSPI_QuadMode (XSPI_HandleTypeDef *hxspi, uint8_t Operation); -static uint8_t QSPI_HighPerfMode (XSPI_HandleTypeDef *hxspi, uint8_t Operation); -static uint8_t qspi_setClockPrescaler (void); - -/** - * @} - */ - -/* Exported functions ---------------------------------------------------------*/ - -/** @addtogroup STM32L475E_IOT01_QSPI_Exported_Functions - * @{ - */ - -/** - * @brief Select a prescaler to have a clock frequency lower than the maximum. - * The MX25R6435F supports a maximum frequency of 80MHz. - * QSPI clock is connected to AHB bus clock. - * @retval Clock prescaler. 0 means error. - */ -static uint8_t qspi_setClockPrescaler(void) { - uint8_t i; - - for(i = 1; i < 255; i++) { - if((HAL_RCC_GetHCLKFreq() / i) <= 80000000) - return i; - } - - return 0; -} - -/** - * @brief Initializes the QSPI interface. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_Init(QSPI_t *obj) -{ - if (obj == NULL) { - return QSPI_ERROR; - } - XSPI_HandleTypeDef *handle = &(obj->handle); - - /* Determine the XSPI to use */ - XSPI_TypeDef *xspi_d0 = pinmap_peripheral(obj->pin_d0, PinMap_XSPI_DATA0); - XSPI_TypeDef *xspi_d1 = pinmap_peripheral(obj->pin_d1, PinMap_XSPI_DATA1); - XSPI_TypeDef *xspi_d2 = pinmap_peripheral(obj->pin_d2, PinMap_XSPI_DATA2); - XSPI_TypeDef *xspi_d3 = pinmap_peripheral(obj->pin_d3, PinMap_XSPI_DATA3); - - XSPI_TypeDef *xspi_sclk = pinmap_peripheral(obj->pin_sclk, PinMap_XSPI_SCLK); - XSPI_TypeDef *xspi_ssel = pinmap_peripheral(obj->pin_ssel, PinMap_XSPI_SSEL); - - /* Pins Dx/SSEL/SCLK must not be NP. */ - if (xspi_d0 == NP || xspi_d1 == NP || xspi_d2 == NP || xspi_sclk == NP || xspi_ssel == NP) { - core_debug("ERROR: at least one QSPI pin has no peripheral\n"); - return QSPI_ERROR; - } - - XSPI_TypeDef *spi_d01 = pinmap_merge_peripheral(xspi_d0, xspi_d1); - XSPI_TypeDef *spi_d23 = pinmap_merge_peripheral(xspi_d2, xspi_d3); - XSPI_TypeDef *spi_dx = pinmap_merge_peripheral(spi_d01, spi_d23); - XSPI_TypeDef *spi_sxxx = pinmap_merge_peripheral(xspi_sclk, xspi_ssel); - - obj->qspi = pinmap_merge_peripheral(spi_dx, spi_sxxx); - - /* Are all pins connected to the same SPI instance? */ - if (obj->qspi == NP) { - core_debug("ERROR: QSPI pins mismatch\n"); - return QSPI_ERROR; - } - - handle->Instance = obj->qspi; - - /* Call the DeInit function to reset the driver */ - if (HAL_XSPI_DeInit(handle) != HAL_OK) { - return QSPI_ERROR; - } - - /* System level initialization */ - BSP_QSPI_MspInit(obj); - -#ifdef OCTOSPI - /* OSPI initialization */ - handle->Init.FifoThreshold = 4; - handle->Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; - handle->Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX; - handle->Init.DeviceSize = POSITION_VAL(MX25R6435F_FLASH_SIZE); - handle->Init.ChipSelectHighTime = 1; - handle->Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; - handle->Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; - handle->Init.ClockPrescaler = 4; /* QSPI clock = 110MHz / ClockPrescaler = 27.5 MHz */ - handle->Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE; - handle->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; - handle->Init.ChipSelectBoundary = 0; - handle->Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED; -#else /* OCTOSPI */ - /* QSPI initialization */ - /* High performance mode clock is limited to 80 MHz */ - handle->Init.ClockPrescaler = qspi_setClockPrescaler() + 1; /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ - handle->Init.FifoThreshold = 4; - handle->Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; - handle->Init.FlashSize = POSITION_VAL(MX25R6435F_FLASH_SIZE) - 1; - handle->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; - handle->Init.ClockMode = QSPI_CLOCK_MODE_0; -#endif - - if (HAL_XSPI_Init(handle) != HAL_OK) { - return QSPI_ERROR; - } - - /* QSPI memory reset */ - if (QSPI_ResetMemory(handle) != QSPI_OK) { - return QSPI_NOT_SUPPORTED; - } - - /* QSPI quad enable */ - if (QSPI_QuadMode(handle, QSPI_QUAD_ENABLE) != QSPI_OK) { - return QSPI_ERROR; - } - - /* High performance mode enable */ - if (QSPI_HighPerfMode(handle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Re-configure the clock for the high performance mode */ - /* High performance mode clock is limited to 80 MHz */ - handle->Init.ClockPrescaler = qspi_setClockPrescaler(); /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ - - if (HAL_XSPI_Init(handle) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Init(handle) != HAL_OK) { - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief De-Initializes the QSPI interface. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_DeInit(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - - /* Call the DeInit function to reset the driver */ - if (HAL_XSPI_DeInit(handle) != HAL_OK) { - return QSPI_ERROR; - } - - /* System level De-initialization */ - BSP_QSPI_MspDeInit(obj); - - return QSPI_OK; -} - -/** - * @brief Reads an amount of data from the QSPI memory. - * @param obj : pointer to QSPI_t structure - * @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(QSPI_t *obj, uint8_t* pData, uint32_t ReadAddr, uint32_t Size) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the read command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = QUAD_INOUT_READ_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.Address = ReadAddr; - sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; - sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; - sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; - sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES; - sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS; - sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; - sCommand.DataMode = HAL_OSPI_DATA_4_LINES; - sCommand.NbData = Size; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the read command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = QUAD_INOUT_READ_CMD; - sCommand.AddressMode = QSPI_ADDRESS_4_LINES; - sCommand.AddressSize = QSPI_ADDRESS_24_BITS; - sCommand.Address = ReadAddr; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES; - sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; - sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; - sCommand.DataMode = QSPI_DATA_4_LINES; - sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; - sCommand.NbData = Size; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Configure the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Reception of the data */ - if (HAL_XSPI_Receive(handle, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief Writes an amount of data to the QSPI memory. - * @param obj : pointer to QSPI_t structure - * @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(QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t Size) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - uint32_t end_addr, current_size, current_addr; - - /* Calculation of the size between the write address and the end of the page */ - current_size = MX25R6435F_PAGE_SIZE - (WriteAddr % MX25R6435F_PAGE_SIZE); - - /* Check if the size of the data is less than the remaining place in the page */ - if (current_size > Size) - { - current_size = Size; - } - - /* Initialize the adress variables */ - current_addr = WriteAddr; - end_addr = WriteAddr + Size; - -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the program command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = QUAD_PAGE_PROG_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; - sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; - sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_4_LINES; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the program command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = QUAD_PAGE_PROG_CMD; - sCommand.AddressMode = QSPI_ADDRESS_4_LINES; - sCommand.AddressSize = QSPI_ADDRESS_24_BITS; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_4_LINES; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Perform the write page by page */ - do - { - sCommand.Address = current_addr; - sCommand.NbData = current_size; - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Configure the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Transmission of the data */ - if (HAL_XSPI_Transmit(handle, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for end of program */ - if (QSPI_AutoPollingMemReady(handle, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Update the address and size variables for next page programming */ - current_addr += current_size; - pData += current_size; - current_size = ((current_addr + MX25R6435F_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25R6435F_PAGE_SIZE; - } while (current_addr < end_addr); - - return QSPI_OK; -} - -/** - * @brief Erases the specified block of the QSPI memory. - * @param obj : pointer to QSPI_t structure - * @param BlockAddress : Block address to erase - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_Erase_Block(QSPI_t *obj, uint32_t BlockAddress) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = BLOCK_ERASE_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.Address = BlockAddress; - sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE; - sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; - sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = BLOCK_ERASE_CMD; - sCommand.AddressMode = QSPI_ADDRESS_1_LINE; - sCommand.AddressSize = QSPI_ADDRESS_24_BITS; - sCommand.Address = BlockAddress; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Send the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(handle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) { - return QSPI_ERROR; - } - return QSPI_OK; -} - -/** - * @brief Erases the specified sector of the QSPI memory. - * @param obj : pointer to QSPI_t structure - * @param Sector : Sector address to erase (0 to 255) - * @retval QSPI memory status - * @note This function is non blocking meaning that sector erase - * operation is started but not completed when the function - * returns. Application has to call BSP_QSPI_GetStatus() - * to know when the device is available again (i.e. erase operation - * completed). - */ -uint8_t BSP_QSPI_Erase_Sector(QSPI_t *obj, uint32_t Sector) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - - if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE)) - { - return QSPI_ERROR; - } - -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = SECTOR_ERASE_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.Address = (Sector * MX25R6435F_SECTOR_SIZE); - sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE; - sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; - sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = SECTOR_ERASE_CMD; - sCommand.AddressMode = QSPI_ADDRESS_1_LINE; - sCommand.AddressSize = QSPI_ADDRESS_24_BITS; - sCommand.Address = (Sector * MX25R6435F_SECTOR_SIZE); - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Send the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief Erases the entire QSPI memory. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_Erase_Chip(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = CHIP_ERASE_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = CHIP_ERASE_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Enable write operations */ - if (QSPI_WriteEnable(handle) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Send the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for end of erase */ - if (QSPI_AutoPollingMemReady(handle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) { - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief Reads current status of the QSPI memory. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_GetStatus(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - uint8_t reg; -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the read security register command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = READ_SEC_REG_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_1_LINE; - sCommand.NbData = 1; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the read security register command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = READ_SEC_REG_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_1_LINE; - sCommand.DummyCycles = 0; - sCommand.NbData = 1; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Configure the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Reception of the data */ - if (HAL_XSPI_Receive(handle, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Check the value of the register */ - if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) { - return QSPI_ERROR; - } - else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0) { - return QSPI_SUSPENDED; - } - - /* Initialize the read status register command */ - sCommand.Instruction = READ_STATUS_REG_CMD; - - /* Configure the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Reception of the data */ - if (HAL_XSPI_Receive(handle, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Check the value of the register */ - if ((reg & MX25R6435F_SR_WIP) != 0) { - return QSPI_BUSY; - } else { - return QSPI_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) -{ - /* Configure the structure with the memory configuration */ - pInfo->FlashSize = MX25R6435F_FLASH_SIZE; - pInfo->EraseSectorSize = MX25R6435F_SECTOR_SIZE; - pInfo->EraseSectorsNumber = (MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE); - pInfo->ProgPageSize = MX25R6435F_PAGE_SIZE; - pInfo->ProgPagesNumber = (MX25R6435F_FLASH_SIZE/MX25R6435F_PAGE_SIZE); - - return QSPI_OK; -} - -/** - * @brief Configure the QSPI in memory-mapped mode - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - OSPI_MemoryMappedTypeDef sMemMappedCfg; - - /* Configure the command for the read instruction */ - sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = QUAD_INOUT_READ_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; - sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; - sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; - sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES; - sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS; - sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; - sCommand.DataMode = HAL_OSPI_DATA_4_LINES; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure the command for the program instruction */ - sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG; - sCommand.Instruction = QUAD_PAGE_PROG_CMD; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DummyCycles = 0; - - /* Configure the command */ - if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure the memory mapped mode */ - sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE; - - if (HAL_OSPI_MemoryMapped(handle, &sMemMappedCfg) != HAL_OK) { - return QSPI_ERROR; - } -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - QSPI_MemoryMappedTypeDef sMemMappedCfg; - - /* Configure the command for the read instruction */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = QUAD_INOUT_READ_CMD; - sCommand.AddressMode = QSPI_ADDRESS_4_LINES; - sCommand.AddressSize = QSPI_ADDRESS_24_BITS; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES; - sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; - sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; - sCommand.DataMode = QSPI_DATA_4_LINES; - sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - - /* Configure the memory mapped mode */ - sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; - - if (HAL_QSPI_MemoryMapped(handle, &sCommand, &sMemMappedCfg) != HAL_OK) { - return QSPI_ERROR; - } -#endif /* OCTOSPI */ - - return QSPI_OK; -} - -/** - * @brief This function suspends an ongoing erase command. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_SuspendErase(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - - /* Check whether the device is busy (erase operation is - in progress). - */ - if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) - { -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the suspend command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - /* Send the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) { - return QSPI_OK; - } - - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief This function resumes a paused erase command. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_ResumeErase(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - - /* Check whether the device is in suspended state */ - if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) - { -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the resume command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = PROG_ERASE_RESUME_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = PROG_ERASE_RESUME_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - /* Send the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - /* - When this command is executed, the status register write in progress bit is set to 1, and - the flag status register program erase controller bit is set to 0. This command is ignored - if the device is not in a suspended state. - */ - - if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) { - return QSPI_OK; - } - - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief This function enter the QSPI memory in deep power down mode. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_EnterDeepPowerDown(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the deep power down command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = DEEP_POWER_DOWN_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the deep power down command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = DEEP_POWER_DOWN_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Send the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* --- Memory takes 10us max to enter deep power down --- */ - /* --- At least 30us should be respected before leaving deep power down --- */ - - return QSPI_OK; -} - -/** - * @brief This function leave the QSPI memory from deep power down mode. - * @param obj : pointer to QSPI_t structure - * @retval QSPI memory status - */ -uint8_t BSP_QSPI_LeaveDeepPowerDown(QSPI_t *obj) -{ - XSPI_HandleTypeDef *handle = &(obj->handle); - -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = NO_OPERATION_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the erase command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = NO_OPERATION_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Send the command */ - if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */ - /* --- Memory takes 35us min to leave deep power down --- */ - - return QSPI_OK; -} - -/** - * @brief Initializes the QSPI MSP. - * @param obj : pointer to QSPI_t structure - * @retval None - */ -__weak void BSP_QSPI_MspInit(QSPI_t *obj) -{ -#ifdef OCTOSPI - - /* Enable the OctoSPI memory interface clock */ - /* Reset the OctoSPI memory interface */ -#if defined(OCTOSPI1) - if (obj->qspi == OCTOSPI1) { - __HAL_RCC_OSPI1_CLK_ENABLE(); - - __HAL_RCC_OSPI1_FORCE_RESET(); - __HAL_RCC_OSPI1_RELEASE_RESET(); - } -#endif -#if defined(OCTOSPI2) - if (obj->qspi == OCTOSPI2) { - __HAL_RCC_OSPI2_CLK_ENABLE(); - - __HAL_RCC_OSPI2_FORCE_RESET(); - __HAL_RCC_OSPI2_RELEASE_RESET(); - } -#endif -#else /* OCTOSPI */ - /* Enable the QuadSPI memory interface clock */ - __HAL_RCC_QSPI_CLK_ENABLE(); - - /* Reset the QuadSPI memory interface */ - __HAL_RCC_QSPI_FORCE_RESET(); - __HAL_RCC_QSPI_RELEASE_RESET(); -#endif /* OCTOSPI */ - - /* Configure QSPI GPIO pins */ - pinmap_pinout(obj->pin_d0, PinMap_XSPI_DATA0); - pinmap_pinout(obj->pin_d1, PinMap_XSPI_DATA1); - pinmap_pinout(obj->pin_d2, PinMap_XSPI_DATA2); - pinmap_pinout(obj->pin_d3, PinMap_XSPI_DATA3); - pinmap_pinout(obj->pin_sclk, PinMap_XSPI_SCLK); - pinmap_pinout(obj->pin_ssel, PinMap_XSPI_SSEL); -} - -/** - * @brief De-Initializes the QSPI MSP. - * @param obj : pointer to QSPI_t structure - * @retval None - */ -__weak void BSP_QSPI_MspDeInit(QSPI_t *obj) -{ - /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration */ - - HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d0), STM_GPIO_PIN(obj->pin_d0)); - HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d1), STM_GPIO_PIN(obj->pin_d1)); - HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d2), STM_GPIO_PIN(obj->pin_d2)); - HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d3), STM_GPIO_PIN(obj->pin_d3)); - HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_sclk), STM_GPIO_PIN(obj->pin_sclk)); - HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_ssel), STM_GPIO_PIN(obj->pin_ssel)); - -#ifdef OCTOSPI -#if defined(OCTOSPI1) - /* Reset the OctoSPI memory interface */ - /* Disable the OctoSPI memory interface clock */ - if (obj->qspi == OCTOSPI1) { - __HAL_RCC_OSPI1_FORCE_RESET(); - __HAL_RCC_OSPI1_RELEASE_RESET(); - - __HAL_RCC_OSPI1_CLK_DISABLE(); - } -#endif -#if defined(OCTOSPI2) - if (obj->qspi == OCTOSPI2) { - __HAL_RCC_OSPI2_FORCE_RESET(); - __HAL_RCC_OSPI2_RELEASE_RESET(); - - __HAL_RCC_OSPI2_CLK_DISABLE(); - } -#endif -#else /* OCTOSPI */ - /* Reset the QuadSPI memory interface */ - __HAL_RCC_QSPI_FORCE_RESET(); - __HAL_RCC_QSPI_RELEASE_RESET(); - - /* Disable the QuadSPI memory interface clock */ - __HAL_RCC_QSPI_CLK_DISABLE(); -#endif /* OCTOSPI */ -} - -/** - * @} - */ - -/** @addtogroup STM32L475E_IOT01_QSPI_Private_Functions - * @{ - */ - -/** - * @brief This function reset the QSPI memory. - * @param hxspi : QSPI handle - * @retval None - */ -static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) -{ -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Initialize the reset enable command */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = RESET_ENABLE_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Initialize the reset enable command */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = RESET_ENABLE_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - /* Send the command */ - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Send the reset memory command */ - sCommand.Instruction = RESET_MEMORY_CMD; - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait the memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief This function send a Write Enable and wait it is effective. - * @param hxspi : QSPI handle - * @retval None - */ -static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) -{ -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - OSPI_AutoPollingTypeDef sConfig; - - /* Enable write operations */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = WRITE_ENABLE_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for write enabling */ - sConfig.Match = MX25R6435F_SR_WEL; - sConfig.Mask = MX25R6435F_SR_WEL; - sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND; - sConfig.Interval = 0x10; - sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; - - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.DataMode = HAL_OSPI_DATA_1_LINE; - sCommand.NbData = 1; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_OSPI_AutoPolling(hxspi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - QSPI_AutoPollingTypeDef sConfig; - - /* Enable write operations */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = WRITE_ENABLE_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_NONE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - - if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Configure automatic polling mode to wait for write enabling */ - sConfig.Match = MX25R6435F_SR_WEL; - sConfig.Mask = MX25R6435F_SR_WEL; - sConfig.MatchMode = QSPI_MATCH_MODE_AND; - sConfig.StatusBytesSize = 1; - sConfig.Interval = 0x10; - sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; - - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.DataMode = QSPI_DATA_1_LINE; - - if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } -#endif /* OCTOSPI */ - - return QSPI_OK; -} - -/** - * @brief This function read the SR of the memory and wait the EOP. - * @param hxspi : QSPI handle - * @param Timeout : Timeout for auto-polling - * @retval None - */ -static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Timeout) -{ -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - OSPI_AutoPollingTypeDef sConfig; - - /* Configure automatic polling mode to wait for memory ready */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_1_LINE; - sCommand.NbData = 1; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - sCommand.DummyCycles = 0; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; - - sConfig.Match = 0; - sConfig.Mask = MX25R6435F_SR_WIP; - sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND; - sConfig.Interval = 0x10; - sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; - - if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_OSPI_AutoPolling(hxspi, &sConfig, Timeout) != HAL_OK) { - return QSPI_ERROR; - } -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - QSPI_AutoPollingTypeDef sConfig; - - /* Configure automatic polling mode to wait for memory ready */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_1_LINE; - sCommand.DummyCycles = 0; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; - - sConfig.Match = 0; - sConfig.Mask = MX25R6435F_SR_WIP; - sConfig.MatchMode = QSPI_MATCH_MODE_AND; - sConfig.StatusBytesSize = 1; - sConfig.Interval = 0x10; - sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; - - if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, Timeout) != HAL_OK) { - return QSPI_ERROR; - } -#endif /* OCTOSPI */ - - return QSPI_OK; -} - -/** - * @brief This function enables/disables the Quad mode of the memory. - * @param hxspi : QSPI handle - * @param Operation : QSPI_QUAD_ENABLE or QSPI_QUAD_DISABLE mode - * @retval None - */ -static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) -{ - uint8_t reg; -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Read status register */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_1_LINE; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - sCommand.DummyCycles = 0; - sCommand.NbData = 1; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Read status register */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_1_LINE; - sCommand.DummyCycles = 0; - sCommand.NbData = 1; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Receive(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Enable write operations */ - if (QSPI_WriteEnable(hxspi) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Activate/deactivate the Quad mode */ - if (Operation == QSPI_QUAD_ENABLE) { - SET_BIT(reg, MX25R6435F_SR_QE); - } else { - CLEAR_BIT(reg, MX25R6435F_SR_QE); - } - - sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; - - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Transmit(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Check the configuration has been correctly done */ - sCommand.Instruction = READ_STATUS_REG_CMD; - - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Receive(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if ((((reg & MX25R6435F_SR_QE) == 0) && (Operation == QSPI_QUAD_ENABLE)) || - (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE))) { - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @brief This function enables/disables the high performance mode of the memory. - * @param hxspi : QSPI handle - * @param Operation : QSPI_HIGH_PERF_ENABLE or QSPI_HIGH_PERF_DISABLE high performance mode - * @retval None - */ -static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) -{ - uint8_t reg[3]; -#ifdef OCTOSPI - OSPI_RegularCmdTypeDef sCommand; - - /* Read status register */ - sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; - sCommand.FlashId = HAL_OSPI_FLASH_ID_1; - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; - sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; - sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; - sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; - sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = HAL_OSPI_DATA_1_LINE; - sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; - sCommand.DummyCycles = 0; - sCommand.NbData = 1; - sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; - sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; -#else /* OCTOSPI */ - QSPI_CommandTypeDef sCommand; - - /* Read status register */ - sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; - sCommand.Instruction = READ_STATUS_REG_CMD; - sCommand.AddressMode = QSPI_ADDRESS_NONE; - sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; - sCommand.DataMode = QSPI_DATA_1_LINE; - sCommand.DummyCycles = 0; - sCommand.NbData = 1; - sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; - sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; - sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; -#endif /* OCTOSPI */ - - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Receive(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Read configuration registers */ - sCommand.Instruction = READ_CFG_REG_CMD; - sCommand.NbData = 2; - - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Receive(hxspi, &(reg[1]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Enable write operations */ - if (QSPI_WriteEnable(hxspi) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Activate/deactivate the Quad mode */ - if (Operation == QSPI_HIGH_PERF_ENABLE) { - SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); - } else { - CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); - } - - sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; - sCommand.NbData = 3; - - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Transmit(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - /* Wait that memory is ready */ - if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { - return QSPI_ERROR; - } - - /* Check the configuration has been correctly done */ - sCommand.Instruction = READ_CFG_REG_CMD; - sCommand.NbData = 2; - - if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if (HAL_XSPI_Receive(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { - return QSPI_ERROR; - } - - if ((((reg[1] & MX25R6435F_CR2_LH_SWITCH) == 0) && (Operation == QSPI_HIGH_PERF_ENABLE)) || - (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE))) { - return QSPI_ERROR; - } - - return QSPI_OK; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file mx25r6435f_driver.c + * @brief This file includes a standard driver for the MX25R6435F QSPI + * memory. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "core_debug.h" +#include "mx25r6435f_driver.h" + +/* Private constants --------------------------------------------------------*/ +#define QSPI_QUAD_DISABLE 0x0 +#define QSPI_QUAD_ENABLE 0x1 + +#define QSPI_HIGH_PERF_DISABLE 0x0 +#define QSPI_HIGH_PERF_ENABLE 0x1 + +/* Private functions ---------------------------------------------------------*/ +static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi); +static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi); +static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Timeout); +static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation); +static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation); +static uint8_t qspi_setClockPrescaler(void); + +/* Exported functions ---------------------------------------------------------*/ +/** + * @brief Select a prescaler to have a clock frequency lower than the maximum. + * The MX25R6435F supports a maximum frequency of 80MHz. + * QSPI clock is connected to AHB bus clock. + * @retval Clock prescaler. 0 means error. + */ +static uint8_t qspi_setClockPrescaler(void) +{ + uint8_t i; + + for (i = 1; i < 255; i++) { + if ((HAL_RCC_GetHCLKFreq() / i) <= 80000000) { + return i; + } + } + + return 0; +} + +/** + * @brief Initializes the QSPI interface. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Init(QSPI_t *obj) +{ + if (obj == NULL) { + return QSPI_ERROR; + } + XSPI_HandleTypeDef *handle = &(obj->handle); + + /* Determine the XSPI to use */ + XSPI_TypeDef *xspi_d0 = pinmap_peripheral(obj->pin_d0, PinMap_XSPI_DATA0); + XSPI_TypeDef *xspi_d1 = pinmap_peripheral(obj->pin_d1, PinMap_XSPI_DATA1); + XSPI_TypeDef *xspi_d2 = pinmap_peripheral(obj->pin_d2, PinMap_XSPI_DATA2); + XSPI_TypeDef *xspi_d3 = pinmap_peripheral(obj->pin_d3, PinMap_XSPI_DATA3); + + XSPI_TypeDef *xspi_sclk = pinmap_peripheral(obj->pin_sclk, PinMap_XSPI_SCLK); + XSPI_TypeDef *xspi_ssel = pinmap_peripheral(obj->pin_ssel, PinMap_XSPI_SSEL); + + /* Pins Dx/SSEL/SCLK must not be NP. */ + if (xspi_d0 == NP || xspi_d1 == NP || xspi_d2 == NP || xspi_sclk == NP || xspi_ssel == NP) { + core_debug("ERROR: at least one QSPI pin has no peripheral\n"); + return QSPI_ERROR; + } + + XSPI_TypeDef *spi_d01 = pinmap_merge_peripheral(xspi_d0, xspi_d1); + XSPI_TypeDef *spi_d23 = pinmap_merge_peripheral(xspi_d2, xspi_d3); + XSPI_TypeDef *spi_dx = pinmap_merge_peripheral(spi_d01, spi_d23); + XSPI_TypeDef *spi_sxxx = pinmap_merge_peripheral(xspi_sclk, xspi_ssel); + + obj->qspi = pinmap_merge_peripheral(spi_dx, spi_sxxx); + + /* Are all pins connected to the same SPI instance? */ + if (obj->qspi == NP) { + core_debug("ERROR: QSPI pins mismatch\n"); + return QSPI_ERROR; + } + + handle->Instance = obj->qspi; + + /* Call the DeInit function to reset the driver */ + if (HAL_XSPI_DeInit(handle) != HAL_OK) { + return QSPI_ERROR; + } + + /* System level initialization */ + BSP_QSPI_MspInit(obj); + +#ifdef OCTOSPI + /* OSPI initialization */ + handle->Init.FifoThreshold = 4; + handle->Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + handle->Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX; + handle->Init.DeviceSize = POSITION_VAL(MX25R6435F_FLASH_SIZE); + handle->Init.ChipSelectHighTime = 1; + handle->Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; + handle->Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; + handle->Init.ClockPrescaler = 4; /* QSPI clock = 110MHz / ClockPrescaler = 27.5 MHz */ + handle->Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE; + handle->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; + handle->Init.ChipSelectBoundary = 0; + handle->Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED; +#else /* OCTOSPI */ + /* QSPI initialization */ + /* High performance mode clock is limited to 80 MHz */ + handle->Init.ClockPrescaler = qspi_setClockPrescaler() + 1; /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ + handle->Init.FifoThreshold = 4; + handle->Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; + handle->Init.FlashSize = POSITION_VAL(MX25R6435F_FLASH_SIZE) - 1; + handle->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; + handle->Init.ClockMode = QSPI_CLOCK_MODE_0; +#endif + + if (HAL_XSPI_Init(handle) != HAL_OK) { + return QSPI_ERROR; + } + + /* QSPI memory reset */ + if (QSPI_ResetMemory(handle) != QSPI_OK) { + return QSPI_NOT_SUPPORTED; + } + + /* QSPI quad enable */ + if (QSPI_QuadMode(handle, QSPI_QUAD_ENABLE) != QSPI_OK) { + return QSPI_ERROR; + } + + /* High performance mode enable */ + if (QSPI_HighPerfMode(handle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Re-configure the clock for the high performance mode */ + /* High performance mode clock is limited to 80 MHz */ + handle->Init.ClockPrescaler = qspi_setClockPrescaler(); /* QSPI clock = systemCoreClock / (ClockPrescaler+1) */ + + if (HAL_XSPI_Init(handle) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Init(handle) != HAL_OK) { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief De-Initializes the QSPI interface. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_DeInit(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + + /* Call the DeInit function to reset the driver */ + if (HAL_XSPI_DeInit(handle) != HAL_OK) { + return QSPI_ERROR; + } + + /* System level De-initialization */ + BSP_QSPI_MspDeInit(obj); + + return QSPI_OK; +} + +/** + * @brief Reads an amount of data from the QSPI memory. + * @param obj : pointer to QSPI_t structure + * @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(QSPI_t *obj, uint8_t *pData, uint32_t ReadAddr, uint32_t Size) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the read command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = QUAD_INOUT_READ_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Address = ReadAddr; + sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES; + sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS; + sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; + sCommand.DataMode = HAL_OSPI_DATA_4_LINES; + sCommand.NbData = Size; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the read command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = QUAD_INOUT_READ_CMD; + sCommand.AddressMode = QSPI_ADDRESS_4_LINES; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.Address = ReadAddr; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES; + sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; + sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; + sCommand.DataMode = QSPI_DATA_4_LINES; + sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; + sCommand.NbData = Size; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Configure the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(handle, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief Writes an amount of data to the QSPI memory. + * @param obj : pointer to QSPI_t structure + * @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(QSPI_t *obj, uint8_t *pData, uint32_t WriteAddr, uint32_t Size) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + uint32_t end_addr, current_size, current_addr; + + /* Calculation of the size between the write address and the end of the page */ + current_size = MX25R6435F_PAGE_SIZE - (WriteAddr % MX25R6435F_PAGE_SIZE); + + /* Check if the size of the data is less than the remaining place in the page */ + if (current_size > Size) { + current_size = Size; + } + + /* Initialize the adress variables */ + current_addr = WriteAddr; + end_addr = WriteAddr + Size; + +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the program command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = QUAD_PAGE_PROG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_4_LINES; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the program command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = QUAD_PAGE_PROG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_4_LINES; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_4_LINES; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Perform the write page by page */ + do { + sCommand.Address = current_addr; + sCommand.NbData = current_size; + + /* Enable write operations */ + if (QSPI_WriteEnable(handle) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Configure the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Transmission of the data */ + if (HAL_XSPI_Transmit(handle, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of program */ + if (QSPI_AutoPollingMemReady(handle, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Update the address and size variables for next page programming */ + current_addr += current_size; + pData += current_size; + current_size = ((current_addr + MX25R6435F_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25R6435F_PAGE_SIZE; + } while (current_addr < end_addr); + + return QSPI_OK; +} + +/** + * @brief Erases the specified block of the QSPI memory. + * @param obj : pointer to QSPI_t structure + * @param BlockAddress : Block address to erase + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Erase_Block(QSPI_t *obj, uint32_t BlockAddress) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = BLOCK_ERASE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Address = BlockAddress; + sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = BLOCK_ERASE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_1_LINE; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.Address = BlockAddress; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Enable write operations */ + if (QSPI_WriteEnable(handle) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK) { + return QSPI_ERROR; + } + return QSPI_OK; +} + +/** + * @brief Erases the specified sector of the QSPI memory. + * @param obj : pointer to QSPI_t structure + * @param Sector : Sector address to erase (0 to 255) + * @retval QSPI memory status + * @note This function is non blocking meaning that sector erase + * operation is started but not completed when the function + * returns. Application has to call BSP_QSPI_GetStatus() + * to know when the device is available again (i.e. erase operation + * completed). + */ +uint8_t BSP_QSPI_Erase_Sector(QSPI_t *obj, uint32_t Sector) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + + if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE / MX25R6435F_SECTOR_SIZE)) { + return QSPI_ERROR; + } + +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = SECTOR_ERASE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Address = (Sector * MX25R6435F_SECTOR_SIZE); + sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = SECTOR_ERASE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_1_LINE; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.Address = (Sector * MX25R6435F_SECTOR_SIZE); + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Enable write operations */ + if (QSPI_WriteEnable(handle) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief Erases the entire QSPI memory. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_Erase_Chip(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = CHIP_ERASE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = CHIP_ERASE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Enable write operations */ + if (QSPI_WriteEnable(handle) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Send the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for end of erase */ + if (QSPI_AutoPollingMemReady(handle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK) { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief Reads current status of the QSPI memory. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_GetStatus(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + uint8_t reg; +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the read security register command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_SEC_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.NbData = 1; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the read security register command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = READ_SEC_REG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_1_LINE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Configure the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(handle, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Check the value of the register */ + if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0) { + return QSPI_ERROR; + } else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0) { + return QSPI_SUSPENDED; + } + + /* Initialize the read status register command */ + sCommand.Instruction = READ_STATUS_REG_CMD; + + /* Configure the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(handle, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Check the value of the register */ + if ((reg & MX25R6435F_SR_WIP) != 0) { + return QSPI_BUSY; + } else { + return QSPI_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) +{ + /* Configure the structure with the memory configuration */ + pInfo->FlashSize = MX25R6435F_FLASH_SIZE; + pInfo->EraseSectorSize = MX25R6435F_SECTOR_SIZE; + pInfo->EraseSectorsNumber = (MX25R6435F_FLASH_SIZE / MX25R6435F_SECTOR_SIZE); + pInfo->ProgPageSize = MX25R6435F_PAGE_SIZE; + pInfo->ProgPagesNumber = (MX25R6435F_FLASH_SIZE / MX25R6435F_PAGE_SIZE); + + return QSPI_OK; +} + +/** + * @brief Configure the QSPI in memory-mapped mode + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + OSPI_MemoryMappedTypeDef sMemMappedCfg; + + /* Configure the command for the read instruction */ + sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = QUAD_INOUT_READ_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES; + sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS; + sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE; + sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES; + sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS; + sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; + sCommand.DataMode = HAL_OSPI_DATA_4_LINES; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure the command for the program instruction */ + sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG; + sCommand.Instruction = QUAD_PAGE_PROG_CMD; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DummyCycles = 0; + + /* Configure the command */ + if (HAL_OSPI_Command(handle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure the memory mapped mode */ + sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE; + + if (HAL_OSPI_MemoryMapped(handle, &sMemMappedCfg) != HAL_OK) { + return QSPI_ERROR; + } +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + QSPI_MemoryMappedTypeDef sMemMappedCfg; + + /* Configure the command for the read instruction */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = QUAD_INOUT_READ_CMD; + sCommand.AddressMode = QSPI_ADDRESS_4_LINES; + sCommand.AddressSize = QSPI_ADDRESS_24_BITS; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES; + sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS; + sCommand.AlternateBytes = MX25R6435F_ALT_BYTES_NO_PE_MODE; + sCommand.DataMode = QSPI_DATA_4_LINES; + sCommand.DummyCycles = MX25R6435F_DUMMY_CYCLES_READ_QUAD; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the memory mapped mode */ + sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; + + if (HAL_QSPI_MemoryMapped(handle, &sCommand, &sMemMappedCfg) != HAL_OK) { + return QSPI_ERROR; + } +#endif /* OCTOSPI */ + + return QSPI_OK; +} + +/** + * @brief This function suspends an ongoing erase command. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_SuspendErase(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + + /* Check whether the device is busy (erase operation is + in progress). + */ + if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the suspend command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = PROG_ERASE_SUSPEND_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + /* Send the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) { + return QSPI_OK; + } + + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function resumes a paused erase command. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_ResumeErase(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + + /* Check whether the device is in suspended state */ + if (BSP_QSPI_GetStatus(obj) == QSPI_SUSPENDED) { +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the resume command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = PROG_ERASE_RESUME_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = PROG_ERASE_RESUME_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + /* Send the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + /* + When this command is executed, the status register write in progress bit is set to 1, and + the flag status register program erase controller bit is set to 0. This command is ignored + if the device is not in a suspended state. + */ + + if (BSP_QSPI_GetStatus(obj) == QSPI_BUSY) { + return QSPI_OK; + } + + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function enter the QSPI memory in deep power down mode. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_EnterDeepPowerDown(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the deep power down command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = DEEP_POWER_DOWN_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the deep power down command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = DEEP_POWER_DOWN_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Send the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* --- Memory takes 10us max to enter deep power down --- */ + /* --- At least 30us should be respected before leaving deep power down --- */ + + return QSPI_OK; +} + +/** + * @brief This function leave the QSPI memory from deep power down mode. + * @param obj : pointer to QSPI_t structure + * @retval QSPI memory status + */ +uint8_t BSP_QSPI_LeaveDeepPowerDown(QSPI_t *obj) +{ + XSPI_HandleTypeDef *handle = &(obj->handle); + +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = NO_OPERATION_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the erase command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = NO_OPERATION_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Send the command */ + if (HAL_XSPI_Command(handle, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */ + /* --- Memory takes 35us min to leave deep power down --- */ + + return QSPI_OK; +} + +/** + * @brief Initializes the QSPI MSP. + * @param obj : pointer to QSPI_t structure + * @retval None + */ +__weak void BSP_QSPI_MspInit(QSPI_t *obj) +{ +#ifdef OCTOSPI + + /* Enable the OctoSPI memory interface clock */ + /* Reset the OctoSPI memory interface */ +#if defined(OCTOSPI1) + if (obj->qspi == OCTOSPI1) { + __HAL_RCC_OSPI1_CLK_ENABLE(); + + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + } +#endif +#if defined(OCTOSPI2) + if (obj->qspi == OCTOSPI2) { + __HAL_RCC_OSPI2_CLK_ENABLE(); + + __HAL_RCC_OSPI2_FORCE_RESET(); + __HAL_RCC_OSPI2_RELEASE_RESET(); + } +#endif +#else /* OCTOSPI */ + /* Enable the QuadSPI memory interface clock */ + __HAL_RCC_QSPI_CLK_ENABLE(); + + /* Reset the QuadSPI memory interface */ + __HAL_RCC_QSPI_FORCE_RESET(); + __HAL_RCC_QSPI_RELEASE_RESET(); +#endif /* OCTOSPI */ + + /* Configure QSPI GPIO pins */ + pinmap_pinout(obj->pin_d0, PinMap_XSPI_DATA0); + pinmap_pinout(obj->pin_d1, PinMap_XSPI_DATA1); + pinmap_pinout(obj->pin_d2, PinMap_XSPI_DATA2); + pinmap_pinout(obj->pin_d3, PinMap_XSPI_DATA3); + pinmap_pinout(obj->pin_sclk, PinMap_XSPI_SCLK); + pinmap_pinout(obj->pin_ssel, PinMap_XSPI_SSEL); +} + +/** + * @brief De-Initializes the QSPI MSP. + * @param obj : pointer to QSPI_t structure + * @retval None + */ +__weak void BSP_QSPI_MspDeInit(QSPI_t *obj) +{ + /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration */ + + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d0), STM_GPIO_PIN(obj->pin_d0)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d1), STM_GPIO_PIN(obj->pin_d1)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d2), STM_GPIO_PIN(obj->pin_d2)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_d3), STM_GPIO_PIN(obj->pin_d3)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_sclk), STM_GPIO_PIN(obj->pin_sclk)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(obj->pin_ssel), STM_GPIO_PIN(obj->pin_ssel)); + +#ifdef OCTOSPI +#if defined(OCTOSPI1) + /* Reset the OctoSPI memory interface */ + /* Disable the OctoSPI memory interface clock */ + if (obj->qspi == OCTOSPI1) { + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + + __HAL_RCC_OSPI1_CLK_DISABLE(); + } +#endif +#if defined(OCTOSPI2) + if (obj->qspi == OCTOSPI2) { + __HAL_RCC_OSPI2_FORCE_RESET(); + __HAL_RCC_OSPI2_RELEASE_RESET(); + + __HAL_RCC_OSPI2_CLK_DISABLE(); + } +#endif +#else /* OCTOSPI */ + /* Reset the QuadSPI memory interface */ + __HAL_RCC_QSPI_FORCE_RESET(); + __HAL_RCC_QSPI_RELEASE_RESET(); + + /* Disable the QuadSPI memory interface clock */ + __HAL_RCC_QSPI_CLK_DISABLE(); +#endif /* OCTOSPI */ +} + +/** + * @brief This function reset the QSPI memory. + * @param hxspi : QSPI handle + * @retval None + */ +static uint8_t QSPI_ResetMemory(XSPI_HandleTypeDef *hxspi) +{ +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Initialize the reset enable command */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = RESET_ENABLE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Initialize the reset enable command */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = RESET_ENABLE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + /* Send the command */ + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Send the reset memory command */ + sCommand.Instruction = RESET_MEMORY_CMD; + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait the memory is ready */ + if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function send a Write Enable and wait it is effective. + * @param hxspi : QSPI handle + * @retval None + */ +static uint8_t QSPI_WriteEnable(XSPI_HandleTypeDef *hxspi) +{ +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + OSPI_AutoPollingTypeDef sConfig; + + /* Enable write operations */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = WRITE_ENABLE_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for write enabling */ + sConfig.Match = MX25R6435F_SR_WEL; + sConfig.Mask = MX25R6435F_SR_WEL; + sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; + + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.NbData = 1; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_OSPI_AutoPolling(hxspi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + QSPI_AutoPollingTypeDef sConfig; + + /* Enable write operations */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = WRITE_ENABLE_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_NONE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + if (HAL_QSPI_Command(hxspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Configure automatic polling mode to wait for write enabling */ + sConfig.Match = MX25R6435F_SR_WEL; + sConfig.Mask = MX25R6435F_SR_WEL; + sConfig.MatchMode = QSPI_MATCH_MODE_AND; + sConfig.StatusBytesSize = 1; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; + + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.DataMode = QSPI_DATA_1_LINE; + + if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } +#endif /* OCTOSPI */ + + return QSPI_OK; +} + +/** + * @brief This function read the SR of the memory and wait the EOP. + * @param hxspi : QSPI handle + * @param Timeout : Timeout for auto-polling + * @retval None + */ +static uint8_t QSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hxspi, uint32_t Timeout) +{ +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + OSPI_AutoPollingTypeDef sConfig; + + /* Configure automatic polling mode to wait for memory ready */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.NbData = 1; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; + + sConfig.Match = 0; + sConfig.Mask = MX25R6435F_SR_WIP; + sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE; + + if (HAL_OSPI_Command(hxspi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_OSPI_AutoPolling(hxspi, &sConfig, Timeout) != HAL_OK) { + return QSPI_ERROR; + } +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + QSPI_AutoPollingTypeDef sConfig; + + /* Configure automatic polling mode to wait for memory ready */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_1_LINE; + sCommand.DummyCycles = 0; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + sConfig.Match = 0; + sConfig.Mask = MX25R6435F_SR_WIP; + sConfig.MatchMode = QSPI_MATCH_MODE_AND; + sConfig.StatusBytesSize = 1; + sConfig.Interval = 0x10; + sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; + + if (HAL_QSPI_AutoPolling(hxspi, &sCommand, &sConfig, Timeout) != HAL_OK) { + return QSPI_ERROR; + } +#endif /* OCTOSPI */ + + return QSPI_OK; +} + +/** + * @brief This function enables/disables the Quad mode of the memory. + * @param hxspi : QSPI handle + * @param Operation : QSPI_QUAD_ENABLE or QSPI_QUAD_DISABLE mode + * @retval None + */ +static uint8_t QSPI_QuadMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) +{ + uint8_t reg; +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Read status register */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Read status register */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_1_LINE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Receive(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Enable write operations */ + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Activate/deactivate the Quad mode */ + if (Operation == QSPI_QUAD_ENABLE) { + SET_BIT(reg, MX25R6435F_SR_QE); + } else { + CLEAR_BIT(reg, MX25R6435F_SR_QE); + } + + sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; + + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Transmit(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Wait that memory is ready */ + if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Check the configuration has been correctly done */ + sCommand.Instruction = READ_STATUS_REG_CMD; + + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Receive(hxspi, ®, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if ((((reg & MX25R6435F_SR_QE) == 0) && (Operation == QSPI_QUAD_ENABLE)) || + (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE))) { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +/** + * @brief This function enables/disables the high performance mode of the memory. + * @param hxspi : QSPI handle + * @param Operation : QSPI_HIGH_PERF_ENABLE or QSPI_HIGH_PERF_DISABLE high performance mode + * @retval None + */ +static uint8_t QSPI_HighPerfMode(XSPI_HandleTypeDef *hxspi, uint8_t Operation) +{ + uint8_t reg[3]; +#ifdef OCTOSPI + OSPI_RegularCmdTypeDef sCommand; + + /* Read status register */ + sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; + sCommand.FlashId = HAL_OSPI_FLASH_ID_1; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; + sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE; + sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; + sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = HAL_OSPI_DATA_1_LINE; + sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DQSMode = HAL_OSPI_DQS_DISABLE; + sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; +#else /* OCTOSPI */ + QSPI_CommandTypeDef sCommand; + + /* Read status register */ + sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; + sCommand.Instruction = READ_STATUS_REG_CMD; + sCommand.AddressMode = QSPI_ADDRESS_NONE; + sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + sCommand.DataMode = QSPI_DATA_1_LINE; + sCommand.DummyCycles = 0; + sCommand.NbData = 1; + sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; + sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; +#endif /* OCTOSPI */ + + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Receive(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Read configuration registers */ + sCommand.Instruction = READ_CFG_REG_CMD; + sCommand.NbData = 2; + + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Receive(hxspi, &(reg[1]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Enable write operations */ + if (QSPI_WriteEnable(hxspi) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Activate/deactivate the Quad mode */ + if (Operation == QSPI_HIGH_PERF_ENABLE) { + SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); + } else { + CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH); + } + + sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD; + sCommand.NbData = 3; + + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Transmit(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + /* Wait that memory is ready */ + if (QSPI_AutoPollingMemReady(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { + return QSPI_ERROR; + } + + /* Check the configuration has been correctly done */ + sCommand.Instruction = READ_CFG_REG_CMD; + sCommand.NbData = 2; + + if (HAL_XSPI_Command(hxspi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if (HAL_XSPI_Receive(hxspi, &(reg[0]), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { + return QSPI_ERROR; + } + + if ((((reg[1] & MX25R6435F_CR2_LH_SWITCH) == 0) && (Operation == QSPI_HIGH_PERF_ENABLE)) || + (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE))) { + return QSPI_ERROR; + } + + return QSPI_OK; +} + +#ifdef __cplusplus +} +#endif + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/mx25r6435f_driver.h b/src/mx25r6435f_driver.h index 95a2e93..62ca051 100644 --- a/src/mx25r6435f_driver.h +++ b/src/mx25r6435f_driver.h @@ -1,188 +1,123 @@ -/** - ****************************************************************************** - * @file mx25r6435f_driver.h - * @author MCD Application Team - * @version V1.1.0 - * @date 21-April-2017 - * @brief This file contains the common defines and functions prototypes for - * the mx25r6435f_driver.c driver. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of STMicroelectronics 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 HOLDER 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. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef _MX25R6435F_DRIVER_H -#define _MX25R6435F_DRIVER_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32_def.h" -#include "PeripheralPins.h" -#include "mx25r6435f_desc.h" - - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup STM32L475E_IOT01 - * @{ - */ - -/** @addtogroup STM32L475E_IOT01_QSPI - * @{ - */ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup STM32L475E_IOT01_QSPI_Exported_Constants QSPI Exported Constants - * @{ - */ - -#if defined(OCTOSPI1) || defined(OCTOSPI2) -#define OCTOSPI -#define XSPI_HandleTypeDef OSPI_HandleTypeDef -#define XSPI_TypeDef OCTOSPI_TypeDef -#define PinMap_XSPI_DATA0 PinMap_OCTOSPI_DATA0 -#define PinMap_XSPI_DATA1 PinMap_OCTOSPI_DATA1 -#define PinMap_XSPI_DATA2 PinMap_OCTOSPI_DATA2 -#define PinMap_XSPI_DATA3 PinMap_OCTOSPI_DATA3 -#define PinMap_XSPI_SCLK PinMap_OCTOSPI_SCLK -#define PinMap_XSPI_SSEL PinMap_OCTOSPI_SSEL -#define HAL_XSPI_Init HAL_OSPI_Init -#define HAL_XSPI_DeInit HAL_OSPI_DeInit -#define HAL_XSPI_TIMEOUT_DEFAULT_VALUE HAL_OSPI_TIMEOUT_DEFAULT_VALUE -#define HAL_XSPI_Command HAL_OSPI_Command -#define HAL_XSPI_Transmit HAL_OSPI_Transmit -#define HAL_XSPI_Receive HAL_OSPI_Receive -#elif defined(QUADSPI) -#define XSPI_HandleTypeDef QSPI_HandleTypeDef -#define XSPI_TypeDef QUADSPI_TypeDef -#define PinMap_XSPI_DATA0 PinMap_QUADSPI_DATA0 -#define PinMap_XSPI_DATA1 PinMap_QUADSPI_DATA1 -#define PinMap_XSPI_DATA2 PinMap_QUADSPI_DATA2 -#define PinMap_XSPI_DATA3 PinMap_QUADSPI_DATA3 -#define PinMap_XSPI_SCLK PinMap_QUADSPI_SCLK -#define PinMap_XSPI_SSEL PinMap_QUADSPI_SSEL -#define HAL_XSPI_Init HAL_QSPI_Init -#define HAL_XSPI_DeInit HAL_QSPI_DeInit -#define HAL_XSPI_TIMEOUT_DEFAULT_VALUE HAL_QPSI_TIMEOUT_DEFAULT_VALUE -#define HAL_XSPI_Command HAL_QSPI_Command -#define HAL_XSPI_Transmit HAL_QSPI_Transmit -#define HAL_XSPI_Receive HAL_QSPI_Receive -#else -#error "QSPI feature not available. MX25R6435F library compilation failed." -#endif /* OCTOSPIx */ - -/* QSPI Error codes */ -#define QSPI_OK ((uint8_t)0x00) -#define QSPI_ERROR ((uint8_t)0x01) -#define QSPI_BUSY ((uint8_t)0x02) -#define QSPI_NOT_SUPPORTED ((uint8_t)0x04) -#define QSPI_SUSPENDED ((uint8_t)0x08) - -/** - * @} - */ - -/* Exported types ------------------------------------------------------------*/ -/** @defgroup STM32L475E_IOT01_QSPI_Exported_Types QSPI Exported Types - * @{ - */ -/* QSPI Info */ -typedef struct { - uint32_t FlashSize; /*!< Size of the flash */ - uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */ - uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */ - uint32_t ProgPageSize; /*!< Size of pages for the program operation */ - uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */ -} QSPI_Info; - - -typedef struct { - XSPI_HandleTypeDef handle; - XSPI_TypeDef *qspi; - PinName pin_d0; - PinName pin_d1; - PinName pin_d2; - PinName pin_d3; - PinName pin_sclk; - PinName pin_ssel; -} QSPI_t; - -/** - * @} - */ - -/* Exported functions --------------------------------------------------------*/ -/** @defgroup STM32L475E_IOT01_QSPI_Exported_Functions QSPI Exported Functions - * @{ - */ -uint8_t BSP_QSPI_Init (QSPI_t *obj); -uint8_t BSP_QSPI_DeInit (QSPI_t *obj); -uint8_t BSP_QSPI_Read (QSPI_t *obj, uint8_t* pData, uint32_t ReadAddr, uint32_t Size); -uint8_t BSP_QSPI_Write (QSPI_t *obj, uint8_t* pData, uint32_t WriteAddr, uint32_t Size); -uint8_t BSP_QSPI_Erase_Block (QSPI_t *obj, uint32_t BlockAddress); -uint8_t BSP_QSPI_Erase_Sector (QSPI_t *obj, uint32_t Sector); -uint8_t BSP_QSPI_Erase_Chip (QSPI_t *obj); -uint8_t BSP_QSPI_GetStatus (QSPI_t *obj); -uint8_t BSP_QSPI_GetInfo (QSPI_Info* pInfo); -uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj); -uint8_t BSP_QSPI_SuspendErase (QSPI_t *obj); -uint8_t BSP_QSPI_ResumeErase (QSPI_t *obj); -uint8_t BSP_QSPI_EnterDeepPowerDown (QSPI_t *obj); -uint8_t BSP_QSPI_LeaveDeepPowerDown (QSPI_t *obj); - -void BSP_QSPI_MspInit(QSPI_t *obj); -void BSP_QSPI_MspDeInit(QSPI_t *obj); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* _MX25R6435F_DRIVER_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/** + ****************************************************************************** + * @file mx25r6435f_driver.h + * @brief This file contains the common defines and functions prototypes for + * the mx25r6435f_driver.c driver. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef _MX25R6435F_DRIVER_H +#define _MX25R6435F_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_def.h" +#include "PeripheralPins.h" +#include "mx25r6435f_desc.h" + +/* Exported constants --------------------------------------------------------*/ +#if defined(OCTOSPI1) || defined(OCTOSPI2) +#define OCTOSPI +#define XSPI_HandleTypeDef OSPI_HandleTypeDef +#define XSPI_TypeDef OCTOSPI_TypeDef +#define PinMap_XSPI_DATA0 PinMap_OCTOSPI_DATA0 +#define PinMap_XSPI_DATA1 PinMap_OCTOSPI_DATA1 +#define PinMap_XSPI_DATA2 PinMap_OCTOSPI_DATA2 +#define PinMap_XSPI_DATA3 PinMap_OCTOSPI_DATA3 +#define PinMap_XSPI_SCLK PinMap_OCTOSPI_SCLK +#define PinMap_XSPI_SSEL PinMap_OCTOSPI_SSEL +#define HAL_XSPI_Init HAL_OSPI_Init +#define HAL_XSPI_DeInit HAL_OSPI_DeInit +#define HAL_XSPI_TIMEOUT_DEFAULT_VALUE HAL_OSPI_TIMEOUT_DEFAULT_VALUE +#define HAL_XSPI_Command HAL_OSPI_Command +#define HAL_XSPI_Transmit HAL_OSPI_Transmit +#define HAL_XSPI_Receive HAL_OSPI_Receive +#elif defined(QUADSPI) +#define XSPI_HandleTypeDef QSPI_HandleTypeDef +#define XSPI_TypeDef QUADSPI_TypeDef +#define PinMap_XSPI_DATA0 PinMap_QUADSPI_DATA0 +#define PinMap_XSPI_DATA1 PinMap_QUADSPI_DATA1 +#define PinMap_XSPI_DATA2 PinMap_QUADSPI_DATA2 +#define PinMap_XSPI_DATA3 PinMap_QUADSPI_DATA3 +#define PinMap_XSPI_SCLK PinMap_QUADSPI_SCLK +#define PinMap_XSPI_SSEL PinMap_QUADSPI_SSEL +#define HAL_XSPI_Init HAL_QSPI_Init +#define HAL_XSPI_DeInit HAL_QSPI_DeInit +#define HAL_XSPI_TIMEOUT_DEFAULT_VALUE HAL_QPSI_TIMEOUT_DEFAULT_VALUE +#define HAL_XSPI_Command HAL_QSPI_Command +#define HAL_XSPI_Transmit HAL_QSPI_Transmit +#define HAL_XSPI_Receive HAL_QSPI_Receive +#else +#error "QSPI feature not available. MX25R6435F library compilation failed." +#endif /* OCTOSPIx */ + +/* QSPI Error codes */ +#define QSPI_OK ((uint8_t)0x00) +#define QSPI_ERROR ((uint8_t)0x01) +#define QSPI_BUSY ((uint8_t)0x02) +#define QSPI_NOT_SUPPORTED ((uint8_t)0x04) +#define QSPI_SUSPENDED ((uint8_t)0x08) + +/* Exported types ------------------------------------------------------------*/ +/* QSPI Info */ +typedef struct { + uint32_t FlashSize; /*!< Size of the flash */ + uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */ + uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */ + uint32_t ProgPageSize; /*!< Size of pages for the program operation */ + uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */ +} QSPI_Info; + + +typedef struct { + XSPI_HandleTypeDef handle; + XSPI_TypeDef *qspi; + PinName pin_d0; + PinName pin_d1; + PinName pin_d2; + PinName pin_d3; + PinName pin_sclk; + PinName pin_ssel; +} QSPI_t; + +/* Exported functions --------------------------------------------------------*/ +uint8_t BSP_QSPI_Init(QSPI_t *obj); +uint8_t BSP_QSPI_DeInit(QSPI_t *obj); +uint8_t BSP_QSPI_Read(QSPI_t *obj, uint8_t *pData, uint32_t ReadAddr, uint32_t Size); +uint8_t BSP_QSPI_Write(QSPI_t *obj, uint8_t *pData, uint32_t WriteAddr, uint32_t Size); +uint8_t BSP_QSPI_Erase_Block(QSPI_t *obj, uint32_t BlockAddress); +uint8_t BSP_QSPI_Erase_Sector(QSPI_t *obj, uint32_t Sector); +uint8_t BSP_QSPI_Erase_Chip(QSPI_t *obj); +uint8_t BSP_QSPI_GetStatus(QSPI_t *obj); +uint8_t BSP_QSPI_GetInfo(QSPI_Info *pInfo); +uint8_t BSP_QSPI_EnableMemoryMappedMode(QSPI_t *obj); +uint8_t BSP_QSPI_SuspendErase(QSPI_t *obj); +uint8_t BSP_QSPI_ResumeErase(QSPI_t *obj); +uint8_t BSP_QSPI_EnterDeepPowerDown(QSPI_t *obj); +uint8_t BSP_QSPI_LeaveDeepPowerDown(QSPI_t *obj); + +void BSP_QSPI_MspInit(QSPI_t *obj); +void BSP_QSPI_MspDeInit(QSPI_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif /* _MX25R6435F_DRIVER_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ From 389edd9863fead4bb5dd9aa7f2754ea90ac0bc98 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 10 Sep 2020 15:23:24 +0200 Subject: [PATCH 5/5] Handle backward compatibility with the STM32 core Signed-off-by: Frederic Pillon --- src/MX25R6435F.h | 16 ++++++++++------ src/mx25r6435f_driver.h | 10 ++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/MX25R6435F.h b/src/MX25R6435F.h index 8ad12da..940b1c3 100644 --- a/src/MX25R6435F.h +++ b/src/MX25R6435F.h @@ -23,23 +23,27 @@ #include "Arduino.h" #include "mx25r6435f_driver.h" +/* + * For backward compatibility define the xSPI pins used by: + * B-L475E-IOT01A and B-L4S5I-IOT01A + */ #ifndef MX25R6435F_D0 - #define MX25R6435F_D0 NC + #define MX25R6435F_D0 PE12 #endif #ifndef MX25R6435F_D1 - #define MX25R6435F_D1 NC + #define MX25R6435F_D1 PE13 #endif #ifndef MX25R6435F_D2 - #define MX25R6435F_D2 NC + #define MX25R6435F_D2 PE14 #endif #ifndef MX25R6435F_D3 - #define MX25R6435F_D3 NC + #define MX25R6435F_D3 PE15 #endif #ifndef MX25R6435F_SCLK - #define MX25R6435F_SCLK NC + #define MX25R6435F_SCLK PE10 #endif #ifndef MX25R6435F_SSEL - #define MX25R6435F_SSEL NC + #define MX25R6435F_SSEL PE11 #endif /* Memory configuration paremeters */ diff --git a/src/mx25r6435f_driver.h b/src/mx25r6435f_driver.h index 62ca051..83e1d3e 100644 --- a/src/mx25r6435f_driver.h +++ b/src/mx25r6435f_driver.h @@ -50,12 +50,22 @@ extern "C" { #elif defined(QUADSPI) #define XSPI_HandleTypeDef QSPI_HandleTypeDef #define XSPI_TypeDef QUADSPI_TypeDef + +#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION > 0x01090000) #define PinMap_XSPI_DATA0 PinMap_QUADSPI_DATA0 #define PinMap_XSPI_DATA1 PinMap_QUADSPI_DATA1 #define PinMap_XSPI_DATA2 PinMap_QUADSPI_DATA2 #define PinMap_XSPI_DATA3 PinMap_QUADSPI_DATA3 #define PinMap_XSPI_SCLK PinMap_QUADSPI_SCLK #define PinMap_XSPI_SSEL PinMap_QUADSPI_SSEL +#else +#define PinMap_XSPI_DATA0 PinMap_QUADSPI +#define PinMap_XSPI_DATA1 PinMap_QUADSPI +#define PinMap_XSPI_DATA2 PinMap_QUADSPI +#define PinMap_XSPI_DATA3 PinMap_QUADSPI +#define PinMap_XSPI_SCLK PinMap_QUADSPI +#define PinMap_XSPI_SSEL PinMap_QUADSPI +#endif #define HAL_XSPI_Init HAL_QSPI_Init #define HAL_XSPI_DeInit HAL_QSPI_DeInit #define HAL_XSPI_TIMEOUT_DEFAULT_VALUE HAL_QPSI_TIMEOUT_DEFAULT_VALUE