/*
 * crc32.c
 *
 *  Created on: 13 août 2022
 *      Author: xavie
 */


#include "crc32.h"

#ifdef SYS_CRC
uint32_t TM_CRC_Calculate32(uint32_t* arr, uint32_t count, uint8_t reset) {
	/* Reset CRC data register if necessary */
	if (reset) {
		/* Reset generator */
		CRC->CR = CRC_CR_RESET;
	}

	/* Calculate CRC */
	while (count--) {
		/* Set new value */
		CRC->DR = *arr++;
	}

	/* Return data */
	return CRC->DR;
}
#endif

uint8_t reflect8(uint8_t val)
{
    uint8_t resVal = 0;

    for(int i = 0; i < 8; i++)
    {
        if ((val & (1 << i)) != 0)
        {
            resVal |= (uint8_t )(1 << (7 - i));
        }
    }

    return resVal;
}

uint32_t reflect32(uint32_t val)
{
    uint32_t resVal = 0;

    for(int i = 0; i < 32; i++)
    {
        if ((val & (1 << i)) != 0)
        {
            resVal |= (uint32_t )(1 << (31 - i));
        }
    }

    return resVal;
}


uint32_t calcCRC32stm(void *data, uint32_t len,
   uint32_t poly, uint32_t seed, uint32_t initCRC, uint32_t inR, uint32_t outR)
{
    const unsigned char *buffer = (const unsigned char*) data;
    unsigned int crc = seed;
    unsigned char byte;

    while( len-- )
    {
        byte = *buffer++;
        if(inR) {
#ifdef SYS_CRC
            byte = __RBIT((uint32_t)byte) >> 24;
#else
            byte = reflect8(byte);
#endif
        }
        crc = crc ^ (byte << 24);
        for( int bit = 0; bit < 8; bit++ )
        {
            if( crc & (1L << 31)) crc = (crc << 1) ^ poly;
            else                  crc = (crc << 1);
        }
    }
    if(outR) {
#ifdef SYS_CRC
        crc = __RBIT(crc);
#else
        crc = reflect32(crc);
#endif
    }
    if(initCRC == 1)    crc = ~crc;
    return crc;
}

/* uint32_t calcCRC32std(void *data, uint32_t len,
   uint32_t poly, uint32_t seed, uint32_t initCRC, uint32_t inR, uint32_t outR)
{
    uint32_t crc;
    unsigned char* current = (unsigned char*) data;
    uint8_t byte;

    crc = seed;

    while (len--) {
        byte = *current++;
        if(inR) {
            byte = reflect8(byte);
        }
        crc ^= byte;
        for (unsigned int j = 0; j < 8; j++) {
            if (crc & 1)
                crc = (crc >> 1) ^ poly;
            else
                crc = crc >> 1;
        }

    }
    if(outR) {
        crc = reflect32(crc);
    }
    if(initCRC == 1)    crc = ~crc;
    return crc;
}*/

#ifdef SYS_CRC
uint32_t crc32_check (CRC_HandleTypeDef *hcrc, uint8_t* buf, uint16_t len) {

	uint32_t* pBuffer = (uint32_t*)buf;
	uint32_t BufferLength = (len/4); //(Length of buf uint8 to Length of buf uint32 is 1 by 4)
	uint32_t index = 0;

	__HAL_CRC_DR_RESET(hcrc);

	for(index = 0; index < BufferLength; index++) {
	   hcrc->Instance->DR = __RBIT(pBuffer[index]);
	}
	return __RBIT(hcrc->Instance->DR) ^ 0xFFFFFFFF;
}
#endif
