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

NCS/Zephyr SPI CS Issues

I am having issue configuring the chip select (CS) in my little test program. I have read through the SPI drivers and debugged through it and from what I can tell I have everything setup right. I am also monitoring the CS signal on a scope to watch for it to go low (active low). Even after the SPI init/config routine runs I never see my CS pin go high.
What am I missing?

main.c : 

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <zephyr.h>
#include <sys/printk.h>
#include <device.h>
#include <drivers/spi.h>

/**
 * @file Sample app using the Cypress CY15B102QN (driver based on Fujitsu MB85RS64V) FRAM through SPI.
 */

#define CY15B102QN_MANUFACTURER_ID_CMD 0x9f
#define CY15B102QN_WRITE_ENABLE_CMD 0x06
#define CY15B102QN_READ_CMD 0x03
#define CY15B102QN_WRITE_CMD 0x02
#define MAX_USER_DATA_LENGTH 1024

#define SPI_DEV DT_LABEL(DT_NODELABEL(spi1))

static uint8_t data[MAX_USER_DATA_LENGTH], cmp_data[MAX_USER_DATA_LENGTH];

static int cy15b102qn_access(const struct device *spi,
			    struct spi_config *spi_cfg,
			    uint8_t cmd, uint16_t addr, void *data, size_t len)
{
	uint8_t access[3];
	struct spi_buf bufs[] = {
		{
			.buf = access,
		},
		{
			.buf = data,
			.len = len
		}
	};
	struct spi_buf_set tx = {
		.buffers = bufs
	};

	access[0] = cmd;

	if (cmd == CY15B102QN_WRITE_CMD || cmd == CY15B102QN_READ_CMD) {
		access[1] = (addr >> 8) & 0xFF;
		access[2] = addr & 0xFF;

		bufs[0].len = 3;
		tx.count = 2;

		if (cmd == CY15B102QN_READ_CMD) {
			struct spi_buf_set rx = {
				.buffers = bufs,
				.count = 2
			};

			return spi_transceive(spi, spi_cfg, &tx, &rx);
		}
	} else {
		tx.count = 1;
	}

	return spi_write(spi, spi_cfg, &tx);
}


static int cy15b102qn_read_id(const struct device *spi,
			     struct spi_config *spi_cfg)
{
	uint8_t id[4];
	int err;

	err = cy15b102qn_access(spi, spi_cfg,
			       CY15B102QN_MANUFACTURER_ID_CMD, 0, &id, 4);
	if (err) {
		printk("Error during ID read\n");
		return -EIO;
	}

        /*
	if (id[0] != 0x04) {
		return -EIO;
	}

	if (id[1] != 0x7f) {
		return -EIO;
	}

	if (id[2] != 0x03) {
		return -EIO;
	}

	if (id[3] != 0x02) {
		return -EIO;
	}
        */

	return 0;
}

static int write_bytes(const struct device *spi, struct spi_config *spi_cfg,
		       uint16_t addr, uint8_t *data, uint32_t num_bytes)
{
	int err;

	/* disable write protect */
	err = cy15b102qn_access(spi, spi_cfg,
			       CY15B102QN_WRITE_ENABLE_CMD, 0, NULL, 0);
	if (err) {
		printk("unable to disable write protect\n");
		return -EIO;
	}

	/* write cmd */
	err = cy15b102qn_access(spi, spi_cfg,
			       CY15B102QN_WRITE_CMD, addr, data, num_bytes);
	if (err) {
		printk("Error during SPI write\n");
		return -EIO;
	}

	return 0;
}

static int read_bytes(const struct device *spi, struct spi_config *spi_cfg,
		      uint16_t addr, uint8_t *data, uint32_t num_bytes)
{
	int err;

	/* read cmd */
	err = cy15b102qn_access(spi, spi_cfg,
			       CY15B102QN_READ_CMD, addr, data, num_bytes);
	if (err) {
		printk("Error during SPI read\n");
		return -EIO;
	}

	return 0;
}

void main(void)
{
	const struct device *spi;
	struct spi_config spi_cfg = {0};

        

	printk("fujitsu FRAM example application\n");

	spi = device_get_binding(SPI_DEV);
	if (!spi) {
		printk("Could not find SPI driver\n");
		return;
	}

        
	int err;
        

        //Setup chip select struct / config
        struct spi_cs_control cs_cfg = {
          .gpio_dev = spi,
          .delay = 10,
          .gpio_pin = 20,
          .gpio_dt_flags = GPIO_ACTIVE_LOW,
          };
        spi_cfg.cs = &cs_cfg;
        

	spi_cfg.operation = SPI_WORD_SET(8);
        //Sets frequency!
	spi_cfg.frequency = 256000U;
        


	err = cy15b102qn_read_id(spi, &spi_cfg);
	if (err) {
		printk("Could not verify FRAM ID\n");
		return;
	}

	/* Do one-byte read/write */
	data[0] = 0xAE;
	err = write_bytes(spi, &spi_cfg, 0x00, data, 1);
	if (err) {
		printk("Error writing to FRAM! errro code (%d)\n", err);
		return;
	} else {
		printk("Wrote 0xAE to address 0x00.\n");
	}

	data[0] = 0x86;
	err = write_bytes(spi, &spi_cfg, 0x01, data, 1);
	if (err) {
		printk("Error writing to FRAM! error code (%d)\n", err);
		return;
	} else {
		printk("Wrote 0x86 to address 0x01.\n");
	}

	data[0] = 0x00;
	err = read_bytes(spi, &spi_cfg, 0x00, data, 1);
	if (err) {
		printk("Error reading from FRAM! error code (%d)\n", err);
		return;
	} else {
		printk("Read 0x%X from address 0x00.\n", data[0]);
	}

	data[0] = 0x00;
	err = read_bytes(spi, &spi_cfg, 0x01, data, 1);
	if (err) {
		printk("Error reading from FRAM! error code (%d)\n", err);
		return;
	} else {
		printk("Read 0x%X from address 0x01.\n", data[0]);
	}

	/* Do multi-byte read/write */
	/* get some random data, and clear out data[] */
	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
		cmp_data[i] = k_cycle_get_32() & 0xFF;
		data[i] = 0x00;
	}

	/* write them to the FRAM */
	err = write_bytes(spi, &spi_cfg, 0x00, cmp_data, sizeof(cmp_data));
	if (err) {
		printk("Error writing to FRAM! error code (%d)\n", err);
		return;
	} else {
		printk("Wrote %d bytes to address 0x00.\n",
		       (uint32_t) sizeof(cmp_data));
	}

	err = read_bytes(spi, &spi_cfg, 0x00, data, sizeof(data));
	if (err) {
		printk("Error reading from FRAM! error code (%d)\n", err);
		return;
	} else {
		printk("Read %d bytes from address 0x00.\n",
		       (uint32_t) sizeof(data));
	}

	err = 0;
	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
		if (cmp_data[i] != data[i]) {
			printk("Data comparison failed @ %d.\n", i);
			err = -EIO;
		}
	}
	if (err == 0) {
		printk("Data comparison successful.\n");
	}
}

nrf52833dk_nrf52833.overlay : 

&spi1 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	
	mosi-pin = <23>;
	miso-pin = <22>;
	sck-pin = <21>;
	clock-frequency = <4000000>;
	
	//cs-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
	spi-device@0 {
                  reg = <0>;
                  label = "CY15B102QN";
				  //cs-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
          };
	
	
	
	//spi-max-frequency = <4000000>;
};

&spi2 {
	status = "disabled";
};

&i2c1 {
    status = "disabled";
};

prj.conf : 

CONFIG_STDOUT_CONSOLE=y
CONFIG_PRINTK=y

CONFIG_SPI=y
#CONFIG_SPI_1=y
#CONFIG_SPI_NRFX=y

CONFIG_GPIO=y

CONFIG_MAIN_STACK_SIZE=4096

zephyr.dts : 

/dts-v1/;

