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

Difference between nrf_drv_spi_transfer() and nrfx_spim_xfer()?

Hi,

My goal is to use a timer to trigger SPI transactions and the spi_event_handler() to trigger bluetooth transfers. In order to make it as fast as possible, I would like to run the SPI clk at least 4MHz (if not 8MHz - which I think is possible, right?) and also use easyDMA. Based off this thread: Thread_link.

It seems like using the peripheral/spi example should be more than enough to handle all that. If that's the case, what benefit does nrf_spi provide? Is on deprecated? If so... which one? Also is there a difference between SPI0, 1, 2, and 4?

Thanks so much!

Kindest regards,

Ryan

Parents
  • Hello Ryan,

    It seems like using the peripheral/spi example should be more than enough to handle all that. If that's the case, what benefit does nrf_spi provide?

    I am not quite sure that I understand your question, but the difference between the SPI and the SPIM peripherals is that the SPIM peripheral has easyDMA, which enabled you to initiate transfers through PPI, triggered by a TIMER instance, for example. The SPI example you are referring to might be using the SPIM driver behind the scenes, depending on your sdk_config configurations.
    Do you have the USE_EASYDMA defined and set in your sdk_config?

    Also is there a difference between SPI0, 1, 2, and 4?

    This refers to their peripheral ID, you can read more about this here. In essence some peripherals share ID, in which case you may only have one of them enabled at any time.
    For some peripherals there may also be specific differences between the different ID's, such as in the SPIM case - you can read about these in the peripheral register documentation.

    Additionally, there are some Erratas for the nRF52840's SPIM3 instance that you should be aware of.

    Best regards,
    Karl

  • Hi Karl,

    Thanks for your quick response!

    I am not quite sure that I understand your question, but the difference between the SPI and the SPIM peripherals is that the SPIM peripheral has easyDMA,

    This was my original understanding but I was confused by the main SPI example which conflicts with this understanding. 

    In the sdk_config for the spi example (spi_pca10056) there are the following:

    // <e> SPI0_ENABLED - Enable SPI0 instance
    //==========================================================
    #ifndef SPI0_ENABLED
    #define SPI0_ENABLED 1
    #endif
    // <q> SPI0_USE_EASY_DMA - Use EasyDMA
    
    #ifndef SPI0_USE_EASY_DMA
    #define SPI0_USE_EASY_DMA 1
    #endif


    BUT if I go to the NRFX_SPIM sections in my sdk there is the following:
    // <e> NRFX_SPIM_ENABLED - nrfx_spim - SPIM peripheral driver
    //==========================================================
    #ifndef NRFX_SPIM_ENABLED
    #define NRFX_SPIM_ENABLED 1
    #endif
    // <q> NRFX_SPIM0_ENABLED  - Enable SPIM0 instance
     
    
    #ifndef NRFX_SPIM0_ENABLED
    #define NRFX_SPIM0_ENABLED 0
    #endif
    


    To summarize, SPI0 is enabled and set to use easyDMA, but no specific NRFX_SPIMs are enabled. What does "SPI0_USE_EASY_DMA" do if it's just for SPI (and not SPIM)? Is the "SPI0_USE_EASY_DMA" config bit just ignored?

    Also, thank you for the heads up on the SPIM3 errata! Is there a particular reason to use SPIM3 instead of SPIM0,1, or 2?

    I'm sorry that my original post was a little confusing! I shouldn't have rushed it so much! Thanks again for your help, I really appreciate it!

    Kindest regards,

    Ryan

