Загрузка данных


/* ... (ваши инклуды) ... */

// Теперь у нас два раздельных пула в DTCM
K_MEM_SLAB_DEFINE_IN_SECT_STATIC(mem_slab_rx, __dtcm_noinit_section, ZEPHYR_AUDIO_BLOCK_SIZE, ZEPHYR_AUDIO_BLOCK_COUNT, 4);
K_MEM_SLAB_DEFINE_IN_SECT_STATIC(mem_slab_tx, __dtcm_noinit_section, ZEPHYR_AUDIO_BLOCK_SIZE, ZEPHYR_AUDIO_BLOCK_COUNT, 4);

/* Модифицированная функция конфигурации: разделяем пулы для направлений */
static bool configure_streams(const struct device *i2s_dev_rx,
                              const struct device *i2s_dev_tx,
                              const struct i2s_config *base_config)
{
    int ret;
    struct i2s_config config = *base_config; // Копируем базу (частота, формат)

    /* Настройка RX */
    config.mem_slab = &mem_slab_rx;
    ret = i2s_configure(i2s_dev_rx, I2S_DIR_RX, &config);
    if (ret < 0) {
        printk("Failed to configure RX: %d\n", ret);
        return false;
    }

    /* Настройка TX */
    config.mem_slab = &mem_slab_tx;
    ret = i2s_configure(i2s_dev_tx, I2S_DIR_TX, &config);
    if (ret < 0) {
        printk("Failed to configure TX: %d\n", ret);
        return false;
    }

    return true;
}

/* Исправляем подготовку трансфера: блоки берем строго из TX пула */
static bool prepare_transfer(const struct device *i2s_dev_tx)
{
    int ret;

    for (int i = 0; i < ZEPHYR_AUDIO_INITIAL_BLOCKS; ++i) {
        void *mem_block;

        /* ОШИБКА ИСПРАВЛЕНА: используем mem_slab_tx */
        ret = k_mem_slab_alloc(&mem_slab_tx, &mem_block, K_NO_WAIT);
        if (ret < 0) {
            printk("Failed to allocate TX block from mem_slab_tx: %d\n", ret);
            return false;
        }

        memset(mem_block, 0, ZEPHYR_AUDIO_BLOCK_SIZE);

        ret = i2s_write(i2s_dev_tx, mem_block, ZEPHYR_AUDIO_BLOCK_SIZE);
        if (ret < 0) {
            printk("Failed to write block %d: %d\n", i, ret);
            return false;
        }
    }
    return true;
}

/* Изменяем функцию старта для корректного вызова */
int zephyr_i2s_start(uint8_t audio_in)
{
    printf("%s: audio_in=%d\n", __func__, audio_in);

    if (start_stream) return 0; // Уже запущено

    /* Для TX (динамика) нужно предварительно заполнить очередь "пустыми" блоками */
    if (!audio_in) {
        if (!prepare_transfer(i2s_dev_tx)) {
            return -1;
        }
    }

    /* Запускаем оба плеча SAI */
    if (!trigger_command(i2s_dev_rx, i2s_dev_tx, I2S_TRIGGER_START)) {
        return -1;
    }

    start_stream = 1;
    return 0;
}