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

Reading JEDEC ID with SPI on nrf9160

Hello,

I have an external flash w25n01gv, I am using this simple spi loopback example to test the spi functionality of nrf9160. I want to read the jedec id of my device and my code is like:

/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>

#include <sys/printk.h>

#include <drivers/spi.h>

//addition for combining blinky

static struct spi_config spi_cfg = {
  .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
  SPI_MODE_CPOL | SPI_MODE_CPHA,
  .frequency = 4000000,
  .slave = 0,
};

struct device * spi_dev;

static void spi_init(void) {
    const char *
      const spiName = "SPI_3";
    spi_dev = device_get_binding(spiName);

    if (spi_dev == NULL) {
      printk("Could not get %s device\n", spiName);
      return;
    }
}

void spi_test_send(void) {
  int err;
  //static u8_t tx_buffer[1];
  //static u8_t rx_buffer[1];
  static u8_t tx_buffer[2] = {
	0X9F,
	0x00
  };
  static u8_t rx_buffer[3];

  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
  };

  struct device * gpio_dev;
  struct spi_cs_control cs_control;

  gpio_dev = device_get_binding("GPIO_0");
  if (!gpio_dev) {
	printk("could not find GPIO device\n");
	return;
  }
  cs_control.delay = 0;
  cs_control.gpio_dev = gpio_dev;
  cs_control.gpio_pin = 13;
  spi_cfg.cs = & cs_control;

  err = spi_transceive(spi_dev, & spi_cfg, & tx, & rx);

  if (err) {
	printk("SPI error: %d\n", err);
  } else {
	/* Connect MISO to MOSI for loopback */

	for (int i = 0; i < 2; i++) {
	  printk("TX transmit: %x\n", tx_buffer[i]);
	}

	for (int i = 0; i < 3; i++) {
	  printk("RX recv: %x\n", rx_buffer[i]);
	}
  }
}

void main(void) {
  printk("SPIM Example\n");
  spi_init();
  printk("After init\n");
  while (1) {
	spi_test_send();
	k_sleep(K_MSEC(1000));
	printk(".");
  }
}

The dataset of my externaş flash says:

so I am expecting to get Ef,AA,2f however what I am receiving is 00 00 ef. I also connected the output pins to logic analyzer but the clk signal and miso also doesn't seems right. What am I doing wrong in the code can you provide me some feedback about it. In the original code before I just do simple modifications I was observing the loopback properly. I was receiving what I was sending so the code was working properly. 

To adjust the chip select I am only using this code:

struct device * gpio_dev;
struct spi_cs_control cs_control;

gpio_dev = device_get_binding("GPIO_0");
if (!gpio_dev) {
  printk("could not find GPIO device\n");
  return;
}
cs_control.delay = 0;
cs_control.gpio_dev = gpio_dev;
cs_control.gpio_pin = 13;
spi_cfg.cs = & cs_control;

does that code changes cs from 1 to 0 automatically? I am doing something wrong in that part?

My overlay file is :

&spi3 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    sck-pin = <11>;
    mosi-pin = <10>;
    miso-pin = <12>;
};

My proj.config is:

# CONFIG_BOARD_ENABLE_CPUNET=n
CONFIG_SPI=y
CONFIG_MAIN_STACK_SIZE=4096
# CONFIG_SPI_0=y
# UART, SPIM, and I2C are shared peripherals on nrf9160
# therefore we choose SPI3
CONFIG_SPI_3=y
CONFIG_SPI_NRFX=y
CONFIG_DEPRECATED_ZEPHYR_INT_TYPES=y

#addition for combining blinky
CONFIG_GPIO=y

Thank you for the help.

