Written a custom script to write product model no into UICR Registers. After updating Model No, DFU was getting failed at state 6 i.e after updating init data after moving bootloader mode.
I uploaded my custom script for your reference.
Written a custom script to write product model no into UICR Registers. After updating Model No, DFU was getting failed at state 6 i.e after updating init data after moving bootloader mode.
I uploaded my custom script for your reference.
Hi,
the attachment appears to be missing, please re-upload it, and I'll have a look. Also, which SDK version are you using? Note that Bootloader in SDKs prior to v.12 used 0x10001080 for its device info structure: http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v11.0.0/bledfu_example_init.html?cp=4_0_8_4_3_1_1_3_1_0#dfu_init_dev_rev_sec
I am copying the shell script that uses JLINKEXE command to write into UICR Registers.
I am using nordic_sdk_11 bootloader. If i am not using script to update Model DFU was successfull.
After moving to bootloader mode as per dfu state machine After InitPacket write transaction.DFU was getting failed with hvx notification with Resp Value 0x06 which means operation failed.
1514286382[on_hvx 350] DEBUG : LM NTF:Got Data, Length: 3, Handle(W): 0xffff (R): 0xffff (N): 0x10 Value - 0x10 0x2 0x6
#!/bin/sh
# flash.model
#
# Flash the model number string into the NRF_UICR->CUSTOMER[0:3] registers.
#
# Initially: Use a canned model number string.
# Later: Model number string will be supplied as an argument to the script.
# Derived from script originally written by:
# Hugh O'Brien [email protected] 2014-05-25
# Program the nRF51822, based on nRF51_Series_Reference_Manual_v2.1.pdf
# Uses SEGGER JLINK
# Presume SoftDevice S110 usage
# Check application for SoftDevice offset however it does not check that
# the application has been compiled against the _correct_ SoftDevice.
# Quoting:
# Nice post. It (writing bootloader address) works with the magic
# register writes and exit sequence, as follows :
# w4 4001e504 2 (NVMC.CONFIG)
# w4 4001e50c 1 (NVMC.ERASEALL)
# w4 10001014 00038000 (UICR.BOOTLOADERADDR)
# r
# g
[ -z $(command -v JLinkExe) ] && echo "Put Segger's JLinkExe on the path" && exit
device="nrf51822"
speed="1000" #unit is KHz, nordic docs recommed 1MHz
wait_time="300" #unit is ms
write_32bit="w4"
base_addr="4001e" #non-volatile memory controller
config_offset="504" #config register, 0 RO, 1 RW, 2 ERASEable
base_UICR_addr="10001" #UICR registers
cust_0_offset="080" #CUSTOMER[0]
cust_1_offset="084" #CUSTOMER[1]
cust_2_offset="088" #CUSTOMER[2]
cust_3_offset="08c" #CUSTOMER[3]
# Model number = "POI-B3R-I"
model_chars_0="2d494f50" # "POI-"
model_chars_1="2d523342" # "B3R-"
model_chars_2="ffff0049" # "I .."
model_chars_3="ffffffff" # "...."
enable_write="1"
set_device="Device"
set_speed="speed"
reset_device="rx" #use the 'delay after reset' version
start_device="g"
close_and_quit="qc"
script_file="flash.model.jlink"
rm $script_file 2>/dev/null #suppress error if not found
touch $script_file
echo selemu >> $script_file
echo $set_device $device >> $script_file
echo $set_speed $speed >> $script_file
echo $reset_device $wait_time >> $script_file
echo "mem 0x100000a4,6" >> $script_file
echo "mem 0x10001080,10" >> $script_file
echo $write_32bit $base_addr$config_offset $enable_write >> $script_file
echo $write_32bit $base_UICR_addr$cust_0_offset $model_chars_0 >> $script_file
echo $write_32bit $base_UICR_addr$cust_1_offset $model_chars_1 >> $script_file
echo $write_32bit $base_UICR_addr$cust_2_offset $model_chars_2 >> $script_file
#echo $write_32bit $base_UICR_addr$cust_3_offset $model_chars_3 >> $script_file
echo "mem 0x10001080,10" >> $script_file
## echo $reset_device $wait_time >> $script_file
echo $start_device >> $script_file
echo $close_and_quit >> $script_file
JLinkExe $script_file <<EOF
0
EOF
echo 'Ignore the "Programming failed @ address 0x10001014" message above.'
rm $script_file
How does this effect DFU?
As per the nordic_sdk_11 documentation,
UICR(0x1000100) to hold device type and revision.
UICR(0x10001080) is Customer Reserved. The area from UICR + 0x80 is reserved for customer usage.
Device type and Device revision stored in UICR.CUSTOMER[0] are checked against the device type and revision specified in the init packet as a part of the pre-validation step, see dfu_init_template.c->dfu_init_prevalidate).
From dfu_init_template.c:
// First check to verify the image to be transfered matches the device type. // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted. if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) && (p_init_packet->device_type != DFU_DEVICE_INFO->device_type)) { return NRF_ERROR_INVALID_DATA; } // Second check to verify the image to be transfered matches the device revision. // If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted. if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) && (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev)) { return NRF_ERROR_INVALID_DATA; }
The pre-validation step will fail if there's a mismatch between what's stored in the UICR and what you have in the init packet.
This check is optional, and you may remove it from dfu_init_template.c if you don't need it.
I am using nrfutil tool to generate .zip file that contain manifest.json, .bin and .dat files. I am sending .dat is init packet for DFU.
nrfutil dfu genpkg --application _build/ble_cloudleaf_app_s130_xxac.hex --application-version 2 LM2.zip
here is contents of manifest.json
"manifest": {
"application": {
"bin_file": "ble_cloudleaf_app_s130_xxac.bin",
"dat_file": "ble_cloudleaf_app_s130_xxac.dat",
"init_packet_data": {
"application_version": 4294967295,
"device_revision": 65535,
"device_type": 65535,
"firmware_crc16": 59631,
"softdevice_req": [
65534
]
}
},
"dfu_version": 0.5
}
}
Instead of removing the optional pre-validation step. Is there a way to update device_type & device_revision fields in init packet to the same model number used in the shell script to update UICR Registers.
If it works fine with out any code changes, I will go with that.
Yes, it is possible to defined the device revision and type to be the same as the model number. You can use the optional --dev-revision and --dev-type arguments when generating the package:
nrfutil command is not accepting model number POI1-BD3i3B as --dev-type & --dev-revision.
nrfutil dfu genpkg --application _build/ble_cloudleaf_app_s130_xxac.hex --dev-type POI1-BD3i3B --application-version 3 LM3.zip
Usage: nrfutil dfu genpkg [OPTIONS] ZIPFILE
Error: Invalid value for "--dev-type": POI1-BD3i3B is not a valid integer
nrfutil dfu genpkg --application _build/ble_cloudleaf_app_s130_xxac.hex --dev-revision POI1-BD3i3B --dev-type POI1-BD3i3B --application-version 3 LM3.zip
Usage: nrfutil dfu genpkg [OPTIONS] ZIPFILE
Error: Invalid value for "--dev-revision": POI1-BD3i3B is not a valid integer
nrfutil command is not accepting model number POI1-BD3i3B as --dev-type & --dev-revision.
nrfutil dfu genpkg --application _build/ble_cloudleaf_app_s130_xxac.hex --dev-type POI1-BD3i3B --application-version 3 LM3.zip
Usage: nrfutil dfu genpkg [OPTIONS] ZIPFILE
Error: Invalid value for "--dev-type": POI1-BD3i3B is not a valid integer
nrfutil dfu genpkg --application _build/ble_cloudleaf_app_s130_xxac.hex --dev-revision POI1-BD3i3B --dev-type POI1-BD3i3B --application-version 3 LM3.zip
Usage: nrfutil dfu genpkg [OPTIONS] ZIPFILE
Error: Invalid value for "--dev-revision": POI1-BD3i3B is not a valid integer