Configuring GPIO pins that are used for SPI under Zephyr

I'm prototyping with a nRF9160 DK using nRF Connect SDK v2.4.0 and the Visual Code extension. I'm using an ADXL372z breakout board that I want to communicate with via SPI. When I've done this in the past using an nRF52840DK, the same ADXL372 breakout board and SDK 17, I have had to configure the GPIO pins used for SCLK and MOSI with NRF_GPIO_PIN_H0H1. I've also had to keep the clock frequency below 1MHz. This is because the jumper wire lengths between the DK and the breakout board make you need a bit more current than normal. Also without using twisted pair wiring with proper grounding, you have to keep line frequencies low.

short ADXL372_spi_master_init(nrf_drv_spi_t m_spi0_master,
                              nrf_drv_spi_evt_handler_t spi_event_handler,
                              bool *xferdone)
{
    uint32_t              err_code = 0;

    m_ad_spi_master = m_spi0_master;

    m_config.ss_pin       = NRF_DRV_SPI_PIN_NOT_USED;
    m_config.irq_priority = APP_IRQ_PRIORITY_LOW;
    m_config.orc          = 0xFF;  // Most devices expect ones as filler/dummy bytes.
    m_config.frequency    = NRF_SPI_FREQ_8M;
    m_config.mode         = NRF_DRV_SPI_MODE_0;  // Corresponds to the datasheet specification CPHA = CPOL = 0
    m_config.bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;  // Put it out the way you put it in

    m_config.sck_pin  = SPI_SCK_PIN;
    m_config.mosi_pin = SPI_MOSI_PIN;
    m_config.miso_pin = SPI_MISO_PIN;
    
    err_code = nrf_drv_spi_init(&m_ad_spi_master, &m_config, spi_event_handler, NULL);    
    APP_ERROR_CHECK(err_code);

    #if (USING_DEVELOPMENT_KIT == 1)
    nrf_gpio_cfg(SPI_SCK_PIN,
                 NRF_GPIO_PIN_DIR_OUTPUT,
                 NRF_GPIO_PIN_INPUT_DISCONNECT,
                 NRF_GPIO_PIN_NOPULL,
                 NRF_GPIO_PIN_H0H1,
                 NRF_GPIO_PIN_NOSENSE);

    nrf_gpio_cfg(SPI_MOSI_PIN,
                 NRF_GPIO_PIN_DIR_OUTPUT,
                 NRF_GPIO_PIN_INPUT_DISCONNECT,
                 NRF_GPIO_PIN_NOPULL,
                 NRF_GPIO_PIN_H0H1,
                 NRF_GPIO_PIN_NOSENSE);
    #endif // (USING_DEVELOPMENT_KIT == 1)

    spixferdone = xferdone;
    m_spi_event_handler = spi_event_handler;

    return (0);
    
}

 This works for prototyping under SDK 17.

I need to do the same using nRF Connect SDK. I can't figure out where to use NRF_GPIO_DRIVE_H0H1 because I don't know how to configure individual GPIO pins under Zephyr. This is my current overlay file:

// To get started, press Ctrl+Space to bring up the completion menu and view the available nodes.
// For more help, browse the DeviceTree documentation at https: //docs.zephyrproject.org/latest/guides/dts/index.html
//
//


&pinctrl
{

    spi3_default: spi3_default
	{
	    group1
		{
		    psels = <NRF_PSEL(SPIM_SCK, 0, 0)>,
				    <NRF_PSEL(SPIM_MOSI, 0, 1)>,
				    <NRF_PSEL(SPIM_MISO, 0, 2)>;

	    };
    };

    spi3_sleep: spi3_sleep
	{
	    group2
		{
		    psels = <NRF_PSEL(SPIM_SCK, 0, 0)>,
				    <NRF_PSEL(SPIM_MOSI, 0, 1)>,
				    <NRF_PSEL(SPIM_MISO, 0, 2)>;
		    low-power-enable;
	    };
	};
};


