Sonsivri

Electronics => Projects => Topic started by: ehnonymouse on November 13, 2012, 08:50:40 20:50



Title: SMBUS CRC calculator on PIC 24
Post by: ehnonymouse on November 13, 2012, 08:50:40 20:50
It uses the PIC24's built in CRC engine, and despite AN1148A it took me a while to get going. It's fully tested and in use, so I hope it saves someone some time.

Code:
//---------------------------------------------------------------------
//
//  FUNCTION :  pec_calculation
//
//  PARAMETERS:  pui8Buffer is a buffer up to 255 bytes long
//               ui8Length is the length of the message
//  DESCRIPTION: 8 Bit CRC; Polynomial is X^8+X^2+X+1
//
//  RETURNS: The checksum of the SMBus (I2C) message
//
//---------------------------------------------------------------------
UINT8 pec_calculation(UINT8 *pu8Buffer, UINT8 u8Length)
{
#define POYNOMIAL_LENGTH 8

    CRCCONbits.PLEN = POYNOMIAL_LENGTH -1;
    CRCXOR = 0x0006;                            // XOR polynomial is (X^8)+(X^2)+X+1, the final 1 isn't written
    CRCCONbits.CSIDL = 1;                       // Stop module when device enters idle mode
    CRCWDAT = 0;                                // Pre-load value
    CRCCONbits.CRCGO = 1;                       // Start CRC module

    do
    {
        while(CRCCONbits.CRCFUL){};             // Do not overflow FIFO
        *(UINT8*) &CRCDAT = *pu8Buffer++;      // Need to byte write this register or it doesn't work
    } while (--u8Length != 0);
    while(CRCCONbits.CRCFUL){};                 // Wait for FIFO to empty
    *(UINT8*) &CRCDAT = 0;
    Nop();
    Nop();
    while (!CRCCONbits.CRCMPT){};               // Wait for calculation to finish

    CRCCONbits.CRCGO = 0;                       // Stop CRC module
    return (UINT8)(CRCWDAT & 0x00FF);


#undef POYNOMIAL_LENGTH
}