Reply
  • Hi Karl,

    Thanks for your quick response!

    I am not quite sure that I understand your question, but the difference between the SPI and the SPIM peripherals is that the SPIM peripheral has easyDMA,

    This was my original understanding but I was confused by the main SPI example which conflicts with this understanding. 

    In the sdk_config for the spi example (spi_pca10056) there are the following:

    // <e> SPI0_ENABLED - Enable SPI0 instance
    //==========================================================
    #ifndef SPI0_ENABLED
    #define SPI0_ENABLED 1
    #endif
    // <q> SPI0_USE_EASY_DMA - Use EasyDMA
    
    #ifndef SPI0_USE_EASY_DMA
    #define SPI0_USE_EASY_DMA 1
    #endif


    BUT if I go to the NRFX_SPIM sections in my sdk there is the following:
    // <e> NRFX_SPIM_ENABLED - nrfx_spim - SPIM peripheral driver
    //==========================================================
    #ifndef NRFX_SPIM_ENABLED
    #define NRFX_SPIM_ENABLED 1
    #endif
    // <q> NRFX_SPIM0_ENABLED  - Enable SPIM0 instance
     
    
    #ifndef NRFX_SPIM0_ENABLED
    #define NRFX_SPIM0_ENABLED 0
    #endif
    


    To summarize, SPI0 is enabled and set to use easyDMA, but no specific NRFX_SPIMs are enabled. What does "SPI0_USE_EASY_DMA" do if it's just for SPI (and not SPIM)? Is the "SPI0_USE_EASY_DMA" config bit just ignored?

    Also, thank you for the heads up on the SPIM3 errata! Is there a particular reason to use SPIM3 instead of SPIM0,1, or 2?

    I'm sorry that my original post was a little confusing! I shouldn't have rushed it so much! Thanks again for your help, I really appreciate it!

    Kindest regards,

    Ryan

