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

porting from SDK 11

I'm trying to port my project from SDK11 to SDK14. I am having troubles understanding how the drivers supposed to be used.

In the files nrf_peripheralXXX_drv.c there is often a state variable m_state, which is changed when the init or stop function of the according peripheral is called. But I can also start or stop peripherals with calls to lower level functions in nrf_peripheralXXX.h. Then the driver module of the peripheral will never know in which state the peripheral is.

I suppose when using a peripheral those functions shouldn't be used in mixed fashion?

Another question why are there ASSERTs now in all the driver functions. This caused me to rewrite so much of my code over again. Because when I was writing a module which supposed to take over in case of an error I just want to disable the peripherals and there interrupts when not used. In this case, I don't want to know whether the "m_state" of the Comparator is NRF_DRV_STATE_INITIALIZED or NRF_DRV_STATE_POWERED_ON I just want to call

nrf_drv_comp_uninit()

That used to work with SDK11 but now in order to keep this logic, I would have to write a peripheral layer myself where I store the current state of the peripheral and provide a function such as my_comp_uninit() and check there in which state the peripheral is.

I'd just like to understand why this has been put in place?

What would help is having functions in the peripheral drivers such as : m_state = nrf_drv_comp_get_state();

cheers Timur

  • Hi,

    In general, there is a difference between configuring, enabling/disabling, and starting/stopping a peripheral. Initializing a driver with some nrf_drv_xx_init() function is yet another thing.

    • When configuring a peripheral you tell it which pins to use, how fast to sample a signal, how much data to transfer, etc. dependent on the peripheral.
    • When Enabled, peripherals override the PINDIR and PORT values set in the GPIO module. In other words, it is at this moment that the peripheral takes control over the GPIOs that you want to use.
    • Starting a peripheral with the START task makes the peripheral perform its actual task. Like transferring data over a serial interface or measure a voltage with the comparator. It is at this moment the peripheral requests the necessary resources like clocks, and starts to draw current.
    • When initiating a driver you tell your application which particular peripheral to use. And if applicable, you also tell it which instance of the peripheral (TWI0, TWI1, etc,) you want. You also tell it which pins to use and a bunch of different stuff specific to the peripheral.

    When using a peripheral the general rule of thumb is: Configure -> Enable -> Start. When you want to turn off the peripheral you should: Stop -> Disable -> (Enter sleep mode, reconfigure, etc.). This will make sure that you won't see any weird glitches on the GPIOs when preparing the peripheral.

    So typically, in the nrf_drv_peripheral_init() functions we configure pins, etc., and enable the peripheral. Some drivers also have separate enable functions. Then in the end, you most likely call some sort of nrf_drv_peripheral_start() function to start the actual measurements or transfers. You should never use the low level hardware abstraction layers (HAL) in e.g. nrf_comp.h. At least not when you use one of our drivers. Then they should only be used by the drivers themselves. So when using drivers the rule of thumb is: init() -> (enable()) -> start(). To disable the peripheral you should: stop() -> (disable()) -> uninit().


    The ASSERT macro was added to the driver to simplify debugging and make it easier to pinpoint exactly where an error occurs. It should be possible though, to "disable" the ASSERT macro by making sure not to define DEBUG_NRF or DEBUG_NRF_USER. As you can see in nrf_assert.h, these two defines decide whether the ASSERT macro sends your application into a system reset or endless while loop or if it just ignores the ASSERT and moves on.

  • Thank you very much, the hint with DEBUG_NRF could have saved my some days of debugging. Should have asked before :-)

    Cheers Timur

Related