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.

  • 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?

  • 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

Reply Children
Related