/ {
	#address-cells = < 0x1 >;
	#size-cells = < 0x1 >;
	model = "Nordic nRF52833 DK NRF52833";
	compatible = "nordic,nrf52833-dk-nrf52833";
	chosen {
		zephyr,entropy = &rng;
		zephyr,flash-controller = &flash_controller;
		zephyr,console = &uart0;
		zephyr,shell-uart = &uart0;
		zephyr,uart-mcumgr = &uart0;
		zephyr,bt-mon-uart = &uart0;
		zephyr,bt-c2h-uart = &uart0;
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
	};
	aliases {
		led0 = &led0;
		led1 = &led1;
		led2 = &led2;
		led3 = &led3;
		pwm-led0 = &pwm_led0;
		sw0 = &button0;
		sw1 = &button1;
		sw2 = &button2;
		sw3 = &button3;
	};
	soc {
		#address-cells = < 0x1 >;
		#size-cells = < 0x1 >;
		compatible = "nordic,nRF52833-QIAA", "nordic,nRF52833", "nordic,nRF52", "simple-bus";
		interrupt-parent = < &nvic >;
		ranges;
		nvic: interrupt-controller@e000e100 {
			compatible = "arm,v7m-nvic";
			reg = < 0xe000e100 0xc00 >;
			interrupt-controller;
			#interrupt-cells = < 0x2 >;
			arm,num-irq-priority-bits = < 0x3 >;
			phandle = < 0x1 >;
		};
		systick: timer@e000e010 {
			compatible = "arm,armv7m-systick";
			reg = < 0xe000e010 0x10 >;
			status = "disabled";
		};
		flash_controller: flash-controller@4001e000 {
			compatible = "nordic,nrf52-flash-controller";
			reg = < 0x4001e000 0x1000 >;
			#address-cells = < 0x1 >;
			#size-cells = < 0x1 >;
			label = "NRF_FLASH_DRV_NAME";
			flash0: flash@0 {
				compatible = "soc-nv-flash";
				label = "NRF_FLASH";
				erase-block-size = < 0x1000 >;
				write-block-size = < 0x4 >;
				reg = < 0x0 0x80000 >;
				partitions {
					compatible = "fixed-partitions";
					#address-cells = < 0x1 >;
					#size-cells = < 0x1 >;
					boot_partition: partition@0 {
						label = "mcuboot";
						reg = < 0x0 0xc000 >;
					};
					slot0_partition: partition@c000 {
						label = "image-0";
						reg = < 0xc000 0x32000 >;
					};
					slot1_partition: partition@3e000 {
						label = "image-1";
						reg = < 0x3e000 0x32000 >;
					};
					scratch_partition: partition@70000 {
						label = "image-scratch";
						reg = < 0x70000 0xa000 >;
					};
					storage_partition: partition@7a000 {
						label = "storage";
						reg = < 0x7a000 0x6000 >;
					};
				};
			};
		};
		sram0: memory@20000000 {
			compatible = "mmio-sram";
			reg = < 0x20000000 0x20000 >;
		};
		adc: adc@40007000 {
			compatible = "nordic,nrf-saadc";
			reg = < 0x40007000 0x1000 >;
			interrupts = < 0x7 0x1 >;
			status = "okay";
			label = "ADC_0";
			#io-channel-cells = < 0x1 >;
		};
		clock: clock@40000000 {
			compatible = "nordic,nrf-clock";
			reg = < 0x40000000 0x1000 >;
			interrupts = < 0x0 0x1 >;
			status = "okay";
			label = "CLOCK";
		};
		ecb: ecb@4000e000 {
			compatible = "nordic,nrf-ecb";
			reg = < 0x4000e000 0x1000 >;
			interrupts = < 0xe 0x1 >;
			status = "okay";
			label = "ECB";
		};
		uart0: uart@40002000 {
			reg = < 0x40002000 0x1000 >;
			interrupts = < 0x2 0x1 >;
			status = "okay";
			label = "UART_0";
			compatible = "nordic,nrf-uarte";
			current-speed = < 0x1c200 >;
			tx-pin = < 0x6 >;
			rx-pin = < 0x8 >;
			rts-pin = < 0x5 >;
			cts-pin = < 0x7 >;
		};
		uart1: arduino_serial: uart@40028000 {
			compatible = "nordic,nrf-uarte";
			reg = < 0x40028000 0x1000 >;
			interrupts = < 0x28 0x1 >;
			status = "okay";
			label = "UART_1";
			current-speed = < 0x1c200 >;
			rx-pin = < 0x21 >;
			tx-pin = < 0x22 >;
		};
		gpiote: gpiote@40006000 {
			compatible = "nordic,nrf-gpiote";
			reg = < 0x40006000 0x1000 >;
			interrupts = < 0x6 0x5 >;
			status = "okay";
			label = "GPIOTE_0";
		};
		gpio0: gpio@50000000 {
			compatible = "nordic,nrf-gpio";
			gpio-controller;
			reg = < 0x50000000 0x200 0x50000500 0x300 >;
			#gpio-cells = < 0x2 >;
			label = "GPIO_0";
			status = "okay";
			port = < 0x0 >;
			phandle = < 0x4 >;
		};
		gpio1: gpio@50000300 {
			compatible = "nordic,nrf-gpio";
			gpio-controller;
			reg = < 0x50000300 0x200 0x50000800 0x300 >;
			#gpio-cells = < 0x2 >;
			ngpios = < 0xa >;
			label = "GPIO_1";
			status = "okay";
			port = < 0x1 >;
			phandle = < 0x6 >;
		};
		i2c0: arduino_i2c: i2c@40003000 {
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40003000 0x1000 >;
			clock-frequency = < 0x186a0 >;
			interrupts = < 0x3 0x1 >;
			status = "okay";
			label = "I2C_0";
			compatible = "nordic,nrf-twi";
			sda-pin = < 0x1a >;
			scl-pin = < 0x1b >;
		};
		i2c1: i2c@40004000 {
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40004000 0x1000 >;
			clock-frequency = < 0x186a0 >;
			interrupts = < 0x4 0x1 >;
			status = "disabled";
			label = "I2C_1";
			compatible = "nordic,nrf-twi";
			sda-pin = < 0x1e >;
			scl-pin = < 0x1f >;
		};
		pwm0: pwm@4001c000 {
			compatible = "nordic,nrf-pwm";
			reg = < 0x4001c000 0x1000 >;
			interrupts = < 0x1c 0x1 >;
			status = "okay";
			label = "PWM_0";
			#pwm-cells = < 0x1 >;
			ch0-pin = < 0xd >;
			ch0-inverted;
			phandle = < 0x5 >;
		};
		pwm1: pwm@40021000 {
			compatible = "nordic,nrf-pwm";
			reg = < 0x40021000 0x1000 >;
			interrupts = < 0x21 0x1 >;
			status = "disabled";
			label = "PWM_1";
			#pwm-cells = < 0x1 >;
		};
		pwm2: pwm@40022000 {
			compatible = "nordic,nrf-pwm";
			reg = < 0x40022000 0x1000 >;
			interrupts = < 0x22 0x1 >;
			status = "disabled";
			label = "PWM_2";
			#pwm-cells = < 0x1 >;
		};
		pwm3: pwm@4002d000 {
			compatible = "nordic,nrf-pwm";
			reg = < 0x4002d000 0x1000 >;
			interrupts = < 0x2d 0x1 >;
			status = "disabled";
			label = "PWM_3";
			#pwm-cells = < 0x1 >;
		};
		qdec: qdec@40012000 {
			compatible = "nordic,nrf-qdec";
			reg = < 0x40012000 0x1000 >;
			interrupts = < 0x12 0x1 >;
			status = "disabled";
			label = "QDEC";
		};
		rng: random@4000d000 {
			compatible = "nordic,nrf-rng";
			reg = < 0x4000d000 0x1000 >;
			interrupts = < 0xd 0x1 >;
			status = "okay";
			label = "RNG";
		};
		spi0: spi@40003000 {
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40003000 0x1000 >;
			interrupts = < 0x3 0x1 >;
			status = "disabled";
			label = "SPI_0";
			compatible = "nordic,nrf-spi";
			sck-pin = < 0x1b >;
			mosi-pin = < 0x1a >;
			miso-pin = < 0x1d >;
		};
		spi1: spi@40004000 {
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40004000 0x1000 >;
			interrupts = < 0x4 0x1 >;
			status = "okay";
			label = "SPI_1";
			compatible = "nordic,nrf-spim";
			sck-pin = < 0x15 >;
			mosi-pin = < 0x17 >;
			miso-pin = < 0x16 >;
			clock-frequency = < 0x3d0900 >;
			spi-device@0 {
				reg = < 0x0 >;
				label = "CY15B102QN";
			};
		};
		spi2: spi@40023000 {
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40023000 0x1000 >;
			interrupts = < 0x23 0x1 >;
			status = "disabled";
			label = "SPI_2";
		};
		spi3: arduino_spi: spi@4002f000 {
			compatible = "nordic,nrf-spim";
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x4002f000 0x1000 >;
			interrupts = < 0x2f 0x1 >;
			status = "okay";
			label = "SPI_3";
			sck-pin = < 0x17 >;
			miso-pin = < 0x16 >;
			mosi-pin = < 0x15 >;
			cs-gpios = < &arduino_header 0x10 0x1 >;
		};
		rtc0: rtc@4000b000 {
			compatible = "nordic,nrf-rtc";
			reg = < 0x4000b000 0x1000 >;
			cc-num = < 0x3 >;
			interrupts = < 0xb 0x1 >;
			status = "okay";
			clock-frequency = < 0x8000 >;
			prescaler = < 0x1 >;
			label = "RTC_0";
		};
		rtc1: rtc@40011000 {
			compatible = "nordic,nrf-rtc";
			reg = < 0x40011000 0x1000 >;
			cc-num = < 0x4 >;
			interrupts = < 0x11 0x1 >;
			status = "okay";
			clock-frequency = < 0x8000 >;
			prescaler = < 0x1 >;
			label = "RTC_1";
		};
		rtc2: rtc@40024000 {
			compatible = "nordic,nrf-rtc";
			reg = < 0x40024000 0x1000 >;
			cc-num = < 0x4 >;
			interrupts = < 0x24 0x1 >;
			status = "okay";
			clock-frequency = < 0x8000 >;
			prescaler = < 0x1 >;
			label = "RTC_2";
		};
		timer0: timer@40008000 {
			compatible = "nordic,nrf-timer";
			status = "okay";
			reg = < 0x40008000 0x1000 >;
			cc-num = < 0x4 >;
			interrupts = < 0x8 0x1 >;
			prescaler = < 0x0 >;
			label = "TIMER_0";
		};
		timer1: timer@40009000 {
			compatible = "nordic,nrf-timer";
			status = "okay";
			reg = < 0x40009000 0x1000 >;
			cc-num = < 0x4 >;
			interrupts = < 0x9 0x1 >;
			prescaler = < 0x0 >;
			label = "TIMER_1";
		};
		timer2: timer@4000a000 {
			compatible = "nordic,nrf-timer";
			status = "okay";
			reg = < 0x4000a000 0x1000 >;
			cc-num = < 0x4 >;
			interrupts = < 0xa 0x1 >;
			prescaler = < 0x0 >;
			label = "TIMER_2";
			phandle = < 0x3 >;
		};
		timer3: timer@4001a000 {
			compatible = "nordic,nrf-timer";
			status = "okay";
			reg = < 0x4001a000 0x1000 >;
			cc-num = < 0x6 >;
			interrupts = < 0x1a 0x1 >;
			prescaler = < 0x0 >;
			label = "TIMER_3";
		};
		timer4: timer@4001b000 {
			compatible = "nordic,nrf-timer";
			status = "okay";
			reg = < 0x4001b000 0x1000 >;
			cc-num = < 0x6 >;
			interrupts = < 0x1b 0x1 >;
			prescaler = < 0x0 >;
			label = "TIMER_4";
		};
		temp: temp@4000c000 {
			compatible = "nordic,nrf-temp";
			reg = < 0x4000c000 0x1000 >;
			interrupts = < 0xc 0x1 >;
			status = "okay";
			label = "TEMP_0";
		};
		usbd: usbd@40027000 {
			compatible = "nordic,nrf-usbd";
			reg = < 0x40027000 0x1000 >;
			interrupts = < 0x27 0x1 >;
			num-bidir-endpoints = < 0x1 >;
			num-in-endpoints = < 0x7 >;
			num-out-endpoints = < 0x7 >;
			num-isoin-endpoints = < 0x1 >;
			num-isoout-endpoints = < 0x1 >;
			status = "okay";
			label = "USBD";
		};
		wdt: wdt0: watchdog@40010000 {
			compatible = "nordic,nrf-watchdog";
			reg = < 0x40010000 0x1000 >;
			interrupts = < 0x10 0x1 >;
			status = "okay";
			label = "WDT";
		};
		ficr: ficr@10000000 {
			compatible = "nordic,nrf-ficr";
			reg = < 0x10000000 0x1000 >;
			status = "okay";
		};
		uicr: uicr@10001000 {
			compatible = "nordic,nrf-uicr";
			reg = < 0x10001000 0x1000 >;
			status = "okay";
		};
		radio: radio@40001000 {
			compatible = "nordic,nrf-radio";
			reg = < 0x40001000 0x1000 >;
			interrupts = < 0x1 0x1 >;
			status = "okay";
			dfe-ant-num = < 0x0 >;
		};
	};
	cpus {
		#address-cells = < 0x1 >;
		#size-cells = < 0x0 >;
		cpu@0 {
			device_type = "cpu";
			compatible = "arm,cortex-m4f";
			reg = < 0x0 >;
		};
	};
	sw_pwm: sw-pwm {
		compatible = "nordic,nrf-sw-pwm";
		status = "disabled";
		label = "SW_PWM";
		generator = < &timer2 >;
		channel-count = < 0x3 >;
		clock-prescaler = < 0x0 >;
		ppi-base = < 0x0 >;
		gpiote-base = < 0x0 >;
		#pwm-cells = < 0x1 >;
	};
	leds {
		compatible = "gpio-leds";
		led0: led_0 {
			gpios = < &gpio0 0xd 0x1 >;
			label = "Green LED 0";
		};
		led1: led_1 {
			gpios = < &gpio0 0xe 0x1 >;
			label = "Green LED 1";
		};
		led2: led_2 {
			gpios = < &gpio0 0xf 0x1 >;
			label = "Green LED 2";
		};
		led3: led_3 {
			gpios = < &gpio0 0x10 0x1 >;
			label = "Green LED 3";
		};
	};
	pwmleds {
		compatible = "pwm-leds";
		pwm_led0: pwm_led_0 {
			pwms = < &pwm0 0xd >;
		};
	};
	buttons {
		compatible = "gpio-keys";
		button0: button_0 {
			gpios = < &gpio0 0xb 0x11 >;
			label = "Push button switch 0";
		};
		button1: button_1 {
			gpios = < &gpio0 0xc 0x11 >;
			label = "Push button switch 1";
		};
		button2: button_2 {
			gpios = < &gpio0 0x18 0x11 >;
			label = "Push button switch 2";
		};
		button3: button_3 {
			gpios = < &gpio0 0x19 0x11 >;
			label = "Push button switch 3";
		};
	};
	arduino_header: connector {
		compatible = "arduino-header-r3";
		#gpio-cells = < 0x2 >;
		gpio-map-mask = < 0xffffffff 0xffffffc0 >;
		gpio-map-pass-thru = < 0x0 0x3f >;
		gpio-map = < 0x0 0x0 &gpio0 0x3 0x0 >, < 0x1 0x0 &gpio0 0x4 0x0 >, < 0x2 0x0 &gpio0 0x1c 0x0 >, < 0x3 0x0 &gpio0 0x1d 0x0 >, < 0x4 0x0 &gpio0 0x1e 0x0 >, < 0x5 0x0 &gpio0 0x1f 0x0 >, < 0x6 0x0 &gpio1 0x1 0x0 >, < 0x7 0x0 &gpio1 0x2 0x0 >, < 0x8 0x0 &gpio1 0x3 0x0 >, < 0x9 0x0 &gpio1 0x4 0x0 >, < 0xa 0x0 &gpio1 0x5 0x0 >, < 0xb 0x0 &gpio1 0x6 0x0 >, < 0xc 0x0 &gpio1 0x7 0x0 >, < 0xd 0x0 &gpio1 0x8 0x0 >, < 0xe 0x0 &gpio0 0x11 0x0 >, < 0xf 0x0 &gpio0 0x13 0x0 >, < 0x10 0x0 &gpio0 0x14 0x0 >, < 0x11 0x0 &gpio0 0x15 0x0 >, < 0x12 0x0 &gpio0 0x16 0x0 >, < 0x13 0x0 &gpio0 0x17 0x0 >, < 0x14 0x0 &gpio0 0x1a 0x0 >, < 0x15 0x0 &gpio0 0x1b 0x0 >;
		phandle = < 0x2 >;
	};
};

CMakeLists.txt : 

# SPDX-License-Identifier: Apache-2.0

set(TEST_DTC_OVERLAY_FILE
  ${CMAKE_CURRENT_SOURCE_DIR}/nrf52833dk_nrf52833.overlay
)

