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
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.