Cálculo CRC ENVIADO

Estoy usando el protocolo SENT en mi proyecto.

En mi implementación SENT, los nibbles de datos son 3. Entonces, datos de 12 bits, incluido un nibble de estado y un nibble de CRC.

Necesito calcular el CRC para 3 nibbles de datos.

El valor semilla para el cálculo de CRC es 5 y el polinomio es

X 4 + X 3 + X 2 + 1

He hecho lo siguiente para el cálculo de CRC:

char CheckSum, i;
char CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
CheckSum= 5; // initialize checksum with seed "0101"
for (i=0; i<3; i++) {
CheckSum = CheckSum ^ Data[i];
CheckSum = CrcLookup[CheckSum];
}

En el analizador SENT, pude ver un error de CRC. El registro es el siguiente

ENVIADO_LOG

¿Alguien puede decirme cómo calcular el CRC para el protocolo SENT?

Nota: tengo 0XABC como nibble de datos y 3 es nibble de estado.

¿Está aplicando los datos [i] en el orden correcto usando 0 -> 1 -> 2 -> 3? Puede ser que tenga que ser: 3 -> 2 -> 1 -> 0
sí, estoy enviando los datos en el orden correcto, MSB es primero
Suma de control = Suma de control^0x0A; Copié su código, pero al comparar CRC Calc con dsPIC32 integrado en CRC, tuve que agregar CheckSum = CheckSum^0x0A; entonces mi cálculo de CRC era el mismo que el cálculo de CRC incorporado.
Siento escribirte más de un año y medio después, pero... ¿Y si Data[i] es mayor que 16? ¿Este caso no generará un error de índice fuera de los límites?

Respuestas (2)

Después de mucha búsqueda, que comprendía seguir la norma SAE J2716 para ver exactamente cómo era la implementación, descubrí que el código estaba mal. El orden de las operaciones se invirtió y, por supuesto, debe asegurarse de no acceder a elementos fuera de los límites, como lo haría con su código.

La implementación correcta debe ser:

uint8_t calculatedCRC, i;
const uint8_t CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
calculatedCRC = 5; // initialize checksum with seed "0101"

for (i = 0; i < 6; i++)
{
    calculatedCRC = CrcLookup[calculatedCRC];
    calculatedCRC = (calculatedCRC ^ Data[i]) & 0x0F;
}
// One more round with 0 as input
calculatedCRC = CrcLookup[calculatedCRC];

Si tiene, como en mi caso, el payload completo en una variable de 32 bits en el formato SDDDDDDC(S es el nibble de estado, C el CRC que debe verificar), entonces el código se puede modificar de esta manera:

uint32_t crcData = YourOriginal32BitSentFrame;

uint8_t calculatedCRC, i;
const uint8_t CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
calculatedCRC = 5; // initialize checksum with seed "0101"

for (i = 0; i < 6; i++)
{
    uint8_t crcDatum = (crcData >> 24) & 0x0F;

    calculatedCRC = CrcLookup[calculatedCRC];
    calculatedCRC = calculatedCRC ^ crcDatum;
    crcData <<= 4;
}
// One more round with 0 as input
calculatedCRC = CrcLookup[calculatedCRC];

Atentamente

Según el documento aquí: http://www.nxp.com/assets/documents/data/en/application-notes/AN4219.pdf

ingrese la descripción de la imagen aquí

Entonces, si tiene el nibble de estado en datos [0], debe intentar calcular CRC sobre datos [1], datos [2] y datos [3].

Así es !! como ya dije, el cálculo de CRC es solo para 3 nibbles de datos. Y estoy computando solo para nibbles de datos, es decir, datos [1], datos [2] y datos [3].
@AbdulGafoor: a menos que haya cambiado su código que se muestra en la pregunta anterior, veo un bucle FOR que itera sobre datos [0], datos [1] y datos [2] en lugar de lo que pretendía.
para el estado estoy usando otro byte. No está incluido en los datos [], ignore mi comentario anterior.