/*********************************************************************************************************//**
 * @file    ht32_misc.c
 * @version $Rev:: 7888         $
 * @date    $Date:: 2024-07-22 #$
 * @brief   This file provides all the miscellaneous firmware functions.
 *************************************************************************************************************
 * @attention
 *
 * Firmware Disclaimer Information
 *
 * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *    code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
 *    proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
 *    other intellectual property laws.
 *
 * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *    code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
 *    other than HOLTEK and the customer.
 *
 * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
 *    only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
 *    the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
 *    the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
 *
 * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
 ************************************************************************************************************/

/* Includes ------------------------------------------------------------------------------------------------*/
#include "ht32_misc.h"

/** @addtogroup HT32_Peripheral_Driver HT32 Peripheral Driver
  * @{
  */

/** @defgroup MISC MISC
  * @brief MISC driver modules
  * @{
  */

/* Private definitions -------------------------------------------------------------------------------------*/
/** @defgroup MISC_Private_Define MISC private definitions
  * @{
  */
#define AIRCR_VECTKEY_MASK    ((u32)0x05FA0000)
#define CTRL_TICKINT_SET      ((u32)0x00000002)
#define CTRL_TICKINT_RESET    ((u32)0xFFFFFFFD)
/**
  * @}
  */

/* Global functions ----------------------------------------------------------------------------------------*/
/** @defgroup MISC_Exported_Functions MISC exported functions
  * @{
  */

/*********************************************************************************************************//**
  * @brief  Configure the SysTick clock source.
  * @param  SysTick_ClockSource: Specify the SysTick clock source.
  *   This parameter can be one of the following values:
  *     @arg SYSTICK_SRC_STCLK  : External reference clock is selected as SysTick clock source.
  *     @arg SYSTICK_SRC_FCLK   : AHB clock is selected as SysTick clock source.
  * @retval  None
  ***********************************************************************************************************/
void SYSTICK_ClockSourceConfig(u32 SysTick_ClockSource)
{
  if (SysTick_ClockSource == SYSTICK_SRC_FCLK)
  {
    SysTick->CTRL |= SYSTICK_SRC_FCLK;
  }
  else
  {
    SysTick->CTRL &= SYSTICK_SRC_STCLK;
  }
}

/*********************************************************************************************************//**
  * @brief  Enable or Disable the SysTick counter.
  * @param  SysTick_Counter: new state of the SysTick counter.
  *   This parameter can be one of the following values:
  *     @arg SYSTICK_COUNTER_DISABLE  : Disable counter
  *     @arg SYSTICK_COUNTER_ENABLE   : Enable counter
  *     @arg SYSTICK_COUNTER_CLEAR    : Clear counter value to 0
  * @retval None
  ***********************************************************************************************************/
void SYSTICK_CounterCmd(u32 SysTick_Counter)
{
  if (SysTick_Counter == SYSTICK_COUNTER_CLEAR)
  {
    SysTick->VAL = SYSTICK_COUNTER_CLEAR;
  }
  else
  {
    if (SysTick_Counter == SYSTICK_COUNTER_ENABLE)
    {
      SysTick->CTRL |= SYSTICK_COUNTER_ENABLE;
    }
    else
    {
      SysTick->CTRL &= SYSTICK_COUNTER_DISABLE;
    }
  }
}

/*********************************************************************************************************//**
  * @brief  Enable or Disable the SysTick Interrupt.
  * @param  NewState: new state of the SysTick Interrupt.
  *   This parameter can be: TRUE or FALSE.
  * @retval None
  ***********************************************************************************************************/
void SYSTICK_IntConfig(bool NewState)
{
  if (NewState != FALSE)
  {
    SysTick->CTRL |= CTRL_TICKINT_SET;
  }
  else
  {
    SysTick->CTRL &= CTRL_TICKINT_RESET;
  }
}

/*********************************************************************************************************//**
  * @brief  Set SysTick counter reload value.
  * @param  SysTick_Reload: SysTick reload new value.
  *   This parameter must be a number between 1 and 0xFFFFFF.
  * @retval None
  ***********************************************************************************************************/
void SYSTICK_SetReloadValue(u32 SysTick_Reload)
{
  SysTick->LOAD = SysTick_Reload;
}

/*********************************************************************************************************//**
 * @brief Get the CRC-CCITT checksum from the given data
 * @param seed: CRC initial data
 * @param buffer: pointer to the given data to be calculated
 * @param length: data length in byte
 * @retval The checksum value
 ************************************************************************************************************/
u16 CRC_CCITT(u16 seed, u8 *buffer, u32 length)
{
  /* CRC-CCITT poly: 0x1021                                                                                 */

  /* config initial data, crc_init_data_set(seed);                                                          */
  CRC->idt = seed;

  /* config poly size 16-bit, crc_poly_size_set(CRC_POLY_SIZE_16B);                                         */
  CRC->ctrl_bit.poly_size = CRC_POLY_SIZE_16B;

  /* config poly default value, crc_poly_value_set(0x1021);                                                 */
  CRC->poly = 0x1021;

  /* config output data reverse mode, crc_reverse_output_data_set(CRC_REVERSE_OUTPUT_NO_AFFECTE);           */
  CRC->ctrl_bit.revod = CRC_REVERSE_OUTPUT_NO_AFFECTE;

  /* config input data reverse mode, crc_reverse_input_data_set(CRC_REVERSE_INPUT_NO_AFFECTE);              */
  CRC->ctrl_bit.revid = CRC_REVERSE_INPUT_NO_AFFECTE;

  /* reset CRC_DT                                                                                           */
  crc_data_reset();

  while (length--)
  {
    wb(&CRC->dt, *buffer++); // byte write
  }

  return (u16)(CRC->dt);
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */
