Subversion Repositories FuelGauge

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f0xx_hal_crc.c
  4.   * @author  MCD Application Team
  5.   * @brief   CRC HAL module driver.
  6.   *          This file provides firmware functions to manage the following
  7.   *          functionalities of the Cyclic Redundancy Check (CRC) peripheral:
  8.   *           + Initialization and de-initialization functions
  9.   *           + Peripheral Control functions
  10.   *           + Peripheral State functions
  11.   *
  12.   @verbatim
  13.  ===============================================================================
  14.                      ##### How to use this driver #####
  15.  ===============================================================================
  16.     [..]
  17.          (+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
  18.          (+) Initialize CRC calculator
  19.              (++) specify generating polynomial (peripheral default or non-default one)
  20.              (++) specify initialization value (peripheral default or non-default one)
  21.              (++) specify input data format
  22.              (++) specify input or output data inversion mode if any
  23.          (+) Use HAL_CRC_Accumulate() function to compute the CRC value of the
  24.              input data buffer starting with the previously computed CRC as
  25.              initialization value
  26.          (+) Use HAL_CRC_Calculate() function to compute the CRC value of the
  27.              input data buffer starting with the defined initialization value
  28.              (default or non-default) to initiate CRC calculation
  29.  
  30.   @endverbatim
  31.   ******************************************************************************
  32.   * @attention
  33.   *
  34.   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  35.   * All rights reserved.</center></h2>
  36.   *
  37.   * This software component is licensed by ST under BSD 3-Clause license,
  38.   * the "License"; You may not use this file except in compliance with the
  39.   * License. You may obtain a copy of the License at:
  40.   *                        opensource.org/licenses/BSD-3-Clause
  41.   *
  42.   ******************************************************************************
  43.   */
  44.  
  45. /* Includes ------------------------------------------------------------------*/
  46. #include "stm32f0xx_hal.h"
  47.  
  48. /** @addtogroup STM32F0xx_HAL_Driver
  49.   * @{
  50.   */
  51.  
  52. /** @defgroup CRC CRC
  53.   * @brief CRC HAL module driver.
  54.   * @{
  55.   */
  56.  
  57. #ifdef HAL_CRC_MODULE_ENABLED
  58.  
  59. /* Private typedef -----------------------------------------------------------*/
  60. /* Private define ------------------------------------------------------------*/
  61. /* Private macro -------------------------------------------------------------*/
  62. /* Private variables ---------------------------------------------------------*/
  63. /* Private function prototypes -----------------------------------------------*/
  64. /** @defgroup CRC_Private_Functions CRC Private Functions
  65.   * @{
  66.   */
  67. static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength);
  68. static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength);
  69. /**
  70.   * @}
  71.   */
  72.  
  73. /* Exported functions --------------------------------------------------------*/
  74.  
  75. /** @defgroup CRC_Exported_Functions CRC Exported Functions
  76.   * @{
  77.   */
  78.  
  79. /** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
  80.   *  @brief    Initialization and Configuration functions.
  81.   *
  82. @verbatim
  83.  ===============================================================================
  84.             ##### Initialization and de-initialization functions #####
  85.  ===============================================================================
  86.     [..]  This section provides functions allowing to:
  87.       (+) Initialize the CRC according to the specified parameters
  88.           in the CRC_InitTypeDef and create the associated handle
  89.       (+) DeInitialize the CRC peripheral
  90.       (+) Initialize the CRC MSP (MCU Specific Package)
  91.       (+) DeInitialize the CRC MSP
  92.  
  93. @endverbatim
  94.   * @{
  95.   */
  96.  
  97. /**
  98.   * @brief  Initialize the CRC according to the specified
  99.   *         parameters in the CRC_InitTypeDef and create the associated handle.
  100.   * @param  hcrc CRC handle
  101.   * @retval HAL status
  102.   */
  103. HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
  104. {
  105.   /* Check the CRC handle allocation */
  106.   if (hcrc == NULL)
  107.   {
  108.     return HAL_ERROR;
  109.   }
  110.  
  111.   /* Check the parameters */
  112.   assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
  113.  
  114.   if (hcrc->State == HAL_CRC_STATE_RESET)
  115.   {
  116.     /* Allocate lock resource and initialize it */
  117.     hcrc->Lock = HAL_UNLOCKED;
  118.     /* Init the low level hardware */
  119.     HAL_CRC_MspInit(hcrc);
  120.   }
  121.  
  122.   hcrc->State = HAL_CRC_STATE_BUSY;
  123.  
  124. #if defined(CRC_POL_POL)
  125.   /* check whether or not non-default generating polynomial has been
  126.    * picked up by user */
  127.   assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse));
  128.   if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE)
  129.   {
  130.     /* initialize peripheral with default generating polynomial */
  131.     WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY);
  132.     MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B);
  133.   }
  134.   else
  135.   {
  136.     /* initialize CRC peripheral with generating polynomial defined by user */
  137.     if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK)
  138.     {
  139.       return HAL_ERROR;
  140.     }
  141.   }
  142. #endif /* CRC_POL_POL */
  143.  
  144.   /* check whether or not non-default CRC initial value has been
  145.    * picked up by user */
  146.   assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse));
  147.   if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE)
  148.   {
  149.     WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE);
  150.   }
  151.   else
  152.   {
  153.     WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue);
  154.   }
  155.  
  156.  
  157.   /* set input data inversion mode */
  158.   assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode));
  159.   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode);
  160.  
  161.   /* set output data inversion mode */
  162.   assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode));
  163.   MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode);
  164.  
  165.   /* makes sure the input data format (bytes, halfwords or words stream)
  166.    * is properly specified by user */
  167.   assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat));
  168.  
  169.   /* Change CRC peripheral state */
  170.   hcrc->State = HAL_CRC_STATE_READY;
  171.  
  172.   /* Return function status */
  173.   return HAL_OK;
  174. }
  175.  
  176. /**
  177.   * @brief  DeInitialize the CRC peripheral.
  178.   * @param  hcrc CRC handle
  179.   * @retval HAL status
  180.   */
  181. HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
  182. {
  183.   /* Check the CRC handle allocation */
  184.   if (hcrc == NULL)
  185.   {
  186.     return HAL_ERROR;
  187.   }
  188.  
  189.   /* Check the parameters */
  190.   assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
  191.  
  192.   /* Check the CRC peripheral state */
  193.   if (hcrc->State == HAL_CRC_STATE_BUSY)
  194.   {
  195.     return HAL_BUSY;
  196.   }
  197.  
  198.   /* Change CRC peripheral state */
  199.   hcrc->State = HAL_CRC_STATE_BUSY;
  200.  
  201.   /* Reset CRC calculation unit */
  202.   __HAL_CRC_DR_RESET(hcrc);
  203.  
  204.   /* Reset IDR register content */
  205.   CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR);
  206.  
  207.   /* DeInit the low level hardware */
  208.   HAL_CRC_MspDeInit(hcrc);
  209.  
  210.   /* Change CRC peripheral state */
  211.   hcrc->State = HAL_CRC_STATE_RESET;
  212.  
  213.   /* Process unlocked */
  214.   __HAL_UNLOCK(hcrc);
  215.  
  216.   /* Return function status */
  217.   return HAL_OK;
  218. }
  219.  
  220. /**
  221.   * @brief  Initializes the CRC MSP.
  222.   * @param  hcrc CRC handle
  223.   * @retval None
  224.   */
  225. __weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
  226. {
  227.   /* Prevent unused argument(s) compilation warning */
  228.   UNUSED(hcrc);
  229.  
  230.   /* NOTE : This function should not be modified, when the callback is needed,
  231.             the HAL_CRC_MspInit can be implemented in the user file
  232.    */
  233. }
  234.  
  235. /**
  236.   * @brief  DeInitialize the CRC MSP.
  237.   * @param  hcrc CRC handle
  238.   * @retval None
  239.   */
  240. __weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
  241. {
  242.   /* Prevent unused argument(s) compilation warning */
  243.   UNUSED(hcrc);
  244.  
  245.   /* NOTE : This function should not be modified, when the callback is needed,
  246.             the HAL_CRC_MspDeInit can be implemented in the user file
  247.    */
  248. }
  249.  
  250. /**
  251.   * @}
  252.   */
  253.  
  254. /** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
  255.   *  @brief    management functions.
  256.   *
  257. @verbatim
  258.  ===============================================================================
  259.                       ##### Peripheral Control functions #####
  260.  ===============================================================================
  261.     [..]  This section provides functions allowing to:
  262.       (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
  263.           using combination of the previous CRC value and the new one.
  264.  
  265.        [..]  or
  266.  
  267.       (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
  268.           independently of the previous CRC value.
  269.  
  270. @endverbatim
  271.   * @{
  272.   */
  273.  
  274. /**
  275.   * @brief  Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
  276.   *         starting with the previously computed CRC as initialization value.
  277.   * @param  hcrc CRC handle
  278.   * @param  pBuffer pointer to the input data buffer, exact input data format is
  279.   *         provided by hcrc->InputDataFormat.
  280.   * @param  BufferLength input data buffer length (number of bytes if pBuffer
  281.   *         type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
  282.   *         number of words if pBuffer type is * uint32_t).
  283.   * @note  By default, the API expects a uint32_t pointer as input buffer parameter.
  284.   *        Input buffer pointers with other types simply need to be cast in uint32_t
  285.   *        and the API will internally adjust its input data processing based on the
  286.   *        handle field hcrc->InputDataFormat.
  287.   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
  288.   */
  289. uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
  290. {
  291.   uint32_t index;      /* CRC input data buffer index */
  292.   uint32_t temp = 0U;  /* CRC output (read from hcrc->Instance->DR register) */
  293.  
  294.   /* Change CRC peripheral state */
  295.   hcrc->State = HAL_CRC_STATE_BUSY;
  296.  
  297.   switch (hcrc->InputDataFormat)
  298.   {
  299.     case CRC_INPUTDATA_FORMAT_WORDS:
  300.       /* Enter Data to the CRC calculator */
  301.       for (index = 0U; index < BufferLength; index++)
  302.       {
  303.         hcrc->Instance->DR = pBuffer[index];
  304.       }
  305.       temp = hcrc->Instance->DR;
  306.       break;
  307.  
  308.     case CRC_INPUTDATA_FORMAT_BYTES:
  309.       temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength);
  310.       break;
  311.  
  312.     case CRC_INPUTDATA_FORMAT_HALFWORDS:
  313.       temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength);    /* Derogation MisraC2012 R.11.5 */
  314.       break;
  315.     default:
  316.       break;
  317.   }
  318.  
  319.   /* Change CRC peripheral state */
  320.   hcrc->State = HAL_CRC_STATE_READY;
  321.  
  322.   /* Return the CRC computed value */
  323.   return temp;
  324. }
  325.  
  326. /**
  327.   * @brief  Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
  328.   *         starting with hcrc->Instance->INIT as initialization value.
  329.   * @param  hcrc CRC handle
  330.   * @param  pBuffer pointer to the input data buffer, exact input data format is
  331.   *         provided by hcrc->InputDataFormat.
  332.   * @param  BufferLength input data buffer length (number of bytes if pBuffer
  333.   *         type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
  334.   *         number of words if pBuffer type is * uint32_t).
  335.   * @note  By default, the API expects a uint32_t pointer as input buffer parameter.
  336.   *        Input buffer pointers with other types simply need to be cast in uint32_t
  337.   *        and the API will internally adjust its input data processing based on the
  338.   *        handle field hcrc->InputDataFormat.
  339.   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
  340.   */
  341. uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
  342. {
  343.   uint32_t index;      /* CRC input data buffer index */
  344.   uint32_t temp = 0U;  /* CRC output (read from hcrc->Instance->DR register) */
  345.  
  346.   /* Change CRC peripheral state */
  347.   hcrc->State = HAL_CRC_STATE_BUSY;
  348.  
  349.   /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
  350.   *  written in hcrc->Instance->DR) */
  351.   __HAL_CRC_DR_RESET(hcrc);
  352.  
  353.   switch (hcrc->InputDataFormat)
  354.   {
  355.     case CRC_INPUTDATA_FORMAT_WORDS:
  356.       /* Enter 32-bit input data to the CRC calculator */
  357.       for (index = 0U; index < BufferLength; index++)
  358.       {
  359.         hcrc->Instance->DR = pBuffer[index];
  360.       }
  361.       temp = hcrc->Instance->DR;
  362.       break;
  363.  
  364.     case CRC_INPUTDATA_FORMAT_BYTES:
  365.       /* Specific 8-bit input data handling  */
  366.       temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength);
  367.       break;
  368.  
  369.     case CRC_INPUTDATA_FORMAT_HALFWORDS:
  370.       /* Specific 16-bit input data handling  */
  371.       temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength);    /* Derogation MisraC2012 R.11.5 */
  372.       break;
  373.  
  374.     default:
  375.       break;
  376.   }
  377.  
  378.   /* Change CRC peripheral state */
  379.   hcrc->State = HAL_CRC_STATE_READY;
  380.  
  381.   /* Return the CRC computed value */
  382.   return temp;
  383. }
  384.  
  385. /**
  386.   * @}
  387.   */
  388.  
  389. /** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
  390.   *  @brief    Peripheral State functions.
  391.   *
  392. @verbatim
  393.  ===============================================================================
  394.                       ##### Peripheral State functions #####
  395.  ===============================================================================
  396.     [..]
  397.     This subsection permits to get in run-time the status of the peripheral.
  398.  
  399. @endverbatim
  400.   * @{
  401.   */
  402.  
  403. /**
  404.   * @brief  Return the CRC handle state.
  405.   * @param  hcrc CRC handle
  406.   * @retval HAL state
  407.   */
  408. HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
  409. {
  410.   /* Return CRC handle state */
  411.   return hcrc->State;
  412. }
  413.  
  414. /**
  415.   * @}
  416.   */
  417.  
  418. /**
  419.   * @}
  420.   */
  421.  
  422. /** @addtogroup CRC_Private_Functions
  423.   * @{
  424.   */
  425.  
  426. /**
  427.   * @brief  Enter 8-bit input data to the CRC calculator.
  428.   *         Specific data handling to optimize processing time.
  429.   * @param  hcrc CRC handle
  430.   * @param  pBuffer pointer to the input data buffer
  431.   * @param  BufferLength input data buffer length
  432.   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
  433.   */
  434. static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength)
  435. {
  436.   uint32_t i; /* input data buffer index */
  437.   uint16_t data;
  438.   __IO uint16_t *pReg;
  439.  
  440.   /* Processing time optimization: 4 bytes are entered in a row with a single word write,
  441.    * last bytes must be carefully fed to the CRC calculator to ensure a correct type
  442.    * handling by the peripheral */
  443.   for (i = 0U; i < (BufferLength / 4U); i++)
  444.   {
  445.     hcrc->Instance->DR = ((uint32_t)pBuffer[4U * i] << 24U) | \
  446.                          ((uint32_t)pBuffer[(4U * i) + 1U] << 16U) | \
  447.                          ((uint32_t)pBuffer[(4U * i) + 2U] << 8U)  | \
  448.                          (uint32_t)pBuffer[(4U * i) + 3U];
  449.   }
  450.   /* last bytes specific handling */
  451.   if ((BufferLength % 4U) != 0U)
  452.   {
  453.     if ((BufferLength % 4U) == 1U)
  454.     {
  455.       *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[4U * i];         /* Derogation MisraC2012 R.11.5 */
  456.     }
  457.     if ((BufferLength % 4U) == 2U)
  458.     {
  459.       data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U];
  460.       pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                    /* Derogation MisraC2012 R.11.5 */
  461.       *pReg = data;
  462.     }
  463.     if ((BufferLength % 4U) == 3U)
  464.     {
  465.       data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U];
  466.       pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                    /* Derogation MisraC2012 R.11.5 */
  467.       *pReg = data;
  468.  
  469.       *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[(4U * i) + 2U];  /* Derogation MisraC2012 R.11.5 */
  470.     }
  471.   }
  472.  
  473.   /* Return the CRC computed value */
  474.   return hcrc->Instance->DR;
  475. }
  476.  
  477. /**
  478.   * @brief  Enter 16-bit input data to the CRC calculator.
  479.   *         Specific data handling to optimize processing time.
  480.   * @param  hcrc CRC handle
  481.   * @param  pBuffer pointer to the input data buffer
  482.   * @param  BufferLength input data buffer length
  483.   * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
  484.   */
  485. static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength)
  486. {
  487.   uint32_t i;  /* input data buffer index */
  488.   __IO uint16_t *pReg;
  489.  
  490.   /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
  491.    * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
  492.    * a correct type handling by the peripheral */
  493.   for (i = 0U; i < (BufferLength / 2U); i++)
  494.   {
  495.     hcrc->Instance->DR = ((uint32_t)pBuffer[2U * i] << 16U) | (uint32_t)pBuffer[(2U * i) + 1U];
  496.   }
  497.   if ((BufferLength % 2U) != 0U)
  498.   {
  499.     pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                 /* Derogation MisraC2012 R.11.5 */
  500.     *pReg = pBuffer[2U * i];
  501.   }
  502.  
  503.   /* Return the CRC computed value */
  504.   return hcrc->Instance->DR;
  505. }
  506.  
  507. /**
  508.   * @}
  509.   */
  510.  
  511. #endif /* HAL_CRC_MODULE_ENABLED */
  512. /**
  513.   * @}
  514.   */
  515.  
  516. /**
  517.   * @}
  518.   */
  519.  
  520. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  521.