Using the flash : https://datasheet4u.com/download_new.php?id=1588116
on SPI : XF_CS (P0.13), SCLK (P1.09) , SDI (P0.08) , SDO (P0.05)
Flash specific parts in the nrf52840dk_nrf52840.overlay
&pinctrl {
uart1_default: uart1_default {
group1 {
psels = <NRF_PSEL(UART_TX, 1, 1)>;
};
group2 {
psels = <NRF_PSEL(UART_RX, 1, 4)>;
bias-pull-up;
};
};
uart1_sleep: uart1_sleep {
group1 {
psels = <NRF_PSEL(UART_TX, 1, 1)>;
};
group2 {
psels = <NRF_PSEL(UART_RX, 1, 4)>;
bias-pull-up;
};
};
i2c0_default: i2c0_default {
group1 {
psels = <NRF_PSEL(TWIM_SDA, 0, 0)>,
<NRF_PSEL(TWIM_SCL, 0, 1)>;
bias-pull-up;
};
};
i2c0_sleep: i2c0_sleep {
group1 {
psels = <NRF_PSEL(TWIM_SDA, 0, 0)>,
<NRF_PSEL(TWIM_SCL, 0, 1)>;
low-power-enable;
// bias-pull-up;
};
};
spi1_default: spi1_default {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 1, 9)>,
<NRF_PSEL(SPIM_MOSI, 0, 8)>,
<NRF_PSEL(SPIM_MISO, 0, 5)>;
};
};
spi1_sleep: spi1_sleep {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 1, 9)>,
<NRF_PSEL(SPIM_MOSI, 0, 8)>,
<NRF_PSEL(SPIM_MISO, 0, 5)>;
low-power-enable;
};
};
// spi2_default: spi2_default {
// group1 {
// psels = <NRF_PSEL(SPIM_SCK, 1, 9)>,
// <NRF_PSEL(SPIM_MOSI, 0, 8)>,
// <NRF_PSEL(SPIM_MISO, 0, 5)>;
// };
// };
// spi2_sleep: spi2_sleep {
// group1 {
// psels = <NRF_PSEL(SPIM_SCK, 1, 9)>,
// <NRF_PSEL(SPIM_MOSI, 0, 8)>,
// <NRF_PSEL(SPIM_MISO, 0, 5)>;
// low-power-enable;
// };
// };
};
&flash0
{
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
slot0_partition: partition@c000 {
reg = <0x0000C000 0x00066000>; /* 408 KiB */
};
slot1_partition: partition@72000 {
reg = <0x00072000 0x00066000>; /* 408 KiB */
};
storage_partition: partition@d8000 {
label = "storage";
reg = <0x000d8000 0x00028000>; /* 160 KiB */
};
};
};
&spi1 {
compatible = "nordic,nrf-spi";
status = "okay";
cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&spi1_default>;
pinctrl-1 = <&spi1_sleep>;
pinctrl-names = "default", "sleep";
mx25r64: mx25r6435f@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <32000000>;
jedec-id = [00 C8 60];
size = <536870912>; /* 512 MiB */
//wp-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
//hold-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
sfdp-bfp = [
e5 20 f3 ff ff ff ff 1f 44 eb 08 6b 08 3b 42 bb
fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52
10 d8 00 ff d4 39 a5 fe 82 d8 14 58 ec 62 16 33
7a 75 7a 75 04 bd d5 5c 29 06 14 00 08 50 00 01
];
// t-enter-dpd = <10000>;
// t-exit-dpd = <35000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
external_storage: partition@0 {
label = "external-storage";
reg = <0x00000000 0x00800000>;
};
};
};
};
/ {
msc_disk0 {
status = "okay";
compatible = "zephyr,flash-disk";
partition = <&external_storage>;
disk-name = "NAND";
cache-size = <4096>;
};
};
main.c
static int mount_app_fs(struct fs_mount_t *mnt)
{
// Clean initialization
mnt->type = FS_FATFS;
mnt->fs_data = &fat_fs;
/* This MUST match the 'disk-name' in your DeviceTree + a colon */
mnt->mnt_point = "/NAND:";
/* Use Disk Access API to bridge the Flash-Disk driver */
mnt->flags = FS_MOUNT_FLAG_USE_DISK_ACCESS;
return fs_mount(mnt);
}
static int setup_flash(struct fs_mount_t *mnt)
{
int rc = 0;
#if CONFIG_DISK_DRIVER_FLASH
unsigned int id;
const struct flash_area *pfa;
mnt->storage_dev = (void *)STORAGE_PARTITION_ID;
id = STORAGE_PARTITION_ID;
rc = flash_area_open(id, &pfa);
printk("Area %u at 0x%x on %s for %u bytes\n",
id, (unsigned int)pfa->fa_off, pfa->fa_dev->name,
(unsigned int)pfa->fa_size);
if (rc < 0 && IS_ENABLED(CONFIG_APP_WIPE_STORAGE)) {
printk("Erasing flash area ... ");
rc = flash_area_flatten(pfa, 0, pfa->fa_size);
printk("%d\n", rc);
}
if (rc < 0) {
flash_area_close(pfa);
}
#endif
return rc;
}
void setup_disk(void);
void setup_disk(void)
{
struct fs_mount_t *mp = &fs_mnt;
struct fs_dir_t dir;
struct fs_statvfs sbuf;
int rc;
fs_dir_t_init(&dir);
// if (IS_ENABLED(CONFIG_DISK_DRIVER_FLASH)) {
// rc = setup_flash(mp);
// if (rc < 0) {
// LOG_ERR("Failed to setup flash area");
// return;
// }
// }
// if (!IS_ENABLED(CONFIG_FILE_SYSTEM_LITTLEFS) &&
// !IS_ENABLED(CONFIG_FAT_FILESYSTEM_ELM)) {
// LOG_INF("No file system selected");
// return;
// }
rc = mount_app_fs(mp);
if (rc < 0) {
LOG_ERR("Failed to mount filesystem");
return;
}
/* Allow log messages to flush to avoid interleaved output */
k_sleep(K_MSEC(50));
printk("Mount %s: %d\n", fs_mnt.mnt_point, rc);
rc = fs_statvfs(mp->mnt_point, &sbuf);
if (rc < 0) {
printk("FAIL: statvfs: %d\n", rc);
return;
}
printk("%s: bsize = %lu ; frsize = %lu ;"
" blocks = %lu ; bfree = %lu\n",
mp->mnt_point,
sbuf.f_bsize, sbuf.f_frsize,
sbuf.f_blocks, sbuf.f_bfree);
rc = fs_opendir(&dir, mp->mnt_point);
printk("%s opendir: %d\n", mp->mnt_point, rc);
if (rc < 0) {
LOG_ERR("Failed to open directory");
}
while (rc >= 0) {
struct fs_dirent ent = { 0 };
rc = fs_readdir(&dir, &ent);
if (rc < 0) {
LOG_ERR("Failed to read directory entries");
break;
}
if (ent.name[0] == 0) {
printk("End of files\n");
break;
}
printk(" %c %zu %s\n",
(ent.type == FS_DIR_ENTRY_FILE) ? 'F' : 'D',
ent.size,
ent.name);
}
(void)fs_closedir(&dir);
return;
}