| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*******************************************************************************
- * File Name : amt630hv120_crc.c
- * Author : Sim
- * Date First Issued : 12/28/2022
- * Description : This file provides all the CRC firmware functions.
- ********************************************************************************
- * History:
- * 12/28/2022: V0.1
- *******************************************************************************/
- /* Includes ------------------------------------------------------------------*/
- #include "chip.h"
- #include "crc.h"
- #define CRC_CTL_WIDTH32_START (1 << 10)
- #define CRC_CTL_WIDTH16_START (1 << 9)
- #define CRC_CTL_WIDTH8_START (1 << 8)
- #define CRC_CTL_INIT_EN (1 << 6)
- #define CRC_CTL_VECTMASK (3 << 2)
- #define CRC_CTL_VECT32 (0 << 2)
- #define CRC_CTL_VECT16 (1 << 2)
- #define CRC_CTL_VECT8 (2 << 2)
- static u32 c_poly8_g = 0x0000008e;
- static u32 c_poly16_g = 0x00008810;
- static u32 c_poly32_g = 0x82608edb;
- typedef union {
- u8 *buf8;
- u16 *buf16;
- u32 *buf32;
- } CrcDataBuf;
- typedef struct
- {
- volatile u32 EN;
- volatile u32 CTRL;
- volatile u32 DATA;
- volatile u32 INIT;
- volatile u32 RET;
- } CRC_TypeDef;
- #define CRC ((CRC_TypeDef*)REGS_CRC_BASE)
- typedef u32 (*crc_algo)(const void *buf, u32 len, u32 init,
- CrcPoly polyopt, CrcDataWidth widthopt);
- static u32 crc_soft(const void *buf, u32 len, u32 init,
- CrcPoly polyopt, CrcDataWidth widthopt)
- {
- CrcDataBuf tmpbuf;
- u8 tmpbit;
- u32 tmp = init;
- u32 result;
- int i;
- u32 poly = c_poly32_g;
- u32 width = 32;
- u32 shift = 31;
- if (widthopt == CRC_DATA_WIDTH8) {
- tmpbuf.buf8 = (u8*)buf;
- width = 8;
- } else if (widthopt == CRC_DATA_WIDTH16) {
- assert((((u32)buf | len) & 1) == 0);
- tmpbuf.buf16 = (u16*)buf;
- width = 16;
- len /= 2;
- } else if (widthopt == CRC_DATA_WIDTH32) {
- assert((((u32)buf | len) & 3) == 0);
- tmpbuf.buf32 = (u32*)buf;
- width = 32;
- len /= 4;
- }
- if (polyopt == CRC_POLY8) {
- poly = c_poly8_g;
- shift = 7;
- } else if (polyopt == CRC_POLY16) {
- poly = c_poly16_g;
- shift = 15;
- } else if (polyopt == CRC_POLY32) {
- poly = c_poly32_g;
- shift = 31;
- }
- while (len--) {
- for (i = 0; i < width; i++) {
- if (widthopt == CRC_DATA_WIDTH8)
- tmpbit = ((tmp >> shift) ^ (*tmpbuf.buf8 >> i)) & 1;
- else if (widthopt == CRC_DATA_WIDTH16)
- tmpbit = ((tmp >> shift) ^ (*tmpbuf.buf16 >> i)) & 1;
- else if (widthopt == CRC_DATA_WIDTH32)
- tmpbit = ((tmp >> shift) ^ (*tmpbuf.buf32 >> i)) & 1;
- if (tmpbit) {
- result = ((((tmp << 1) >> 1) ^ ((poly << 1) >> 1)) << 1) | 1;
- } else {
- result = tmp << 1;
- }
- tmp = result;
- }
- if (widthopt == CRC_DATA_WIDTH8)
- tmpbuf.buf8++;
- else if (widthopt == CRC_DATA_WIDTH16)
- tmpbuf.buf16++;
- else if (widthopt == CRC_DATA_WIDTH32)
- tmpbuf.buf32++;
- }
- return result;
- }
- u32 CRC_Calc(const void *buf, u32 len, u32 init,
- CrcPoly polyopt, CrcDataWidth widthopt)
- {
- CrcDataBuf tmpbuf;
- u32 result;
- int i;
- if (widthopt == CRC_DATA_WIDTH8) {
- tmpbuf.buf8 = (u8*)buf;
- } else if (widthopt == CRC_DATA_WIDTH16) {
- assert((((u32)buf | len) & 1) == 0);
- tmpbuf.buf16 = (u16*)buf;
- len /= 2;
- } else if (widthopt == CRC_DATA_WIDTH32) {
- assert((((u32)buf | len) & 3) == 0);
- tmpbuf.buf32 = (u32*)buf;
- len /= 4;
- }
- // if (sema_take(SEMA_GATE_CRC, portMAX_DELAY) != pdPASS) {
- // return 0xffffffff;
- // }
- CRC->INIT = init;
- CRC->CTRL |= CRC_CTL_INIT_EN;
- CRC->CTRL &= ~CRC_CTL_INIT_EN;
- CRC->CTRL &= ~CRC_CTL_VECTMASK;
- if (polyopt == CRC_POLY8)
- CRC->CTRL |= CRC_CTL_VECT8;
- else if (polyopt == CRC_POLY16)
- CRC->CTRL |= CRC_CTL_VECT16;
- else if (polyopt == CRC_POLY32)
- CRC->CTRL |= CRC_CTL_VECT32;
- if (widthopt == CRC_DATA_WIDTH8)
- CRC->CTRL |= CRC_CTL_WIDTH8_START;
- else if (widthopt == CRC_DATA_WIDTH16)
- CRC->CTRL |= CRC_CTL_WIDTH16_START;
- if (widthopt == CRC_DATA_WIDTH32)
- CRC->CTRL |= CRC_CTL_WIDTH32_START;
- for (i = 0; i < len; i++) {
- if (widthopt == CRC_DATA_WIDTH8)
- CRC->DATA = tmpbuf.buf8[i];
- else if (widthopt == CRC_DATA_WIDTH16)
- CRC->DATA = tmpbuf.buf16[i];
- else if (widthopt == CRC_DATA_WIDTH32)
- CRC->DATA = tmpbuf.buf32[i];
- }
- udelay(10);
- result = CRC->RET;
- if (widthopt == CRC_DATA_WIDTH8)
- CRC->CTRL &= ~CRC_CTL_WIDTH8_START;
- else if (widthopt == CRC_DATA_WIDTH16)
- CRC->CTRL &= ~CRC_CTL_WIDTH16_START;
- if (widthopt == CRC_DATA_WIDTH32)
- CRC->CTRL &= ~CRC_CTL_WIDTH32_START;
- // sema_give(SEMA_GATE_CRC);
- return result;
- }
- static u32 crc_align(const void *buf, u32 len, u32 init, CrcPoly polyopt, int hardaccel)
- {
- const u32 *buf32;
- const u8 *buf8;
- u32 leftsize = len;
- u32 size;
- u32 align;
- u32 crc = init;
- crc_algo algo;
- if (hardaccel)
- algo = CRC_Calc;
- else
- algo = crc_soft;
- align = (u32)buf & 3;
- size = 4 - align;
- size = size > leftsize ? leftsize : size;
- if (align) {
- crc = algo(buf, size, init, polyopt, CRC_DATA_WIDTH8);
- leftsize -= size;
- buf32 = (u32*)((u8*)buf + size);
- } else {
- buf32 = (u32*)buf;
- }
- if (leftsize == 0)
- return crc;
- align = leftsize & 3;
- size = leftsize & ~3;
- if (size)
- crc = algo(buf32, size, crc, polyopt, CRC_DATA_WIDTH32);
- buf8 = (u8*)buf32 + size;
- if (align)
- crc = algo(buf8, align, crc, polyopt, CRC_DATA_WIDTH8);
- return crc;
- }
- u32 xcrc32(const void *buf, u32 len, u32 init, CrcSel hardaccel)
- {
- return crc_align(buf, len, init, CRC_POLY32, hardaccel);
- }
- u16 xcrc16(const void *buf, u32 len, u32 init, CrcSel hardaccel)
- {
- return crc_align(buf, len, init, CRC_POLY16, hardaccel) & 0xffff;
- }
- u16 xcrc8(const void *buf, u32 len, u32 init, CrcSel hardaccel)
- {
- return crc_align(buf, len, init, CRC_POLY8, hardaccel) & 0xff;
- }
|