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