BLE startup with SD troubles

I am modifying the Qorvo UWB SDK to add BLE operations. 

I have posted a couple other topics about different issues..

I have ported my code to the latest Qorvo SDK, They use an interesting trick to include the SD binary in the linked file (elf/hex) 

they convert the binary to a string of bytes c file to complie and link and use a label in the ld file to position it. 

before I was leaving space for the sd binary, and using the Ozone debugger script to load the SD hex over the loaded elf binary

anyhow.. it seems the SD state has changed using the included file.. (I am using s140 as I need both central and peripheral) 

my old ble init code ( left out the checking of the err_code in this post to keep the code issue small )

err_code = nrf_sdh_enable_request();    // new returns 8 (already init)  --------- oops (_sdh_disable_request();  make err_code=0, but the rest still fails.. 

uint32_t ram_start = 0;
ble_cfg_t ble_cfg;

// Step 1: Set default BLE configuration FIRST - this establishes base RAM requirements
err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);  // returns 0 and the value expected

#define TOTAL_BLE_CONNECTIONS 8 // 1 phone + 7 beacons (conservative limit)

memset(&ble_cfg, 0, sizeof(ble_cfg));
ble_cfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count = TOTAL_BLE_CONNECTIONS;
ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = NRF_SDH_BLE_GAP_EVENT_LENGTH; // Default event length

err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);  // returns 8, invalid state------------------------------------------- what to do about this ------

memset(&ble_cfg, 0, sizeof(ble_cfg));
ble_cfg.gap_cfg.role_count_cfg.adv_set_count = 1; // Enable 1 advertising set
ble_cfg.gap_cfg.role_count_cfg.periph_role_count = 1; // Enable 1 peripheral connection


// Enable central role for controller to connect to beacons
// Match role count to connection count (conservative limit)
ble_cfg.gap_cfg.role_count_cfg.central_role_count = TOTAL_BLE_CONNECTIONS - 1; // Subtract 1 for phone connection
ble_cfg.gap_cfg.role_count_cfg.central_sec_count = 0; // Disable central security (not needed for beacons)
QLOGD("Enabling central role: 1 peripheral + %d central = %d total connections",
TOTAL_BLE_CONNECTIONS - 1, TOTAL_BLE_CONNECTIONS);

err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start);  // this USES ram_start, not gets it.. 
err_code = nrf_sdh_ble_enable(&ram_start);

then set GAP parms

but now that the SD is in the loaded elf, it appears to be inited, before my app code gets loaded, see the comments in the code above.

