caplcanoecrc8

CAPL script for checksum CRC 8 SAE-J1850 calculation


I'm new to CAPL programming and trying to create a node which can send an message with Checksum (CRC 8 SAE-J1850) and message counter to my ECU via CAN bus.

The polynomial used is P = x^8 + x^4 + x^3 + x^2 + 1 -- Init value = 0xFF

Can anyone help me with a CAPL script to encode the 32 bit message to send on CAN bus.

Thanks


Solution

  • I suggest to read and understand first how to calculate crc in http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
    together with AUTOSAR specification you would be able to create script.

    there are 2 way to calculate crc:

    1. directly calculate from payload
    2. use look up table (which faster in processing data).

    you should try both to cross check results are identical.

    the program flow, you could also follow AUTOSAR Spec.

    ex: increment sequence counter > collect Payload Data Byte > calculate CRC > update Payload Data Bytes > send PDU

    also cross check when payload change with calculator in http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
    here is sample code:

    // Your_PDU frame layout:
    // Byte 0 = CRC
    // Byte 1 Bit 0-3 = ALIVE
    // Byte 1 Bit 4-7 = data
    // Byte 2-4 = data
    // Byte 5 Bit 0-3 = data
    
    
    variables
    {
    // Simulate CRC and ALIVE
      message Your_PDU Your_PDU_Sim;
      msTimer t1;
      int j = 0;
      int aliveCounterVal=0;
      byte data_TX[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      int TxCounter = 0;
      int IsFirstCall=1;
      byte crc_sim = 0xFF;        // Start value 
      byte final_XOR = 0xFF;  // Final XOR-value
      int b = 0;
      int index = 0x00;
      int crc8_table[256] = {
    0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
    0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
    0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
    0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
    0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
    0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
    0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
    0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
    0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
    0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
    0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
    0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
    0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
    0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
    0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
    0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
    };  // Table CRC8_SAE_J1850
    }
      
    void CRC_Protect()
    {
    //  write("CRC_Protect");
      // Alive Counter
          // increment
          if(j==15)
          {
            aliveCounterVal=j;
            j=0;
          }
          else  
          { 
            aliveCounterVal=j;
            j++;
          }
    
        Your_PDU_Sim.byte(1) = (Your_PDU_Sim.byte(1) & 0xF0) | (aliveCounterVal & 0x0F);
        data_TX[1] = Your_PDU_Sim.byte(1);
        data_TX[2] = Your_PDU_Sim.byte(2);
        data_TX[3] = Your_PDU_Sim.byte(3);
        data_TX[4] = Your_PDU_Sim.byte(4);
        data_TX[5] = Your_PDU_Sim.byte(5);
        // Calculate CRC
        for(b=1;b<6;b++)
        {
          if(IsFirstCall)
          {
            IsFirstCall=0;
            crc_sim = 0xFF;
          }
          index = crc_sim ^ data_TX[b];
          crc_sim = crc8_table[index];
        }
        crc_sim = crc_sim ^ final_XOR;
        Your_PDU_Sim.byte(0)= crc_sim;
    }
    
    on timer t1 // Simulation Your_PDU
    {
        IsFirstCall=1;
        CRC_Protect();
        output(Your_PDU_Sim);
        setTimer(t1, 1000);
    }
    
    on start
    {
        setTimer(t1, 1000);
    }
    
    on sysvar_update sysvar::Panel_Value
    {
        // change payload
        Your_PDU_Sim.byte(1) = 0x00;
        Your_PDU_Sim.byte(2) = 0x00;
        Your_PDU_Sim.byte(3) = 0x00;
        Your_PDU_Sim.byte(4) = 0x00;
        Your_PDU_Sim.byte(5) = 0x00;
    }