/**
 *******************************************************************************
 * @file    dpm32m0xx_crc.h
 *
 * @brief   Header file for CRC firmware driver.
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 *******************************************************************************/

#ifndef __DPM32M0XX_CRC_H__
#define __DPM32M0XX_CRC_H__


#ifdef __cplusplus
extern "C" {
#endif

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

#include "dpm32m0xx.h"

/**
 ******************************************************************************
 * @brief CRC mode enumeration.
 *****************************************************************************/
typedef enum
{
  CRC_MODE_CRC32            = 0x00UL,   /* CRC32. */
  CRC_MODE_CRC16_1021       = 0x01UL,   /* CRC16_1021. */
  CRC_MODE_CRC16_8005       = 0x02UL    /* CRC16_8005. */
} CRC_ModeEnum;


/**
 ******************************************************************************
 * @brief CRC input data reverse type enumeration.
 *****************************************************************************/
typedef enum
{
  CRC_INPUT_REV_NO            = 0x00UL,               /* Input data not reverse. */
  CRC_INPUT_REV_8BITS         = 0x04UL,               /* Input data reverse at 8 bits. */
  CRC_INPUT_REV_16BITS        = 0x08UL,               /* Input data reverse at 16 bits. */
  CRC_INPUT_REV_32BITS        = CRC_CR_REV_IN_Msk     /* Input data reverse at 32 bits. */
} CRC_InputRevTypeEnum;


/**
 ******************************************************************************
 * @brief CRC output data reverse type enumeration.
 *****************************************************************************/
typedef enum
{
  CRC_OUTPUT_REV_NO          = 0x00UL,               /* Output data not reverse. */
  CRC_OUTPUT_REV_YES         = CRC_CR_REV_OUT_Msk    /* Output data reverse. */
} CRC_OutputRevTypeEnum;


/**
 ******************************************************************************
 * @brief CRC output data xor type enumeration.
 *****************************************************************************/
typedef enum
{
  CRC_OUTPUT_XOR_ALL0              = 0x00UL,             /* Output data xor 0x00000000. */
  CRC_OUTPUT_XOR_ALLF              = CRC_CR_XOR_OUT_Msk  /* Output data xor 0xFFFFFFFF. */
} CRC_OutputXorTypeEnum;


/**
 ******************************************************************************
 * @brief CRC initialization structure definition.
 *****************************************************************************/
typedef struct
{
  CRC_ModeEnum                CRC_Mode;             /* CRC mode. This parameter can be a value of @ref CRC_ModeEnum. */

  CRC_InputRevTypeEnum        CRC_InputRevType;     /* CRC input data reserse type.
                                                        This parameter can be a value of @ref CRC_InputRevTypeEnum. */

  CRC_OutputRevTypeEnum       CRC_OutputRevType;    /* CRC output data reserse type.
                                                        This parameter can be a value of @ref CRC_OutputRevTypeEnum. */

  CRC_OutputXorTypeEnum       CRC_OutputXorType;    /* CRC output data xor type.
                                                        This parameter can be a value of @ref CRC_OutputXorTypeEnum. */

  uint32_t                    CRC_InitValue;        /* CRC initial data. 
                                                        This parameter can be a number between 0x00000000 and 0xFFFFFFFF.*/
} CRC_InitTypeStruct;



/* CRC Param Check. */
#define IS_CRC_MODE(x)  (((x) == CRC_MODE_CRC32)       ||\
                         ((x) == CRC_MODE_CRC16_1021)  ||\
                         ((x) == CRC_MODE_CRC16_8005)  )

#define IS_CRC_INPUT_REV_TYPE(x)  (((x) == CRC_INPUT_REV_NO)    ||\
                                   ((x) == CRC_INPUT_REV_8BITS)    ||\
                                   ((x) == CRC_INPUT_REV_16BITS)   ||\
                                   ((x) == CRC_INPUT_REV_32BITS))

#define IS_CRC_OUTPUT_REV_TYPE(x)  (((x) == CRC_OUTPUT_REV_NO)       ||\
                                    ((x) == CRC_OUTPUT_REV_YES))

#define IS_CRC_OUTPUT_XOR_TYPE(x)  (((x)==CRC_OUTPUT_XOR_ALL0)       ||\
                                    ((x)==CRC_OUTPUT_XOR_ALLF))



/* Deinitializes and initialization functions. */
void                    CRC_DeInit(void);
void                    CRC_Init(CRC_InitTypeStruct *CRC_InitType);
void                    CRC_StructInit(CRC_InitTypeStruct *CRC_InitType);


/* Configuration of the CRC computation unit. */
void                    CRC_SetMode(CRC_ModeEnum CRC_Mode);
void                    CRC_SetInputReverseType(CRC_InputRevTypeEnum CRC_InputRevType);
void                    CRC_SetOutputReverseType(CRC_OutputRevTypeEnum CRC_OutputRevType);
void                    CRC_SetOutputXorType(CRC_OutputXorTypeEnum CRC_OutputXorType);


/* CRC computation. */
void                    CRC_SetInitValue(uint32_t CRC_InitValue);
#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015) || \
    defined (DPM32M026) || defined (DPM32T55x)
uint32_t                CRC_CalcCRC8bits(uint8_t CRC_Data);
uint32_t                CRC_CalcCRC16bits(uint16_t CRC_Data);
#else /* DPM32M08x || DPM32M05x || DPM32M03x */
void                    CRC_CalcCRC8bits(uint8_t CRC_Data);
uint16_t                CRC_CalcCRC16bits(uint16_t CRC_Data);
#endif /* DPM32M036 || DPM32M030 || DPM32M015 || DPM32M026 || DPM32T55x */
uint32_t                CRC_CalcCRC32bits(uint32_t CRC_Data);
uint32_t                CRC_CalcCRCBuf8bits(uint8_t* pBuffer, uint32_t BufferLength);
uint32_t                CRC_CalcCRCBuf16bits(uint16_t* pBuffer, uint32_t BufferLength);
uint32_t                CRC_CalcCRCBuf32bits(uint32_t* pBuffer, uint32_t BufferLength);
uint32_t                CRC_GetCRCResult(void);



#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic pop
#endif

#ifdef __cplusplus
}
#endif

#endif /* __DPM32M0XX_CRC_H__ */
