This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
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

question about SPI availability on nrf5340 with secure and non secure modes

1. Your documents mention only SPI3 and SPI4 are available in non- secure mode.. which means spi-0,1,2 should not be available in non-secure mode.. But if i use nrfx drivers, I am able to use spi-2 in secure and non secure mode.. so does nrfx drivers override SPM ? 
2. Are all SPI ports (0-4) available in secure mode ? is there a list of what's available in secure mode ?
3. My device will use uart0, i2c1, spi2, i2c3 and spi4 and qspi in my device.. can Nordic confirm if this is possible in either non-secure or secure mode or do i have to use some kind of mixed mode ?
4. are all SPI ports available in your latest nrf5340 samples ? devzone is wild and has stories of spi3 not being accessible.. will i be wrong to expect to know a single sourceof truth somewhere that says what's available in each mode or of there are any gotachs if i want to use a lot of peripherals ?

  • Hello!

    First some clarification here: as explained in both the nRF9160 and nRF5340 documentation the ARM TrustZone enables the MCU to be divided into secure and non-secure domains, but a secure application will always be running at the bottom. By default the secure partition has access to all peripherals, including SPI and access is granted to the non-secure partition by using the Secure Partition Manager (SPM). With this in mind, here's answers to your question:
    1. nRFX should not override SPM. Could you explain how you tested this?
    2. All peripherals are available to secure applications. 
    3. All non-secure applications are "mixed" as in as they run on top of a secure partition. The usage of peripherals you suggest should be possible regardless, but as you touched on in your first question some peripherals aren't handled by SPM currently and will thus not be available in non-secure applications. This can be fixed after the summer holidays, but it's quite trivial to add new peripherals yourself by copy pasting and renaming existing peripherals in the SPM library (<ncs_root>\nrf\subsys\spm).
    4. In secure mode all SPI ports are available. As mentioned above some peripherals are not yet configured by SPM to be available in non-secure application. The most important thing to remember when using several peripherals is to not have overlapping instances (e.g. UART0 and I2C0 cannot be enabled at the same time).

    Best regards,
    Carl Richard

  • Thank you.. this really helps.. 
    2. All peripherals are available to secure applications. : I could have guessed that but needed to hear from you guys and thank you.. that makes perfect sense now
    3. Understood .. that kinda aligns with what I have read on devzone but always great to get it confirmed .. Thank you
    4. Got it.. and I already knew about not using overlapping peripherals (as you could see from my use case where I will be using uart0, i2c1, spi2, i2c3 and spi4 and qspi )

    1. I wish i could just send an example project/code for you to test but it is part of my current project and will take time to isolate it.
    But here is essentially what I did

    using a custom board (but haven;t ported to my own device tree yet and just using nrf5340dk name)
    here's my nrf5340dk_nrf5340_cpuappns.overlay

    // UART debug port
    &uart0 {
    status = "okay";
    tx-pin = < 0x19 >;
    rx-pin = < 0x1a >;
    };

    &i2c1 {
    status = "okay";
    compatible = "nordic,nrf-twim";
    sda-pin = <4>;
    scl-pin = <5>;
    clock-frequency = <I2C_BITRATE_STANDARD>;
    };

    and here's nrf5340dk_nrf5340_cpuapp.overlay

    // UART debug port
    &uart0 {
    status = "okay";
    tx-pin = < 0x19 >;
    rx-pin = < 0x1a >;
    };

    &i2c1 {
    status = "okay";
    compatible = "nordic,nrf-twim";
    sda-pin = <4>;
    scl-pin = <5>;
    clock-frequency = <I2C_BITRATE_STANDARD>;
    };

    here's proj.conf (as definitions not necessarily needed by code i will past below)

    #
    # Copyright (c) 2019 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
    #
    # General config
    CONFIG_ASSERT=y

    # Logging
    CONFIG_UART_CONSOLE=y
    CONFIG_SERIAL=y

    # Stacks and heaps
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_HEAP_MEM_POOL_SIZE=16384

    # I2C
    CONFIG_I2C=y
    CONFIG_I2C_NRFX=y
    CONFIG_I2C_1=y
    CONFIG_NRFX_TWIM1=y
    CONFIG_NRFX_TWIM3=y

    # Rebooot
    CONFIG_REBOOT=n

    #SPI
    CONFIG_SPI=n
    CONFIG_NRFX_SPIM=y
    CONFIG_NRFX_SPIM2=y
    CONFIG_NRFX_SPIM3=y
    CONFIG_NRFX_SPIM4=y

    # Use PWM
    CONFIG_PWM=y
    CONFIG_DEPRECATED_ZEPHYR_INT_TYPES=y
    CONFIG_ADC=y

    # Use GPIO
    CONFIG_GPIO=y

    I build secure version build with command  west build -b nrf5340dk_nrf5340_cpuapp -p
    and non secure version with command  west build -b nrf5340dk_nrf5340_cpuappns -p
    and I am using NCS SDK 1.5.1


    and here's the code.. if SPI_2 was not available in non-secure build, i would expect this code to not run and  unable to access my SPI slave and read/write registers.. But I cna do that wiht secure and non-secure build and using SPI_2.. hence my confusion.. My guess is I have missed something very obvious as this is NOT supposed tow work the way i see it working

    #define SPI_INSTANCE 2
    static const nrfx_spim_t spim2 = NRFX_SPIM_INSTANCE(SPI_INSTANCE);
    
    #define SPIM2_XXXXXX_CS_PIN (45)
    #define SPIM2_SCK_PIN (40)
    #define SPIM2_MISO_PIN (42)
    #define SPIM2_MOSI_PIN (41)
    
    #define SPIM2_DEFAULT_CONFIG(_pin_sck, _pin_mosi, _pin_miso, _pin_ss)   \
    {                                                                           \
        .sck_pin        = _pin_sck,                                             \
        .mosi_pin       = _pin_mosi,                                            \
        .miso_pin       = _pin_miso,                                            \
        .ss_pin         = _pin_ss,                                              \
        .ss_active_high = false,                                                \
        .irq_priority   = NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY,                \
        .orc            = 0xFF,                                                 \
        .frequency      = NRF_SPIM_FREQ_4M,                                     \
        .mode           = NRF_SPIM_MODE_0,                                      \
        .bit_order      = NRF_SPIM_BIT_ORDER_MSB_FIRST,                         \
        .miso_pull      = NRF_GPIO_PIN_NOPULL,                                  \
        NRFX_SPIM_DEFAULT_EXTENDED_CONFIG                                       \
    }
    
    
    static nrfx_spim_config_t spim2_config = SPIM2_DEFAULT_CONFIG(SPIM2_SCK_PIN, SPIM2_MOSI_PIN, SPIM2_MISO_PIN, SPIM2_XXXXXX_CS_PIN);
    static uint8_t m_tx_buf[] = {0x28, 0x00, 0x00, 0x00};
    
    static uint8_t m_rx_buf[sizeof(m_tx_buf)];
    static const uint8_t m_length = sizeof(m_tx_buf);
    static uint8_t m_got_lis2dw12_ID = 0;
    
    static volatile bool spim2_xfer_done; /**< Flag used to indicate that SPIM instance completed the transfer. */
    
    
    static void manual_spim2_isr_setup()
    {
    	IRQ_DIRECT_CONNECT(SPIM2_SPIS2_TWIM2_TWIS2_UARTE2_IRQn, 0,
    			   nrfx_spim_2_irq_handler, 0);
    	irq_enable(SPIM2_SPIS2_TWIM2_TWIS2_UARTE2_IRQn);
    
    }
    
    void spim2_event_handler(nrfx_spim_evt_t const *p_event, void *p_context)
    {
    
        if (p_event->type == NRFX_SPIM_EVENT_DONE)
        {
            spim2_xfer_done = true;
        }
        for(int i = 0; i < sizeof(m_rx_buf); i++)
        {
    		printk("%x ", m_rx_buf[i]);
        }
        printk("\n");
    }
    
    void main(void) {
        nrfx_spim_xfer_desc_t spim2_xfer_desc = NRFX_SPIM_XFER_TRX(m_tx_buf, m_length, m_rx_buf, m_length);
        printk("\n\n SPI based XXX read Id test");
        nrfx_err_t err_code;
    
              printk("\n\n Read from register 0xc1\n");
             memset(m_rx_buf, 0, m_length);
              spim2_xfer_done = false;
    
              //prepare write values
              m_tx_buf[0] = 0xc1;
              m_tx_buf[1] = 0x00;
              m_tx_buf[2] = 0x00;
              m_tx_buf[3] = 0x00;
    
              err_code = nrfx_spim_xfer(&spim2, &spim2_xfer_desc, 0);
    
              if (err_code == NRFX_ERROR_BUSY) {
                printk("SPI busy\n");
              } else if (err_code != NRFX_SUCCESS) {
                printk("Error code = %d\n", err_code);
              }
    
              while (!spim2_xfer_done) {
                __WFE();
              }
    }

  • Hello again!

    Good to hear that this answered some of your questions and thank you for the description! I actually managed to do the same myself while testing here, so I have reached out to the developers to get some more insight on what might be going on. Will report back here if I get any feasible answers.

    Best regards,
    Carl Richard

  • any update on " I actually managed to do the same myself while testing here, so I have reached out to the developers to get some more insight on what might be going on. Will report back here if I get any feasible answers.".. 

  • Hello again!

    I haven't gotten any response to my inquiry yet, likely due to most of our developers being away on summer holidays. I'll ping them and see if I get anything back!

    Thank you for your patience.

    Best regards,
    Carl Richard

Related