This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR2311: BSL CRC implementation?

Part Number: MSP430FR2311


Hi,

I have a function in my application code which calculates the hash of the entire FRAM region of my chip. It is implemented in the code attached. If I were to have the same arguments to the BSL (namely, the start address being 0xf100 and the length being 1920 16bit words), is this an equivalent operation to what I have below?

Also what is the 16 bit polynominal used? I'm using 0x1021 for CRC16 CCITT, but I don't seem to get the same result. 

// Address of the first and last word
#define FIRMWARE_START_ADDRESS  FRAM_START
#define FIRMWARE_FRAM_SIZE      1920
static void CrcFirmware(void)
{
  uint16_t i;
  uint16_t* flash_ptr = (uint16_t*)FIRMWARE_START_ADDRESS;
  
  // Write the first word in to initalize crc hardware
  CRCINIRES = flash_ptr[0];
  
  for (i = 1; i < FIRMWARE_FRAM_SIZE; i++)
  {
    CRCDI = flash_ptr[i];
  }
  
  // Save the result
  firmware_crc = CRCINIRES;
}

  • Please find the CRC register level code example of FR2311 http://dev.ti.com/tirex/explore/node?node=AN-HELWgg07MbSBgA.5OyQ__IOGqZri__LATEST

    This code is the same with the CRC code in BSL

  • Looking at this, I do see a __no_operation(); after the word is contributed to the crc accumulator. Do you know what the purpose of this is? I don't see a nop() being required in the CRC module documentation.

  • __no_operation() is for debug, (set BP, monitor variable). nop is not MUST in CRC code as the document description.

  • I'm still not able to get a matching CRC.

    With a freshly erased mcu, I am performing a CRC with the attached arguments. It should be two words, and if the mcu is freshly erased, both words are 0xfffff. The result I get from this is 0xff00, which does not agree with the software defined crc CCITT algorithm, which results in 0x1d0f. Any ideas?

    The image below shows the transaction during the CRC request. This occurs after (in order) we mass erase the mcu, then unlock it with the default password. The CRC result on two words of [0xffff, 0xffff} does not agree with the attached code snippit which should compute the exact same result in software

    #include <stdio.h>
    #include <stdint.h>
    
    unsigned int CRC_Init = 0xFFFF;
    unsigned int i;
    unsigned int CRC_Input[]= {0xffff, 0xffff, 0x5042, 0x0010,  // 16 random 16-bit numbers
                               0x7ff7, 0xf86a, 0xb58e, 0x7651,  // these numbers can be
                               0x8b88, 0x0679, 0x0123, 0x9599,  // modified if desired
                               0xc58c, 0xd1e2, 0xe144, 0xb691 };
    unsigned int CRC_Results;
    unsigned int SW_Results;
    unsigned int CRC_New;
    
    // Software Algorithm Function Definition
    unsigned int CCITT_Update(unsigned int, unsigned int);
    
    int main(void)
    {
        CRC_New = CRC_Init;                     // Put CRC Init value into CRC_New
        for(i = 0; i < 2; i++)
        {
            // Input values into Software algorithm (requires 8-bit inputs)
            // Clear upper 8 bits to get lower byte
            unsigned int LowByte = (CRC_Input[i] & 0x00FF);
            // Shift right 8 bits to get upper byte
            unsigned int UpByte = (CRC_Input[i] >> 8);
            // First input lower byte
            CRC_New = CCITT_Update(CRC_New,LowByte);
            // Then input upper byte
            CRC_New = CCITT_Update(CRC_New,UpByte);
        }
        SW_Results = 0xffff;
        
        printf("%x\r\n", (uint32_t)CRC_New);
    
    }
    
    // Software algorithm - CCITT CRC16 code
    unsigned int CCITT_Update(unsigned int init, unsigned int input)
    {
        unsigned int CCITT;
        CCITT =(unsigned char)(init >> 8)|(init << 8);
        CCITT ^= input;
        CCITT ^= (unsigned char)(CCITT & 0xFF) >> 4;
        CCITT ^= (CCITT << 8) << 4;
        CCITT ^= ((CCITT & 0xFF) << 4) << 1;
        return CCITT;
    }

  • I've put a few hours into this now, and I cannot under any circumstances replicate the results that the BSL gives. TI, could you perform the following:

    * Put the MSP430FR2311 into BSL mode

    * Mass erase

    * Unlock

    * Send a CRC command starting at 0xf100 of length 2

    The result I get is 0xff00. Using the software defined CRC code provided in the answer above, the CRC for this should be 0x1d0f. This would seem to indicate that the BSL result is incorrect. 

  • TI: This answer does not work.

    Please follow the steps below:

    * Enter BSL

    * Mass erase

    * Unlock with default password

    * Request a CRC from 0xf100 of length 2

    * The result should be 0xff00

    * Using the code in the suggested answer, change the first 2 words of the CRC data to 0xffff and change the CRC length to 2. The result will not be similar to what the BSL is calculating. This indicates that the BSL is not calculating CRC the same way as this code.

  • Hi Chris Seto: Thanks for your detailed feedback! we are busy on the other case today and we just read and understand you problem. we will have the test following your step tomorrow.

    I checked the CRC code including hardware CRC and software CRC. I think the code should be correct.

    if you have time, could you please reduce the CRC calculation length ,for example 32 bytes from start address of FRAM and check if the CRC result is matched or not. it should be help to isolate this issue.

  • Hi Xiaodong,

    Even with a CRC length of 1 this fails. Again, referring to my procedure above, can you confirm that a CRC of length 1 word on data of 0xffff should result in a CRC of 0xff00? Because this is what A BSL CRC yields after a mass erase. This is not correct according to your sample code, which should result in a CRC of 0. Again, please try the attached code. This should result in the same CRC as a request to the BSL to CRC a word of length 1 after a mass erase.

    #include <stdint.h>
    #include <stdio.h>
    
    uint16_t CRC_Init = 0xFFFF;
    uint16_t i;
    uint16_t CRC_Input[]= {0xffff, 0x1096, 0x5042, 0x0010,  // 16 random 16-bit numbers
                               0x7ff7, 0xf86a, 0xb58e, 0x7651,  // these numbers can be
                               0x8b88, 0x0679, 0x0123, 0x9599,  // modified if desired
                               0xc58c, 0xd1e2, 0xe144, 0xb691 };
    uint16_t CRC_Results;
    uint16_t SW_Results;
    uint16_t CRC_New;
    
    // Software algorithm - CCITT CRC16 code
    uint16_t CCITT_Update(uint16_t init, uint16_t input)
    {
        uint16_t CCITT;
        CCITT =(uint8_t)(init >> 8)|(init << 8);
        CCITT ^= input;
        CCITT ^= (uint8_t)(CCITT & 0xFF) >> 4;
        CCITT ^= (CCITT << 8) << 4;
        CCITT ^= ((CCITT & 0xFF) << 4) << 1;
        return CCITT;
    }
    
    int main(void)
    {
        CRC_New = CRC_Init;                     // Put CRC Init value into CRC_New
        for(i = 0; i < 1; i++)
        {
            // Input values into Software algorithm (requires 8-bit inputs)
            // Clear upper 8 bits to get lower byte
            unsigned int LowByte = (CRC_Input[i] & 0x00FF);
            // Shift right 8 bits to get upper byte
            unsigned int UpByte = (CRC_Input[i] >> 8);
            // First input lower byte
            CRC_New = CCITT_Update(CRC_New,LowByte);
            // Then input upper byte
            CRC_New = CCITT_Update(CRC_New,UpByte);
        }
        SW_Results = CRC_New;
        
        printf("%x\r\n", SW_Results);
    }
    
    
    

  • Ok. I just figured out what is going on here. 

    The BSL is NOT 16bit word aligned. It is byte aligned. This means that if you want to CRC, for example, 4 16bit words, then length value to give to the BSL needs to be 8, not 4. 

    I don't know what TI has implemented here, but this need to be documented somewhere. I'm guessing this is done so that the user can request the BSL to produce a CRC for non word aligned data which will still be correct when used with word data, but again, whatever is going on here, it needs to be documented. 

    I am now able to get the following code to agree with a request to the BSL for a CRC of the entire FRAM region. with the following BSL arguments: start 0xf100, length 1920 (words) * 2

    #define FIRMWARE_START_ADDRESS  0xf100
    #define FIRMWARE_FRAM_SIZE      1920
    #define CRC_INIT 0xffff
    static void CrcFirmware(void)
    {
      uint16_t i;
      uint16_t* flash_ptr = (uint16_t*)FIRMWARE_START_ADDRESS;
      
      // Write the first word in to initalize crc hardware
      CRCINIRES = CRC_INIT;
      
      for (i = 0; i < FIRMWARE_FRAM_SIZE; i++)
      {
        CRCDIRB = flash_ptr[i];
      }
      
      // Save the result
      firmware_crc = CRCINIRES;
    }

     

  • Hi Chris Seto

    Thanks for your update and clarify. we have do the test and confirm the CRC result is the same between BSL and code example as the length is by "byte".

    From our discussion, we understood that the description of length (Command Data) is not 100% unclear on page 21 of BSL UG. but, there is the hint to dedicate the length is by "byte" on "Example for UART PI" below and code exmaple.

    But I fully agree with you the definition of length is not clear (should point out the length is by "byte"). I will request the modification on the BSL UG to update the definition of length.

    Thanks for your comment again! You are welcome to share us valuable comment again.

  • Hi Chris Seto

    I think your question has been solved. if yes, I will close this thread.

    Thanks for your comment again! You are welcome to share us valuable comment again.

**Attention** This is a public forum