/*
 * Copyright 2020-2022 Yuntu Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef STCU_DRIVER_H
#define STCU_DRIVER_H

/*! @file stcu_driver.h */

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

/*!
 * @defgroup stcu_driver STCU Driver
 * @ingroup stcu
 * @brief Self-Test Control Unit Driver
 * @details This section describes the programming interface of the STCU driver.
 * @{
 */
/*******************************************************************************
 * Variables
 ******************************************************************************/

/*******************************************************************************
 * Definitions
 ******************************************************************************/

#define STCU_STATUS_FAIL_MASK   (STCU_STATUS_DUPLICATED_BIT_ERR_MASK \
 | STCU_STATUS_TIMEOUT_MASK                                          \
 | STCU_STATUS_CRC_ERR_MASK                                          \
 | STCU_STATUS_FSM_ERR_MASK                                          \
 | STCU_STATUS_BIST_FAIL_MASK                                        \
 | STCU_STATUS_NONCRITICAL_FAULT_MASK                                \
 | STCU_STATUS_CRITICAL_FAULT_MASK)

/*!
 * @brief STCU error injection type
 * Implements : stcu_error_injection_t_Class
 */
/* REF
00000b (0x00) - Not inject error to STCU.
00001b (0x01) - Inject watchdog time-out error to STCU.
00010b (0x02) - Inject CRC error to STCU.
00011b (0x03) - Inject FSM error to STCU.
00100b (0x04) - Inject MBIST fail to STCU.
00101b (0x05) - Inject LBIST fail to STCU.
00110b (0x06) - Inject duplicated bit error to STCU.
 */
typedef enum
{
    STCU_NO_ERROR_INJECTION = 0x00U,             /*!< No error injection */
    STCU_INJECT_WDG_TIMEOUT_ERROR = 0x01U,       /*!< Inject watchdog timeout error */
    STCU_INJECT_CRC_ERROR = 0x02U,               /*!< Inject CRC error */
    STCU_INJECT_FSM_ERROR = 0x03U,               /*!< Inject FSM error */
    STCU_INJECT_MBIST_FAIL = 0x04U,              /*!< Inject MBIST fail */
    STCU_INJECT_LBIST_FAIL = 0x05U,              /*!< Inject LBIST fail */
    STCU_INJECT_DUPLICATED_BIT_ERROR = 0x06U     /*!< Inject duplicated bit error */
} stcu_error_injection_mode_t;

typedef enum
{
    STCU_NO_VALID_RESULT = 0x00U,                /*!< No valid result */
    STCU_CHECK_PASS = 0x01U,                     /*!< Check pass */
    STCU_CHECK_FAIL = 0x02U                      /*!< Check fail */
} stcu_run_result_t;

/*!
 * @brief STCU engine run sequence mode selection
 * Implements : stcu_sequence_mode_t_Class
 */
typedef enum
{
    STCU_SEQUENCE_MODE_PARALLEL = 0x00U, /*!< Parallel mode */
    STCU_SEQUENCE_MODE_SERIAL = 0x01U /*!< Serial mode */
} stcu_sequence_mode_t;

/*!
 * @brief STCU LBIST configuration
 * Implements : stcu_lbist_config_t_Class
 */
typedef struct
{
    bool lbist_enable;              /*!< LBIST engine enable */
    uint32_t lbctrl_cfg;            /*!< LBIST control configuration */
    uint32_t lbist_start_value;     /*!< LBIST start value */
    uint32_t lbist_end_value;       /*!< LBIST end value */
    uint64_t lbist_init_seed;       /*!< LBIST initial seed */
    uint64_t lbist_init_misr;       /*!< LBIST initial MISR */
    uint64_t lbist_final_misr;      /*!< LBIST final MISR */
    uint8_t lbist_speed;            /*!< LBIST speed */
} stcu_lbist_config_t;

/*!
 * @brief STCU user configuration structure
 * Implements : stcu_user_config_t_Class
 */
typedef struct
{
    uint32_t wdgTimeoutCnt;                         /*!< STCU internal watchdog timeout microseconds */
    uint16_t crcSeed;                               /*!< CRC check init value */
    uint16_t crcXorValue;                           /*!< CRC check XOR value */
    stcu_error_injection_mode_t errorInjectionMode; /*!< Error injection Mode */
    uint8_t errorInjectionType;                     /*!< Error injection type */
    bool clearResult;                               /*!< Auto clear previous run result */
    stcu_sequence_mode_t lbistMode;                /*!< LBIST run mode */
    stcu_sequence_mode_t mbistMode;                /*!< MBIST run mode */
    uint32_t lbistEngine;                          /*!< LBIST engine selection */
    uint32_t mbistEngine;                          /*!< MBIST engine selection */
    uint32_t mbistAlgorithm;                       /*!< MBIST algorithm selection */
    stcu_lbist_config_t lbistConfig[STCU_LBCTRL_COUNT];               /*!< LBIST configuration */
} stcu_user_config_t;

/*******************************************************************************
 * API
 ******************************************************************************/
/*!
 * @name STCU DRIVER API
 * @{
 */

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Initializes the STCU module
 *
 * This function initializes STCU driver based on user configuration input.
 * The user must make sure that the clock is enabled
 *
 * @param[in] instance The STCU instance number
 * @param[in] userConfigPtr Pointer to structure of initialization
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 * @retval STATUS_BUSY STCU result is pending for access
 */
status_t STCU_DRV_Init(uint32_t instance,
                       const stcu_user_config_t *userConfigPtr);

/*!
 * @brief Start STCU engine
 *
 * This function starts the STCU engine
 * STCU module should be initialized before calling this function
 *
 * @param[in] instance The STCU instance number
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 */

status_t STCU_DRV_Start(uint32_t instance);

/*!
 * @brief Read STCU run result
 *
 * This function reads the STCU run result
 */

stcu_run_result_t STCU_DRV_GetResult(uint32_t instance);

/*!
 * @brief Read STCU run result
 *
 * This function clears the STCU run result, this step is necessary for
 * the next run, otherwise the STCU won't start.
 */

void STCU_DRV_ClearResult(uint32_t instance);

/*!
 * @brief Sets the default configuration
 *
 * This function sets the default configuration
 *
 * @param[in] instance The STCU instance number
 * @return Execution status (success)
 * @retval STATUS_SUCCESS Operation was successful
 */
status_t STCU_DRV_Deinit(uint32_t instance);

/*!
 * @brief Get default configures the STCU module for configuration structure
 *
 * This function Get default configures the STCU module for user configuration structure
 *
 * @param[out] userConfigPtr Pointer to structure of initialization
 * @return Execution status (success)
 */
status_t STCU_DRV_GetDefaultConfig(stcu_user_config_t *userConfigPtr);

/*! @} */

#if defined(__cplusplus)
}
#endif

/*! @} */

#endif /* STCU_DRIVER_H */
/*******************************************************************************
 * EOF
 ******************************************************************************/
