Home > OS >  stm32 assigning value to register through a cast
stm32 assigning value to register through a cast

Time:10-23

in STM32_HAL_CRC there is a function, that calculates CRC for data, that is passed byte by byte.

and if data length is npt a multiple of 4, it calculates CRC of tail:

if ((BufferLength % 4U) != 0U)
  {
    if ((BufferLength % 4U) == 1U)
    {
      *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[4U * i];         /* Derogation MisraC2012 R.11.5 */
    }
    if ((BufferLength % 4U) == 2U)
    {
      data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i)   1U];
      pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                    /* Derogation MisraC2012 R.11.5 */
      *pReg = data;
    }
    if ((BufferLength % 4U) == 3U)
    {
      data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i)   1U];
      pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR);                    /* Derogation MisraC2012 R.11.5 */
      *pReg = data;

      *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[(4U * i)   2U];  /* Derogation MisraC2012 R.11.5 */
    }

pBuffer is pointer to uint8_t array;

CRC Data Register is 32bit width and

Each write operation to the data register creates a combination of the previous CRC value (stored in CRC_DR) and the new one. CRC computation is done on the whole 32-bit data word or byte by byte depending on the format of the data being written.

so, FE,

*(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[4U * i];

writes tail data to MSB(assuming CRC_DR is big endian) of CRC_DR and crc computation with InitialValue = previousCrcResult and income = previousCrcResult & (pBuffer[4U * i] << 24) is performed;

after this operation 0x651F2550 in DR is changed on 0x340BC6D9

but when I try this:

_hcrc.Instance->DR = ncrc & ((((uint32_t)pBuffer[4U * i]) << 24) | 0x00FFFFFF);

0x651F2550 in DR is changed on 0x1D87D8BB

also I proposed that CRC_DR is little endian, and tried this:

_hcrc.Instance->DR = ncrc & (0xFFFFFF00 | ((uint32_t)pBuffer[4U * i]));

0x651F2550 in DR is changed on 0xEBCF331F

As for me, the last one looks clearly the same to this

So I don't understand where am I wrong.

And also don't understand what is happening there.

CodePudding user response:

Both of your code suggestions that start _hcrc.Instance->DR = are writing 32-bit words to the peripheral. This is a different operation from writing a byte to either end of that register. The peripheral knows what type you write and performs more or less CRC cycles depending on the size.

The manual says that byte writes should be right aligned, so you need to do:

*(__IO uint8_t *)(&hcrc->Instance->DR) =

Note that the intermediate cast to void pointer in the HAL is unnecessary.

If you don't want to include the HAL headers then replace __IO with volatile.

  • Related