This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Can I run the ble_app_uart example code from nRF5_SDK_12 with S130 on nRF51822QFAAH0?

Story Short: When trying to run the ble_app_uart example on a custom board with a nRF51822QFAAH0 chip, the code faults and resets at the point in tries to call sd_softdevice_enable.

What are the prerequisites for running the examples of the new SDK on nRF51822QFAAH0?

Long Explanation:

I am on a MBP, OSX 10.11.6

I have downloaded the most recent (as of April 25th, 2017) SDK in

~/Downloads/nrfdev/nRF5_SDK_12

My current version of arm-none-eabi-gcc is installed via homebrew. Install directory is in:

/usr/local/Cellar/arm-none-eabi-gcc/20150921/bin

and with a symbolic link to:

/usr/local/bin

In order to compile I have changed the Makefile.posix in

~/Downloads/nrfdev/nRF5_SDK_12/components/toolchain/gcc

so that the first line

GNU_INSTALL_ROOT := /usr/local/gcc-arm-none-eabi-4_9-2015q3

now reads

GNU_INSTALL_ROOT := /usr/local

If I go to

~/Downloads/nrfdev/nRF5_SDK_12/examples/ble_peripheral/ble_app_uart/pca10028/s130/armgcc

and run “make” it compiles.

I have a Bluz board (Raytac MDBT40-236R based on nRF51822QFAC-A1) to which I connect my MBP via the ST-LINK on a STM32F4DISCOVERY board (version MB997C).

I then use openocd to flash the softdevice and code with a shell script which contains one line:

openocd -f interface/stlink-v2.cfg   -f target/nrf51.cfg -c "init; reset halt;nrf51 mass_erase; program ../../../../../../components/softdevice/s130/hex/s130_nrf51_2.0.1_softdevice.hex verify;program ./_build/nrf51422_xxac.hex verify;reset

This works, and I can see the Nordic_UART in the nRF Toolbox app on my iPhone. If I change RX_PIN_NUMBER to 12 and TX_PIN_NUMBER to 12, then, when connecting the Bluz chip with a FTDI TTL-232R cable, I can also send and see messages between a serial console on my MBP and the nRF Toolbox app on my phone. So this works.

Now, I have a custom board with a nRF51822QFAA-H0.

As far as I can tell from the infocenter compatibility matrix, this particular chip (16kB RAM, IC rev 3) should work with SDK12 and s130.

But when I upload to this chip the Nordic_UART never shows up on my phone. This is somewhat expected, as the code uploaded is based on the pca10028 SD board with 32kB RAM.

So I change this line in the linker file ble_app_uart_gcc_nrf51.ld

RAM (rwx) :  ORIGIN = 0x20001fe8, LENGTH = 0x6018

to

RAM (rwx) :  ORIGIN = 0x20001fe8, LENGTH = 0x2018

so that we use a total of 0x4000 (16kB) instead of 0x8000 (32kB) of RAM.

I also insert a breakpoint in the main function in the main.c file, just before entering the function ble_stack_init()

Using gdb to step through from here I get this output:

$ arm-none-eabi-gdb _build/nrf51422_xxac.out --silent -ex "target remote localhost:3333"
Reading symbols from _build/nrf51422_xxac.out...done.
Remote debugging using localhost:3333
main () at ../../../main.c:601
601	    __BKPT(1);
(gdb) s
0x0001d89e in ble_stack_init () at ../../../main.c:391
391	    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
(gdb) 
Note: automatically using hardware breakpoints for read-only addresses.
394	    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
(gdb) 
softdevice_handler_init (p_clock_lf_cfg=p_clock_lf_cfg@entry=0x20003f70, 
    p_ble_evt_buffer=p_ble_evt_buffer@entry=0x20002420 <BLE_EVT_BUFFER.8118>, 
    ble_evt_buffer_size=ble_evt_buffer_size@entry=72, 
    evt_schedule_func=evt_schedule_func@entry=0x0)
    at ../../../../../../components/softdevice/common/softdevice_handler/softdevice_handler.c:261
261	        return NRF_ERROR_INVALID_PARAM;
(gdb) 
259	    if (p_ble_evt_buffer == NULL)
(gdb) 
265	    if (!is_word_aligned(p_ble_evt_buffer))
(gdb) 
283	    bool power_clock_isr_enabled = nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn);
(gdb) 
nrf_drv_common_irq_enable_check (IRQn=POWER_CLOCK_IRQn)
    at ../../../../../../components/drivers_nrf/common/nrf_drv_common.h:269
269	    return 0 != (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] &
(gdb) 
softdevice_handler_init (p_clock_lf_cfg=p_clock_lf_cfg@entry=0x20003f70, 
    p_ble_evt_buffer=p_ble_evt_buffer@entry=0x20002420 <BLE_EVT_BUFFER.8118>, 
    ble_evt_buffer_size=ble_evt_buffer_size@entry=72, 
    evt_schedule_func=evt_schedule_func@entry=0x0)
    at ../../../../../../components/softdevice/common/softdevice_handler/softdevice_handler.c:270
