Hi,
I want to make external flash with little fs where wave files are stored, and with I2S play this files.
I have an example based on v2.4.1/zephyr/samples/hello_world
My prj.conf
# Flash CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_MPU_ALLOW_FLASH_WRITE=y # Bluetooth CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="Intonavi" CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y # Change TX Power # FOTA CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y CONFIG_SECURE_BOOT=y CONFIG_SB_SIGNING_KEY_FILE="priv.pem" # QSPI CONFIG_NORDIC_QSPI_NOR=y # Little FS CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_LITTLEFS=y # I2S CONFIG_I2S=y
My pm_static.yml
EMPTY_0: address: 0x15200 end_address: 0x16000 placement: before: - s1_pad region: flash_primary size: 0xe00 EMPTY_1: address: 0x22200 end_address: 0x23000 placement: before: - mcuboot_pad region: flash_primary size: 0xe00 EMPTY_2: address: 0xfd000 end_address: 0xfe000 placement: after: - mcuboot_secondary region: flash_primary size: 0x1000 app: address: 0x23200 end_address: 0x90000 region: flash_primary size: 0x6ce00 app_image: address: 0x23200 end_address: 0x90000 orig_span: &id001 - app region: flash_primary size: 0x6ce00 span: *id001 b0: address: 0x0 end_address: 0x8000 placement: after: - start region: flash_primary size: 0x8000 b0_container: address: 0x0 end_address: 0x9000 orig_span: &id002 - b0 - provision region: flash_primary size: 0x9000 span: *id002 data_storage: address: 0xfe000 end_address: 0x100000 region: flash_primary size: 0x2000 mcuboot: address: 0x9200 end_address: 0x15200 placement: before: - mcuboot_primary region: flash_primary sharers: 0x1 size: 0xc000 mcuboot_pad: address: 0x23000 end_address: 0x23200 placement: align: start: 0x1000 before: - mcuboot_primary_app region: flash_primary sharers: 0x2 size: 0x200 mcuboot_primary: address: 0x23000 end_address: 0x90000 orig_span: &id003 - mcuboot_pad - app region: flash_primary sharers: 0x1 size: 0x6d000 span: *id003 mcuboot_primary_app: address: 0x23200 end_address: 0x90000 orig_span: &id004 - app region: flash_primary size: 0x6ce00 span: *id004 mcuboot_secondary: address: 0x90000 end_address: 0xfd000 placement: after: - mcuboot_primary align: start: 0x1000 align_next: 0x1000 region: flash_primary share_size: - mcuboot_primary size: 0x6d000 provision: address: 0x8000 end_address: 0x9000 placement: after: - b0 align: start: 0x1000 region: flash_primary size: 0x1000 s0: address: 0x9000 end_address: 0x15200 orig_span: &id005 - mcuboot - s0_pad region: flash_primary size: 0xc200 span: *id005 s0_image: address: 0x9200 end_address: 0x15200 orig_span: &id006 - mcuboot region: flash_primary size: 0xc000 span: *id006 s0_pad: address: 0x9000 end_address: 0x9200 placement: after: - b0_container align: start: 0x1000 region: flash_primary share_size: - mcuboot_pad size: 0x200 s1: address: 0x16000 end_address: 0x22200 orig_span: &id007 - s1_pad - s1_image region: flash_primary size: 0xc200 span: *id007 s1_image: address: 0x16200 end_address: 0x22200 placement: after: - s1_pad - s0 region: flash_primary share_size: - mcuboot size: 0xc000 s1_pad: address: 0x16000 end_address: 0x16200 placement: after: - s0 align: start: 0x1000 region: flash_primary share_size: - mcuboot_pad size: 0x200 data_storage: address: 0xfe000 end_address: 0x100000 placement: before: - end region: flash_primary size: 0x2000 sram_primary: address: 0x20000000 end_address: 0x20040000 region: sram_primary size: 0x40000 external_flash: address: 0x0 end_address: 0x800000 region: external_flash size: 0x800000 littlefs_storage: address: 0x0 device: mx25r64 end_address: 0x800000 region: external_flash size: 0x800000
My nrf52840dk_nrf52840.overlay
/ { chosen { nordic,pm-ext-flash = &mx25r64; }; }; &pinctrl { i2s0_default_alt: i2s0_default_alt { group1 { psels = <NRF_PSEL(I2S_SCK_M, 1, 15)>, <NRF_PSEL(I2S_LRCK_M, 1, 12)>, <NRF_PSEL(I2S_SDOUT, 1, 13)>, <NRF_PSEL(I2S_SDIN, 1, 14)>; }; }; }; i2s_rxtx: &i2s0 { status = "okay"; pinctrl-0 = <&i2s0_default_alt>; pinctrl-names = "default"; };
My main.c
#include <zephyr/kernel.h> #include <zephyr/fs/fs.h> #include <zephyr/fs/littlefs.h> #include <zephyr/device.h> #include <zephyr/drivers/i2s.h> FS_LITTLEFS_DECLARE_DEFAULT_CONFIG (storage); static struct fs_mount_t lfs_storage_mnt = { .type = FS_LITTLEFS, .fs_data = &storage, .storage_dev = (void *)FLASH_AREA_ID(littlefs_storage), .mnt_point = "/lfs", }; #define SAMPLE_FREQUENCY 44100 #define SAMPLE_BIT_WIDTH 16 #define BYTES_PER_SAMPLE sizeof(int16_t) #define NUMBER_OF_CHANNELS 1 /* Such block length provides an echo with the delay of 100 ms. */ #define SAMPLES_PER_BLOCK ((SAMPLE_FREQUENCY / 10) * NUMBER_OF_CHANNELS) #define TIMEOUT 1000 #define INITIAL_BLOCKS 2 #define BLOCK_SIZE (BYTES_PER_SAMPLE * SAMPLES_PER_BLOCK) #define BLOCK_COUNT (INITIAL_BLOCKS) K_MEM_SLAB_DEFINE_STATIC(mem_slab, BLOCK_SIZE, BLOCK_COUNT, 4); int main(void) { printk("Hello World! %s\n", CONFIG_BOARD); int ret = 0; const struct device *const i2s_dev = DEVICE_DT_GET(DT_NODELABEL(i2s_rxtx)); if (i2s_dev == NULL) { printk("I2S device not found\n"); return 0; } else printk("I2S device is found\n"); struct i2s_config i2s_cfg = { .word_size = BYTES_PER_SAMPLE, .channels = NUMBER_OF_CHANNELS, .format = I2S_FMT_DATA_FORMAT_I2S | I2S_FMT_CLK_NF_NB, .options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER, .frame_clk_freq = SAMPLE_FREQUENCY, .block_size = BLOCK_SIZE, .timeout = TIMEOUT, .mem_slab = &mem_slab }; // BLOCK 1 --------------------------------- ret = i2s_configure(i2s_dev, I2S_DIR_TX, &i2s_cfg); if (ret < 0) { printk ("Failed to configure I2S\n"); return 0; } else printk ("I2S configured OK: %d\n", ret); // END BLOCK 1 --------------------------------- ret = fs_mount (&lfs_storage_mnt); if (ret < 0) { printf("Error mounting LittleFS: %d\n", ret); return 0; } // BLOCK 2 --------------------------------- struct fs_statvfs stat; ret = fs_statvfs("/lfs", &stat); if (ret < 0) { printf("Error getting filesystem status: %d\n", ret); return 0; } printk ("%s: bsize = %lu ; frsize = %lu ; blocks = %lu ; bfree = %lu\n", lfs_storage_mnt.mnt_point, stat.f_bsize, stat.f_frsize, stat.f_blocks, stat.f_bfree); // END BLOCK 2 --------------------------------- struct fs_file_t file; const char *file_path = "/lfs/sound"; ret = fs_open(&file, file_path, FS_O_CREATE | FS_O_RDWR); if (ret < 0) { printk("FAIL: open %s: %d\n", file_path, ret); return 0; } else printk("Opend %s: %d\n", file_path, ret); fs_close(&file); return 0; }
Little FS is mounted OK.
I2S device are also found OK
i2s_configure also OK.
fs_statvfs always return corrected values.
But problem is with fs_open.
1. When flash this code I got error -16 when try to open file with fs_open.
2. When I comment "BLOCK 1" fs_open return 0, so everything is OK. Running before fs_open function fs_statvfs magically make everyfing OK.
3. When I comment also "BLOCK 2" (both blocks are commented) I got error -16. Simply open file with fs_open without fs_statvfs return -16.