/**
******************************************************************************
* @file aps6408.c
* @modify MCD Application Team
* @brief This file provides the APS6408 SRAM OSPI 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
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "aps6408.h"
/** @addtogroup BSP
* @{
*/
/** @addtogroup Components
* @{
*/
/** @defgroup APS6408 APS6408
* @{
*/
/** @defgroup APS6408_Exported_Functions APS6408 Exported Functions
* @{
*/
/* Read/Write Array Commands *********************/
/**
* @brief Reads an amount of data from the OSPI memory.
* @param Ctx Component object pointer
* @param pData Pointer to data to be read
* @param ReadAddr Read start address
* @param Size Size of data to read
* @param LatencyCode Latency used for the access
* @param BurstType Type of burst used for the access
* @retval OSPI memory status
*/
int32_t APS6408_Read(OSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size, uint32_t LatencyCode,
uint32_t BurstType)
{
OSPI_RegularCmdTypeDef sCommand = {0};
/* Initialize the read command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = (BurstType == 0U) ? APS6408_READ_LINEAR_BURST_CMD : APS6408_READ_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.Address = ReadAddr;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.NbData = Size;
sCommand.DummyCycles = LatencyCode;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Reception of the data */
if (HAL_OSPI_Receive(Ctx, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/**
* @brief Reads an amount of data in DMA mode from the OSPI memory.
* @param Ctx Component object pointer
* @param pData Pointer to data to be read
* @param ReadAddr Read start address
* @param Size Size of data to read
* @param LatencyCode Latency used for the access
* @param BurstType Type of burst used for the access
* @retval OSPI memory status
*/
int32_t APS6408_Read_DMA(OSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size,
uint32_t LatencyCode, uint32_t BurstType)
{
OSPI_RegularCmdTypeDef sCommand;
/* Initialize the read command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = ((BurstType == 0U) ? APS6408_READ_LINEAR_BURST_CMD : APS6408_READ_CMD);
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.Address = ReadAddr;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.NbData = Size;
sCommand.DummyCycles = LatencyCode;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Reception of the data */
if (HAL_OSPI_Receive_DMA(Ctx, pData) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/**
* @brief Writes an amount of data to the OSPI memory.
* @param Ctx Component object pointer
* @param pData Pointer to data to be written
* @param WriteAddr Write start address
* @param Size Size of data to write
* @param LatencyCode Latency used for the access
* @param BurstType Type of burst used for the access
* @retval OSPI memory status
*/
int32_t APS6408_Write(OSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size, uint32_t LatencyCode,
uint32_t BurstType)
{
OSPI_RegularCmdTypeDef sCommand = {0};
/* Initialize the write command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.Instruction = (BurstType == 0U) ? APS6408_WRITE_LINEAR_BURST_CMD : APS6408_WRITE_CMD;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Address = WriteAddr;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.NbData = Size;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.DummyCycles = LatencyCode;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Transmission of the data */
if (HAL_OSPI_Transmit(Ctx, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/**
* @brief Writes an amount of data in DMA mode to the OSPI memory.
* @param Ctx Component object pointer
* @param pData Pointer to data to be written
* @param WriteAddr Write start address
* @param Size Size of data to write
* @param LatencyCode Latency used for the access
* @param BurstType Type of burst used for the access
* @retval OSPI memory status
*/
int32_t APS6408_Write_DMA(OSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size,
uint32_t LatencyCode, uint32_t BurstType)
{
OSPI_RegularCmdTypeDef sCommand;
/* Initialize the write command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = ((BurstType == 0U) ? APS6408_WRITE_LINEAR_BURST_CMD : APS6408_WRITE_CMD);
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.Address = WriteAddr;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.NbData = Size;
sCommand.DummyCycles = (LatencyCode - 1U);
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Transmission of the data */
if (HAL_OSPI_Transmit_DMA(Ctx, pData) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/**
* @brief Enable memory mapped mode for the OSPI memory.
* @param Ctx Component object pointer
* @retval OSPI memory status
*/
int32_t APS6408_EnableMemoryMappedMode(OSPI_HandleTypeDef *Ctx, uint32_t ReadLatencyCode, uint32_t WriteLatencyCode,
uint32_t BurstType)
{
OSPI_RegularCmdTypeDef sCommand;
OSPI_MemoryMappedTypeDef sMemMappedCfg;
/* Initialize the write command */
sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = (BurstType == 0U) ? APS6408_WRITE_LINEAR_BURST_CMD : APS6408_WRITE_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.DummyCycles = WriteLatencyCode;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Initialize the read command */
sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
sCommand.Instruction = APS6408_READ_CMD;
sCommand.DummyCycles = ReadLatencyCode;
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* OctoSPI activation of memory-mapped mode */
sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE;
sMemMappedCfg.TimeOutPeriod = 0x34U;
if (HAL_OSPI_MemoryMapped(Ctx, &sMemMappedCfg) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/* Register/Setting Commands **************************************************/
/**
* @brief Read mode register value
* @param Ctx Component object pointer
* @param Address Register address
* @param Value Register value pointer
* @param LatencyCode Latency used for the access
* @retval error status
*/
int32_t APS6408_ReadReg(OSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t *Value, uint32_t LatencyCode)
{
OSPI_RegularCmdTypeDef sCommand = {0};
/* Initialize the read register command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = APS6408_READ_REG_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.Address = Address;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.NbData = 2;
sCommand.DummyCycles = LatencyCode;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Reception of the data */
if (HAL_OSPI_Receive(Ctx, (uint8_t *)Value, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/**
* @brief Write mode register
* @param Ctx Component object pointer
* @param Address Register address
* @param Value Value to write to register
* @retval error status
*/
int32_t APS6408_WriteReg(OSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t Value)
{
OSPI_RegularCmdTypeDef sCommand = {0};
/* Initialize the write register command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = APS6408_WRITE_REG_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.Address = Address;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.NbData = 2;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Transmission of the data */
if (HAL_OSPI_Transmit(Ctx, (uint8_t *)(&Value), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/* ID Commands ****************************************************************/
/**
* @brief Read Flash IDs.
* Vendor ID, Device ID, Device Density
* @param Ctx Component object pointer
* @param ID IDs pointer (2 * 8-bits value)
* @param LatencyCode Latency used for the access
* @retval error status
*/
int32_t APS6408_ReadID(OSPI_HandleTypeDef *Ctx, uint8_t *ID, uint32_t LatencyCode)
{
/* Read the Mode Register 1 and 2 */
if (APS6408_ReadReg(Ctx, APS6408_MR1_ADDRESS, ID, LatencyCode) != APS6408_OK)
{
return APS6408_ERROR;
}
/* Keep only Vendor ID from Mode Register 1 */
*ID &= (APS6408_MR1_VENDOR_ID);
/* Keep only Device ID and Device Density from Mode Register 2 */
*(ID + 1) &= (APS6408_MR2_DEVICE_ID | APS6408_MR2_DENSITY);
return APS6408_OK;
}
/* Power down Commands ********************************************************/
/**
* @brief Memory enter deep power-down command
* @param Ctx Component object pointer
* @retval error status
*/
int32_t APS6408_EnterPowerDown(OSPI_HandleTypeDef *Ctx)
{
/* Update the deep power down value of the MR6 register */
if (APS6408_WriteReg(Ctx, APS6408_MR6_ADDRESS, APS6408_MR6_HS_DEEP_POWER_DOWN) != APS6408_OK)
{
return APS6408_ERROR;
}
/* --- Memory enter deep power down as soon nCS goes high --- */
/* --- At least 500us should be respected before leaving deep power down --- */
return APS6408_OK;
}
/**
* @brief Flash leave deep power-down command
* @param Ctx Component object pointer
* @retval error status
*/
int32_t APS6408_LeavePowerDown(OSPI_HandleTypeDef *Ctx)
{
/* --- A dummy command is sent to the memory, as the nCS should be low for at least 60 ns --- */
/* --- Memory takes 150us max to leave deep power down --- */
OSPI_RegularCmdTypeDef sCommand = {0};
/* Initialize the command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = APS6408_READ_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.Address = 0;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.NbData = 0;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
return APS6408_OK;
}
/* Reset Command **************************************************************/
/**
* @brief Reset the memory
* @param Ctx Component object pointer
* @retval error status
*/
int32_t APS6408_Reset(OSPI_HandleTypeDef *Ctx)
{
OSPI_RegularCmdTypeDef sCommand = {0};
/* Initialize the command */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = APS6408_RESET_CMD;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.Address = 0;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.NbData = 0;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return APS6408_ERROR;
}
/* Need to wait tRST */
HAL_Delay(1);
return APS6408_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/