set(PRJ_CONF_FILE
  prj.conf
  ${CMAKE_CURRENT_LIST_DIR}/prj.conf
)

cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(spi_fujitsu_fram)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

SDK: nRF Connect SDK v1.5.1

Parents
  • Hello, Jansens!

    The SPI documentation specifies that a gpio node is supposed to be used when instantiating a spi_cs_control structure. I see that you are using the SPI device for this, which I believe won't work. Could you try to use a gpio node (like they do in the documentation) instead?

    Please report back your results!

    Best regards,
    Carl Richard

  • Hi Carl,

    That did help, but I am still having issues with not seeing anything being output by MOSI line I have hooked up to my scope. See my cy15b102qn_read_id function to see where it is failing, basically when I make the call to spi_write using my OPCODE, I never see anything on MOSI. I have followed through the program using the debugger and am unable to figure out why it is not sending the OPCODE over MOSI.

    I will post my updated code and config below:
    main.c: 

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <errno.h>
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <device.h>
    #include <drivers/spi.h>
    
    /**
     * @file Sample app using the Cypress CY15B102QN (driver based on Fujitsu MB85RS64V) FRAM through SPI.
     */
    
    #define CY15B102QN_MANUFACTURER_ID_CMD 0x9f
    #define CY15B102QN_WRITE_ENABLE_CMD 0x06
    #define CY15B102QN_READ_CMD 0x03
    #define CY15B102QN_WRITE_CMD 0x02
    #define MAX_USER_DATA_LENGTH 1024
    
    #define SPI_DEV DT_LABEL(DT_NODELABEL(spi1))
    
    static uint8_t data[MAX_USER_DATA_LENGTH], cmp_data[MAX_USER_DATA_LENGTH];
    
    static int cy15b102qn_access(const struct device *spi,
    			    struct spi_config *spi_cfg,
    			    uint8_t cmd, uint16_t addr, void *data, size_t len)
    {
    	uint8_t access[3] = {0,0,0};
    	struct spi_buf bufs[] = {
    		{
    			.buf = access,
                            .len = len //DO I NEED THIS? I ADDED!
    		},
    		{
    			.buf = data,
    			.len = len
    		}
    	};
    	struct spi_buf_set tx = {
    		.buffers = bufs
    	};
    
    	access[0] = cmd;
    
    	if (cmd == CY15B102QN_WRITE_CMD || cmd == CY15B102QN_READ_CMD) {
    		access[1] = (addr >> 8) & 0xFF;
    		access[2] = addr & 0xFF;
    
    		bufs[0].len = 3;
    		tx.count = 2;
    
    		if (cmd == CY15B102QN_READ_CMD) {
    			struct spi_buf_set rx = {
    				.buffers = bufs,
    				.count = 2
    			};
    
    			return spi_transceive(spi, spi_cfg, &tx, &rx);
    		}
    	} else {
    		tx.count = 1;
                    printk("tx.buffers.buf: 0x%X\n", tx.buffers->buf);
                    
    	}
    
    	return spi_write(spi, spi_cfg, &tx);
    }
    
    
    static int cy15b102qn_read_id(const struct device *spi,
    			     struct spi_config *spi_cfg)
    {
    	uint8_t id[9];
    	int err;
    
            printk("initalized id[0]: 0x%X\n", id[0]);
    
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_MANUFACTURER_ID_CMD, 0, &id, 9);
    	if (err) {
    		printk("Error during ID read\n");
    		return -EIO;
    	}
    
            
            //CY15B102QN-50SXE DEVICE ID: 7F7F7F7F7F7FC22A60
            printk("read id[0]: 0x%X\n", id[0]);
            
    	if (id[0] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[1] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[2] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[3] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[4] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[5] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[6] != 0xC2) {
    		return -EIO;
    	}
    
            if (id[7] != 0x2A) {
    		return -EIO;
    	}
    
            if (id[8] != 0x60) {
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int write_bytes(const struct device *spi, struct spi_config *spi_cfg,
    		       uint16_t addr, uint8_t *data, uint32_t num_bytes)
    {
    	int err;
    
    	/* disable write protect */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_WRITE_ENABLE_CMD, 0, NULL, 0);
    	if (err) {
    		printk("unable to disable write protect\n");
    		return -EIO;
    	}
    
    	/* write cmd */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_WRITE_CMD, addr, data, num_bytes);
    	if (err) {
    		printk("Error during SPI write\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int read_bytes(const struct device *spi, struct spi_config *spi_cfg,
    		      uint16_t addr, uint8_t *data, uint32_t num_bytes)
    {
    	int err;
    
    	/* read cmd */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_READ_CMD, addr, data, num_bytes);
    	if (err) {
    		printk("Error during SPI read\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    void main(void)
    {
    	const struct device *spi;
    	struct spi_config spi_cfg = {0};
    
            //Setup chip select struct / config
            struct spi_cs_control *cs_cfg =
              &(struct spi_cs_control) {
                    .gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
                    .delay = 2,
                    .gpio_pin = 20,
                    .gpio_dt_flags = GPIO_ACTIVE_LOW
            };
            spi_cfg.cs = cs_cfg;
    
            //Set word size
            spi_cfg.operation = SPI_WORD_SET(8);
            //Sets frequency!
    	spi_cfg.frequency = 256000U;
            //spi_cfg.frequency = 4000000U;
    
    	printk("fujitsu FRAM example application\n");
    
    	spi = device_get_binding(SPI_DEV);
    	if (!spi) {
    		printk("Could not find SPI driver\n");
    		return;
    	}
    
    	int err;
    	err = cy15b102qn_read_id(spi, &spi_cfg);
    	if (err) {
    		printk("Could not verify FRAM ID\n");
    		return;
    	}
    
    	/* Do one-byte read/write */
    	data[0] = 0xAE;
    	err = write_bytes(spi, &spi_cfg, 0x00, data, 1);
    	if (err) {
    		printk("Error writing to FRAM! errro code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote 0xAE to address 0x00.\n");
    	}
    
    	data[0] = 0x86;
    	err = write_bytes(spi, &spi_cfg, 0x01, data, 1);
    	if (err) {
    		printk("Error writing to FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote 0x86 to address 0x01.\n");
    	}
    
    	data[0] = 0x00;
    	err = read_bytes(spi, &spi_cfg, 0x00, data, 1);
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read 0x%X from address 0x00.\n", data[0]);
    	}
    
    	data[0] = 0x00;
    	err = read_bytes(spi, &spi_cfg, 0x01, data, 1);
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read 0x%X from address 0x01.\n", data[0]);
    	}
    
    	/* Do multi-byte read/write */
    	/* get some random data, and clear out data[] */
    	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
    		cmp_data[i] = k_cycle_get_32() & 0xFF;
    		data[i] = 0x00;
    	}
    
    	/* write them to the FRAM */
    	err = write_bytes(spi, &spi_cfg, 0x00, cmp_data, sizeof(cmp_data));
    	if (err) {
    		printk("Error writing to FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote %d bytes to address 0x00.\n",
    		       (uint32_t) sizeof(cmp_data));
    	}
    
    	err = read_bytes(spi, &spi_cfg, 0x00, data, sizeof(data));
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read %d bytes from address 0x00.\n",
    		       (uint32_t) sizeof(data));
    	}
    
    	err = 0;
    	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
    		if (cmp_data[i] != data[i]) {
    			printk("Data comparison failed @ %d.\n", i);
    			err = -EIO;
    		}
    	}
    	if (err == 0) {
    		printk("Data comparison successful.\n");
    	}
    }


    nrf52833dk_nrf52833.overlay : 
    &spi1 {
    	compatible = "nordic,nrf-spim";
    	status = "okay";
    	
    	mosi-pin = <23>;
    	miso-pin = <22>;
    	sck-pin = <21>;
    	clock-frequency = <4000000>;
    	
    	cs-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
    	
    	
    	
    };
    
    &spi2 {
    	status = "disabled";
    };
    
    &i2c1 {
        status = "disabled";
    };
    
    

    prj.conf : 

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_PRINTK=y
    
    CONFIG_SPI=y
    #CONFIG_SPI_1=y
    #CONFIG_SPI_NRFX=y
    
    CONFIG_GPIO=y
    
    CONFIG_MAIN_STACK_SIZE=4096

    zephyr.dts : 

    /dts-v1/;
    
    / {
    	#address-cells = < 0x1 >;
    	#size-cells = < 0x1 >;
    	model = "Nordic nRF52833 DK NRF52833";
    	compatible = "nordic,nrf52833-dk-nrf52833";
    	chosen {
    		zephyr,entropy = &rng;
    		zephyr,flash-controller = &flash_controller;
    		zephyr,console = &uart0;
    		zephyr,shell-uart = &uart0;
    		zephyr,uart-mcumgr = &uart0;
    		zephyr,bt-mon-uart = &uart0;
    		zephyr,bt-c2h-uart = &uart0;
    		zephyr,sram = &sram0;
    		zephyr,flash = &flash0;
    		zephyr,code-partition = &slot0_partition;
    	};
    	aliases {
    		led0 = &led0;
    		led1 = &led1;
    		led2 = &led2;
    		led3 = &led3;
    		pwm-led0 = &pwm_led0;
    		sw0 = &button0;
    		sw1 = &button1;
    		sw2 = &button2;
    		sw3 = &button3;
    	};
    	soc {
    		#address-cells = < 0x1 >;
    		#size-cells = < 0x1 >;
    		compatible = "nordic,nRF52833-QIAA", "nordic,nRF52833", "nordic,nRF52", "simple-bus";
    		interrupt-parent = < &nvic >;
    		ranges;
    		nvic: interrupt-controller@e000e100 {
    			compatible = "arm,v7m-nvic";
    			reg = < 0xe000e100 0xc00 >;
    			interrupt-controller;
    			#interrupt-cells = < 0x2 >;
    			arm,num-irq-priority-bits = < 0x3 >;
    			phandle = < 0x1 >;
    		};
    		systick: timer@e000e010 {
    			compatible = "arm,armv7m-systick";
    			reg = < 0xe000e010 0x10 >;
    			status = "disabled";
    		};
    		flash_controller: flash-controller@4001e000 {
    			compatible = "nordic,nrf52-flash-controller";
    			reg = < 0x4001e000 0x1000 >;
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x1 >;
    			label = "NRF_FLASH_DRV_NAME";
    			flash0: flash@0 {
    				compatible = "soc-nv-flash";
    				label = "NRF_FLASH";
    				erase-block-size = < 0x1000 >;
    				write-block-size = < 0x4 >;
    				reg = < 0x0 0x80000 >;
    				partitions {
    					compatible = "fixed-partitions";
    					#address-cells = < 0x1 >;
    					#size-cells = < 0x1 >;
    					boot_partition: partition@0 {
    						label = "mcuboot";
    						reg = < 0x0 0xc000 >;
    					};
    					slot0_partition: partition@c000 {
    						label = "image-0";
    						reg = < 0xc000 0x32000 >;
    					};
    					slot1_partition: partition@3e000 {
    						label = "image-1";
    						reg = < 0x3e000 0x32000 >;
    					};
    					scratch_partition: partition@70000 {
    						label = "image-scratch";
    						reg = < 0x70000 0xa000 >;
    					};
    					storage_partition: partition@7a000 {
    						label = "storage";
    						reg = < 0x7a000 0x6000 >;
    					};
    				};
    			};
    		};
    		sram0: memory@20000000 {
    			compatible = "mmio-sram";
    			reg = < 0x20000000 0x20000 >;
    		};
    		adc: adc@40007000 {
    			compatible = "nordic,nrf-saadc";
    			reg = < 0x40007000 0x1000 >;
    			interrupts = < 0x7 0x1 >;
    			status = "okay";
    			label = "ADC_0";
    			#io-channel-cells = < 0x1 >;
    		};
    		clock: clock@40000000 {
    			compatible = "nordic,nrf-clock";
    			reg = < 0x40000000 0x1000 >;
    			interrupts = < 0x0 0x1 >;
    			status = "okay";
    			label = "CLOCK";
    		};
    		ecb: ecb@4000e000 {
    			compatible = "nordic,nrf-ecb";
    			reg = < 0x4000e000 0x1000 >;
    			interrupts = < 0xe 0x1 >;
    			status = "okay";
    			label = "ECB";
    		};
    		uart0: uart@40002000 {
    			reg = < 0x40002000 0x1000 >;
    			interrupts = < 0x2 0x1 >;
    			status = "okay";
    			label = "UART_0";
    			compatible = "nordic,nrf-uarte";
    			current-speed = < 0x1c200 >;
    			tx-pin = < 0x6 >;
    			rx-pin = < 0x8 >;
    			rts-pin = < 0x5 >;
    			cts-pin = < 0x7 >;
    		};
    		uart1: arduino_serial: uart@40028000 {
    			compatible = "nordic,nrf-uarte";
    			reg = < 0x40028000 0x1000 >;
    			interrupts = < 0x28 0x1 >;
    			status = "okay";
    			label = "UART_1";
    			current-speed = < 0x1c200 >;
    			rx-pin = < 0x21 >;
    			tx-pin = < 0x22 >;
    		};
    		gpiote: gpiote@40006000 {
    			compatible = "nordic,nrf-gpiote";
    			reg = < 0x40006000 0x1000 >;
    			interrupts = < 0x6 0x5 >;
    			status = "okay";
    			label = "GPIOTE_0";
    		};
    		gpio0: gpio@50000000 {
    			compatible = "nordic,nrf-gpio";
    			gpio-controller;
    			reg = < 0x50000000 0x200 0x50000500 0x300 >;
    			#gpio-cells = < 0x2 >;
    			label = "GPIO_0";
    			status = "okay";
    			port = < 0x0 >;
    			phandle = < 0x2 >;
    		};
    		gpio1: gpio@50000300 {
    			compatible = "nordic,nrf-gpio";
    			gpio-controller;
    			reg = < 0x50000300 0x200 0x50000800 0x300 >;
    			#gpio-cells = < 0x2 >;
    			ngpios = < 0xa >;
    			label = "GPIO_1";
    			status = "okay";
    			port = < 0x1 >;
    			phandle = < 0x6 >;
    		};
    		i2c0: arduino_i2c: i2c@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			clock-frequency = < 0x186a0 >;
    			interrupts = < 0x3 0x1 >;
    			status = "okay";
    			label = "I2C_0";
    			compatible = "nordic,nrf-twi";
    			sda-pin = < 0x1a >;
    			scl-pin = < 0x1b >;
    		};
    		i2c1: i2c@40004000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			clock-frequency = < 0x186a0 >;
    			interrupts = < 0x4 0x1 >;
    			status = "disabled";
    			label = "I2C_1";
    			compatible = "nordic,nrf-twi";
    			sda-pin = < 0x1e >;
    			scl-pin = < 0x1f >;
    		};
    		pwm0: pwm@4001c000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x4001c000 0x1000 >;
    			interrupts = < 0x1c 0x1 >;
    			status = "okay";
    			label = "PWM_0";
    			#pwm-cells = < 0x1 >;
    			ch0-pin = < 0xd >;
    			ch0-inverted;
    			phandle = < 0x5 >;
    		};
    		pwm1: pwm@40021000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x40021000 0x1000 >;
    			interrupts = < 0x21 0x1 >;
    			status = "disabled";
    			label = "PWM_1";
    			#pwm-cells = < 0x1 >;
    		};
    		pwm2: pwm@40022000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x40022000 0x1000 >;
    			interrupts = < 0x22 0x1 >;
    			status = "disabled";
    			label = "PWM_2";
    			#pwm-cells = < 0x1 >;
    		};
    		pwm3: pwm@4002d000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x4002d000 0x1000 >;
    			interrupts = < 0x2d 0x1 >;
    			status = "disabled";
    			label = "PWM_3";
    			#pwm-cells = < 0x1 >;
    		};
    		qdec: qdec@40012000 {
    			compatible = "nordic,nrf-qdec";
    			reg = < 0x40012000 0x1000 >;
    			interrupts = < 0x12 0x1 >;
    			status = "disabled";
    			label = "QDEC";
    		};
    		rng: random@4000d000 {
    			compatible = "nordic,nrf-rng";
    			reg = < 0x4000d000 0x1000 >;
    			interrupts = < 0xd 0x1 >;
    			status = "okay";
    			label = "RNG";
    		};
    		spi0: spi@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			interrupts = < 0x3 0x1 >;
    			status = "disabled";
    			label = "SPI_0";
    			compatible = "nordic,nrf-spi";
    			sck-pin = < 0x1b >;
    			mosi-pin = < 0x1a >;
    			miso-pin = < 0x1d >;
    		};
    		spi1: spi@40004000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			interrupts = < 0x4 0x1 >;
    			status = "okay";
    			label = "SPI_1";
    			compatible = "nordic,nrf-spim";
    			sck-pin = < 0x15 >;
    			mosi-pin = < 0x17 >;
    			miso-pin = < 0x16 >;
    			clock-frequency = < 0x3d0900 >;
    			cs-gpios = < &gpio0 0x14 0x1 >;
    		};
    		spi2: spi@40023000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40023000 0x1000 >;
    			interrupts = < 0x23 0x1 >;
    			status = "disabled";
    			label = "SPI_2";
    		};
    		spi3: arduino_spi: spi@4002f000 {
    			compatible = "nordic,nrf-spim";
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x4002f000 0x1000 >;
    			interrupts = < 0x2f 0x1 >;
    			status = "okay";
    			label = "SPI_3";
    			sck-pin = < 0x17 >;
    			miso-pin = < 0x16 >;
    			mosi-pin = < 0x15 >;
    			cs-gpios = < &arduino_header 0x10 0x1 >;
    		};
    		rtc0: rtc@4000b000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x4000b000 0x1000 >;
    			cc-num = < 0x3 >;
    			interrupts = < 0xb 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_0";
    		};
    		rtc1: rtc@40011000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x40011000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x11 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_1";
    		};
    		rtc2: rtc@40024000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x40024000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x24 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_2";
    		};
    		timer0: timer@40008000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x40008000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x8 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_0";
    		};
    		timer1: timer@40009000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x40009000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x9 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_1";
    		};
    		timer2: timer@4000a000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4000a000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0xa 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_2";
    			phandle = < 0x4 >;
    		};
    		timer3: timer@4001a000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4001a000 0x1000 >;
    			cc-num = < 0x6 >;
    			interrupts = < 0x1a 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_3";
    		};
    		timer4: timer@4001b000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4001b000 0x1000 >;
    			cc-num = < 0x6 >;
    			interrupts = < 0x1b 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_4";
    		};
    		temp: temp@4000c000 {
    			compatible = "nordic,nrf-temp";
    			reg = < 0x4000c000 0x1000 >;
    			interrupts = < 0xc 0x1 >;
    			status = "okay";
    			label = "TEMP_0";
    		};
    		usbd: usbd@40027000 {
    			compatible = "nordic,nrf-usbd";
    			reg = < 0x40027000 0x1000 >;
    			interrupts = < 0x27 0x1 >;
    			num-bidir-endpoints = < 0x1 >;
    			num-in-endpoints = < 0x7 >;
    			num-out-endpoints = < 0x7 >;
    			num-isoin-endpoints = < 0x1 >;
    			num-isoout-endpoints = < 0x1 >;
    			status = "okay";
    			label = "USBD";
    		};
    		wdt: wdt0: watchdog@40010000 {
    			compatible = "nordic,nrf-watchdog";
    			reg = < 0x40010000 0x1000 >;
    			interrupts = < 0x10 0x1 >;
    			status = "okay";
    			label = "WDT";
    		};
    		ficr: ficr@10000000 {
    			compatible = "nordic,nrf-ficr";
    			reg = < 0x10000000 0x1000 >;
    			status = "okay";
    		};
    		uicr: uicr@10001000 {
    			compatible = "nordic,nrf-uicr";
    			reg = < 0x10001000 0x1000 >;
    			status = "okay";
    		};
    		radio: radio@40001000 {
    			compatible = "nordic,nrf-radio";
    			reg = < 0x40001000 0x1000 >;
    			interrupts = < 0x1 0x1 >;
    			status = "okay";
    			dfe-ant-num = < 0x0 >;
    		};
    	};
    	cpus {
    		#address-cells = < 0x1 >;
    		#size-cells = < 0x0 >;
    		cpu@0 {
    			device_type = "cpu";
    			compatible = "arm,cortex-m4f";
    			reg = < 0x0 >;
    		};
    	};
    	sw_pwm: sw-pwm {
    		compatible = "nordic,nrf-sw-pwm";
    		status = "disabled";
    		label = "SW_PWM";
    		generator = < &timer2 >;
    		channel-count = < 0x3 >;
    		clock-prescaler = < 0x0 >;
    		ppi-base = < 0x0 >;
    		gpiote-base = < 0x0 >;
    		#pwm-cells = < 0x1 >;
    	};
    	leds {
    		compatible = "gpio-leds";
    		led0: led_0 {
    			gpios = < &gpio0 0xd 0x1 >;
    			label = "Green LED 0";
    		};
    		led1: led_1 {
    			gpios = < &gpio0 0xe 0x1 >;
    			label = "Green LED 1";
    		};
    		led2: led_2 {
    			gpios = < &gpio0 0xf 0x1 >;
    			label = "Green LED 2";
    		};
    		led3: led_3 {
    			gpios = < &gpio0 0x10 0x1 >;
    			label = "Green LED 3";
    		};
    	};
    	pwmleds {
    		compatible = "pwm-leds";
    		pwm_led0: pwm_led_0 {
    			pwms = < &pwm0 0xd >;
    		};
    	};
    	buttons {
    		compatible = "gpio-keys";
    		button0: button_0 {
    			gpios = < &gpio0 0xb 0x11 >;
    			label = "Push button switch 0";
    		};
    		button1: button_1 {
    			gpios = < &gpio0 0xc 0x11 >;
    			label = "Push button switch 1";
    		};
    		button2: button_2 {
    			gpios = < &gpio0 0x18 0x11 >;
    			label = "Push button switch 2";
    		};
    		button3: button_3 {
    			gpios = < &gpio0 0x19 0x11 >;
    			label = "Push button switch 3";
    		};
    	};
    	arduino_header: connector {
    		compatible = "arduino-header-r3";
    		#gpio-cells = < 0x2 >;
    		gpio-map-mask = < 0xffffffff 0xffffffc0 >;
    		gpio-map-pass-thru = < 0x0 0x3f >;
    		gpio-map = < 0x0 0x0 &gpio0 0x3 0x0 >, < 0x1 0x0 &gpio0 0x4 0x0 >, < 0x2 0x0 &gpio0 0x1c 0x0 >, < 0x3 0x0 &gpio0 0x1d 0x0 >, < 0x4 0x0 &gpio0 0x1e 0x0 >, < 0x5 0x0 &gpio0 0x1f 0x0 >, < 0x6 0x0 &gpio1 0x1 0x0 >, < 0x7 0x0 &gpio1 0x2 0x0 >, < 0x8 0x0 &gpio1 0x3 0x0 >, < 0x9 0x0 &gpio1 0x4 0x0 >, < 0xa 0x0 &gpio1 0x5 0x0 >, < 0xb 0x0 &gpio1 0x6 0x0 >, < 0xc 0x0 &gpio1 0x7 0x0 >, < 0xd 0x0 &gpio1 0x8 0x0 >, < 0xe 0x0 &gpio0 0x11 0x0 >, < 0xf 0x0 &gpio0 0x13 0x0 >, < 0x10 0x0 &gpio0 0x14 0x0 >, < 0x11 0x0 &gpio0 0x15 0x0 >, < 0x12 0x0 &gpio0 0x16 0x0 >, < 0x13 0x0 &gpio0 0x17 0x0 >, < 0x14 0x0 &gpio0 0x1a 0x0 >, < 0x15 0x0 &gpio0 0x1b 0x0 >;
    		phandle = < 0x3 >;
    	};
    };
    