Parents Reply
  • Hi Simon,

    I already found that and tried. The problem is that flash has an already existing driver I think thats the problem why it doesn't work for my case. What should I wrote these parts in the code:

    #if (CONFIG_SPI_FLASH_W25QXXDV - 0)
    /* NB: W25Q16DV is a JEDEC spi-nor device, but has a separate driver. */
    #define FLASH_DEVICE CONFIG_SPI_FLASH_W25QXXDV_DRV_NAME
    #define FLASH_NAME "W25QXXDV"
    

    the overlay that the sample used is:

    &spi3 {
            compatible = "nordic,nrf-spim";
            status = "okay";
            sck-pin = <10>;
            mosi-pin = <11>;
            miso-pin = <12>;
            cs-gpios = <&gpio0 13 0>;
    
            w25q32@0 {
                    compatible = "winbond,w25q32", "jedec,spi-nor";
                    label = "W25Q32";
                    reg = <0>;
                    jedec-id = [ef 40 16];
                    size = <0x4000000>;
                    spi-max-frequency = <1000000>;
            };
    };
    
    

    I tried to change the whole code acccording to my external flash which has very similar command set with spi_nor so I though that I can directly use it as my driver then I implemented the code in the following:

    main.c:

    /*
     * Copyright (c) 2016 Intel Corporation.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <drivers/flash.h>
    #include <device.h>
    #include <devicetree.h>
    #include <stdio.h>
    #include <string.h>
    
    #if (CONFIG_SPI_FLASH_W25N01GV - 0)
    /* NB: W25Q16DV is a JEDEC spi-nor device, but has a separate driver. */
    #define FLASH_DEVICE CONFIG_SPI_FLASH_W25N01GV_DRV_NAME
    #define FLASH_NAME "W25N01GV"
    #elif (CONFIG_SPI_NOR - 0) ||				\
    	DT_NODE_HAS_STATUS(DT_INST(0, jedec_spi_nor), okay)
    #define FLASH_DEVICE DT_LABEL(DT_INST(0, jedec_spi_nor))
    #define FLASH_NAME "JEDEC SPI-NOR"
    #elif (CONFIG_NORDIC_QSPI_NOR - 0) || \
    	DT_NODE_HAS_STATUS(DT_INST(0, nordic_qspi_nor), okay)
    #define FLASH_DEVICE DT_LABEL(DT_INST(0, nordic_qspi_nor))
    #define FLASH_NAME "JEDEC QSPI-NOR"
    #else
    #error Unsupported flash driver
    #endif
    
    #if defined(CONFIG_BOARD_ADAFRUIT_FEATHER_STM32F405)
    #define FLASH_TEST_REGION_OFFSET 0xf000
    #else
    #define FLASH_TEST_REGION_OFFSET 0xff000
    #endif
    #define FLASH_SECTOR_SIZE        4096
    
    
    
    
    void main(void)
    {
    	const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 };
    	const size_t len = sizeof(expected);
    	uint8_t buf[sizeof(expected)];
    	const struct device *flash_dev;
    	int rc;
    
    	printf("\n" FLASH_NAME " SPI flash testing\n");
    	printf("==========================\n");
    
    	flash_dev = device_get_binding(FLASH_DEVICE);
    
    	if (!flash_dev) {
    		printf("SPI flash driver %s was not found!\n",
    		       FLASH_DEVICE);
    		return;
    	}
    
    	/* Write protection needs to be disabled before each write or
    	 * erase, since the flash component turns on write protection
    	 * automatically after completion of write and erase
    	 * operations.
    	 */
    	printf("\nTest 1: Flash erase\n");
    	flash_write_protection_set(flash_dev, false);
    
    	rc = flash_erase(flash_dev, FLASH_TEST_REGION_OFFSET,
    			 FLASH_SECTOR_SIZE);
    	if (rc != 0) {
    		printf("Flash erase failed! %d\n", rc);
    	} else {
    		printf("Flash erase succeeded!\n");
    	}
    
    	printf("\nTest 2: Flash write\n");
    	flash_write_protection_set(flash_dev, false);
    
    	printf("Attempting to write %u bytes\n", len);
    	rc = flash_write(flash_dev, FLASH_TEST_REGION_OFFSET, expected, len);
    	if (rc != 0) {
    		printf("Flash write failed! %d\n", rc);
    		return;
    	}
    
    	memset(buf, 0, len);
    	rc = flash_read(flash_dev, FLASH_TEST_REGION_OFFSET, buf, len);
    	if (rc != 0) {
    		printf("Flash read failed! %d\n", rc);
    		return;
    	}
    
    	if (memcmp(expected, buf, len) == 0) {
    		printf("Data read matches data written. Good!!\n");
    	} else {
    		const uint8_t *wp = expected;
    		const uint8_t *rp = buf;
    		const uint8_t *rpe = rp + len;
    
    		printf("Data read does not match data written!!\n");
    		while (rp < rpe) {
    			printf("%08x wrote %02x read %02x %s\n",
    			       (uint32_t)(FLASH_TEST_REGION_OFFSET + (rp - buf)),
    			       *wp, *rp, (*rp == *wp) ? "match" : "MISMATCH");
    			++rp;
    			++wp;
    		}
    	}
    }
    

    overlay:

    &spi3 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    sck-pin = <10>;
    mosi-pin = <11>;
    miso-pin = <12>;
    cs-gpios = <&gpio0 13 0>;
    
    w25n01gv@0 {
    //compatible = "winbond,w25q32", "jedec,spi-nor";
    compatible = "jedec,spi-nor";
    label = "W25N01GV";
    reg = <0>;
    jedec-id = [ef AA 21];
    size = <0x4000000>;
    spi-max-frequency = <4000000>;
    };
    };
    
    

    proj.conf

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_FLASH=y
    CONFIG_SPI=y
    CONFIG_SPI_NOR=y

    In the output it says that:

    Can you guide me please what I am missing?

    Thank you for the help so much

Children
Related