270	    mp_ble_evt_buffer     = (uint8_t *)p_ble_evt_buffer;
(gdb) 
271	    m_ble_evt_buffer_size = ble_evt_buffer_size;
(gdb) 
283	    bool power_clock_isr_enabled = nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn);
(gdb) 
nrf_drv_common_irq_enable_check (IRQn=POWER_CLOCK_IRQn)
    at ../../../../../../components/drivers_nrf/common/nrf_drv_common.h:269
269	    return 0 != (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] &
(gdb) 
softdevice_handler_init (p_clock_lf_cfg=p_clock_lf_cfg@entry=0x20003f70, 
    p_ble_evt_buffer=p_ble_evt_buffer@entry=0x20002420 <BLE_EVT_BUFFER.8118>, 
    ble_evt_buffer_size=ble_evt_buffer_size@entry=72, 
    evt_schedule_func=evt_schedule_func@entry=0x0)
    at ../../../../../../components/softdevice/common/softdevice_handler/softdevice_handler.c:271
271	    m_ble_evt_buffer_size = ble_evt_buffer_size;
(gdb) 
279	    m_evt_schedule_func = evt_schedule_func;
(gdb) 
283	    bool power_clock_isr_enabled = nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn);
(gdb) 
nrf_drv_common_irq_enable_check (IRQn=POWER_CLOCK_IRQn)
    at ../../../../../../components/drivers_nrf/common/nrf_drv_common.h:269
269	    return 0 != (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] &
(gdb) 
softdevice_handler_init (p_clock_lf_cfg=p_clock_lf_cfg@entry=0x20003f70, 
    p_ble_evt_buffer=p_ble_evt_buffer@entry=0x20002420 <BLE_EVT_BUFFER.8118>, 
    ble_evt_buffer_size=ble_evt_buffer_size@entry=72, 
    evt_schedule_func=evt_schedule_func@entry=0x0)
    at ../../../../../../components/softdevice/common/softdevice_handler/softdevice_handler.c:284
284	    if (power_clock_isr_enabled)
(gdb) 
300	    err_code = sd_softdevice_enable(p_clock_lf_cfg, softdevice_fault_handler);
(gdb) 
sd_softdevice_enable (p_clock_lf_cfg=0x20003f70, 
    fault_handler=fault_handler@entry=0x1efd1 <softdevice_fault_handler>)
    at ../../../../../../components/softdevice/s130/headers/nrf_sdm.h:229
229	SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
(gdb) next
0x00000750 in ?? ()
(gdb) 

calling backtrace this shows in a more condensed version.

(gdb) bt
#0  0x00000750 in ?? ()
#1  <signal handler called>
#2  0x0001efc6 in sd_softdevice_enable (p_clock_lf_cfg=0x20003f70, 
    fault_handler=fault_handler@entry=0x1efd1 <softdevice_fault_handler>)
    at ../../../../../../components/softdevice/s130/headers/nrf_sdm.h:229
#3  0x0001f0f0 in softdevice_handler_init (
    p_clock_lf_cfg=p_clock_lf_cfg@entry=0x20003f70, 
    p_ble_evt_buffer=p_ble_evt_buffer@entry=0x20002420 <BLE_EVT_BUFFER.8118>, 
    ble_evt_buffer_size=ble_evt_buffer_size@entry=72, 
    evt_schedule_func=evt_schedule_func@entry=0x0)
    at ../../../../../../components/softdevice/common/softdevice_handler/softdevice_handler.c:300
#4  0x0001d8b4 in ble_stack_init () at ../../../main.c:394
#5  main () at ../../../main.c:602
(gdb) 

I have tried setting a breakpoint the softdevice_fault_handler in softdevice_handler.c, but it does not reach it.

I am quite aware that it is probably because I have not configured memory regions correctly, but having a hard time figuring out what to do.

Does anyone have any suggestions?

  • Does your custom board have the 32kHz LFCLK crystal? If not, you may need to change the clock-source in the call to sd_softdevice_enable to use the synthesized LFCLK (I know a lot of the demos assume an external 32kHz source is present). If you have a 32kHz crystal, or you've already made the change... then obviously that's not relevant. But this bit us on our first custom board when we tried to use the examples.

  • That's a really good point. We don't have a LFCLK crystal on the board, just the HF crystal. I changed it to internal clock, and after removing the breakpoint it now works! Thanks!

    For future reference, I made a duplicate of the file pca10028.h in the folder path/to/nRF5_SDK_12/components/boards and named it custom_board.h. In line 142 I changed NRF_CLOCK_LF_SRC_XTAL to NRF_CLOCK_LF_SRC_SYNTH. Then in the Makefile I changed both instances of DBOARD_PCA10028 to DBOARD_CUSTOM

    Thanks again MarcF. I've been stuck for two days :)

Related