Reply
  • Hi Carl,

    That did help, but I am still having issues with not seeing anything being output by MOSI line I have hooked up to my scope. See my cy15b102qn_read_id function to see where it is failing, basically when I make the call to spi_write using my OPCODE, I never see anything on MOSI. I have followed through the program using the debugger and am unable to figure out why it is not sending the OPCODE over MOSI.

    I will post my updated code and config below:
    main.c: 

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <errno.h>
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <device.h>
    #include <drivers/spi.h>
    
    /**
     * @file Sample app using the Cypress CY15B102QN (driver based on Fujitsu MB85RS64V) FRAM through SPI.
     */
    
    #define CY15B102QN_MANUFACTURER_ID_CMD 0x9f
    #define CY15B102QN_WRITE_ENABLE_CMD 0x06
    #define CY15B102QN_READ_CMD 0x03
    #define CY15B102QN_WRITE_CMD 0x02
    #define MAX_USER_DATA_LENGTH 1024
    
    #define SPI_DEV DT_LABEL(DT_NODELABEL(spi1))
    
    static uint8_t data[MAX_USER_DATA_LENGTH], cmp_data[MAX_USER_DATA_LENGTH];
    
    static int cy15b102qn_access(const struct device *spi,
    			    struct spi_config *spi_cfg,
    			    uint8_t cmd, uint16_t addr, void *data, size_t len)
    {
    	uint8_t access[3] = {0,0,0};
    	struct spi_buf bufs[] = {
    		{
    			.buf = access,
                            .len = len //DO I NEED THIS? I ADDED!
    		},
    		{
    			.buf = data,
    			.len = len
    		}
    	};
    	struct spi_buf_set tx = {
    		.buffers = bufs
    	};
    
    	access[0] = cmd;
    
    	if (cmd == CY15B102QN_WRITE_CMD || cmd == CY15B102QN_READ_CMD) {
    		access[1] = (addr >> 8) & 0xFF;
    		access[2] = addr & 0xFF;
    
    		bufs[0].len = 3;
    		tx.count = 2;
    
    		if (cmd == CY15B102QN_READ_CMD) {
    			struct spi_buf_set rx = {
    				.buffers = bufs,
    				.count = 2
    			};
    
    			return spi_transceive(spi, spi_cfg, &tx, &rx);
    		}
    	} else {
    		tx.count = 1;
                    printk("tx.buffers.buf: 0x%X\n", tx.buffers->buf);
                    
    	}
    
    	return spi_write(spi, spi_cfg, &tx);
    }
    
    
    static int cy15b102qn_read_id(const struct device *spi,
    			     struct spi_config *spi_cfg)
    {
    	uint8_t id[9];
    	int err;
    
            printk("initalized id[0]: 0x%X\n", id[0]);
    
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_MANUFACTURER_ID_CMD, 0, &id, 9);
    	if (err) {
    		printk("Error during ID read\n");
    		return -EIO;
    	}
    
            
            //CY15B102QN-50SXE DEVICE ID: 7F7F7F7F7F7FC22A60
            printk("read id[0]: 0x%X\n", id[0]);
            
    	if (id[0] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[1] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[2] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[3] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[4] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[5] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[6] != 0xC2) {
    		return -EIO;
    	}
    
            if (id[7] != 0x2A) {
    		return -EIO;
    	}
    
            if (id[8] != 0x60) {
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int write_bytes(const struct device *spi, struct spi_config *spi_cfg,
    		       uint16_t addr, uint8_t *data, uint32_t num_bytes)
    {
    	int err;
    
    	/* disable write protect */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_WRITE_ENABLE_CMD, 0, NULL, 0);
    	if (err) {
    		printk("unable to disable write protect\n");
    		return -EIO;
    	}
    
    	/* write cmd */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_WRITE_CMD, addr, data, num_bytes);
    	if (err) {
    		printk("Error during SPI write\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int read_bytes(const struct device *spi, struct spi_config *spi_cfg,
    		      uint16_t addr, uint8_t *data, uint32_t num_bytes)
    {
    	int err;
    
    	/* read cmd */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_READ_CMD, addr, data, num_bytes);
    	if (err) {
    		printk("Error during SPI read\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    void main(void)
    {
    	const struct device *spi;
    	struct spi_config spi_cfg = {0};
    
            //Setup chip select struct / config
            struct spi_cs_control *cs_cfg =
              &(struct spi_cs_control) {
                    .gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
                    .delay = 2,
                    .gpio_pin = 20,
                    .gpio_dt_flags = GPIO_ACTIVE_LOW
            };
            spi_cfg.cs = cs_cfg;
    
            //Set word size
            spi_cfg.operation = SPI_WORD_SET(8);
            //Sets frequency!
    	spi_cfg.frequency = 256000U;
            //spi_cfg.frequency = 4000000U;
    
    	printk("fujitsu FRAM example application\n");
    
    	spi = device_get_binding(SPI_DEV);
    	if (!spi) {
    		printk("Could not find SPI driver\n");
    		return;
    	}
    
    	int err;
    	err = cy15b102qn_read_id(spi, &spi_cfg);
    	if (err) {
    		printk("Could not verify FRAM ID\n");
    		return;
    	}
    
    	/* Do one-byte read/write */
    	data[0] = 0xAE;
    	err = write_bytes(spi, &spi_cfg, 0x00, data, 1);
    	if (err) {
    		printk("Error writing to FRAM! errro code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote 0xAE to address 0x00.\n");
    	}
    
    	data[0] = 0x86;
    	err = write_bytes(spi, &spi_cfg, 0x01, data, 1);
    	if (err) {
    		printk("Error writing to FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote 0x86 to address 0x01.\n");
    	}
    
    	data[0] = 0x00;
    	err = read_bytes(spi, &spi_cfg, 0x00, data, 1);
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read 0x%X from address 0x00.\n", data[0]);
    	}
    
    	data[0] = 0x00;
    	err = read_bytes(spi, &spi_cfg, 0x01, data, 1);
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read 0x%X from address 0x01.\n", data[0]);
    	}
    
    	/* Do multi-byte read/write */
    	/* get some random data, and clear out data[] */
    	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
    		cmp_data[i] = k_cycle_get_32() & 0xFF;
    		data[i] = 0x00;
    	}
    
    	/* write them to the FRAM */
    	err = write_bytes(spi, &spi_cfg, 0x00, cmp_data, sizeof(cmp_data));
    	if (err) {
    		printk("Error writing to FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote %d bytes to address 0x00.\n",
    		       (uint32_t) sizeof(cmp_data));
    	}
    
    	err = read_bytes(spi, &spi_cfg, 0x00, data, sizeof(data));
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read %d bytes from address 0x00.\n",
    		       (uint32_t) sizeof(data));
    	}
    
    	err = 0;
    	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
    		if (cmp_data[i] != data[i]) {
    			printk("Data comparison failed @ %d.\n", i);
    			err = -EIO;
    		}
    	}
    	if (err == 0) {
    		printk("Data comparison successful.\n");
    	}
    }


    nrf52833dk_nrf52833.overlay : 
    &spi1 {
    	compatible = "nordic,nrf-spim";
    	status = "okay";
    	
    	mosi-pin = <23>;
    	miso-pin = <22>;
    	sck-pin = <21>;
    	clock-frequency = <4000000>;
    	
    	cs-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
    	
    	
    	
    };
    
    &spi2 {
    	status = "disabled";
    };
    
    &i2c1 {
        status = "disabled";
    };
    
    

    prj.conf : 

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_PRINTK=y
    
    CONFIG_SPI=y
    #CONFIG_SPI_1=y
    #CONFIG_SPI_NRFX=y
    
    CONFIG_GPIO=y
    
    CONFIG_MAIN_STACK_SIZE=4096

    zephyr.dts : 

    /dts-v1/;
    
    / {
    	#address-cells = < 0x1 >;
    	#size-cells = < 0x1 >;
    	model = "Nordic nRF52833 DK NRF52833";
    	compatible = "nordic,nrf52833-dk-nrf52833";
    	chosen {
    		zephyr,entropy = &rng;
    		zephyr,flash-controller = &flash_controller;
    		zephyr,console = &uart0;
    		zephyr,shell-uart = &uart0;
    		zephyr,uart-mcumgr = &uart0;
    		zephyr,bt-mon-uart = &uart0;
    		zephyr,bt-c2h-uart = &uart0;
    		zephyr,sram = &sram0;
    		zephyr,flash = &flash0;
    		zephyr,code-partition = &slot0_partition;
    	};
    	aliases {
    		led0 = &led0;
    		led1 = &led1;
    		led2 = &led2;
    		led3 = &led3;
    		pwm-led0 = &pwm_led0;
    		sw0 = &button0;
    		sw1 = &button1;
    		sw2 = &button2;
    		sw3 = &button3;
    	};
    	soc {
    		#address-cells = < 0x1 >;
    		#size-cells = < 0x1 >;
    		compatible = "nordic,nRF52833-QIAA", "nordic,nRF52833", "nordic,nRF52", "simple-bus";
    		interrupt-parent = < &nvic >;
    		ranges;
    		nvic: interrupt-controller@e000e100 {
    			compatible = "arm,v7m-nvic";
    			reg = < 0xe000e100 0xc00 >;
    			interrupt-controller;
    			#interrupt-cells = < 0x2 >;
    			arm,num-irq-priority-bits = < 0x3 >;
    			phandle = < 0x1 >;
    		};
    		systick: timer@e000e010 {
    			compatible = "arm,armv7m-systick";
    			reg = < 0xe000e010 0x10 >;
    			status = "disabled";
    		};
    		flash_controller: flash-controller@4001e000 {
    			compatible = "nordic,nrf52-flash-controller";
    			reg = < 0x4001e000 0x1000 >;
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x1 >;
    			label = "NRF_FLASH_DRV_NAME";
    			flash0: flash@0 {
    				compatible = "soc-nv-flash";
    				label = "NRF_FLASH";
    				erase-block-size = < 0x1000 >;
    				write-block-size = < 0x4 >;
    				reg = < 0x0 0x80000 >;
    				partitions {
    					compatible = "fixed-partitions";
    					#address-cells = < 0x1 >;
    					#size-cells = < 0x1 >;
    					boot_partition: partition@0 {
    						label = "mcuboot";
    						reg = < 0x0 0xc000 >;
    					};
    					slot0_partition: partition@c000 {
    						label = "image-0";
    						reg = < 0xc000 0x32000 >;
    					};
    					slot1_partition: partition@3e000 {
    						label = "image-1";
    						reg = < 0x3e000 0x32000 >;
    					};
    					scratch_partition: partition@70000 {
    						label = "image-scratch";
    						reg = < 0x70000 0xa000 >;
    					};
    					storage_partition: partition@7a000 {
    						label = "storage";
    						reg = < 0x7a000 0x6000 >;
    					};
    				};
    			};
    		};
    		sram0: memory@20000000 {
    			compatible = "mmio-sram";
    			reg = < 0x20000000 0x20000 >;
    		};
    		adc: adc@40007000 {
    			compatible = "nordic,nrf-saadc";
    			reg = < 0x40007000 0x1000 >;
    			interrupts = < 0x7 0x1 >;
    			status = "okay";
    			label = "ADC_0";
    			#io-channel-cells = < 0x1 >;
    		};
    		clock: clock@40000000 {
    			compatible = "nordic,nrf-clock";
    			reg = < 0x40000000 0x1000 >;
    			interrupts = < 0x0 0x1 >;
    			status = "okay";
    			label = "CLOCK";
    		};
    		ecb: ecb@4000e000 {
    			compatible = "nordic,nrf-ecb";
    			reg = < 0x4000e000 0x1000 >;
    			interrupts = < 0xe 0x1 >;
    			status = "okay";
    			label = "ECB";
    		};
    		uart0: uart@40002000 {
    			reg = < 0x40002000 0x1000 >;
    			interrupts = < 0x2 0x1 >;
    			status = "okay";
    			label = "UART_0";
    			compatible = "nordic,nrf-uarte";
    			current-speed = < 0x1c200 >;
    			tx-pin = < 0x6 >;
    			rx-pin = < 0x8 >;
    			rts-pin = < 0x5 >;
    			cts-pin = < 0x7 >;
    		};
    		uart1: arduino_serial: uart@40028000 {
    			compatible = "nordic,nrf-uarte";
    			reg = < 0x40028000 0x1000 >;
    			interrupts = < 0x28 0x1 >;
    			status = "okay";
    			label = "UART_1";
    			current-speed = < 0x1c200 >;
    			rx-pin = < 0x21 >;
    			tx-pin = < 0x22 >;
    		};
    		gpiote: gpiote@40006000 {
    			compatible = "nordic,nrf-gpiote";
    			reg = < 0x40006000 0x1000 >;
    			interrupts = < 0x6 0x5 >;
    			status = "okay";
    			label = "GPIOTE_0";
    		};
    		gpio0: gpio@50000000 {
    			compatible = "nordic,nrf-gpio";
    			gpio-controller;
    			reg = < 0x50000000 0x200 0x50000500 0x300 >;
    			#gpio-cells = < 0x2 >;
    			label = "GPIO_0";
    			status = "okay";
    			port = < 0x0 >;
    			phandle = < 0x2 >;
    		};
    		gpio1: gpio@50000300 {
    			compatible = "nordic,nrf-gpio";
    			gpio-controller;
    			reg = < 0x50000300 0x200 0x50000800 0x300 >;
    			#gpio-cells = < 0x2 >;
    			ngpios = < 0xa >;
    			label = "GPIO_1";
    			status = "okay";
    			port = < 0x1 >;
    			phandle = < 0x6 >;
    		};
    		i2c0: arduino_i2c: i2c@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			clock-frequency = < 0x186a0 >;
    			interrupts = < 0x3 0x1 >;
    			status = "okay";
    			label = "I2C_0";
    			compatible = "nordic,nrf-twi";
    			sda-pin = < 0x1a >;
    			scl-pin = < 0x1b >;
    		};
    		i2c1: i2c@40004000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			clock-frequency = < 0x186a0 >;
    			interrupts = < 0x4 0x1 >;
    			status = "disabled";
    			label = "I2C_1";
    			compatible = "nordic,nrf-twi";
    			sda-pin = < 0x1e >;
    			scl-pin = < 0x1f >;
    		};
    		pwm0: pwm@4001c000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x4001c000 0x1000 >;
    			interrupts = < 0x1c 0x1 >;
    			status = "okay";
    			label = "PWM_0";
    			#pwm-cells = < 0x1 >;
    			ch0-pin = < 0xd >;
    			ch0-inverted;
    			phandle = < 0x5 >;
    		};
    		pwm1: pwm@40021000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x40021000 0x1000 >;
    			interrupts = < 0x21 0x1 >;
    			status = "disabled";
    			label = "PWM_1";
    			#pwm-cells = < 0x1 >;
    		};
    		pwm2: pwm@40022000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x40022000 0x1000 >;
    			interrupts = < 0x22 0x1 >;
    			status = "disabled";
    			label = "PWM_2";
    			#pwm-cells = < 0x1 >;
    		};
    		pwm3: pwm@4002d000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x4002d000 0x1000 >;
    			interrupts = < 0x2d 0x1 >;
    			status = "disabled";
    			label = "PWM_3";
    			#pwm-cells = < 0x1 >;
    		};
    		qdec: qdec@40012000 {
    			compatible = "nordic,nrf-qdec";
    			reg = < 0x40012000 0x1000 >;
    			interrupts = < 0x12 0x1 >;
    			status = "disabled";
    			label = "QDEC";
    		};
    		rng: random@4000d000 {
    			compatible = "nordic,nrf-rng";
    			reg = < 0x4000d000 0x1000 >;
    			interrupts = < 0xd 0x1 >;
    			status = "okay";
    			label = "RNG";
    		};
    		spi0: spi@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			interrupts = < 0x3 0x1 >;
    			status = "disabled";
    			label = "SPI_0";
    			compatible = "nordic,nrf-spi";
    			sck-pin = < 0x1b >;
    			mosi-pin = < 0x1a >;
    			miso-pin = < 0x1d >;
    		};
    		spi1: spi@40004000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			interrupts = < 0x4 0x1 >;
    			status = "okay";
    			label = "SPI_1";
    			compatible = "nordic,nrf-spim";
    			sck-pin = < 0x15 >;
    			mosi-pin = < 0x17 >;
    			miso-pin = < 0x16 >;
    			clock-frequency = < 0x3d0900 >;
    			cs-gpios = < &gpio0 0x14 0x1 >;
    		};
    		spi2: spi@40023000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40023000 0x1000 >;
    			interrupts = < 0x23 0x1 >;
    			status = "disabled";
    			label = "SPI_2";
    		};
    		spi3: arduino_spi: spi@4002f000 {
    			compatible = "nordic,nrf-spim";
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x4002f000 0x1000 >;
    			interrupts = < 0x2f 0x1 >;
    			status = "okay";
    			label = "SPI_3";
    			sck-pin = < 0x17 >;
    			miso-pin = < 0x16 >;
    			mosi-pin = < 0x15 >;
    			cs-gpios = < &arduino_header 0x10 0x1 >;
    		};
    		rtc0: rtc@4000b000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x4000b000 0x1000 >;
    			cc-num = < 0x3 >;
    			interrupts = < 0xb 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_0";
    		};
    		rtc1: rtc@40011000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x40011000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x11 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_1";
    		};
    		rtc2: rtc@40024000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x40024000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x24 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_2";
    		};
    		timer0: timer@40008000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x40008000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x8 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_0";
    		};
    		timer1: timer@40009000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x40009000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x9 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_1";
    		};
    		timer2: timer@4000a000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4000a000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0xa 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_2";
    			phandle = < 0x4 >;
    		};
    		timer3: timer@4001a000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4001a000 0x1000 >;
    			cc-num = < 0x6 >;
    			interrupts = < 0x1a 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_3";
    		};
    		timer4: timer@4001b000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4001b000 0x1000 >;
    			cc-num = < 0x6 >;
    			interrupts = < 0x1b 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_4";
    		};
    		temp: temp@4000c000 {
    			compatible = "nordic,nrf-temp";
    			reg = < 0x4000c000 0x1000 >;
    			interrupts = < 0xc 0x1 >;
    			status = "okay";
    			label = "TEMP_0";
    		};
    		usbd: usbd@40027000 {
    			compatible = "nordic,nrf-usbd";
    			reg = < 0x40027000 0x1000 >;
    			interrupts = < 0x27 0x1 >;
    			num-bidir-endpoints = < 0x1 >;
    			num-in-endpoints = < 0x7 >;
    			num-out-endpoints = < 0x7 >;
    			num-isoin-endpoints = < 0x1 >;
    			num-isoout-endpoints = < 0x1 >;
    			status = "okay";
    			label = "USBD";
    		};
    		wdt: wdt0: watchdog@40010000 {
    			compatible = "nordic,nrf-watchdog";
    			reg = < 0x40010000 0x1000 >;
    			interrupts = < 0x10 0x1 >;
    			status = "okay";
    			label = "WDT";
    		};
    		ficr: ficr@10000000 {
    			compatible = "nordic,nrf-ficr";
    			reg = < 0x10000000 0x1000 >;
    			status = "okay";
    		};
    		uicr: uicr@10001000 {
    			compatible = "nordic,nrf-uicr";
    			reg = < 0x10001000 0x1000 >;
    			status = "okay";
    		};
    		radio: radio@40001000 {
    			compatible = "nordic,nrf-radio";
    			reg = < 0x40001000 0x1000 >;
    			interrupts = < 0x1 0x1 >;
    			status = "okay";
    			dfe-ant-num = < 0x0 >;
    		};
    	};
    	cpus {
    		#address-cells = < 0x1 >;
    		#size-cells = < 0x0 >;
    		cpu@0 {
    			device_type = "cpu";
    			compatible = "arm,cortex-m4f";
    			reg = < 0x0 >;
    		};
    	};
    	sw_pwm: sw-pwm {
    		compatible = "nordic,nrf-sw-pwm";
    		status = "disabled";
    		label = "SW_PWM";
    		generator = < &timer2 >;
    		channel-count = < 0x3 >;
    		clock-prescaler = < 0x0 >;
    		ppi-base = < 0x0 >;
    		gpiote-base = < 0x0 >;
    		#pwm-cells = < 0x1 >;
    	};
    	leds {
    		compatible = "gpio-leds";
    		led0: led_0 {
    			gpios = < &gpio0 0xd 0x1 >;
    			label = "Green LED 0";
    		};
    		led1: led_1 {
    			gpios = < &gpio0 0xe 0x1 >;
    			label = "Green LED 1";
    		};
    		led2: led_2 {
    			gpios = < &gpio0 0xf 0x1 >;
    			label = "Green LED 2";
    		};
    		led3: led_3 {
    			gpios = < &gpio0 0x10 0x1 >;
    			label = "Green LED 3";
    		};
    	};
    	pwmleds {
    		compatible = "pwm-leds";
    		pwm_led0: pwm_led_0 {
    			pwms = < &pwm0 0xd >;
    		};
    	};
    	buttons {
    		compatible = "gpio-keys";
    		button0: button_0 {
    			gpios = < &gpio0 0xb 0x11 >;
    			label = "Push button switch 0";
    		};
    		button1: button_1 {
    			gpios = < &gpio0 0xc 0x11 >;
    			label = "Push button switch 1";
    		};
    		button2: button_2 {
    			gpios = < &gpio0 0x18 0x11 >;
    			label = "Push button switch 2";
    		};
    		button3: button_3 {
    			gpios = < &gpio0 0x19 0x11 >;
    			label = "Push button switch 3";
    		};
    	};
    	arduino_header: connector {
    		compatible = "arduino-header-r3";
    		#gpio-cells = < 0x2 >;
    		gpio-map-mask = < 0xffffffff 0xffffffc0 >;
    		gpio-map-pass-thru = < 0x0 0x3f >;
    		gpio-map = < 0x0 0x0 &gpio0 0x3 0x0 >, < 0x1 0x0 &gpio0 0x4 0x0 >, < 0x2 0x0 &gpio0 0x1c 0x0 >, < 0x3 0x0 &gpio0 0x1d 0x0 >, < 0x4 0x0 &gpio0 0x1e 0x0 >, < 0x5 0x0 &gpio0 0x1f 0x0 >, < 0x6 0x0 &gpio1 0x1 0x0 >, < 0x7 0x0 &gpio1 0x2 0x0 >, < 0x8 0x0 &gpio1 0x3 0x0 >, < 0x9 0x0 &gpio1 0x4 0x0 >, < 0xa 0x0 &gpio1 0x5 0x0 >, < 0xb 0x0 &gpio1 0x6 0x0 >, < 0xc 0x0 &gpio1 0x7 0x0 >, < 0xd 0x0 &gpio1 0x8 0x0 >, < 0xe 0x0 &gpio0 0x11 0x0 >, < 0xf 0x0 &gpio0 0x13 0x0 >, < 0x10 0x0 &gpio0 0x14 0x0 >, < 0x11 0x0 &gpio0 0x15 0x0 >, < 0x12 0x0 &gpio0 0x16 0x0 >, < 0x13 0x0 &gpio0 0x17 0x0 >, < 0x14 0x0 &gpio0 0x1a 0x0 >, < 0x15 0x0 &gpio0 0x1b 0x0 >;
    		phandle = < 0x3 >;
    	};
    };
    

