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

/*!
 * @file pcrc_driver.h
 * @version 1.4.0
 */

#ifndef PCRC_DRIVER_H
#define PCRC_DRIVER_H

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

/*!
 * @defgroup pcrc_driver PCRC Driver
 * @ingroup pcrc
 * @brief Cyclic Redundancy Check Peripheral Driver
 * @details This section describes the programming interface of the PCRC driver.
 * @{
 */
/*******************************************************************************
 * Variables
 ******************************************************************************/

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

/*!
 * @brief PCRC type of transpose of read write data
 * Implements : pcrc_transpose_t_Class
 */
typedef enum
{
    PCRC_TRANSPOSE_NONE = 0x00U,        /*!< No transpose */
    PCRC_BIT_SWAP_IN_BYTE = 0x01U,      /*!< Transpose bits in bytes */
    PCRC_BIT_SWAP_IN_WORD = 0x02U,      /*!< Transpose bits in words */
    PCRC_BYTE_SWAP_IN_WORD = 0x04U      /*!< Transpose bytes in word */
} pcrc_transpose_t;

/*!
 * @brief PCRC configuration structure.
 * Implements : pcrc_user_config_t_Class
 */
typedef struct
{
    pcrc_transpose_t readTranspose;          /*!< Type of transpose when reading PCRC result. */
    pcrc_transpose_t writeTranspose;         /*!< Type of transpose when writing PCRC input data. */
    bool complementChecksum;                /*!< True if the result shall be complement of the actual checksum. */
    uint8_t crcWidth;                       /*!< Selects bits width of PCRC polynomials. */
    uint32_t seed;                          /*!< Starting checksum value. */
    uint32_t poly;                          /*!< The polynomials of PCRC protocol */
} pcrc_user_config_t;

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

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

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

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

/*!
 * @brief Appends 32-bit data to the current PCRC calculation and returns new result
 *
 * This function appends 32-bit data to the current PCRC calculation
 * and returns new result. If the newSeed is true, seed set and
 * result are calculated from the seed new value (new PCRC calculation)
 *
 * @param[in] instance The PCRC instance number
 * @param[in] data Input data for PCRC calculation
 * @param[in] newSeed Sets new PCRC calculation
 *            - true: New seed set and used for new calculation.
 *            - false: Seed argument ignored, continues old calculation.
 * @param[in] seed New seed if newSeed is true, else ignored
 * @return New PCRC result
 */
uint32_t PCRC_DRV_GetCrc32(uint32_t instance,
                          uint32_t data,
                          bool newSeed,
                          uint32_t seed);

/*!
 * @brief Appends 16-bit data to the current PCRC calculation and returns new result
 *
 * This function appends 16-bit data to the current PCRC calculation
 * and returns new result. If the newSeed is true, seed set and
 * result are calculated from the seed new value (new PCRC calculation)
 *
 * @param[in] instance The PCRC instance number
 * @param[in] data Input data for PCRC calculation
 * @param[in] newSeed Sets new PCRC calculation
 *            - true: New seed set and used for new calculation.
 *            - false: Seed argument ignored, continues old calculation.
 * @param[in] seed New seed if newSeed is true, else ignored
 * @return New PCRC result
 */
uint32_t PCRC_DRV_GetCrc16(uint32_t instance,
                          uint16_t data,
                          bool newSeed,
                          uint32_t seed);

/*!
 * @brief Appends 8-bit data to the current PCRC calculation and returns new result
 *
 * This function appends 8-bit data to the current PCRC calculation
 * and returns new result. If the newSeed is true, seed set and
 * result are calculated from the seed new value (new PCRC calculation)
 *
 * @param[in] instance The PCRC instance number
 * @param[in] data Input data for PCRC calculation
 * @param[in] newSeed Sets new PCRC calculation
 *            - true: New seed set and used for new calculation.
 *            - false: Seed argument ignored, continues old calculation.
 * @param[in] seed New seed if newSeed is true, else ignored
 * @return New PCRC result
 */
uint32_t PCRC_DRV_GetCrc8(uint32_t instance,
                         uint8_t data,
                         bool newSeed,
                         uint32_t seed);

/*!
 * @brief Appends a block of bytes to the current PCRC calculation
 *
 * This function appends a block of bytes to the current PCRC calculation
 *
 * @param[in] instance The PCRC instance number
 * @param[in] data Data for current PCRC calculation
 * @param[in] dataSize Length of data to be calculated
 */
void PCRC_DRV_WriteData(uint32_t instance,
                       const uint8_t *data,
                       uint32_t dataSize);

/*!
 * @brief Appends a block of half word to the current PCRC calculation
 *
 * This function appends a block of half words to the current PCRC calculation
 *
 * @param[in] instance The PCRC instance number
 * @param[in] data Data for current PCRC calculation
 * @param[in] dataSize Length of data in half words to be calculated
 */
void PCRC_DRV_WriteData16(uint32_t instance,
                         const uint16_t *data,
                         uint32_t dataSize);

/*!
 * @brief Appends a block of word to the current PCRC calculation
 *
 * This function appends a block of words to the current PCRC calculation
 *
 * @param[in] instance The PCRC instance number
 * @param[in] data Data for current PCRC calculation
 * @param[in] dataSize Length of data in words to be calculated
 */
void PCRC_DRV_WriteData32(uint32_t instance,
                         const uint32_t *data,
                         uint32_t dataSize);

/*!
 * @brief Returns the current result of the PCRC calculation
 *
 * This function returns the current result of the PCRC calculation
 *
 * @param[in] instance The PCRC instance number
 * @return Result of PCRC calculation
 */
uint32_t PCRC_DRV_GetCrcResult(uint32_t instance);

/*!
 * @brief Configures the PCRC module from a user configuration structure
 *
 * This function configures the PCRC module from a user configuration structure
 *
 * @param[in] instance The PCRC instance number
 * @param[in] userConfigPtr Pointer to structure of initialization
 * @return Execution status (success)
 */
status_t PCRC_DRV_Configure(uint32_t instance,
                           const pcrc_user_config_t *userConfigPtr);

/*!
 * @brief Get configures of the PCRC module currently
 *
 * This function Get configures of the PCRC module currently
 *
 * @param[in] instance The PCRC instance number
 * @param[out] userConfigPtr Pointer to structure of initialization
 * @return Execution status (success)
 */
status_t PCRC_DRV_GetConfig(uint32_t instance,
                           pcrc_user_config_t *const userConfigPtr);

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

/*! @} */

#if defined(__cplusplus)
}
#endif

/*! @} */

#endif /* PCRC_DRIVER_H */
/*******************************************************************************
 * EOF
 ******************************************************************************/
