Can't open file with littleFS and I2S in nRF52840 and nRF Connect SDK 2.4.1

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.

Related