375 lines
11 KiB
C
375 lines
11 KiB
C
/**
|
|
******************************************************************************
|
|
* @file b_wl5m_subg_eeprom.c
|
|
* @author MCD Application Team
|
|
* @brief This file provides a set of functions needed to manage
|
|
* an I2C M24256DFMC6TG EEPROM memory.
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2022 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "b_wl5m_subg_bus.h"
|
|
#include "b_wl5m_subg_eeprom.h"
|
|
|
|
/** @addtogroup BSP
|
|
* @{
|
|
*/
|
|
|
|
/** @addtogroup B_WL5M_SUBG
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup B_WL5M_SUBG_EEPROM B-WL5M-SUBG EEPROM
|
|
* @brief This file includes the I2C EEPROM driver of B-WL5M-SUBG board.
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup B_WL5M_SUBG_EEPROM_Private_Types B-WL5M-SUBG EEPROM Private Types
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup B_WL5M_SUBG_EEPROM_Private_Defines B-WL5M-SUBG EEPROM Private Defines
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup B_WL5M_SUBG_EEPROM_Private_Macros B-WL5M-SUBG EEPROM Private Macros
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup B_WL5M_SUBG_EEPROM_Private_Variables B-WL5M-SUBG EEPROM Private Variables
|
|
* @{
|
|
*/
|
|
__IO uint8_t EEPROMAddressWrite = 0xAC;
|
|
__IO uint8_t EEPROMAddressRead = 0xAD;
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup B_WL5M_SUBG_EEPROM_Private_Functions_Prototypes B-WL5M-SUBG EEPROM Private Functions Prototypes
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/** @defgroup B_WL5M_SUBG_EEPROM_Private_Functions B-WL5M-SUBG EEPROM Private Functions
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Initializes peripherals used by the I2C EEPROM driver.
|
|
* @note Initialize could be long causing by the call of I2C_GetTiming which computes
|
|
* the best I2C configuration
|
|
* @retval BSP_ERROR_NONE (0) if operation is correctly performed, else return value
|
|
* different from BSP_ERROR_NONE (0)
|
|
*/
|
|
int32_t BSP_EEPROM_Init(void)
|
|
{
|
|
/* I2C Initialization */
|
|
B_WL5M_SUBG_I2C_Init();
|
|
|
|
/* Select the EEPROM address and check if OK */
|
|
if(BSP_I2C2_IsReady(EEPROMAddressRead, EEPROM_MAX_TRIALS) != BSP_ERROR_NONE)
|
|
{
|
|
return BSP_ERROR_PERIPH_FAILURE;
|
|
}
|
|
return BSP_ERROR_NONE;
|
|
}
|
|
|
|
/**
|
|
* @brief DeInitializes the EEPROM.
|
|
* @retval EEPROM state
|
|
*/
|
|
int32_t BSP_EEPROM_DeInit(void)
|
|
{
|
|
return B_WL5M_SUBG_I2C_DeInit();
|
|
}
|
|
|
|
/**
|
|
* @brief Reads a block of data from the EEPROM.
|
|
* @param pBuffer: pointer to the buffer that receives the data read from
|
|
* the EEPROM.
|
|
* @param ReadAddr: EEPROM's internal address to start reading from.
|
|
* @param NumByteToRead: pointer to the variable holding number of bytes to
|
|
* be read from the EEPROM.
|
|
*
|
|
* @retval BSP_ERROR_NONE (0) if operation is correctly performed, else return value
|
|
* different from BSP_ERROR_NONE (0) or the timeout user callback.
|
|
*/
|
|
int32_t BSP_EEPROM_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
|
|
{
|
|
uint32_t buffersize = *NumByteToRead;
|
|
|
|
if(BSP_I2C2_ReadReg16(EEPROMAddressRead, ReadAddr, pBuffer, buffersize) != HAL_OK)
|
|
{
|
|
BSP_EEPROM_TIMEOUT_UserCallback();
|
|
return BSP_ERROR_PERIPH_FAILURE;
|
|
}
|
|
|
|
/* If all operations OK, return BSP_ERROR_NONE (0) */
|
|
return BSP_ERROR_NONE;
|
|
}
|
|
|
|
/**
|
|
* @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
|
|
*
|
|
* @note The number of bytes (combined to write start address) must not
|
|
* cross the EEPROM page boundary. This function can only write into
|
|
* the boundaries of an EEPROM page.
|
|
* This function doesn't check on boundaries condition (in this driver
|
|
* the function BSP_EEPROM_WriteBuffer() which calls BSP_EEPROM_WritePage() is
|
|
* responsible of checking on Page boundaries).
|
|
*
|
|
* @param pBuffer: pointer to the buffer containing the data to be written to
|
|
* the EEPROM.
|
|
* @param WriteAddr: EEPROM's internal address to write to.
|
|
* @param NumByteToWrite: pointer to the variable holding number of bytes to
|
|
* be written into the EEPROM.
|
|
*
|
|
* @retval BSP_ERROR_NONE (0) if operation is correctly performed, else return value
|
|
* different from BSP_ERROR_NONE (0) or the timeout user callback.
|
|
*/
|
|
int32_t BSP_EEPROM_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
|
|
{
|
|
uint32_t buffersize = *NumByteToWrite;
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
if(BSP_I2C2_WriteReg16(EEPROMAddressWrite, WriteAddr, pBuffer, buffersize) != HAL_OK)
|
|
{
|
|
BSP_EEPROM_TIMEOUT_UserCallback();
|
|
status = BSP_ERROR_PERIPH_FAILURE;
|
|
}
|
|
|
|
if(BSP_EEPROM_WaitEepromStandbyState() != BSP_ERROR_NONE)
|
|
{
|
|
return BSP_ERROR_PERIPH_FAILURE;
|
|
}
|
|
|
|
/* If all operations OK, return BSP_ERROR_NONE (0) */
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Writes buffer of data to the I2C EEPROM.
|
|
* @param pBuffer: pointer to the buffer containing the data to be written
|
|
* to the EEPROM.
|
|
* @param WriteAddr: EEPROM's internal address to write to.
|
|
* @param NumByteToWrite: number of bytes to write to the EEPROM.
|
|
* @retval BSP_ERROR_NONE (0) if operation is correctly performed, else return value
|
|
* different from BSP_ERROR_NONE (0) or the timeout user callback.
|
|
*/
|
|
int32_t BSP_EEPROM_WriteBuffer(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
|
|
{
|
|
uint16_t numofpage = 0;
|
|
uint16_t numofsingle = 0;
|
|
uint16_t count = 0;
|
|
uint16_t addr = 0;
|
|
uint8_t dataindex = 0;
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
addr = WriteAddr % EEPROM_PAGESIZE;
|
|
count = EEPROM_PAGESIZE - addr;
|
|
numofpage = NumByteToWrite / EEPROM_PAGESIZE;
|
|
numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
|
|
|
|
/* If WriteAddr is EEPROM_PAGESIZE aligned */
|
|
if(addr == 0)
|
|
{
|
|
/* If NumByteToWrite < EEPROM_PAGESIZE */
|
|
if(numofpage == 0)
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = numofsingle;
|
|
/* Start writing data */
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
}
|
|
/* If NumByteToWrite > EEPROM_PAGESIZE */
|
|
else
|
|
{
|
|
while(numofpage--)
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = EEPROM_PAGESIZE;
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
WriteAddr += EEPROM_PAGESIZE;
|
|
pBuffer += EEPROM_PAGESIZE;
|
|
}
|
|
|
|
if(numofsingle!=0)
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = numofsingle;
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* If WriteAddr is not EEPROM_PAGESIZE aligned */
|
|
else
|
|
{
|
|
/* If NumByteToWrite < EEPROM_PAGESIZE */
|
|
if(numofpage== 0)
|
|
{
|
|
/* If the number of data to be written is more than the remaining space
|
|
in the current page: */
|
|
if(NumByteToWrite > count)
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = count;
|
|
/* Write the data contained in same page */
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
/* Store the number of data to be written */
|
|
dataindex = (NumByteToWrite - count);
|
|
/* Write the remaining data in the following page */
|
|
status = BSP_EEPROM_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = numofsingle;
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
}
|
|
}
|
|
/* If NumByteToWrite > EEPROM_PAGESIZE */
|
|
else
|
|
{
|
|
NumByteToWrite -= count;
|
|
numofpage = NumByteToWrite / EEPROM_PAGESIZE;
|
|
numofsingle = NumByteToWrite % EEPROM_PAGESIZE;
|
|
|
|
if(count != 0)
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = count;
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
WriteAddr += count;
|
|
pBuffer += count;
|
|
}
|
|
|
|
while(numofpage--)
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = EEPROM_PAGESIZE;
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
WriteAddr += EEPROM_PAGESIZE;
|
|
pBuffer += EEPROM_PAGESIZE;
|
|
}
|
|
if(numofsingle != 0)
|
|
{
|
|
/* Store the number of data to be written */
|
|
dataindex = numofsingle;
|
|
status = BSP_EEPROM_WritePage(pBuffer, WriteAddr, (uint8_t*)(&dataindex));
|
|
if(status != BSP_ERROR_NONE)
|
|
{
|
|
return status;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If all operations OK, return BSP_ERROR_NONE (0) */
|
|
return BSP_ERROR_NONE;
|
|
}
|
|
|
|
/**
|
|
* @brief Wait for EEPROM Standby state.
|
|
*
|
|
* @note This function allows to wait and check that EEPROM has finished the
|
|
* last operation. It is mostly used after Write operation: after receiving
|
|
* the buffer to be written, the EEPROM may need additional time to actually
|
|
* perform the write operation. During this time, it doesn't answer to
|
|
* I2C packets addressed to it. Once the write operation is complete
|
|
* the EEPROM responds to its address.
|
|
*
|
|
* @retval BSP_ERROR_NONE (0) if operation is correctly performed, else return value
|
|
* different from BSP_ERROR_NONE (0) or the timeout user callback.
|
|
*/
|
|
int32_t BSP_EEPROM_WaitEepromStandbyState(void)
|
|
{
|
|
/* Check if the maximum allowed number of trials has bee reached */
|
|
if(BSP_I2C2_IsReady(EEPROMAddressWrite, EEPROM_MAX_TRIALS) != HAL_OK)
|
|
{
|
|
/* If the maximum number of trials has been reached, exit the function */
|
|
BSP_EEPROM_TIMEOUT_UserCallback();
|
|
return BSP_ERROR_PERIPH_FAILURE;
|
|
}
|
|
return BSP_ERROR_NONE;
|
|
}
|
|
|
|
/**
|
|
* @brief Basic management of the timeout situation.
|
|
* @retval None
|
|
*/
|
|
__weak void BSP_EEPROM_TIMEOUT_UserCallback(void)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|