nrf 9160 modem programming issue

Hi,

we are ramping up production, and need to make many production jigs, and programming in parrallell since the programming of the modem takes 1 min +.

We are using an stm32 on each jig, and programming the 4 processrs successfully (9160, 822, 840 and 833) however, when trying to update the modem firmware in the 9160 it fails.

(we do all this in parralell, so we are 4 times faster than using seggers, and the cost (factory wants 8 jigs) is a lot less, and faster and more reliable since programming the modem with the segger fails about 50% of the time and needs to be restarted (using nrfjprog etc).

We have tried  to follow both recommended and alternative method from https://infocenter.nordicsemi.com/index.jsp?topic=%2Fnan_041%2FAPP%2Fnan_production_programming%2Fintro.html

and looked at the latest nrf_dfu_api.py but to no avail.

Basically the instructions are flawed in many areas, but we get to the point where we can successfully verify the digest of the modem so that we know what fw loader we need to program in ram, we get acknowledment that the fw loader has started, and we get no errors during the programming when we use the recommended routine, but when we try to verify the firmware digest we get errors. 

The nrf_dfu_api.py uses a third method that is completely different than what the description is, and for now we ignore this. (it programs in chunks of 261096 bytes and pads both end and beginning with 0xFF to accomplish 8kB boundaries when programming.

The alternative method description does..

So the questions we have:

Is there an updated firmware update procedure we can take part of?

if not, can you elaborate:

  • Split the contents of the HEX file into contiguous sections that are page aligned and 7 KB large.

    What do you mean by page alinged? What page size? 7 kB is never aligned to 4 kB page size.
    Should we repeat step 3 to 9 rather than step 4 to 9?
    when all is fihished, shall we do anything more before we verify?

  • Verification:
    We can't even verify a correctly written fw (with nrfjprog).
    in the digest file, we have 4 sha digests (we get neither, because if we do what the .py file does, we get different errors depending if we first load the fw loader in or not.
    without the fw loader loaded (but everything preppared, ie up until we've read out the diget of the fw loader correctly)  we get the 
    NRF91_IPC_FAULT_EVENT set to one.
    if we load the firmware in the processor before we try to do the verifcation we get 
    NRF91_IPC_COMMAND_EVENT set to one, but when we read out 
    0x2000000C we get error 0x5a000002, and when then reading 0x20000010 we get error 3. (this is taken from the procedure of modem verification in the py file.. it is not mentioned in the description.) 
    The area 0x20000010 to 0x20000030 is always 3000060000000005000000c027000006c2ea1fd no matter if we read out on 1.3.5 or 1.1.6 (the modem fw in the chips originally).

    . There is something cryptic about this written in the procedure (
    1. 0x2000000C writes (0x3) and reads (0x7) responses from the modem. If the response is 0xA5xxxxxx, it is an acknowledgement of the command. If the response is 0x5Axxxxxx, it is an error where the last six digits is the error code.) but there are no descriptions of error codes.

    As you can read we're getting to worlds end with this, can you please elaborate how the recommended method is going to work, and why the python scrips you provide don't use that method?

Parents
  • **UPDATE**

    After sniffing how nrfjprog does this, verification now works, the trick is that you can't send larger chunks than 65k for verificationm, I have also verified this with the python code, where your python code gets the same error as I had before changing to only verify 65 k chunks at the time..

    Also, note that you can't verify the first file, ie on adress 0x59602000 with length 2360, since then it responds with an error.

    I still don't get the programming to work, so please, can you send me the relevant sections of nrfjprog python code so I can get that to work?

  • Hello,

    Thank you for the update.

    We are looking into it internally and I will hopefully have some more information next week.

    Please let us know if you get any further in the meantime.

    Best regards,

    Michal

  • Just wanted to let you know, that we are still looking into it. It is quite a complicated question, so I'm not exactly sure when I will have more information, but I will get back to you when I will find out more.

    Best regards,

    Michal

  • I have found out a few things internally, I'll try to summarize it to you tomorrow.

    Best regards,

    Michal

  • Sorry for the delay, here are some notes from our engineers:

    4.4.1 Recommended method 

    • This method is supported for modem firmware versions from 1.3.5 and higher. 
    • 2. Split the contents of the HEX file into contiguous sections that are 8 KB aligned and up to 56KB large. 
    • 3. Write the data to 0x2000001C + offset, where the offset is 0 or 0xE000. 
    • Add a new step between 3. and 4.: 
      If not programming the first section, poll IPC.MODEM_CTRL_EVENT… 
    • 4: If all sections not yet programmed, write the following 
    • 4a: starting → target 
    • 5: last page → last section 
    • 7. Poll IPC.MODEM_CTRL_EVENT. If you get 0x5A000001, the command is not supported, and you should use the alternative method instead. You should get 0xA5000005 if the command succeeded. 
    • 9: pages → sections 
    • 9: Step 4 → (New step between 3. and 4.) 
    • consider copying IPC.MODEM_CTRL_EVENT response description from 'Alternative method' step 5. 

    4.4.2 Alternative method 

    • 2. Split the contents of the HEX file into contiguous sections that are 8 KB aligned and up to 64KB large. 

    4.5 Verifying the modem 

    • The digest is in 0x20000010-0x2000002C, stored in little-endian words. For example, a digest of 925372E7512EBE1C06805F6BC58721BBE2ED2A82F362F05151ED25FBB2A48E4D would read out as the following words: {0x925372e7, 0x512ebe1c, 0x6805f6b, 0xc58721bb, 0xe2ed2a82, 0xf362f051, 0x51ed25fb, 0xb2a48e4d}. 
    • Ranges in the digest.txt file are given in inclusive notation, so “0x00006000--0x0000FFFF” would be a length of 0xa000 (40KB). 
Reply
  • Sorry for the delay, here are some notes from our engineers:

    4.4.1 Recommended method 

    • This method is supported for modem firmware versions from 1.3.5 and higher. 
    • 2. Split the contents of the HEX file into contiguous sections that are 8 KB aligned and up to 56KB large. 
    • 3. Write the data to 0x2000001C + offset, where the offset is 0 or 0xE000. 
    • Add a new step between 3. and 4.: 
      If not programming the first section, poll IPC.MODEM_CTRL_EVENT… 
    • 4: If all sections not yet programmed, write the following 
    • 4a: starting → target 
    • 5: last page → last section 
    • 7. Poll IPC.MODEM_CTRL_EVENT. If you get 0x5A000001, the command is not supported, and you should use the alternative method instead. You should get 0xA5000005 if the command succeeded. 
    • 9: pages → sections 
    • 9: Step 4 → (New step between 3. and 4.) 
    • consider copying IPC.MODEM_CTRL_EVENT response description from 'Alternative method' step 5. 

    4.4.2 Alternative method 

    • 2. Split the contents of the HEX file into contiguous sections that are 8 KB aligned and up to 64KB large. 

    4.5 Verifying the modem 

    • The digest is in 0x20000010-0x2000002C, stored in little-endian words. For example, a digest of 925372E7512EBE1C06805F6BC58721BBE2ED2A82F362F05151ED25FBB2A48E4D would read out as the following words: {0x925372e7, 0x512ebe1c, 0x6805f6b, 0xc58721bb, 0xe2ed2a82, 0xf362f051, 0x51ed25fb, 0xb2a48e4d}. 
    • Ranges in the digest.txt file are given in inclusive notation, so “0x00006000--0x0000FFFF” would be a length of 0xa000 (40KB). 
Children
Related