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

What's the official way to implement a simple peripheral (SPI, I2C, etc) with NCS?

Hi there,

I'm struggling to find straight forward peripheral interface documentation for an NCS project.  I see there's something called nrfx (https://github.com/NordicSemiconductor/nrfx) and also Zephyr has peripheral APIs (https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/reference/peripherals/index.html).  Which is correct?  

For nrfx, I don't see any examples of usage of this.  For Zephyr APIs, how do I configure them?

Thanks

  • As far as I know, the Zephyr API uses the the nrfx HAL as can be seen in https://github.com/zephyrproject-rtos/zephyr/blob/master/drivers/spi/spi_nrfx_spim.c for example. These functions (as well as other drivers) are the once that are called from the api->dostuff() function calls in the Zephyr drivers.

    If I understood correctly, when you enable perihperals in the Kconfig you choose which underlying driver that gets called from the Zephyr API. I guess using Zephyr API makes your project more easy to port if you switch MCU in the future.

    I personally try to use the Zephyr API as much as possible to try to keep the code as coherent as possible. One drawback of this is that there is not 100% clear what is happening configuration wise with the perihperals and you need to manually check the drivers to see what Zephyr does when it sets up everything.

    However, I am wondering, same as you, which method is the "correct" one according to nordic since I've seen on Devzone that several people use the nrfx functions directly instead of the Zephyr one. I guess it is a convenice vs control issue.

    Would be nice to have an official answer from a Nordic rep about the subject. Will NCS diverge more from Zephyr in the future?

  • Thanks .  Hopefully we can get a Nordic engineer to see this and give us some guidance.

  • If you would like to fully utilize all the advantages Zephyr brings with it, I would recommend you to use the Zephyr API. In Zephyr you use Kconfigs (through prj.conf) and the device tree/dts (through overlay files) to set up a project, read more about this in 1. Concepts in NCS. If you use the nrfx layer, the stuff you've set in prj.conf and overlay files (and all the other Kconfig and dts files) will not be seen. Using the Zephyr API makes it quicker and easier to set up a project (Given that everything works as expected and you have a good intuitive understanding of how the SDK works). There might be more advantages of using the Zephyr API that I have missed, but this is what I though of right now.

    Some developers likes to have more control over what they're doing, with less abstractions from the hardware, then the nrfx drivers might be a better option. 

    From my point of view, I would recommend you to use the Zephyr API, as it will reduce the development time, make the application more scalable/portable/cross-compatible and reduce the amount of code you write (less chances of bugs). I don't have a complete overview of this, so if anyone could prove me wrong on any of these points, I would be more than happy.

    Since NCS/Zephyr is still quite new, there are circumstances where the nrfx layer has to be used. E.g. if you want to use I2S with Zephyr, you have to use the nrfx drivers, since it's not supported on the top layer (I think there is on-going work right on this right now).

    Shaney is correct in that the Zephyr API uses the nrfx drivers. The figure below (from NCS tutorial part 3) might give you an overview of how it works:

    Best regards,

    Simon

  • I'm still struggling with this.  I'm using the nRF52840dk and it seems to be "kind of" supported.  I find myself piecing together how to do this from forum posts and disparate documentation.  Honestly this is strange, why can't I just go to one set of documentation that describes the libraries needed and how to use them?  Why is so much of the NCS "documentation" actually just obfuscated examples that I need to reverse engineer?  I feel like I should just be able to #include a header file and do straight forward established I2C functions.

  • Do I look at NCS docs?  Zephyr docs?  nrfx, the old softdevices?  This is not clear.

Related