SoftDevice and Application firmware upgrade from 6.1.1 to 7.2.0 issue

I am trying to upgrade SoftDevice and Application firmware from v6.1.1 to v7.2.0 on Nordic USB840M dongle and I am facing a strange issue after such upgrade.
Please find below the steps I am doing:
  1. Generate the upgrade zip package: 
  2. nrfutil pkg generate --hw-version 52 --sd-req 0xB6 --sd-id 0x100 --softdevice ".\s140_nrf52_7.2.0_softdevice.hex" --application-version 1 --application ".\connectivity_4.1.1_usb_for_s140_7.2.0.hex" --key-file ".\private.pem" ".\sd_app_6.1.1_to_7.2.0.zip"
    Zip created at .\sd_app_6.1.1_to_7.2.0.zip
  3. Program the dongle: 
  4. NrfUtil.exe dfu usb-serial -pkg ".\sd_app_6.1.1_to_7.2.0.zip" -p COM7
      [####################################]  100%
    Device programmed.
After such upgrade the device appears in the device manager as USB Serial Device (COM8) with VID_1915&PID_521B and with the pretty old driver installed:
Then I've performed the downgrade of SoftDevice from 7.2.0 to 6.1.1. Please find below the steps I am doing:
  1. Generate the downgrade zip package: 
  2. nrfutil pkg generate --hw-version 52 --sd-req 0x100 --sd-id 0xB6 --softdevice ".\s140_nrf52_6.1.1_softdevice.hex" --application-version 1 --application ".\connectivity_4.1.1_usb_for_s140_6.1.1.hex" --key-file ".\private.pem" ".\sd_app_7.2.0_to_6.1.1.zip"
    Zip created at .\sd_app_7.2.0_to_6.1.1.zip
  3. Program the dongle:
  4. NrfUtil.exe dfu usb-serial -pkg ".\sd_app_7.2.0_to_6.1.1.zip" -p COM7
      [####################################]  100%
    Device programmed.
After such downgrade the device appears in the device manager as nRF Connect USB CDC ACM (COM6) with VID_1915&PID_C00A and with the new driver installed:
I have attached the SoftDevice and Application firmware hex files:
I have installed nRF Connect for Desktop 3.10.0
Any help or insights are much appreciated.
Parents
  • Hi,

    This seems related to USB only, so the SoftDevice itself should not be relevant, but the SDK could be. Are you also changing SDK version, or only SoftDevice? Which (two) SDK versions are you using? Also, are there any issues or does this still work and you just wonder why Windows picks one driver in one case and another diver in the other case?

  • Hi Einar,

    Thank you for your response!

    I am changing the SDK version. Previously the connectivity application firmware was built using nRF5_SDK_15.3.0 and SoftDevice of v6.1.1 is part of that SDK. Now I am building the connectivity application firmware using nRF5_SDK_17.1.0 where SoftDevice of v7.2.0 is part of.

    It seems the problem is not with just drivers, the device itself is not functioning - sd_rpc_open API which initializes the SoftDevice module fails with error 0x000d NRF_ERROR_TIMEOUT after an upgrade.

  • Understood, thank you!

    Is there any way to use SoftDevice v7.2.0 with the connectivity application of v6.1.1? For example, generate the upgrade zip package with SD v7.2.0 and the connectivity app of v6.1.1 and then program the dongle by nrfutil. I need SD v7.2.0 because it supports the BLE_GATTC_OPT_UUID_DISC option.

  • There is always a way, provided you are willing to do the effort. There are API changes between major versions of the SoftDevice, so some porting will have to be involved. I suspect the easiest is to stick with SDK 15.3 and the patch form the from pc-ble-driver repo, and use that as a starting point. Then port that to SoftDevice 7.2.0 first and get that working. Then add BLE_GATTC_OPT_UUID_DISC to the serialization code on the nRF and the pc-ble-driver. I cannot say exactly how much effort this will take, though.

    An alternative could perhaps be to consider if you can achieve your end goal differently, without using BLE_GATTC_OPT_UUID_DISC.

  • Hi Einar,

    this is what I was originally doing - I was adding the serialization code for BLE_GATTC_OPT_UUID_DISC option to nRF SDK 15.3.0 and pc-ble-driver. Then in my client application I was attempting to call sd_ble_opt_set(adapter, BLE_GATTC_OPT_UUID_DISC, &uuid_opt), but it was failing with the error 0x8001 NRF_ERROR_SD_RPC_ENCODE. I've made an assumption that it fails because I was still using SoftDevice 6.1.1 which does not have BLE_GATTC_OPT_UUID_DISC option.

    So, now my main question (and challenge) is how to port nRF SDK 15.3.0 to SoftDevice 7.2.0. I would appreciate any help or insights on this.

  • Yuriy Sharamaha said:
    So, now my main question (and challenge) is how to port nRF SDK 15.3.0 to SoftDevice 7.2.0. I would appreciate any help or insights on this.

    I suggest you refer to the migration document for 7.2.0. This is part of the zip distribution of the SoftDevice. That contains the API changes for the SoftDevice, and you need to follow that back to 6.1.1 and accommodate for any changes to SDK code that is being used.

  • Hi Einar,

    So, I have just recompiled the connectivity application from nRF SDK 15.3.0 and used the S140 v7.2.0 headers. I have also adjusted the linker script to accommodate the larger SoftDevice.

    Original memory config:

    MEMORY
    {
    FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xda000
    RAM (rwx) : ORIGIN = 0x2001ad58, LENGTH = 0x252a8

    Updated memory config:

    MEMORY
    {
    FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xd9000
    RAM (rwx) : ORIGIN = 0x200198d8, LENGTH = 0x26728

    The compilation succeeded and new connectivity application firmware hex files have been generated.

    Then I have used nrfutil to create the upgrade zip package containing new connectivity application firmware hex file and new SoftDevice v7.2.0 hex file.

    The device has been programmed successfully and now it appears properly in the device manager.

    Moreover, sd_rpc_open API succeeds and sd_ble_version_get API returns subversion_number set to 0x100 which corresponds to SoftDevice v7.2.0

    Apparently, the connectivity application and SoftDevice seem to be run fine.

    However, call sd_ble_opt_set(adapter, BLE_GATTC_OPT_UUID_DISC, &uuid_opt) still fails with the same error 0x8001 NRF_ERROR_SD_RPC_ENCODE. Am I missing something?

Reply
  • Hi Einar,

    So, I have just recompiled the connectivity application from nRF SDK 15.3.0 and used the S140 v7.2.0 headers. I have also adjusted the linker script to accommodate the larger SoftDevice.

    Original memory config:

    MEMORY
    {
    FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xda000
    RAM (rwx) : ORIGIN = 0x2001ad58, LENGTH = 0x252a8

    Updated memory config:

    MEMORY
    {
    FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xd9000
    RAM (rwx) : ORIGIN = 0x200198d8, LENGTH = 0x26728

    The compilation succeeded and new connectivity application firmware hex files have been generated.

    Then I have used nrfutil to create the upgrade zip package containing new connectivity application firmware hex file and new SoftDevice v7.2.0 hex file.

    The device has been programmed successfully and now it appears properly in the device manager.

    Moreover, sd_rpc_open API succeeds and sd_ble_version_get API returns subversion_number set to 0x100 which corresponds to SoftDevice v7.2.0

    Apparently, the connectivity application and SoftDevice seem to be run fine.

    However, call sd_ble_opt_set(adapter, BLE_GATTC_OPT_UUID_DISC, &uuid_opt) still fails with the same error 0x8001 NRF_ERROR_SD_RPC_ENCODE. Am I missing something?

Children
  • Did you add support for the new option (BLE_GATTC_OPT_UUID_DISC) in the serialization library, in ble_opt_set_req_dec() and ble_cfg_set_req_enc()?

  • In nRF5_SDK_15.3.0_59ac345\components\serialization\connectivity\codecs\ble\serializers\ble_conn.c there are following implementations of ble_opt_set_req_dec/ble_opt_set_rsp_enc functions:

    uint32_t ble_opt_set_req_dec(uint8_t const * const   p_buf,
                                 uint16_t                packet_len,
                                 uint32_t *  const       p_opt_id,
                                 ble_opt_t **const       pp_opt )
    {
        SER_REQ_DEC_BEGIN(SD_BLE_OPT_SET);
    
        SER_ASSERT_NOT_NULL(p_opt_id);
        SER_ASSERT_NOT_NULL(pp_opt);
        SER_ASSERT_NOT_NULL(*pp_opt);
    
        SER_PULL_uint32(p_opt_id);
    
        SER_PULL_COND(pp_opt, NULL);
        if (*pp_opt)
        {
            field_decoder_handler_t fp_decoder = NULL;
            void * p_struct = NULL;
    
            switch (*p_opt_id)
            {
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
                case BLE_COMMON_OPT_CONN_BW:
                    fp_decoder = ble_common_opt_conn_bw_t_dec;
                    p_struct   = &((*pp_opt)->common_opt.conn_bw);
                break;
    #endif
                case BLE_COMMON_OPT_PA_LNA:
                    fp_decoder = ble_common_opt_pa_lna_t_dec;
                    p_struct   = &((*pp_opt)->common_opt.pa_lna);
                break;
                case BLE_COMMON_OPT_CONN_EVT_EXT:
                    fp_decoder = ble_common_opt_conn_evt_ext_t_dec;
                    p_struct   = &((*pp_opt)->common_opt.conn_evt_ext);
                break;
                case BLE_GAP_OPT_CH_MAP:
                    fp_decoder = ble_gap_opt_ch_map_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.ch_map);
                break;
                case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
                    fp_decoder = ble_gap_opt_local_conn_latency_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.local_conn_latency);
                break;
                case BLE_GAP_OPT_PASSKEY:
                    fp_decoder = ble_gap_opt_passkey_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.passkey);
                break;
                case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT:
                    fp_decoder = ble_gap_opt_auth_payload_timeout_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.auth_payload_timeout);
                break;
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
                case BLE_GAP_OPT_EXT_LEN:
                    fp_decoder = ble_gap_opt_ext_len_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.ext_len);
                break;
    #endif
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
                case BLE_GAP_OPT_SCAN_REQ_REPORT:
                    fp_decoder = ble_gap_opt_scan_req_report_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.scan_req_report);
                break;
    #endif
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
                case BLE_GAP_OPT_COMPAT_MODE:
                    fp_decoder = ble_gap_opt_compat_mode_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.compat_mode);
                break;
    #else
    #ifndef S112
                case BLE_GAP_OPT_COMPAT_MODE_1:
                    fp_decoder = ble_gap_opt_compat_mode_1_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.compat_mode_1);
                break;
    #endif
                case BLE_GAP_OPT_SLAVE_LATENCY_DISABLE:
                    fp_decoder = ble_gap_opt_slave_latency_disable_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.slave_latency_disable);
                break;
    #endif
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION == 4
                case BLE_GAP_OPT_COMPAT_MODE_2:
                    fp_decoder = ble_gap_opt_compat_mode_2_t_dec;
                    p_struct   = &((*pp_opt)->gap_opt.compat_mode_2);
                break;
    #endif
                default:
                    SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM);
                break;
            }
    
            SER_PULL_FIELD(p_struct, fp_decoder);
        }
    
        SER_REQ_DEC_END;
    }
    
    
    uint32_t ble_opt_set_rsp_enc(uint32_t                return_code,
                                 uint8_t * const         p_buf,
                                 uint32_t * const        p_buf_len)
    {
        SER_RSP_ENC_RESULT_ONLY(SD_BLE_OPT_SET);
    }
    

    In pc-ble-driver\src\sd_api_v6\sdk\components\serialization\application\codecs\ble\serializers\ble_app.c there are following implementations of ble_opt_set_req_dec/ble_opt_set_rsp_enc functions:

    uint32_t ble_opt_set_req_enc(uint32_t const          opt_id,
                                 ble_opt_t const * const p_opt,
                                 uint8_t * const         p_buf,
                                 uint32_t * const        p_buf_len)
    {
        SER_REQ_ENC_BEGIN(SD_BLE_OPT_SET);
    
        SER_PUSH_uint32(&opt_id);
    
        field_encoder_handler_t fp_encoder = NULL;
        void const *            p_struct = NULL;
    
        SER_PUSH_COND(p_opt, NULL);
        if (p_opt)
        {
            switch (opt_id)
            {
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
                case BLE_COMMON_OPT_CONN_BW:
                    fp_encoder = ble_common_opt_conn_bw_t_enc;
                    p_struct   = &(p_opt->common_opt.conn_bw);
                break;
    #endif
                case BLE_COMMON_OPT_PA_LNA:
                    fp_encoder = ble_common_opt_pa_lna_t_enc;
                    p_struct   = &(p_opt->common_opt.pa_lna);
                break;
                case BLE_COMMON_OPT_CONN_EVT_EXT:
                    fp_encoder = ble_common_opt_conn_evt_ext_t_enc;
                    p_struct   = &(p_opt->common_opt.conn_evt_ext);
                break;
                case BLE_GAP_OPT_CH_MAP:
                    fp_encoder = ble_gap_opt_ch_map_t_enc;
                    p_struct   = &(p_opt->gap_opt.ch_map);
                break;
                case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
                    fp_encoder = ble_gap_opt_local_conn_latency_t_enc;
                    p_struct   = &(p_opt->gap_opt.local_conn_latency);
                break;
                case BLE_GAP_OPT_PASSKEY:
                    fp_encoder = ble_gap_opt_passkey_t_enc;
                    p_struct   = &(p_opt->gap_opt.passkey);
                break;
                case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT:
                    fp_encoder = ble_gap_opt_auth_payload_timeout_t_enc;
                    p_struct   = &(p_opt->gap_opt.auth_payload_timeout);
                break;
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
                case BLE_GAP_OPT_EXT_LEN:
                    fp_encoder = ble_gap_opt_ext_len_t_enc;
                    p_struct   = &(p_opt->gap_opt.ext_len);
                break;
    #endif
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
                case BLE_GAP_OPT_SCAN_REQ_REPORT:
                    fp_encoder = ble_gap_opt_scan_req_report_t_enc;
                    p_struct   = &(p_opt->gap_opt.scan_req_report);
                break;
    #endif
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
                case BLE_GAP_OPT_COMPAT_MODE:
                    fp_encoder = ble_gap_opt_compat_mode_t_enc;
                    p_struct   = &(p_opt->gap_opt.compat_mode);
                break;
    #else
    #ifndef S112
                case BLE_GAP_OPT_COMPAT_MODE_1:
                    fp_encoder = ble_gap_opt_compat_mode_1_t_enc;
                    p_struct   = &(p_opt->gap_opt.compat_mode_1);
                break;
    #endif
                case BLE_GAP_OPT_SLAVE_LATENCY_DISABLE:
                    fp_encoder = ble_gap_opt_slave_latency_disable_t_enc;
                    p_struct   = &(p_opt->gap_opt.slave_latency_disable);
                break;
    #endif
    #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION == 4
                case BLE_GAP_OPT_COMPAT_MODE_2:
                    fp_encoder = ble_gap_opt_compat_mode_2_t_enc;
                    p_struct   = &(p_opt->gap_opt.compat_mode_2);
                break;
    #endif
                default:
                    SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM);
                break;
            }
    
            SER_PUSH_FIELD(p_struct, fp_encoder);
        }
    
        SER_REQ_ENC_END;
    }
    
    
    uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf,
                                 uint32_t              packet_len,
                                 uint32_t * const      p_result_code)
    {
        SER_RSP_DEC_RESULT_ONLY(SD_BLE_OPT_SET);
    }
    

    Unfortunately none of functions do have BLE_GATTC_OPT_UUID_DISC option handled.

    How should that code look like for nRF SDK and pc-ble-driver?

  • Hi Einar,

    Please disregard my above request - I have already implemented the serialization/deserialization code in nRF5 SDK and pc-ble-driver for BLE_GATTC_OPT_UUID_DISC option. So that, sd_ble_opt_set does not throw an error now when calling with BLE_GATTC_OPT_UUID_DISC option. Seems working. Thank you very much for your help.

    Yuriy

  • Hi Yuriy,

    That is good to hear! Thanks for letting us know.

    Einar

Related