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.

LP-MSPM0L1306: BSL Standalone Verification: CRC mismatch

Part Number: LP-MSPM0L1306
Other Parts Discussed in Thread: MSPM0L1306,

Tool/software:

I am writing a host-side (Linux) I2C BSL flasher for the MSPM0L1306. I am able to enter BSL mode via the GPIO invoke sequence, connect, mass erase, and flash data to the device. However, standalone verification is not working as I would expect. I am using the same CRC algorithm that's used to calculate the checksum for the BSL messages to calculate the expected CRC on the data block I am trying to verify. However, the CRC returned from the Standalone Verification command does not match the CRC I am calculating. Below is the function I am using to send the Standalone Verification message to the BSL. bsl_crc32 is the function I have to generate the CRC32 locally.

bool bsl_verify_simple(uint32_t addr, uint32_t len_data) {

uint32_t crc32;

bsl_txbuf[0] = 0x80; //PACKET_HEADER

bsl_txbuf[1] = 9; //CMD_BYTE(1) + ADDRS_BYTES(4) + VERIFY_BYTES(4)

bsl_txbuf[2] = 0;

bsl_txbuf[3] = 0x26; //CMD_VERIFY

*(uint32_t *) &bsl_txbuf[4] = addr; //HDR_LEN_CMD_BYTES(4)

*(uint32_t *) &bsl_txbuf[8] = len_data; //HDR_LEN_CMD_BYTES(4) + ADDRS_BYTES(4)

crc32 = bsl_crc32(&bsl_txbuf[3], 9); //CMD_BYTE(1) + ADDRS_BYTES(4) + VERIFY_BYTES(4)

*(uint32_t *) &bsl_txbuf[12] = crc32; //HDR_LEN_CMD_BYTES(4) + ADDRS_BYTES(4) + VERIFY_BYTES(4)

uint8_t tx_len = 16; //HDR_LEN_CMD_BYTES(4) + ADDRS_BYTES(4) + VERIFY_BYTES(4) + CRC_BYTES(4)



if (!i2c_write(bsl_txbuf, tx_len)) return false;


uint8_t rx_len = 13; // ACK_BYTE(1) + HDR_LEN_CMD_BYTES(4) + VERIFY_BYTES(4) + CRC_BYTES(4)

if (!i2c_read(bsl_rxbuf, rx_len)) return false;



// Check for ack

if (bsl_rxbuf[0] != BSL_ACK_OK) return false;

return true;

}

int main() {
<setup, invoke, connect, etc>
// verifying blank flash to test CRC
if (!bsl_verify(0, 1024)) goto err;

const uint8_t test_data_empty[1024] = {0x00};
bsl_crc32(test_data_empty, ARRAY_LEN(test_data_empty));
}

The BSL is accepting and handling the message (returning both an ACK as well as the correct response to indicate it is a Standalone Verification response) but the result does not match. I also tried comparing to an array of length 1024 of 0xFF and the CRC still does not match. Below is the raw buffer being built from above and sent to the device along with the response.

bsl_verify (sent):

0x80 0x09 0x00 0x26 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x00 0xa4 0xb8 0x14 0xef

bsl_verify(recv):

0x00 0x08 0x05 0x00 0x32 0x0b 0x00 0xc5 0x47 0x3d 0x93 0x08 0x6b

crc_recv: 0x47c5000b

crc_calc: 0x104a50d1

Is the CRC algorithm used for the Standalone Verification different than the one used for the message checksum verification? The datasheet makes no mention of it, and looking at the secondary BSL examples (which state the example implementation should match the ROM BSL) the CRC parameters are the same as the datasheet.

Related, the MSPM0 Bootloader User's Guide (slau887) has several errors in section 4.3.10 Standalone Verification. The command structure shown is the response packet, not the command packet. The example command (Host) specifies address 0x20000000 and length 0x400. The example response (BSL) is not a Standalone Verification response (0x32) but rather a Core Message Response (0x3B), with message content 0x05 (Invalid memory range):

H | LEN |CMD| A  A  A  A  | D D D D  |  CRC    |

80 09 00 26 00 00 00 20 00 04 00 00 A0 97 D5 2E

response

BSL: 00 08 02 00 3B 05 B7 F6 FE F2 (MSG: invalid address!)
  • Hi Jay,

    There is a bug when using cache to read the data at address 0x0~0x8 at first time. So if you do CRC except address 0x0~8 or do the CRC second time will solve the issue. 

  • Thanks for the response Gary. I retested, running a mass erase and requesting the verification 3 times in a row (just to be safe). I got the same response back each time - 0x47c5000b.

    Tried the same thing starting at address 0xA instead of 0x0 and saw the same result. Am I doing something wrong when calling the standalone verification? 

  • The bug is when you read a non-0xFFFF data at address 0x0~8 it will give 0xFFFF, so you use blank device it will be the same. If use some data not 0xFFF at 0x0~8 that will be different.

  • If I copy the application I am flashing into a buffer of size 1024 (can be any value, 0x00, 0xFF, or anything in between), and flash and verify that, the CRC matches. However if I don't the CRC does not match. It does not seem to matter where in the flash I write the app (0x00, 0x400, etc) nor how many times I re-run the standalone verification. This doesn't seem to match the behavior you are describing.


    const uint8_t test_data_empty[0x400] = {0x00};
    memcpy(test_data_empty, app_data, ARRAY_LEN(app_data));
    if (!bsl_flash(0x00, test_data_empty, ARRAY_LEN(test_data_empty))) goto err;
    if (!bsl_verify_simple(0x00, 0x400)) goto err;
    printf("CRC app + test_data_empty: 0x%08x\n", *((uint32_t *) &bsl_rxbuf[HDR_LEN_CMD_BYTES + CMD_BYTE]));
    bsl_crc32(test_data_empty, ARRAY_LEN(test_data_empty));

    > CRC app + test_data_empty: 0x7df05312
    > crc: 0x7df05312
  • I have do the test and got the correct CRC results with no issue

    What I do is using two LP-MSPM0L1306, one as BSL target and one as the BSL host.

    I connect the device followed the guidance from the MSPM0 Bootloader (BSL) Implementation (Rev. C)

    For the software from host side you can refer to this one 

    bsl_host_mcu_to_mspm0l11xx_l13xx_target_uart_LP_MSPM0L1306_nortos_ticlang.zip

    You can see I have add a software breakpoint in the code, and  BSL CRC command and a software CRC

    For the software CRC results as below

    What I get from the BSL CRC are the same as below

  • Thanks Gary! I appreciate the double check. Do you mind posting the line where you program the flash? What is the segment size? In my testing, if the segment I program is less than 1024B and I do the CRC check, it does not match my local CRC. However if I ensure that I am programming at least 1024B (with the empty space following the application with 0xFF, as per blank flash), it validates properly.

    For example:

    @0000
    00 00 00 00 00 00 00 00 AF 01 00 00 AF 01 CA CA
    q

    Would fail, but if I pad the remainder of it like so:

    @0000
    00 00 00 00 00 00 00 00 AF 01 00 00 AF 01 CA CA
    FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    ...
    q

    So that it is at least 1024 bytes long, it will pass. At this point I have it working with that workaround, I just want to confirm that's expected.

  • Do you mind posting the line where you program the flash?

    It is at here

    What is the segment size?

    Do you mean the firmware size? If so you can refer to the file of application_image_uart.h

    So that it is at least 1024 bytes long, it will pass.

    Yes, for the CRC has the limitation that need to check area bigger than 1024