/*
 * Copyright 2020-2023 Yuntu Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
/*!
* @file eeprom_driver.h
*/
#ifndef EEPROM_DRIVER_H
#define EEPROM_DRIVER_H

#include <stddef.h>
#include "device_registers.h"
#include "status.h"
#include "osif.h"

/*!
 * @ingroup eeprom
 * @addtogroup eeprom_driver
 * @{
 */

/*******************************************************************************
 * Definitions
 ******************************************************************************/
typedef enum
{
    EEPROM_EVENT_COMPLETE              = 0x01U,    /*!< Operation completed */
    EEPROM_EVENT_CMD_FAIL_ERROR        = 0x02U,    /*!< An error occured when command launch */
    EEPROM_EVENT_ACCESS_ERROR          = 0x03U,    /*!< An access error occured when command launch */
    EEPROM_EVENT_UNRECOVERABLE_ERROR   = 0x04U,    /*!< An unrecoverable error occured when command launch */
    EEPROM_EVENT_RECOVERABLE_ERROR     = 0x05U,    /*!< A recoverable error occured when command launch */
} eeprom_event_t;

/*******************************************************************************
* Callback function prototype
*******************************************************************************/

/*! @brief Call back function pointer data type for eeprom event */
typedef void (*eeprom_callback_t)(eeprom_event_t event);

/*!
 * @brief EEPROM configuration structure.
 */
typedef struct
{
    bool readVerifyEnable;               /*!< true: enable read verify after erase or program, false: disable read verify */
    bool errorInterruptEnable;           /*!< Error interrupt enable. */
    bool eccErrorInterruptEnable;        /*!< ECC Error interrupt enable. */
    eeprom_callback_t callback;          /*!< Callback function pointer */
    uint32_t* writeBufferPtr;            /*!< Write buffer pointer */
} eeprom_user_config_t;


typedef struct {
/*! @cond DRIVER_INTERNAL_USE_ONLY */
    eeprom_callback_t callback;     /*!< Callback function pointer */
    volatile status_t opStatus;     /*!< Operation status */
    volatile bool isBlocking;       /*!< Blocking method flag */
    semaphore_t writeComplete;      /*!< Write complete semaphore */
    volatile uint32_t dest;         /*!< Destination address for write data */
    volatile uint32_t leftSize;     /*!< Left size of write data */
    volatile uint32_t bufIdx;       /*!< Buffer index for write data */
    uint32_t* bufPtr;               /*!< Buffer pointer for write data */
/*! @endcond */
} eeprom_state_t;

/*******************************************************************************
 * API
 ******************************************************************************/
/*!
 * @name EEPROM DRIVER API
 * @{
 */
