Setting up SPIS with Interrupts using Zephyr

Howdy,

I am currently working on the nRF52840 chip and trying to convert my SPIS code from being in my main while loop into being interrupt driven. I am using Zephyr to do this, but having trouble figuring out how the interrupt should be attached. I mainly need this since the SPI transmission is asynchronous and currently it locks my while loop waiting for it. This hurts since I needed to use my while loop for synchronous monitoring and processing. I should note that his is my first time using Zephyr. I have provided my SPI code below into section. Here is my config.

CONFIG_SPI=y
CONFIG_SPI_SLAVE=y

Below is where I am getting my errors on defining the pointers. The error is coming from the define for "MY_ISR_ARG". It is saying that "'__device_DEVICE_DEFINE' was not declared in this scope".

#include <zephyr/device.h>
#include <zephyr/devicetree/spi.h>
#include <zephyr/dt-bindings/spi/spi.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/logging/log.h>
#include <autoconf.h>
#define SPI_DEV DT_NODELABEL(spi1)
#define MY_DEV_IRQ 24 /* device uses IRQ 24 */
#define MY_ISR_ARG DEVICE_GET(DEVICE_DEFINE(spi1)) /* argument passed to my_isr(), in this case a pointer to the device */

Here is the part where I am handling all the SPI setup outside of the main function. I know that everything here should work fine with the exception of the SPI_ISR function, from testing in the while loop.

static const struct device *spi_dev;

static const struct spi_config spi_cfg = {
	.frequency= 2500000,
	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_OP_MODE_SLAVE
			| SPI_CONFIG_CPHA_Leading | SPI_CONFIG_CPOL_ActiveLow, // 8-bit data, MSB first
	// .cs = (struct spi_cs_control){
	// 	.gpio = GPIO_DT_SPEC_GET(SPI_DEV, cs_gpios),
	// 	.delay = 0u,
	// },
};

static uint8_t rx_buf[SPI_DATA_LEN] = {0}; // Received data from master should be 98 bytes, change if needed

struct spi_buf spi_rx = {
	.buf = rx_buf, 
	.len = sizeof(rx_buf) // Receive buffer
};

const struct spi_buf_set rx_buffers = {
	.buffers = &spi_rx, 
	.count = 1
};

void SPI_ISR(){
	int ret = spi_read(spi_dev, &spi_cfg, &rx_buffers);
	if (ret >= 0) {
		printk("Received data from master:");
		memcpy(The_Vocal_data, rx_buf, sizeof(rx_buf));
		for(int i = 0; i < 20; i++){
			printk("%d ",rx_buf[i]);
		}
		printk("\n");
	} else {
		printk("SPI transceive error: %d\n", ret);
		memset(The_Vocal_data, 0, sizeof(rx_buf));
	}
}

The last part of the code takes place before the main while loop in the main function. I know that IRQ_CONNECT is incorrect but no clue as to why it is not correct.

const struct device *spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi1));
	spi_dev = DEVICE_DT_GET(SPI_DEV);
	if(!spi_dev){
		printk("Device not found: SPI\n");
		return 0;
	}
	if (!device_is_ready(spi_dev)) {
		printk("%s: device not ready.\n");
		return 0;
	}
	IRQ_CONNECT(MY_DEV_IRQ, 2, my_isr, MY_ISR_ARG, 0);
   	irq_enable(MY_DEV_IRQ);

Any help with this would be much appreciated. 

Parents Reply Children
Related