thanks for any help.. 

  • Error is in line 42 of your linker script.

    On a more serious note: The SD only works when flashed into its intended position and nowhere else. VERY difficult to do in a normal LD linker script. Mergehex is a lot simpler to use.

    Note that the old SDKs should not be used for new development. Look at the NCS SDK, which already uses the linker for the nordic BTLE stuff.

  • the ble_stack_init() function from the examples SDK_17_1_0/examples/ble_central_and_peripheral/experimental/ble_app_interactive/ble_m fail same rc=8, 

    these are the first calls to SD

    from the example

    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }

  • no, line 42 of the .ld is in a comment.. mergehex may be useful, but cannot be used with the elf, which I want to use for source debugging..  i had an Ozone script that load the elf (with free space for SD) and then loaded the SD hex over it.. 
    this worked great...

    this is the Ozone function I had been using, but don't need it now.

    void TargetDownload (void) {
       Util.Log("Downloading Program.");
       Exec.Download("/home/sam/Downloads/DW3_QM33_SDK_1.0.2.new/SDK/Firmware/BuildOutput/DW3_QM33_SDK_UCI/FreeRTOS/Type2AB_EVB/Type2AB_EVB-DW3_QM33_SDK_UCI-FreeRTOS.elf");
       Target.LoadMemory("/home/sam/Downloads/DW3_QM33_SDK_1.0.2.new/SDK/Firmware/SDK_BSP/Nordic/NORDIC_SDK_17_1_0/components/softdevice/s14hex/s140_nrf52_7.2.0_softdevice.hex",0x0);
    }
    
    void _SetupTarget(void) {
      unsigned int SP;
      unsigned int PC;
      unsigned int VectorTableAddr;
    
      VectorTableAddr = 0; //Elf.GetBaseAddr(); //0 ; // 0x27000;
    
      if (VectorTableAddr == 0xFFFFFFFF) {
        Util.Log("Project file error: failed to get program base");
      } else {
        SP = Target.ReadU32(VectorTableAddr);
        Target.SetReg("SP", SP);
    
        PC = Target.ReadU32(VectorTableAddr + 4);
        Target.SetReg("PC", PC);
      }
    }

    the ld file, c source and map file sections to show it works properly

     /*   __HeapBase
     *   __HeapLimit  ---- line 42
     *   __StackLimit
     *   __StackTop
     *   __stack
     */
    ENTRY(Reset_Handler)
    
    flash_page_min_align = 4096;
    
    MEMORY
    {
        RAM (rwx)      : ORIGIN = 0x20013000, LENGTH = 0x2D000  /* 0x20000000 to 0x200026FF RAM section is dedicated to SoftDevice */
        FLASH (rx)     : ORIGIN = 0x00000000, LENGTH = 1M - 4K - 4K /* 1M minus calib_sha/calib sections. */
        CALIB_SHA (rw) : ORIGIN = 0x000FE000, LENGTH = 4K
        CALIB (rw)     : ORIGIN = 0x000FF000, LENGTH = 4K
    }
    
    SECTIONS
    {
        .soft_device (0x00000000) :
        {
            KEEP(*(.soft_device_prog))
        } > FLASH
    
        /* start with interrupt vectors - s140 softdevice is ~154KB, so start application at 0x27000 */
        .isr_vectors (0x27000) :
        
    and the map output  shows it in the right place. 
    
    Memory Configuration
    
    Name             Origin             Length             Attributes
    RAM              0x20013000         0x0002d000         xrw
    FLASH            0x00000000         0x000fe000         xr
    CALIB_SHA        0x000fe000         0x00001000         rw
    CALIB            0x000ff000         0x00001000         rw
    *default*        0x00000000         0xffffffff
    
    Linker script and memory map
    
    LOAD /Applications/ArmGNUToolchain/15.2.rel1/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/15.2.1/thumb/v7e-m+fp/hard/crti.o
    LOAD /Applications/ArmGNUToolchain/15.2.rel1/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/15.2.1/thumb/v7e-m+fp/hard/crtbegin.o
    LOAD /Applications/ArmGNUToolchain/15.2.rel1/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/15.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/crt0.o
                    0x00001000                        flash_page_min_align = 0x1000
    
    .soft_device    0x00000000    0x26634
     *(.soft_device_prog)
     .soft_device_prog
                    0x00000000    0x26634 SoftDeviceNrfx/libSoftDeviceNrfx.a(s140_nrf52_7.2.0_softdevice.c.obj)
                    0x00000000                soft_device_prog
    
    .isr_vectors    0x00027000    0x4b9ec
                    0x00027000                        . = ALIGN (0x4)

    The Qorvo sdk is in the old Nordic SDK 17.1 format.. nothing I can do about that 

  • interestingly, if for Ozone I use the same setupTarget 

    void _SetupTarget(void) {
      unsigned int SP;
      unsigned int PC;
      unsigned int VectorTableAddr;
    
      VectorTableAddr = 0; //Elf.GetBaseAddr(); //0 ; // 0x27000;
    
      if (VectorTableAddr == 0xFFFFFFFF) {
        Util.Log("Project file error: failed to get program base");
      } else {
        SP = Target.ReadU32(VectorTableAddr);
        Target.SetReg("SP", SP);
    
        PC = Target.ReadU32(VectorTableAddr + 4);
        Target.SetReg("PC", PC);
      }
    }

    my ble init code runs fine..

    the elf entrypoint is not in the SD code 

    ENTRY(Reset_Handler)

    Qorvo provides another package with SD 113, which uses the same c sourcefile/ld/entrypoint for loading the sd hex code.

    and it runs ok.. (but I haven't tried it with Ozone)

  • some additional code changes for different tasking model. 

Related