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

using SPI with PPI in zephyr

HI,

we are using the nrf52840 in our new poroduct and we are running the zephyr/ncs RTOS on it.

for real time reasons I need to read from a SPI bus upon a GPIO trigger and in the context of the SPI done interrupt save the read data to a buffer.

I was able to do this on another product that we have without zephyr using the nrf SDK on a baremetal application.

the problem with zephyr is that the SPI HW abstraction controls the event handler from SPIM and I don't have access to it and also even if I want to hack this by directly accessing it with the nrfx spim driver I don;t know how this will work with the zephyr power manager!

if someone has an Idea how to best do this in zephyr/ncs I would appreciate the help.

Thanks,

Samer.

Parents
  • I believe the attached example may be of help. It show how to setup gpiote event to trigger a callback, which again trigger a spi transfer, which again trigger a spi callback when finished. If you are using an nRF52-DK, then pushing button1 will execute the transfer, shown by a very quick blink on led1.

    3554.nrfx_with_spi.zip

    /*
     * Copyright (c) 2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    
    #include <drivers/gpio.h>
    #include <nrfx_gpiote.h>
    #include <nrfx_ppi.h>
    #include <nrfx_spim.h>
    
    #include <logging/log.h>
    LOG_MODULE_REGISTER(nrfx_sample, LOG_LEVEL_INF);
    
    #define INPUT_PIN DT_GPIO_PIN(DT_ALIAS(sw0), gpios)
    #define CSN DT_GPIO_PIN(DT_ALIAS(led1), gpios)
    
    #define BUF_SIZE 10
    uint8_t buffer_tx[BUF_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    uint8_t buffer_rx[BUF_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
    nrfx_spim_xfer_desc_t transfer = {
    	.p_tx_buffer = buffer_tx, ///< Pointer to TX buffer.
    	.tx_length = BUF_SIZE, ///< TX buffer length.
    	.p_rx_buffer = buffer_rx, ///< Pointer to RX buffer.
    	.rx_length = BUF_SIZE ///< RX buffer length.
    };
    
    nrfx_spim_t spi_instance = NRFX_SPIM_INSTANCE(1);
    nrfx_spim_config_t spi_config =
    	NRFX_SPIM_DEFAULT_CONFIG(28, 29, 30, NRFX_SPIM_PIN_NOT_USED);
    
    static void button_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    	nrfx_err_t err;
    
    	LOG_INF("GPIO input event callback, start SPI transfer");
    
    	nrf_gpio_pin_clear(CSN);
    	err = nrfx_spim_xfer(&spi_instance, &transfer, 0);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("SPI transfer error: %08x", err);
    		return;
    	}
    }
    
    static void spim_handler(nrfx_spim_evt_t const *p_event, void *p_context)
    {
    	if (p_event->type == NRFX_SPIM_EVENT_DONE) {
    		LOG_INF("SPI transfer finished");
    		nrf_gpio_pin_set(CSN);
    	}
    }
    
    void main(void)
    {
    	nrfx_err_t err;
    
    	LOG_INF("gpiote + spim sample on %s", CONFIG_BOARD);
    
    	IRQ_CONNECT(GPIOTE_IRQn, 7, nrfx_isr, nrfx_gpiote_irq_handler, 0);
    
    	err = nrfx_gpiote_init(0);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_init error: %08x", err);
    		return;
    	}
    
    	nrfx_gpiote_in_config_t const in_config = {
    		.sense = NRF_GPIOTE_POLARITY_HITOLO,
    		.pull = NRF_GPIO_PIN_PULLUP,
    		.is_watcher = false,
    		.hi_accuracy = true,
    		.skip_gpio_setup = false,
    	};
    
    	err = nrfx_gpiote_in_init(INPUT_PIN, &in_config, button_handler);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_in_init error: %08x", err);
    		return;
    	}
    
    	nrfx_gpiote_in_event_enable(INPUT_PIN, true);
    
    	LOG_INF("nrfx_gpiote is initialized");
    
    	IRQ_CONNECT(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn, 6, nrfx_isr,
    		    nrfx_spim_1_irq_handler, 0);
    
    	err = nrfx_spim_init(&spi_instance, &spi_config, spim_handler, NULL);
    	if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_spim_init error: %08x", err);
    		return;
    	}
    
    	nrf_gpio_pin_set(CSN);
    	nrf_gpio_cfg_output(CSN);
    
    	LOG_INF("nrfx_spim is initialized, push button1 to start spi transfer");
    }
    

    Hope it helps.
    Kenneth

  • To reduce current you may want to set .hi_accuracy = false.

    Kenneth

Reply Children
No Data
Related