Children
  • Hello again!

    Good to hear that it helped. Are you getting any errors when running the code, or is the MOSI just silent?

    I also see that UART1 is enabled in the DTS. This will conflict with SPI1, so please try to disable UART1 in the overlay or change your SPI instance.

    Best regards,
    Carl Richard

  • Carl,

    I went ahead and updated my overlay to disable UART1, see : 

    &spi1 {
    	compatible = "nordic,nrf-spim";
    	status = "okay";
    	
    	mosi-pin = <23>;
    	miso-pin = <22>;
    	sck-pin = <21>;
    	clock-frequency = <4000000>;
    	label = "CY15B102QN";
    	cs-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
    	
    	//spidev: spi-device@0 {
        //              reg = <0>;
        //              label = "CY15B102QN";
        //      };
    	
    };
    
    &spi2 {
    	status = "disabled";
    };
    
    &uart1 {
    	status = "disabled";
    };
    
    &i2c1 {
        status = "disabled";
    };
    
    


    I get no errors when running code or building, I simply just see MOSI as silent when trying to read the manufacture ID (see cy15b102qn_read_id(const struct device *spi,
    struct spi_config *spi_cfg)).

    Updated main.c : 

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <errno.h>
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <device.h>
    #include <drivers/spi.h>
    
    /**
     * @file Sample app using the Cypress CY15B102QN (driver based on Fujitsu MB85RS64V) FRAM through SPI.
     */
    
    #define CY15B102QN_MANUFACTURER_ID_CMD 0x9f
    #define CY15B102QN_WRITE_ENABLE_CMD 0x06
    #define CY15B102QN_READ_CMD 0x03
    #define CY15B102QN_WRITE_CMD 0x02
    #define MAX_USER_DATA_LENGTH 1024
    
    #define SPI_DEV DT_LABEL(DT_NODELABEL(spi1))
    
    static uint8_t data[MAX_USER_DATA_LENGTH], cmp_data[MAX_USER_DATA_LENGTH];
    
    static int cy15b102qn_access(const struct device *spi,
    			    struct spi_config *spi_cfg,
    			    uint8_t cmd, uint16_t addr, void *data, size_t len)
    {
    	uint8_t access[3] = {0};
    	struct spi_buf bufs[] = {
    		{
    			.buf = access,
                            //.len = len //DO I NEED THIS? I ADDED!
    		},
    		{
    			.buf = data,
    			.len = len
    		}
    	};
    	struct spi_buf_set tx = {
    		.buffers = bufs
    	};
    
    	access[0] = cmd;
    
    	if (cmd == CY15B102QN_WRITE_CMD || cmd == CY15B102QN_READ_CMD) {
    		access[1] = (addr >> 8) & 0xFF;
    		access[2] = addr & 0xFF;
    
    		bufs[0].len = 3;
    		tx.count = 2;
    
    		if (cmd == CY15B102QN_READ_CMD) {
    			struct spi_buf_set rx = {
    				.buffers = bufs,
    				.count = 2
    			};
    
    			return spi_transceive(spi, spi_cfg, &tx, &rx);
    		}
    	} else {
    		tx.count = 1;
                    //printk("tx.buffers.buf: 0x%X\n", tx.buffers->buf);
                    
    	}
    
    	return spi_write(spi, spi_cfg, &tx);
    }
    
    
    static int cy15b102qn_read_id(const struct device *spi,
    			     struct spi_config *spi_cfg)
    {
    	uint8_t id[9] = {0};
    	int err;
    
            printk("initalized id[0]: 0x%X\n", id[0]);
            printk("initalized id[1]: 0x%X\n", id[1]);
            printk("initalized id[2]: 0x%X\n", id[2]);
            printk("initalized id[3]: 0x%X\n", id[3]);
            printk("initalized id[4]: 0x%X\n", id[4]);
            printk("initalized id[5]: 0x%X\n", id[5]);
            printk("initalized id[6]: 0x%X\n", id[6]);
            printk("initalized id[7]: 0x%X\n", id[7]);
            printk("initalized id[8]: 0x%X\n", id[8]);
    
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_MANUFACTURER_ID_CMD, 0, &id, 9);
    	if (err) {
    		printk("Error during ID read\n");
    		return -EIO;
    	}
    
            //CY15B102QN-50SXE DEVICE ID: 7F7F7F7F7F7FC22A60
            printk("read id[0]: 0x%X\n", id[0]);
            printk("read id[1]: 0x%X\n", id[1]);
            printk("read id[2]: 0x%X\n", id[2]);
            printk("read id[3]: 0x%X\n", id[3]);
            printk("read id[4]: 0x%X\n", id[4]);
            printk("read id[5]: 0x%X\n", id[5]);
            printk("read id[6]: 0x%X\n", id[6]);
            printk("read id[7]: 0x%X\n", id[7]);
            printk("read id[8]: 0x%X\n", id[8]);
            
    	if (id[0] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[1] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[2] != 0x7F) {
    		return -EIO;
    	}
    
    	if (id[3] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[4] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[5] != 0x7F) {
    		return -EIO;
    	}
    
            if (id[6] != 0xC2) {
    		return -EIO;
    	}
    
            if (id[7] != 0x2A) {
    		return -EIO;
    	}
    
            if (id[8] != 0x60) {
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int write_bytes(const struct device *spi, struct spi_config *spi_cfg,
    		       uint16_t addr, uint8_t *data, uint32_t num_bytes)
    {
    	int err;
    
    	/* disable write protect */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_WRITE_ENABLE_CMD, 0, NULL, 0);
    	if (err) {
    		printk("unable to disable write protect\n");
    		return -EIO;
    	}
    
    	/* write cmd */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_WRITE_CMD, addr, data, num_bytes);
    	if (err) {
    		printk("Error during SPI write\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static int read_bytes(const struct device *spi, struct spi_config *spi_cfg,
    		      uint16_t addr, uint8_t *data, uint32_t num_bytes)
    {
    	int err;
    
    	/* read cmd */
    	err = cy15b102qn_access(spi, spi_cfg,
    			       CY15B102QN_READ_CMD, addr, data, num_bytes);
    	if (err) {
    		printk("Error during SPI read\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    void main(void)
    {
    	const struct device *spi;
    	struct spi_config spi_cfg = {0};
    
            //Setup chip select struct / config
            struct spi_cs_control *cs_cfg =
              &(struct spi_cs_control) {
                    .gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
                    .delay = 2,
                    .gpio_pin = 20,
                    .gpio_dt_flags = GPIO_ACTIVE_LOW
            };
            spi_cfg.cs = cs_cfg;
    
            //Set word size
            spi_cfg.operation = SPI_WORD_SET(8);
            //Sets frequency!
    	spi_cfg.frequency = 256000U;
            //spi_cfg.frequency = 4000000U;
    
    	printk("fujitsu FRAM example application\n");
    
    	spi = device_get_binding(SPI_DEV);
    	if (!spi) {
    		printk("Could not find SPI driver\n");
    		return;
    	}
    
    	int err;
    	err = cy15b102qn_read_id(spi, &spi_cfg);
    	if (err) {
    		printk("Could not verify FRAM ID\n");
    		return;
    	}
    
    	/* Do one-byte read/write */
    	data[0] = 0xAE;
    	err = write_bytes(spi, &spi_cfg, 0x00, data, 1);
    	if (err) {
    		printk("Error writing to FRAM! errro code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote 0xAE to address 0x00.\n");
    	}
    
    	data[0] = 0x86;
    	err = write_bytes(spi, &spi_cfg, 0x01, data, 1);
    	if (err) {
    		printk("Error writing to FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote 0x86 to address 0x01.\n");
    	}
    
    	data[0] = 0x00;
    	err = read_bytes(spi, &spi_cfg, 0x00, data, 1);
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read 0x%X from address 0x00.\n", data[0]);
    	}
    
    	data[0] = 0x00;
    	err = read_bytes(spi, &spi_cfg, 0x01, data, 1);
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read 0x%X from address 0x01.\n", data[0]);
    	}
    
    	/* Do multi-byte read/write */
    	/* get some random data, and clear out data[] */
    	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
    		cmp_data[i] = k_cycle_get_32() & 0xFF;
    		data[i] = 0x00;
    	}
    
    	/* write them to the FRAM */
    	err = write_bytes(spi, &spi_cfg, 0x00, cmp_data, sizeof(cmp_data));
    	if (err) {
    		printk("Error writing to FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Wrote %d bytes to address 0x00.\n",
    		       (uint32_t) sizeof(cmp_data));
    	}
    
    	err = read_bytes(spi, &spi_cfg, 0x00, data, sizeof(data));
    	if (err) {
    		printk("Error reading from FRAM! error code (%d)\n", err);
    		return;
    	} else {
    		printk("Read %d bytes from address 0x00.\n",
    		       (uint32_t) sizeof(data));
    	}
    
    	err = 0;
    	for (uint32_t i = 0; i < sizeof(cmp_data); i++) {
    		if (cmp_data[i] != data[i]) {
    			printk("Data comparison failed @ %d.\n", i);
    			err = -EIO;
    		}
    	}
    	if (err == 0) {
    		printk("Data comparison successful.\n");
    	}
    }
    

    This is the serial output I get when running this program : 

    *** Booting Zephyr OS build v2.4.99-ncs2-2-g5049afda7b9f  ***
    fujitsu FRAM example application
    initalized id[0]: 0x0
    initalized id[1]: 0x0
    initalized id[2]: 0x0
    initalized id[3]: 0x0
    initalized id[4]: 0x0
    initalized id[5]: 0x0
    initalized id[6]: 0x0
    initalized id[7]: 0x0
    initalized id[8]: 0x0
    read id[0]: 0x0
    read id[1]: 0x0
    read id[2]: 0x0
    read id[3]: 0x0
    read id[4]: 0x0
    read id[5]: 0x0
    read id[6]: 0x0
    read id[7]: 0x0
    read id[8]: 0x0
    Could not verify FRAM ID

    As you can see it is failing to read the ID, and when I step through/debug I don't see any issue. And as I mentioned I see no output on MOSI with my scope, it just sits low.

    Updated Zephyr.dts : 

    /dts-v1/;
    
    / {
    	#address-cells = < 0x1 >;
    	#size-cells = < 0x1 >;
    	model = "Nordic nRF52833 DK NRF52833";
    	compatible = "nordic,nrf52833-dk-nrf52833";
    	chosen {
    		zephyr,entropy = &rng;
    		zephyr,flash-controller = &flash_controller;
    		zephyr,console = &uart0;
    		zephyr,shell-uart = &uart0;
    		zephyr,uart-mcumgr = &uart0;
    		zephyr,bt-mon-uart = &uart0;
    		zephyr,bt-c2h-uart = &uart0;
    		zephyr,sram = &sram0;
    		zephyr,flash = &flash0;
    		zephyr,code-partition = &slot0_partition;
    	};
    	aliases {
    		led0 = &led0;
    		led1 = &led1;
    		led2 = &led2;
    		led3 = &led3;
    		pwm-led0 = &pwm_led0;
    		sw0 = &button0;
    		sw1 = &button1;
    		sw2 = &button2;
    		sw3 = &button3;
    	};
    	soc {
    		#address-cells = < 0x1 >;
    		#size-cells = < 0x1 >;
    		compatible = "nordic,nRF52833-QIAA", "nordic,nRF52833", "nordic,nRF52", "simple-bus";
    		interrupt-parent = < &nvic >;
    		ranges;
    		nvic: interrupt-controller@e000e100 {
    			compatible = "arm,v7m-nvic";
    			reg = < 0xe000e100 0xc00 >;
    			interrupt-controller;
    			#interrupt-cells = < 0x2 >;
    			arm,num-irq-priority-bits = < 0x3 >;
    			phandle = < 0x1 >;
    		};
    		systick: timer@e000e010 {
    			compatible = "arm,armv7m-systick";
    			reg = < 0xe000e010 0x10 >;
    			status = "disabled";
    		};
    		flash_controller: flash-controller@4001e000 {
    			compatible = "nordic,nrf52-flash-controller";
    			reg = < 0x4001e000 0x1000 >;
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x1 >;
    			label = "NRF_FLASH_DRV_NAME";
    			flash0: flash@0 {
    				compatible = "soc-nv-flash";
    				label = "NRF_FLASH";
    				erase-block-size = < 0x1000 >;
    				write-block-size = < 0x4 >;
    				reg = < 0x0 0x80000 >;
    				partitions {
    					compatible = "fixed-partitions";
    					#address-cells = < 0x1 >;
    					#size-cells = < 0x1 >;
    					boot_partition: partition@0 {
    						label = "mcuboot";
    						reg = < 0x0 0xc000 >;
    					};
    					slot0_partition: partition@c000 {
    						label = "image-0";
    						reg = < 0xc000 0x32000 >;
    					};
    					slot1_partition: partition@3e000 {
    						label = "image-1";
    						reg = < 0x3e000 0x32000 >;
    					};
    					scratch_partition: partition@70000 {
    						label = "image-scratch";
    						reg = < 0x70000 0xa000 >;
    					};
    					storage_partition: partition@7a000 {
    						label = "storage";
    						reg = < 0x7a000 0x6000 >;
    					};
    				};
    			};
    		};
    		sram0: memory@20000000 {
    			compatible = "mmio-sram";
    			reg = < 0x20000000 0x20000 >;
    		};
    		adc: adc@40007000 {
    			compatible = "nordic,nrf-saadc";
    			reg = < 0x40007000 0x1000 >;
    			interrupts = < 0x7 0x1 >;
    			status = "okay";
    			label = "ADC_0";
    			#io-channel-cells = < 0x1 >;
    		};
    		clock: clock@40000000 {
    			compatible = "nordic,nrf-clock";
    			reg = < 0x40000000 0x1000 >;
    			interrupts = < 0x0 0x1 >;
    			status = "okay";
    			label = "CLOCK";
    		};
    		ecb: ecb@4000e000 {
    			compatible = "nordic,nrf-ecb";
    			reg = < 0x4000e000 0x1000 >;
    			interrupts = < 0xe 0x1 >;
    			status = "okay";
    			label = "ECB";
    		};
    		uart0: uart@40002000 {
    			reg = < 0x40002000 0x1000 >;
    			interrupts = < 0x2 0x1 >;
    			status = "okay";
    			label = "UART_0";
    			compatible = "nordic,nrf-uarte";
    			current-speed = < 0x1c200 >;
    			tx-pin = < 0x6 >;
    			rx-pin = < 0x8 >;
    			rts-pin = < 0x5 >;
    			cts-pin = < 0x7 >;
    		};
    		uart1: arduino_serial: uart@40028000 {
    			compatible = "nordic,nrf-uarte";
    			reg = < 0x40028000 0x1000 >;
    			interrupts = < 0x28 0x1 >;
    			status = "disabled";
    			label = "UART_1";
    			current-speed = < 0x1c200 >;
    			rx-pin = < 0x21 >;
    			tx-pin = < 0x22 >;
    		};
    		gpiote: gpiote@40006000 {
    			compatible = "nordic,nrf-gpiote";
    			reg = < 0x40006000 0x1000 >;
    			interrupts = < 0x6 0x5 >;
    			status = "okay";
    			label = "GPIOTE_0";
    		};
    		gpio0: gpio@50000000 {
    			compatible = "nordic,nrf-gpio";
    			gpio-controller;
    			reg = < 0x50000000 0x200 0x50000500 0x300 >;
    			#gpio-cells = < 0x2 >;
    			label = "GPIO_0";
    			status = "okay";
    			port = < 0x0 >;
    			phandle = < 0x2 >;
    		};
    		gpio1: gpio@50000300 {
    			compatible = "nordic,nrf-gpio";
    			gpio-controller;
    			reg = < 0x50000300 0x200 0x50000800 0x300 >;
    			#gpio-cells = < 0x2 >;
    			ngpios = < 0xa >;
    			label = "GPIO_1";
    			status = "okay";
    			port = < 0x1 >;
    			phandle = < 0x6 >;
    		};
    		i2c0: arduino_i2c: i2c@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			clock-frequency = < 0x186a0 >;
    			interrupts = < 0x3 0x1 >;
    			status = "okay";
    			label = "I2C_0";
    			compatible = "nordic,nrf-twi";
    			sda-pin = < 0x1a >;
    			scl-pin = < 0x1b >;
    		};
    		i2c1: i2c@40004000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			clock-frequency = < 0x186a0 >;
    			interrupts = < 0x4 0x1 >;
    			status = "disabled";
    			label = "I2C_1";
    			compatible = "nordic,nrf-twi";
    			sda-pin = < 0x1e >;
    			scl-pin = < 0x1f >;
    		};
    		pwm0: pwm@4001c000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x4001c000 0x1000 >;
    			interrupts = < 0x1c 0x1 >;
    			status = "okay";
    			label = "PWM_0";
    			#pwm-cells = < 0x1 >;
    			ch0-pin = < 0xd >;
    			ch0-inverted;
    			phandle = < 0x5 >;
    		};
    		pwm1: pwm@40021000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x40021000 0x1000 >;
    			interrupts = < 0x21 0x1 >;
    			status = "disabled";
    			label = "PWM_1";
    			#pwm-cells = < 0x1 >;
    		};
    		pwm2: pwm@40022000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x40022000 0x1000 >;
    			interrupts = < 0x22 0x1 >;
    			status = "disabled";
    			label = "PWM_2";
    			#pwm-cells = < 0x1 >;
    		};
    		pwm3: pwm@4002d000 {
    			compatible = "nordic,nrf-pwm";
    			reg = < 0x4002d000 0x1000 >;
    			interrupts = < 0x2d 0x1 >;
    			status = "disabled";
    			label = "PWM_3";
    			#pwm-cells = < 0x1 >;
    		};
    		qdec: qdec@40012000 {
    			compatible = "nordic,nrf-qdec";
    			reg = < 0x40012000 0x1000 >;
    			interrupts = < 0x12 0x1 >;
    			status = "disabled";
    			label = "QDEC";
    		};
    		rng: random@4000d000 {
    			compatible = "nordic,nrf-rng";
    			reg = < 0x4000d000 0x1000 >;
    			interrupts = < 0xd 0x1 >;
    			status = "okay";
    			label = "RNG";
    		};
    		spi0: spi@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			interrupts = < 0x3 0x1 >;
    			status = "disabled";
    			label = "SPI_0";
    			compatible = "nordic,nrf-spi";
    			sck-pin = < 0x1b >;
    			mosi-pin = < 0x1a >;
    			miso-pin = < 0x1d >;
    		};
    		spi1: spi@40004000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			interrupts = < 0x4 0x1 >;
    			status = "okay";
    			label = "CY15B102QN";
    			compatible = "nordic,nrf-spim";
    			sck-pin = < 0x15 >;
    			mosi-pin = < 0x17 >;
    			miso-pin = < 0x16 >;
    			clock-frequency = < 0x3d0900 >;
    			cs-gpios = < &gpio0 0x14 0x1 >;
    		};
    		spi2: spi@40023000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40023000 0x1000 >;
    			interrupts = < 0x23 0x1 >;
    			status = "disabled";
    			label = "SPI_2";
    		};
    		spi3: arduino_spi: spi@4002f000 {
    			compatible = "nordic,nrf-spim";
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x4002f000 0x1000 >;
    			interrupts = < 0x2f 0x1 >;
    			status = "okay";
    			label = "SPI_3";
    			sck-pin = < 0x17 >;
    			miso-pin = < 0x16 >;
    			mosi-pin = < 0x15 >;
    			cs-gpios = < &arduino_header 0x10 0x1 >;
    		};
    		rtc0: rtc@4000b000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x4000b000 0x1000 >;
    			cc-num = < 0x3 >;
    			interrupts = < 0xb 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_0";
    		};
    		rtc1: rtc@40011000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x40011000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x11 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_1";
    		};
    		rtc2: rtc@40024000 {
    			compatible = "nordic,nrf-rtc";
    			reg = < 0x40024000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x24 0x1 >;
    			status = "okay";
    			clock-frequency = < 0x8000 >;
    			prescaler = < 0x1 >;
    			label = "RTC_2";
    		};
    		timer0: timer@40008000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x40008000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x8 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_0";
    		};
    		timer1: timer@40009000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x40009000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0x9 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_1";
    		};
    		timer2: timer@4000a000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4000a000 0x1000 >;
    			cc-num = < 0x4 >;
    			interrupts = < 0xa 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_2";
    			phandle = < 0x4 >;
    		};
    		timer3: timer@4001a000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4001a000 0x1000 >;
    			cc-num = < 0x6 >;
    			interrupts = < 0x1a 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_3";
    		};
    		timer4: timer@4001b000 {
    			compatible = "nordic,nrf-timer";
    			status = "okay";
    			reg = < 0x4001b000 0x1000 >;
    			cc-num = < 0x6 >;
    			interrupts = < 0x1b 0x1 >;
    			prescaler = < 0x0 >;
    			label = "TIMER_4";
    		};
    		temp: temp@4000c000 {
    			compatible = "nordic,nrf-temp";
    			reg = < 0x4000c000 0x1000 >;
    			interrupts = < 0xc 0x1 >;
    			status = "okay";
    			label = "TEMP_0";
    		};
    		usbd: usbd@40027000 {
    			compatible = "nordic,nrf-usbd";
    			reg = < 0x40027000 0x1000 >;
    			interrupts = < 0x27 0x1 >;
    			num-bidir-endpoints = < 0x1 >;
    			num-in-endpoints = < 0x7 >;
    			num-out-endpoints = < 0x7 >;
    			num-isoin-endpoints = < 0x1 >;
    			num-isoout-endpoints = < 0x1 >;
    			status = "okay";
    			label = "USBD";
    		};
    		wdt: wdt0: watchdog@40010000 {
    			compatible = "nordic,nrf-watchdog";
    			reg = < 0x40010000 0x1000 >;
    			interrupts = < 0x10 0x1 >;
    			status = "okay";
    			label = "WDT";
    		};
    		ficr: ficr@10000000 {
    			compatible = "nordic,nrf-ficr";
    			reg = < 0x10000000 0x1000 >;
    			status = "okay";
    		};
    		uicr: uicr@10001000 {
    			compatible = "nordic,nrf-uicr";
    			reg = < 0x10001000 0x1000 >;
    			status = "okay";
    		};
    		radio: radio@40001000 {
    			compatible = "nordic,nrf-radio";
    			reg = < 0x40001000 0x1000 >;
    			interrupts = < 0x1 0x1 >;
    			status = "okay";
    			dfe-ant-num = < 0x0 >;
    		};
    	};
    	cpus {
    		#address-cells = < 0x1 >;
    		#size-cells = < 0x0 >;
    		cpu@0 {
    			device_type = "cpu";
    			compatible = "arm,cortex-m4f";
    			reg = < 0x0 >;
    		};
    	};
    	sw_pwm: sw-pwm {
    		compatible = "nordic,nrf-sw-pwm";
    		status = "disabled";
    		label = "SW_PWM";
    		generator = < &timer2 >;
    		channel-count = < 0x3 >;
    		clock-prescaler = < 0x0 >;
    		ppi-base = < 0x0 >;
    		gpiote-base = < 0x0 >;
    		#pwm-cells = < 0x1 >;
    	};
    	leds {
    		compatible = "gpio-leds";
    		led0: led_0 {
    			gpios = < &gpio0 0xd 0x1 >;
    			label = "Green LED 0";
    		};
    		led1: led_1 {
    			gpios = < &gpio0 0xe 0x1 >;
    			label = "Green LED 1";
    		};
    		led2: led_2 {
    			gpios = < &gpio0 0xf 0x1 >;
    			label = "Green LED 2";
    		};
    		led3: led_3 {
    			gpios = < &gpio0 0x10 0x1 >;
    			label = "Green LED 3";
    		};
    	};
    	pwmleds {
    		compatible = "pwm-leds";
    		pwm_led0: pwm_led_0 {
    			pwms = < &pwm0 0xd >;
    		};
    	};
    	buttons {
    		compatible = "gpio-keys";
    		button0: button_0 {
    			gpios = < &gpio0 0xb 0x11 >;
    			label = "Push button switch 0";
    		};
    		button1: button_1 {
    			gpios = < &gpio0 0xc 0x11 >;
    			label = "Push button switch 1";
    		};
    		button2: button_2 {
    			gpios = < &gpio0 0x18 0x11 >;
    			label = "Push button switch 2";
    		};
    		button3: button_3 {
    			gpios = < &gpio0 0x19 0x11 >;
    			label = "Push button switch 3";
    		};
    	};
    	arduino_header: connector {
    		compatible = "arduino-header-r3";
    		#gpio-cells = < 0x2 >;
    		gpio-map-mask = < 0xffffffff 0xffffffc0 >;
    		gpio-map-pass-thru = < 0x0 0x3f >;
    		gpio-map = < 0x0 0x0 &gpio0 0x3 0x0 >, < 0x1 0x0 &gpio0 0x4 0x0 >, < 0x2 0x0 &gpio0 0x1c 0x0 >, < 0x3 0x0 &gpio0 0x1d 0x0 >, < 0x4 0x0 &gpio0 0x1e 0x0 >, < 0x5 0x0 &gpio0 0x1f 0x0 >, < 0x6 0x0 &gpio1 0x1 0x0 >, < 0x7 0x0 &gpio1 0x2 0x0 >, < 0x8 0x0 &gpio1 0x3 0x0 >, < 0x9 0x0 &gpio1 0x4 0x0 >, < 0xa 0x0 &gpio1 0x5 0x0 >, < 0xb 0x0 &gpio1 0x6 0x0 >, < 0xc 0x0 &gpio1 0x7 0x0 >, < 0xd 0x0 &gpio1 0x8 0x0 >, < 0xe 0x0 &gpio0 0x11 0x0 >, < 0xf 0x0 &gpio0 0x13 0x0 >, < 0x10 0x0 &gpio0 0x14 0x0 >, < 0x11 0x0 &gpio0 0x15 0x0 >, < 0x12 0x0 &gpio0 0x16 0x0 >, < 0x13 0x0 &gpio0 0x17 0x0 >, < 0x14 0x0 &gpio0 0x1a 0x0 >, < 0x15 0x0 &gpio0 0x1b 0x0 >;
    		phandle = < 0x3 >;
    	};
    };
    

  • Hello again!

    Just spent some time debugging your code. You need to include the size of your access buffer in order for the tx buffer to be valid for transfer. I made it work using this code:

    	uint8_t access[3] = {0};
    	struct spi_buf bufs[] = {
    		{
    			.buf = access,
                .len = sizeof(access) //ADD HERE
    		},
    		{
    			.buf = data,
    			.len = len
    		}


    Best regards,
    Carl Richard

  • Carl,

    I had tried hard coding this previously to no success. I just tried doing it via your recommended and I still am having issues with incorrect MOSI output.

    I am expecting to see "1001 1111" (0x9F) on my scope from MOSI. I am seeing "11 1001 1111" (0x39F), see the pictures of my scope below. I took multiple pictures showing the time delta of each high/low.

    Note: I have specified SPI to operate at 256,000 Hz both in code and overlay config. This gives a period of ~4us.



    I have stepped through the debugger and can't see what is wrong based off the values being passed to the Zephyr SPI functions according to their documentation. Here is that screenshot:



    And here is the doc page for the OP code I am trying to send in case you want some context:

    Best,

    Sam

  • Hello again, Sam!

    Thank you for your patience with this. I have done some more testing and can verify that I see the same as you on the MOSI line. However, the actual decoded SPI data is correct as the clock (SCK) isn't running during the first two bytes. I.e: if the end device behaves correctly and starts reading with the SCK it should only get 0x9F.

    Isn't it responding correctly?

    Best regards,
    Carl Richard

Related