Hi,
I'm developing my custom board with nrf52840 to work with Matter. I designed the board to make it as similar as possible to the development kit so I used the same external flash (mx25r6435f). When flashing Matter template sample (sdk v2.3.0) I see the following error in the console:
I: nRF5 802154 radio initialized
E: JEDEC id [00 00 00] expect [c2 28 17]
I: 4 Sectors of 4096 bytes
I: alloc wra: 1, f80
I: data wra: 1, 1c8
However, when testing external flash with spi_flash everything works. What can cause problems with the external flash only in Matter examples?
This is part of my dts file:
&qspi { status = "okay"; pinctrl-0 = <&qspi_default>; pinctrl-1 = <&qspi_sleep>; pinctrl-names = "default", "sleep"; mx25r64: mx25r6435f@0 { compatible = "nordic,qspi-nor"; reg = <0>; /* MX25R64 supports only pp and pp4io */ writeoc = "pp4io"; /* MX25R64 supports all readoc options */ readoc = "read4io"; sck-frequency = <8000000>; jedec-id = [c2 28 17]; sfdp-bfp = [ e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 68 44 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff ]; size = <67108864>; has-dpd; t-enter-dpd = <10000>; t-exit-dpd = <35000>; }; };
and according to the example I created this overlay for my custom board:
/* Copyright (c) 2021 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ / { chosen { nordic,pm-ext-flash = &mx25r64; }; }; / { /* * In some default configurations within the nRF Connect SDK, * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. * This devicetree overlay ensures that default is overridden wherever it * is set, as this application uses the RNG node for entropy exclusively. */ chosen { zephyr,entropy = &rng; }; }; /* Disable unused peripherals to reduce power consumption */ &adc { status = "disabled"; }; &uart1 { status = "disabled"; }; &pwm0 { status = "disabled"; }; &spi1 { status = "disabled"; }; &spi3 { status = "disabled"; }; &usbd { status = "disabled"; };
The spi_flash code I used to test external flash:
/* * Copyright (c) 2016 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/kernel.h> #include <zephyr/drivers/flash.h> #include <zephyr/device.h> #include <zephyr/devicetree.h> #include <stdio.h> #include <string.h> #if defined(CONFIG_BOARD_ADAFRUIT_FEATHER_STM32F405) #define SPI_FLASH_TEST_REGION_OFFSET 0xf000 #elif defined(CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1) || \ defined(CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M3) /* The FPGA bitstream is stored in the lower 536 sectors of the flash. */ #define SPI_FLASH_TEST_REGION_OFFSET \ DT_REG_SIZE(DT_NODE_BY_FIXED_PARTITION_LABEL(fpga_bitstream)) #elif defined(CONFIG_BOARD_NPCX9M6F_EVB) || \ defined(CONFIG_BOARD_NPCX7M6FB_EVB) #define SPI_FLASH_TEST_REGION_OFFSET 0x7F000 #else #define SPI_FLASH_TEST_REGION_OFFSET 0xff000 #endif #define SPI_FLASH_SECTOR_SIZE 8192 void single_sector_test(const struct device *flash_dev) { const uint8_t expected[] = { 0x55, 0xaa, 0x66, 0x99 }; const size_t len = sizeof(expected); uint8_t buf[sizeof(expected)]; int rc; printf("\nPerform test on single sector"); /* 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"); /* Full flash erase if SPI_FLASH_TEST_REGION_OFFSET = 0 and * SPI_FLASH_SECTOR_SIZE = flash size */ rc = flash_erase(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, SPI_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"); printf("Attempting to write %zu bytes\n", len); rc = flash_write(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, expected, len); if (rc != 0) { printf("Flash write failed! %d\n", rc); return; } while (true) { memset(buf, 0, len); rc = flash_read(flash_dev, SPI_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)(SPI_FLASH_TEST_REGION_OFFSET + (rp - buf)), *wp, *rp, (*rp == *wp) ? "match" : "MISMATCH"); ++rp; ++wp; } } k_msleep(100); } } int main(void) { const struct device *flash_dev = DEVICE_DT_GET(DT_ALIAS(spi_flash0)); if (!device_is_ready(flash_dev)) { printk("%s: device not ready.\n", flash_dev->name); return 0; } printf("\n%s SPI flash testing\n", flash_dev->name); printf("==========================\n"); single_sector_test(flash_dev); return 0; }