/*
 * @file exo_io_al_stm32f7xx_crc.c
 *
 * @brief This file contains wrapper function definition for I2C interface
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "exo_io_al_stm32f7xx_crc.h"
#include "exo_osal.h"
#include "exo_common.h"
#ifndef LINUX_TEMP_PORT
#include "stm32f7xx_hal.h"
#endif


CRC_HandleTypeDef hcrc;

/*
 * @brief This API is use to Initialization hardware CRC.
 */
hal_ret_sts io_hal_stm32f7xx_crc_init(ioal_crc_hdle *ioal_hcrc)
{
	  hal_ret_sts ret_sts = HAL_MAX_ERR;

	  hcrc.Instance = CRC;

	  /* The default polynomial is used */
	  hcrc.Init.DefaultPolynomialUse    = DEFAULT_POLYNOMIAL_DISABLE;
	  hcrc.Init.GeneratingPolynomial    = CRC_POLYNOMIAL_FACTOR;
	  hcrc.Init.CRCLength               = CRC_POLYLENGTH_32B;
	  /* The default init value is used */
	  hcrc.Init.DefaultInitValueUse     = DEFAULT_INIT_VALUE_ENABLE;
	  /* The input data are not inverted */
	  hcrc.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_NONE;
	  /* The output data are not inverted */
	  hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
	  /* The input data are 32-bit long words */
	  hcrc.InputDataFormat              = CRC_INPUTDATA_FORMAT_WORDS;

	    if (HAL_CRC_Init(&hcrc) == HAL_OK)
	    {
		   /* Initialization Error */
		   ret_sts = HAL_SCS;
		   ioal_hcrc->intf_gen_info.vdp_intf_inst_hdle = &hcrc;
	    }

	    else
	    {
		   ret_sts = HAL_IO_VDP_ERR;
	    }

	    return ret_sts;
}

/*
 *  @brief This API is use to determine the input data format for CRC.
 */
hal_ret_sts io_hal_stm32f7xx_crc_calculation (ioal_crc_hdle *ioal_hcrc, uint8_t *input_data_buffer, uint32_t input_data_buffer_size, uint32_t *crc_output_value)
{
	  hal_ret_sts ret_sts = HAL_MAX_ERR;
	  CRC_HandleTypeDef *hcrc_hdl;

	  hcrc_hdl = (CRC_HandleTypeDef *)ioal_hcrc->intf_gen_info.vdp_intf_inst_hdle;
	/*
	 * determine input data format based on size
	 */
	  if(input_data_buffer_size != 0 && input_data_buffer_size < INPUT_DATA_SIZE_MAX)
	  {
		  if (input_data_buffer_size % 4 == 0)
		  {
			  hcrc_hdl->InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS;
		  	  input_data_buffer_size >>= 2; // divide by 4
		  }
		  else if (input_data_buffer_size % 4 == 2)
		  {
			  hcrc_hdl->InputDataFormat = CRC_INPUTDATA_FORMAT_HALFWORDS;
		  }
		  else
		  {
			  hcrc_hdl->InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
		  }


		  *crc_output_value = HAL_CRC_Calculate(hcrc_hdl, (uint32_t *)input_data_buffer, input_data_buffer_size);
		  ret_sts = HAL_SCS;
	  }

	  	else
	  	{
			 ret_sts = HAL_IO_VDP_ERR;
	  	}

	    return ret_sts;
}