/*** link SPI pin configurations with a device ***/
my_spi3: &spi3
{
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi3_default>;
	pinctrl-1 = <&spi3_sleep>;
	pinctrl-names = "default", "Sleep";
	cs-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>, <&gpio0 29 GPIO_ACTIVE_LOW>;

	winbondflash: flash@0
	{
		compatible = "winbond,w25n01", "jedec,spi-nor";
		size = <1073741824>;
		reg = <0>;
		label = "1GBIT_FLASH_DEVICE";
		spi-max-frequency = <1000000>;
		jedec-id = [ EF AA 21  ];	//UNIQUE TO SPECIFIC FLASH CHIP BEING USED W25N01G
	};

	adxl372: spi-dev-adxl372@1
	{
		compatible = "adi,adxl372";
		spi-max-frequency = <1000000>;
		reg = <1>;
		int1-gpios = <&gpio0 19 0>;
	};
	

};

This is my initialization and use

#include "spi3.h"
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/logging/log.h>

struct spi_cs_control adxl372_spi_cs = 
{
	.gpio = SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(adxl372)),
	.delay = 0,
};


static const struct spi_config adxl372_spi3_cfg = 
{
	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
				 SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA,
	.frequency = 400000,
	.slave = 0,
	.cs = &adxl372_spi_cs,
};

struct spi_cs_control winbond1g_spi_cs = 
{
	.gpio = SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(winbondflash)),
	.delay = 0,
};


static const struct spi_config winbond1g_spi3_cfg = 
{
	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
				 SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA,
	.frequency = 400000,
	.slave = 0,
	.cs = &winbond1g_spi_cs,
};

static const struct device *spi3_dev;

uint8_t init_spi3(void)
{
	int      err;

	spi3_dev = DEVICE_DT_GET(DT_NODELABEL(spi3));

    if (spi3_dev == NULL)
    {
		printk("Could not get %s device\n", spi3_dev->name);
        return 1;
    }
	printk("SPI Device: %s\n", spi3_dev->name);

    return 0;
}


int adxl372_id(void)
{
	static uint8_t tx_buffer[2];
	static uint8_t rx_buffer[2];

	const struct spi_buf tx_buf =
	{
		.buf = tx_buffer,
		.len = sizeof(tx_buffer)
	};
	const struct spi_buf_set tx =
	{
		.buffers = &tx_buf,
		.count = 1
	};

	struct spi_buf rx_buf =
	{
		.buf = rx_buffer,
		.len = sizeof(rx_buffer),
	};
	const struct spi_buf_set rx =
	{
		.buffers = &rx_buf,
		.count = 1
	};


	// last byte of rx contains the response from the accelerometer
    // Shift the register's address to the left by one, inorder to
    // clear bit 0, and set bit 0 high per the adxl372 data sheet's
    // specification for the read command structure of the device's SPI Protocal.

	tx_buffer[0] = (0x02 << 1) + 1;

	int error = spi_transceive(spi3_dev, &adxl372_spi3_cfg, &tx, &rx);
	if (error != 0)
	{
		printk("SPI transceive error: %i\n", error);
		return error;
	}

	if(rx_buffer[1] == 0xfa)
	{
		printk("Successfull ACC communication\n");
	}
	else
	{
		printk("Faild ACC communication\n");
		printk("SPI Tx bytes: ");
		for (int i = 0; i < sizeof(tx_buffer); i++)
		{
			printk("%x ", tx_buffer[i]);
		}
		printk(" SPI Rx bytes: ");
		for (int i = 0; i < sizeof(rx_buffer); i++)
		{
			printk("%x ", rx_buffer[i]);
		}
		printk("\n");
	}

	return 0;
}

 This is a screen shot of the adxl372_id function in action (

How do I configure the GPIO pins I'm using for SCLK and MOSI to be NRF_GPIO_PIN_H0H1 ? Should I do that GPIO configuration in my Overlay file and how would I do that?

Why is my clock line normally high ?

Greatly appreciate any help and advice. Thank you.

Parents Reply Children
No Data
Related