nr52832 + nRF Connect 1.8.0 + External Flash

Hello Team,

We are interfacing nRF52832 with an external flash for data storage. Could you please point to the right document/link/code reference on how to interface external flash (on SPI) with nRF52832 on nRF Connect SDK 1.8.0?

Thanks!

Parents Reply Children
  • Hi Hakon,

    Thank you very much for the reference. It helped and I've setup my flash with it. However, I've a couple of issues. Could you please guide?

    1. Wrong page size info:

    Page size I am getting is: 65536. For W25Q80DV, page size is 256 bytes. Chip size is correct.

    W25Q80DV SPI flash testing
    ==========================
    Using W25Q80DV, chip size: 1048576 bytes (page: 65536)

    2. Fails to get the Device in first attempt.

    When I flash the device for the first time using JTAG (I use VS Code so whenever I flash the program it resets the chip), it always fail to get the device.

    W25Q80DV SPI flash testing
    ==========================
    SPI flash driver W25Q80DV was not found!

    However, if I reset my device using reset button it gets the driver and can write/read the chip.

    W25Q80DV SPI flash testing
    ==========================
    Using W25Q80DV, chip size: 1048576 bytes (page: 65536)
    
    Test 1: Flash erase
    Flash erase succeeded!
    
    Test 2: Flash write
    Attempting to write 4 bytes
    Data read matches data written. Good!!

    Reference:

    Overlayfile

    arduino_spi: &spi2 {
    	compatible = "nordic,nrf-spi";
    	status = "okay";
    	sck-pin = <27>;
    	mosi-pin = <26>;
    	miso-pin = <28>;
    	cs-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
    
    	w25q80dv: w25q80dv@0 {
    		compatible = "jedec,spi-nor";
    		label = "W25Q80DV";
    		reg = <0>;
    		spi-max-frequency = <40000000>;
    		//wp-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
    		//hold-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
    		size = <0x800000>;
    		has-dpd;
    		t-enter-dpd = <3000>;
    		t-exit-dpd = <30000>;
    		jedec-id = [ef 40 14];
    	};
    };
    

    SPI flash test Code: (ref: samples/drivers/spi_flash)

    void spi_test_flash_api(void)
    {
    #define FLASH_NAME "W25Q80DV"
    #define FLASH_TEST_REGION_OFFSET (0xff000)
    #define FLASH_SECTOR_SIZE (4096)
    #define FLASH_DEVICE DT_LABEL(DT_INST(0, jedec_spi_nor))
    
            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;
            
            const char *const spiName = "W25Q80DV";
    
            printk("\n" FLASH_NAME " SPI flash testing\n");
    
            printk("==========================\n");
    
            flash_dev = device_get_binding(FLASH_NAME);
            if (!flash_dev)
            {
                    printk("SPI flash driver %s was not found!\n",
                           FLASH_NAME);
                    return;
            }
    
    #ifdef CONFIG_FLASH_PAGE_LAYOUT
            struct flash_pages_info pages_info;
            size_t page_count, chip_size;
            page_count = flash_get_page_count(flash_dev);
            (void)flash_get_page_info_by_idx(flash_dev, 0, &pages_info);
            chip_size = page_count * pages_info.size;
            printk("Using %s, chip size: %u bytes (page: %u)\n",
                   FLASH_NAME, chip_size, pages_info.size);
    
    #endif
    
            /* 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.
             */
            printk("\nTest 1: Flash erase\n");
    
            rc = flash_erase(flash_dev, FLASH_TEST_REGION_OFFSET,
                             FLASH_SECTOR_SIZE);
            if (rc != 0)
            {
                    printk("Flash erase failed! %d\n", rc);
            }
            else
            {
                    printk("Flash erase succeeded!\n");
            }
    
    
            printk("\nTest 2: Flash write\n");
            printk("Attempting to write %zu bytes\n", len);
            rc = flash_write(flash_dev, FLASH_TEST_REGION_OFFSET, expected, len);
            if (rc != 0)
            {
                    printk("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)
            {
                    printk("Flash read failed! %d\n", rc);
                    return;
            }
    
            if (memcmp(expected, buf, len) == 0)
            {
                    printk("Data read matches data written. Good!!\n");
            }
            else
            {
                    const uint8_t *wp = expected;
                    const uint8_t *rp = buf;
                    const uint8_t *rpe = rp + len;
    
                    printk("Data read does not match data written!!\n");
                    while (rp < rpe)
                    {
                            printk("%08x wrote %02x read %02x %s\n",
                                   (uint32_t)(FLASH_TEST_REGION_OFFSET + (rp - buf)),
                                   *wp, *rp, (*rp == *wp) ? "match" : "MISMATCH");
                            ++rp;
                            ++wp;
                    }
            }
    }
    

    Thanks!

  • embeddedER said:

    Thank you very much for the reference. It helped and I've setup my flash with it. However, I've a couple of issues. Could you please guide?

    1. Wrong page size info:

    Page size I am getting is: 65536. For W25Q80DV, page size is 256 bytes. Chip size is correct.

    I believe the erase sector on your flash is 4k aligned?

    Could you try adding this config?

    CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096

    embeddedER said:

    2. Fails to get the Device in first attempt.

    When I flash the device for the first time using JTAG (I use VS Code so whenever I flash the program it resets the chip), it always fail to get the device.

    Since it works after a reset, it indicates that everything else is running as intended, meaning that the physical setup etc is OK.

    Could you try setting the page size to 4k and see if this issue still happens?

     

    Kind regards,

    Håkon

Related