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

SPI/I2C Step on nRF52833 to read BMI160 outputs

Hello,

I am trying to read BMI160 outputs using SPI protocol but I am struggling to get a successful build from my code. 

The build fails at the first line of my code //static nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE( 0 ); // SPI instance// 

The complier doesn't recognise NRF_DRV_SPI_INSTANCE even though it is in the libraries into nrf_drv_spi library. 

I don't know what I am doing wrong? Could I get some help please?

Please find below my code. 

Thanks a lot.

Parents
  • The complier doesn't recognise NRF_DRV_SPI_INSTANCE even though it is in the libraries into nrf_drv_spi library

    Have you made the necessary settings in sdk_config.h ?

  • Thank you Awneil.

    Sorry for the code post. I repost it below.

    Could you tell me please what settings I need to made into sdk_config.h ?

    Thank you very much.

  • So you want to use the SPI 0 instance. Please make sure these are set in sdk_config.h:

    #define SPI_ENABLED 1
    #define SPI0_ENABLED 1
    #define SPI0_USE_EASY_DMA 1

    These are the same settings that are set in the spi example from SDK\examples\peripheral\spi

    Best regards,

    Edvin

  • Thank you Edwin. 

    I did the settings in sdk_config.h. 

    I am having the follwoing error in nrf_drv_spi.h: 

    'NRF_DRV_SPI_INSTANCE_0' undeclared here (not in a function); did you mean 'NRF_DRV_SPI_INSTANCE_'?

    I don't understand why. It is exactly like in the spi example. Could you help me please?

    Thanks a lot

  • Hi Edwin, 

    I am new to Embedded code. I am really to struggling to set everything up properly. I believe there are many settings I am not aware of. Is there a document/guide to help me with this?

    Thanks a lot

  • Not on this particularly, as far as I know. Only the general documentation on infocenter.nordicsemi.com.

    I don't know what SDK you are using, so I'll try to explain using SDK17.0.2. If you are starting the development now, I suggest you use this SDK version.

    Take a look at the example found in SDK\examples\peripheral\spi\

    This example also uses SPI instance 0. If you search for "NRF_DRV_SPI_INSTANCE_0" in this project, you will see that you will see some hits in the file nrf_drv_spi.h, but they are not that obvious what they are doing. On top of that there is the NRFX definitions and NRF definitions that seems to be fighting eachother, which may be quite confusing. I am sorry for this. 

    Let us start from main.c:

    NRF_DRV_SPI_INSTANCE(SPI_INSTANCE) is a macro. Since SPI_INSTANCE is defined as 0, it basically says: NRF_DRV_SPI_INSTANCE(0);

    NRF_DRV_SPI_INSTANCE() is a macro that takes one parameter as input. This is defined in nrf_drv_spi.h on line 119.

    #define NRF_DRV_SPI_INSTANCE(id)    NRF_DRV_SPI_INSTANCE_(id)

    NRF_DRV_SPI_INSTANCE_(id) is another macro, which is set to:

    NRF_DRV_SPI_INSTANCE_ ## id, meaning that whenevery you write NRF_DRV_SPI_INSTANCE(0) it is translated to NRF_DRV_SPI_INSTANCE_0. 

    Now, if this is not defined, you will get this error message that you are seeing because you set nrf_drv_spi_t spi = something that is not defined.

    If you look further down in nrf_drv_spi.h, there are some definitions of NRF_DRI_SPI_INSTANCE_0, but they are only defined if some conditions are fulfilled:

    #if NRFX_CHECK(NRFX_SPIM0_ENABLED)
        #define NRF_DRV_SPI_INSTANCE_0 \
            { 0, { .spim = NRFX_SPIM_INSTANCE(0) }, true }
    #elif NRFX_CHECK(NRFX_SPI0_ENABLED)
        #define NRF_DRV_SPI_INSTANCE_0 \
            { 0, { .spi = NRFX_SPI_INSTANCE(0) }, false }
    #endif

    So either NRFX_CHECK(NRF_SPIM0_ENABLED) or NRFX_CHECK(NRFX_SPI0_ENABLED) needs to return true.

    the macro NRFX_CHECK() just checks that the define inside the parenthesis is defined and it is set to true/1.

    In this example, NRFX_SPIM0_ENABLED is actually true, although it is a bit confusing. If you look in sdk_config.h line 514, you see that it is defined to 0 (so it really shouldn't have returned true). But if you search your project for NRFX_SPIM0_ENABLED, you see that it is used in a file called apply_old_config.h. Look at that file, line 811-871:

    #if defined(SPI_PRESENT) && !defined(SPIM_PRESENT)
    
    #undef NRFX_SPI0_ENABLED
    #define NRFX_SPI0_ENABLED   SPI0_ENABLED
    #undef NRFX_SPIM0_ENABLED
    #define NRFX_SPIM0_ENABLED  0
    
    #undef NRFX_SPI1_ENABLED
    #define NRFX_SPI1_ENABLED   SPI1_ENABLED
    #undef NRFX_SPIM1_ENABLED
    #define NRFX_SPIM1_ENABLED  0
    
    #undef NRFX_SPI2_ENABLED
    #define NRFX_SPI2_ENABLED   SPI2_ENABLED
    #undef NRFX_SPIM2_ENABLED
    #define NRFX_SPIM2_ENABLED  0
    
    #elif !defined(SPI_PRESENT) && defined(SPIM_PRESENT)
    
    #undef NRFX_SPI0_ENABLED
    #define NRFX_SPI0_ENABLED   0
    #undef NRFX_SPIM0_ENABLED
    #define NRFX_SPIM0_ENABLED  SPI0_ENABLED
    
    #undef NRFX_SPI1_ENABLED
    #define NRFX_SPI1_ENABLED   0
    #undef NRFX_SPIM1_ENABLED
    #define NRFX_SPIM1_ENABLED  SPI1_ENABLED
    
    #undef NRFX_SPI2_ENABLED
    #define NRFX_SPI2_ENABLED   0
    #undef NRFX_SPIM2_ENABLED
    #define NRFX_SPIM2_ENABLED  SPI2_ENABLED
    
    #else // -> defined(SPI_PRESENT) && defined(SPIM_PRESENT)
    
    #undef NRFX_SPI0_ENABLED
    #define NRFX_SPI0_ENABLED   (SPI0_ENABLED && !SPI0_USE_EASY_DMA)
    #undef NRFX_SPIM0_ENABLED
    #define NRFX_SPIM0_ENABLED  (SPI0_ENABLED && SPI0_USE_EASY_DMA)
    
    #undef NRFX_SPI1_ENABLED
    #define NRFX_SPI1_ENABLED   (SPI1_ENABLED && !SPI1_USE_EASY_DMA)
    #undef NRFX_SPIM1_ENABLED
    #define NRFX_SPIM1_ENABLED  (SPI1_ENABLED && SPI1_USE_EASY_DMA)
    
    #undef NRFX_SPI2_ENABLED
    #define NRFX_SPI2_ENABLED   (SPI2_ENABLED && !SPI2_USE_EASY_DMA)
    #undef NRFX_SPIM2_ENABLED
    #define NRFX_SPIM2_ENABLED  (SPI2_ENABLED && SPI2_USE_EASY_DMA)
    
    #endif // -> defined(SPI_PRESENT) && defined(SPIM_PRESENT)

    So first, if SPI_ENABLED is defined (which it is) and then there are a few #ifs that are not true:

    #if defined(SPI_PRESENT) && !defined(SPIM_PRESENT)

    and 

    #elif !defined(SPI_PRESENT) && defined(SPIM_PRESENT)

    which both return false.

    That means that we jump to:

    #else // -> defined(SPI_PRESENT) && defined(SPIM_PRESENT)

    which is true.

    then NRFX_SPIM0_ENABLED is undefined, and defined to:

    (SPI0_ENABLED && SPI0_USE_EASY_DMA)

    To be clear, NRFX_SPI0_ENABLED will be false (0), and NRFX_SPIM0_ENABLED will be set to true (1).

    Now, since NRFX_SPIM0_ENABLED is defined to 1, that means that the original check in nrf_drv_spi.h will be:

    #if NRFX_CHECK(NRFX_SPIM0_ENABLED) which will return true, and 

    #define NRF_DRV_SPI_INSTANCE_0 \
    { 0, { .spim = NRFX_SPIM_INSTANCE(0) }, true }

    will define NRF_DRV_SPI_INSTANCE_0.

    This is why I asked you to set SPI_ENABLED to 1, SPI_ENABLED to 1 and SPI0_USE_EASY_DMA to 1. Using that combination, apply_old_config.h will set the rest. Is apply_old_config.h included in your project? in the spi example this is included via:

    nrfx_glue.h, which is included by nrfx.h, which is included by a lot of files, among others from nrf_drv_spi.h, nrfx_spi.h, nrfx_spim.h and a lot more.

    Best regards,

    Edvin

  • Thank you so so much Edwin. This is a very clear answer. I do understand now. This is helping getting familiar with the Nordic environment. 

    I was using SDK 17.0.0. I just downloaded 17.0.2 and added my bmi160 program into the spi project. The project has successfully built whereas it hasn't in the spi project of SDK 17.0.0. 

    Thanks a lot. 

Reply Children
No Data
Related