Children
  • Hello Ryan,

    ryerye120 said:
    Thanks again for your help, I really appreciate it!

    No problem at all, I am happy to help!

    ryerye120 said:
    I'm sorry that my original post was a little confusing!

    No need to apologize, I do my best to understand what you mean and I ask if there is anything I am uncertain about! Slight smile

    ryerye120 said:

    This was my original understanding but I was confused by the main SPI example which conflicts with this understanding. 

    In the sdk_config for the spi example (spi_pca10056) there are the following:

    Yes, I definitively see how this could be confusing - especially so since the SPI_ENABLED define is targeting the legacy nrf_drv_spi driver, which is the predecessor of the nrfx_spi driver. If you look into the nrf_drv_spi.h file you can see the effects of the SPI0_USE_EASY_DMA define - it switches the driver to use nrfx_spim instead, behind the scenes.
    The reason for this forwarding is to provide backwards compatibility to older projects when the new nrfx drivers were released, but I concur that it might seem strange when starting to work with the nrfx drivers directly.

    As an additional note, I would recommend that you remove all legacy peripheral defines from your sdk_config (such as SPI_ENABLED, SAADC_ENABLED, etc) and instead only have your nrfx driver defines present (such as NRFX_SPIM_ENABLED, NRFX_SAADC_ENABLED, etc). This is recommended due to the apply_old_config.h file - which was added for backwards compatibility - which will overwrite your NRFX defines if the legacy *_ENABLED is left defined in the sdk_config.

    ryerye120 said:
    To summarize, SPI0 is enabled and set to use easyDMA, but no specific NRFX_SPIMs are enabled. What does "SPI0_USE_EASY_DMA" do if it's just for SPI (and not SPIM)? Is the "SPI0_USE_EASY_DMA" config bit just ignored?


    As mentioned, it makes the switch to the SPIM driver instead, since the SPIM driver is implemented with easyDMA.

    ryerye120 said:
    Also, thank you for the heads up on the SPIM3 errata! Is there a particular reason to use SPIM3 instead of SPIM0,1, or 2?

    The SPIM3 is the high speed instance, so if you need speeds over 8 MHz you will need to use SPIM3 like detailed in the SPI instance register's I referenced in my previous comment.

    Please do not hesitate to ask if any part of this still should be unclear! The backwards compatibility files and behavior is known for having caused some confusion in the past.

    Best regards,
    Karl

  • Karl!

    This has helped so much! Things make a lot more sense now - especially this:

    This is recommended due to the apply_old_config.h file - which was added for backwards compatibility - which will overwrite your NRFX defines if the legacy *_ENABLED is left defined in the sdk_config.

    I kept running into this "apply_old_config.h" and was really confused as to why it existed. Now I know what it is and how to avoid getting tangled in it!

    Speaking of which:

    As an additional note, I would recommend that you remove all legacy peripheral defines from your sdk_config (such as SPI_ENABLED, SAADC_ENABLED, etc) and instead only have your nrfx driver defines present (such as NRFX_SPIM_ENABLED, NRFX_SAADC_ENABLED, etc).

    So just to confirm, peripheral drivers that start with "NRFX" are up to date and other driver enables that are labeled with "legacy layer" in the sdk_config.h can/should be removed? I know this sounds like a reformulation of what you just said but I want to confirm so that I don't accidentally break things.

    I went through and removed all the unused legacy driver enables in my sdk_config.h. I left UART and GPIOTE because removing them broke other things (I'll come back to that later).

    The SPIM3 is the high speed instance, so if you need speeds over 8 MHz you will need to use SPIM3 like detailed in the SPI instance register's I referenced in my previous comment.

    Now that you mention it I remember reading this. I went through the errata and went through the nrfx_spim example and it seems like the example has specific comments/workarounds specific to spim3. Is it safe to assume that building off the nrfx_spim3 example is ok? It seems that the biggest issue I have to keep in mind is #198 (SPIM3 transmit data might be corrupted). That seems straightforward to workaround though.

    Again, thank you! This has already been incredibly helpful.

    Kindest regards,

    Ryan

  • Hello,

    ryerye120 said:
    This has helped so much! Things make a lot more sense now
    ryerye120 said:
    Again, thank you! This has already been incredibly helpful.

    I am happy to hear that, Ryan! :) 

    ryerye120 said:
    So just to confirm, peripheral drivers that start with "NRFX" are up to date and other driver enables that are labeled with "legacy layer" in the sdk_config.h can/should be removed? I know this sounds like a reformulation of what you just said but I want to confirm so that I don't accidentally break things.

    No problem, I completely understand that you would like to confirm it explicitly.
    The answer is yes - when using the nrfx drivers you should remove their legacy configurations in the sdk_config entirely.
    To add to the possible confusion, most of the legacy drivers are just macro forwarding to the nrfx implementation in the later SDK releases, so even if you leave the legacy defines and configurations in the sdk_config it will use the nrfx drivers behind the scenes. - This especially obfuscates things since your NRFX_* configurations will not be used with the NRFX_ driver, due to the apply_old_config (if <peripheral>_ENABLED is defined).
    I am sorry for any confusion this might have caused you.

    ryerye120 said:
    Now that you mention it I remember reading this. I went through the errata and went through the nrfx_spim example and it seems like the example has specific comments/workarounds specific to spim3. Is it safe to assume that building off the nrfx_spim3 example is ok? It seems that the biggest issue I have to keep in mind is #198 (SPIM3 transmit data might be corrupted). That seems straightforward to workaround though.

    Which example exactly are you referring to when you say nrfx_spim3 example?
    In general, there is no problem using the SPIM3 (or any other peripheral or instance) as long as you are aware of the possible Erratas and their workarounds.
    Most of the Erratas with the nRF devices have their workarounds implemented in the particular peripheral driver already, so you do not have to change any implementation yourself, but if they do not you might have to use the peripheral in a certain way for it to function as expected.
    The workaround described in each errata is tested and verified to negate the issue, so as long as they are present (either in your own implementation or in the driver) you can use the peripheral as you would like without concern! :) 

    Best regards,
    Karl

  • Hey Karl,

    I am sorry for any confusion this might have caused you.

    It's no problem at all! I'm really glad you mentioned it otherwise I totally would have missed this!

    Which example exactly are you referring to when you say nrfx_spim3 example?

    Sorry, I should have been more precise. The nrfx_spim example project (which happens to use SPIM3) is what I was referring to. This is different from the spi and spis example projects.


    The workaround described in each errata is tested and verified to negate the issue, so as long as they are present (either in your own implementation or in the driver) you can use the peripheral as you would like without concern! :) 

    Sounds good! If I run into any issues I'll post another ticket, but in the meantime, all my questions have been answered! Thank you so much for your time and help, Karl!

    Kindest regards,

    Ryan

  • Hello again Ryan,

    Sounds good! If I run into any issues I'll post another ticket, but in the meantime, all my questions have been answered! Thank you so much for your time and help, Karl!

    Great! I am happy to hear that! :) 

    Sorry, I should have been more precise. The nrfx_spim example project (which happens to use SPIM3) is what I was referring to. This is different from the spi and spis example projects.

    Oh, right, thank you for clarifying this.

    Please do not hesitate to open another ticket if you should encounter any other issues or questions in the future.

    Good luck with your development!

    Best regards,
    Karl

Related