/** * @brief Initializes the CRC polynomial if different from default one. * @param hcrc: CRC handle * @param Pol: CRC generating polynomial (7, 8, 16 or 32-bit long) * This parameter is written in normal representation, e.g. * for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 is written 0x65 * for a polynomial of degree 16, X^16 + X^12 + X^5 + 1 is written 0x1021 * @param PolyLength: CRC polynomial length * This parameter can be one of the following values: * @arg CRC_POLYLENGTH_7B: 7-bit long CRC (generating polynomial of degree 7) * @arg CRC_POLYLENGTH_8B: 8-bit long CRC (generating polynomial of degree 8) * @arg CRC_POLYLENGTH_16B: 16-bit long CRC (generating polynomial of degree 16) * @arg CRC_POLYLENGTH_32B: 32-bit long CRC (generating polynomial of degree 32) * @retval HAL status */ HAL_StatusTypeDef HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef *hcrc, uint32_t Pol, uint32_t PolyLength) { uint32_t msb = 31; /* polynomial degree is 32 at most, so msb is initialized to max value */ /* Check the parameters */ assert_param(IS_CRC_POL_LENGTH(PolyLength)); /* check polynomial definition vs polynomial size: * polynomial length must be aligned with polynomial * definition. HAL_ERROR is reported if Pol degree is * larger than that indicated by PolyLength. * Look for MSB position: msb will contain the degree of * the second to the largest polynomial member. E.g., for * X^7 + X^6 + X^5 + X^2 + 1, msb = 6. */ while (((Pol & ((uint32_t)(0x1) << msb)) == 0) && (msb-- > 0)) { } switch (PolyLength) { case CRC_POLYLENGTH_7B: if (msb >= HAL_CRC_LENGTH_7B) { return HAL_ERROR; } break; case CRC_POLYLENGTH_8B: if (msb >= HAL_CRC_LENGTH_8B) { return HAL_ERROR; } break; case CRC_POLYLENGTH_16B: if (msb >= HAL_CRC_LENGTH_16B) { return HAL_ERROR; } break; case CRC_POLYLENGTH_32B: /* no polynomial definition vs. polynomial length issue possible */ break; default: break; } /* set generating polynomial */ WRITE_REG(hcrc->Instance->POL, Pol); /* set generating polynomial size */ MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, PolyLength); /* Return function status */ return HAL_OK; }
/** * @brief Initializes the CRC according to the specified * parameters in the CRC_InitTypeDef and creates the associated handle. * @param hcrc: CRC handle * @retval HAL status */ HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc) { /* Check the CRC handle allocation */ if(hcrc == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance)); if(hcrc->State == HAL_CRC_STATE_RESET) { /* Allocate lock resource and initialize it */ hcrc->Lock = HAL_UNLOCKED; /* Init the low level hardware */ HAL_CRC_MspInit(hcrc); } /* Change CRC peripheral state */ hcrc->State = HAL_CRC_STATE_BUSY; /* check whether or not non-default generating polynomial has been * picked up by user */ assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse)); if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE) { /* initialize IP with default generating polynomial */ WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY); MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B); } else { /* initialize CRC IP with generating polynomial defined by user */ assert_param(IS_CRC_POL_LENGTH(hcrc->Init.CRCLength)); if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK) { return HAL_ERROR; } } /* check whether or not non-default CRC initial value has been * picked up by user */ assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse)); if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE) { WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE); } else { WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue); } /* set input data inversion mode */ assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode)); MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode); /* set output data inversion mode */ assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode)); MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode); /* makes sure the input data format (bytes, halfwords or words stream) * is properly specified by user */ assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat)); /* Change CRC peripheral state */ hcrc->State = HAL_CRC_STATE_READY; /* Return function status */ return HAL_OK; }