#if defined(__cplusplus)
extern "C" {
#endif


/*!
 * @brief EEPROM driver initialization function.
 *
 * This function initializes EEPROM driver based on user configuration input.
 * The user must make sure that the clock is enabled
 *
 * @param[in] instance The EEPROM instance number
 * @param[in] userConfigPtr Pointer to structure of initialization
 * @param[in] eepromStatePtr Pointer to EEPROM state structure
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 */
status_t EEPROM_DRV_Init(uint8_t instance, const eeprom_user_config_t * userConfigPtr, eeprom_state_t * eepromStatePtr);

/*!
 * @brief EEPROM driver de-initialization function.
 *
 * This function de-initializes EEPROM driver.
 *
 * @param[in] instance The EEPROM instance number
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 */

status_t EEPROM_DRV_Deinit(uint8_t instance);

/*!
 * @brief EEPROM Erase all.
 *
 * This function will erase all EEPROM array.
 *
 * @param[in] instance The EEPROM instance number
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 */

status_t EEPROM_DRV_EraseAll(uint8_t instance);

/*!
 * @brief EEPROM driver erase function.
 * @note This function will erase EEPROM array with given address and size.
 * @param[in] instance The EEPROM instance number
 * @param[in] addr The EEPROM address, should be 4 bytes aligned
 * @param[in] size The EEPROM erase size in bytes, should be 4 bytes aligned
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 */

status_t EEPROM_DRV_Erase(uint8_t instance, uint32_t addr, uint32_t size);

/*!
 * @brief EEPROM driver program function.
 * @note This function will program EEPROM array with given address and data.
 *       The program operation is always blocking.
 *       Use EEPROM_DRV_Write32 function for normal data access.
 * @param[in] instance The EEPROM instance number
 * @param[in] addr The EEPROM address, should be 4 bytes aligned
 * @param[in] size The EEPROM erase size in bytes, should be 4 bytes aligned
 * @param[in] data The EEPROM data, should be 4 bytes aligned
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 */
status_t EEPROM_DRV_Program(uint8_t instance, uint32_t addr, uint32_t size, uint32_t* data);

/*!
 * @brief EEPROM driver wait idle.
 *
 * This function will wait EEPROM idle.
 *
 * @param[in] instance The EEPROM instance number
 * @return EEPROM status (success or busy)
 * @retval STATUS_SUCCESS Operation was successful
 */

status_t EEPROM_DRV_WaitIdle(uint8_t instance);

/*!
 * @brief EEPROM driver read function.
 *
 * This function reads 32bit data from EEPROM.
 * Note: EEPROM support CPU direct access, user can use CPU direct access to read data from EEPROM.
 *       When using CPU direct access, make sure EEPROM is not busy.
 *
 * @param[in] instance The EEPROM instance number
 * @param[in] addr The EEPROM address
 * @param[out] data The EEPROM data
 * @return Read access status (success or failure)
 * @retval STATUS_SUCCESS Operation was successful
 */
status_t EEPROM_DRV_Read32(uint8_t instance, uint32_t addr, uint32_t *data);

/*!
 * @brief EEPROM driver blocking write function.
 *
 * This function write 32bit data to EEPROM and wait write operation complete.
 *
 * @param[in] instance The EEPROM instance number
 * @param[in] addr The EEPROM address
 * @param[in] data The EEPROM data
 * @return Write access status (success or failure)
 * @retval STATUS_SUCCESS Operation was successful
 */
status_t EEPROM_DRV_Write32(uint8_t instance, uint32_t addr, uint32_t data);


/*!
 * @brief EEPROM driver write function by blocking method.
 *
 * Blocking means that the function does not return until the write is all complete.
 *
 * @param[in] instance The EEPROM instance number
 * @param[in] addr The EEPROM address
 * @param[in] size The EEPROM data size in bytes
 * @param[in] pData The EEPROM data pointer
 * @param[in] timeout The timeout value in milliseconds
 * @return Write access status (success or timeout)
 * @retval STATUS_SUCCESS Operation was successful
 */
status_t EEPROM_DRV_WriteBlocking(uint8_t instance, uint32_t addr, uint32_t size, const void * pData, uint32_t timeout);

/*!
 * @brief EEPROM driver write function by aynchronous no-blocking method.
 *
 * Non-blocking means that the function returns immediately after the write is started.
 * The user should check the status of the write operation using the callback function.
 *
 * @param[in] instance The EEPROM instance number
 * @param[in] addr The EEPROM address
 * @param[in] size The EEPROM data size in bytes
 * @param[in] pData The EEPROM data pointer
 * @return Write access status (success or failure)
 * @retval STATUS_SUCCESS Operation was successful
 */
status_t EEPROM_DRV_WriteAsync(uint8_t instance, uint32_t addr, uint32_t size, const void * pData);

/*!
 * @brief EEPROM driver get status function.
 *
 * This function returns the current status of the EEPROM driver.
 *
 * @param[in] instance The EEPROM instance number
 * @return EEPROM status (busy or idle)
 * @retval true Driver is busy with an operation
 * @retval false Driver is idle
 */
bool EEPROM_DRV_IsBusy(uint32_t instance);

/*!
 * @brief EEPROM driver get write status function.
 *
 * This function returns the current status of the EEPROM driver write operation.
 *
 * @param[in] instance The EEPROM instance number
 * @return EEPROM write status (success or failure)
 * @retval STATUS_SUCCESS Operation was successful
 * @retval STATUS_ERROR Operation failed
 */
status_t EEPROM_DRV_GetWriteStatus(uint32_t instance);

/*! @} */

#if defined(__cplusplus)
}
#endif

/*! @} */

#endif /* EEPROM_DRIVER_H */
/*******************************************************************************
 * EOF
 ******************************************************************************/
