This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Using the SD API directly - is it straightforward, or too much hassle?

I am experienced with ARM Cortex-M devices, but new to Nordic. I am using C++, and have a publisher-subcriber event driven framework of my own in place already. My own software timers are integrated with this (driven by SysTick or RTCx or whatever). My question relates to how best to integrate all this with the NRF52 SDK. I've just started working through some of the BLE examples. I'm slightly hampered by also being new to BLE...

There seems to be a huge layer of abstraction between the application and the actual SoftDevice API. I try to never use macros which generate lines of code, and the SDK appears to be riddled with them. Is it *practical* to just use the SD API directly, and where might I find examples of this? I can see the documentation online for the SD API, including a lot of useful-looking sequence charts, but no PDF. In principle, it looks like a relatively small number of API calls to set up my advertising, services and whatnot, implementing an ISR to receive events, and then pressing go. I'll need to make sure my application's vector table is at the right location, and to give the SoftDevice enough RAM, but that's about it. Is that a fair assessment?   

For context, I found it *much* simpler and cleaner to configure and operate the hardware peripherals directly through registers. I dispensed with the HAL and drivers entirely (except for the convenient definitions of bitmasks and so on). And my driver classes are integrated with my application framework...

Thanks.


Al

Parents Reply Children
  • Thanks for the reply. I've been reading more source, and reading the API documentation. I'll implement something and see how it works out. A beacon seems pretty simple to get the ball rolling.

  • It seems I have fallen at the first hurdle. I cannot even enable the SD.

    I have an application which basically does this:

        // main.cpp

        void my_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
        {
           // Currently empty - perhaps that's an issue.
        }

        extern "C" void SD_EVENT_IRQHandler()
        {
           // Currently empty
        }

        void main()
        {
            // Zero initialise
            nrf_clock_lf_cfg_t clock = {};
            
            // Set up LF clock - contents identical to beacon example.
            clock.source = ...
            ...    
            
            // Enable the SD. This call does not return, but apparently enters an infinite loop.
            // It does not appear to call my_fault_handler() before doing that.
            uint32_t err_code = sd_softdevice_enable(&clock, my_fault_handler);
            
            // Other API calls
            ...
         
            while (true);
        }

        
    The same code (in C) works in the beacon example. I'm using the same board (PCA10040), with the same SD (132) installed, and the same linker script. The only difference is that my file is main.cpp rather than main.c. The startup assembler and SystemInit() are the same. Hmm... now that I think about it, the toolchain *might* be different. I used Keil5 for the example, but my project is CMake sitting over the GNU ARM tools (debugging with Ozone). Pretty sure Keil is configured to use the same compiler and linker, but I'll have to check. Maybe Ozone is the problem - doesn't like SVC or something... I'll try GCC build for the example when I return to work to eliminate some of these questions, but would be grateful for any other insights I can try out.

    I briefly worried about whether extern "C" (or the lack of it) might be an issue, but it appears the SD API is C++-aware. My code doesn't declare any observers: is that an issue?

    I've spent a good while trawling the beacon and HRS examples to work out what API calls I need to set them up. Populating some of the data structures looks a bit convoluted, but in principle at least, it seems as I suspected: I'll need a sequence of API calls to configure the stack, construct the advertisement, services, characteristics, and so on. Peer management nontwithstanding, it all seems pretty straightforward. Or should be. So I'm a bit puzzled at the moment. What subtlety might have I missed?



    Al  




Related