/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <audio/dmic.h>

#define LOG_LEVEL LOG_LEVEL_INF
#include <logging/log.h>
LOG_MODULE_REGISTER(dmic_sample);

#define AUDIO_SAMPLE_FREQ	48000
#define AUDIO_SAMPLE_WIDTH	32
#define SAMPLES_PER_FRAME	(64)

#define NUM_MIC_CHANNELS	8
#define MIC_FRAME_SAMPLES	(SAMPLES_PER_FRAME * NUM_MIC_CHANNELS)
#define MIC_FRAME_BYTES		(MIC_FRAME_SAMPLES * AUDIO_SAMPLE_WIDTH / 8)

#define LP_SRAM_BASE		0xBE800000
#define LP_SRAM_BASE_UNCACHED	0x9E800000
#define LP_SRAM_SIZE		(16 << 10)

#define DMIC_DEV_NAME		"PDM"
#define MIC_IN_BUF_COUNT	2

#define FRAMES_PER_ITERATION	100
#define NUM_ITERATIONS		4
#define DELAY_BTW_ITERATIONS	K_MSEC(20)

static struct k_mem_slab dmic_mem_slab;
static char audio_buffers[MIC_FRAME_BYTES * MIC_IN_BUF_COUNT];
static struct device *dmic_device;

static void dmic_init(void)
{
	int ret;
	struct pcm_stream_cfg stream = {
		.pcm_rate		= AUDIO_SAMPLE_FREQ,
		.pcm_width		= AUDIO_SAMPLE_WIDTH,
		.block_size		= MIC_FRAME_BYTES,
		.mem_slab		= &dmic_mem_slab,
	};
	struct dmic_cfg cfg = {
		.io = {
			.min_pdm_clk_freq	= 1024000,
			.max_pdm_clk_freq	= 4800000,
			.min_pdm_clk_dc		= 48,
			.max_pdm_clk_dc		= 52,
			.pdm_clk_pol		= 0,
			.pdm_data_pol		= 0,
		},
		.streams			= &stream,
		.channel = {
			.req_chan_map_lo	=
				dmic_build_channel_map(0, 0, PDM_CHAN_RIGHT) |
				dmic_build_channel_map(1, 0, PDM_CHAN_LEFT) |
				dmic_build_channel_map(2, 2, PDM_CHAN_RIGHT) |
				dmic_build_channel_map(3, 2, PDM_CHAN_LEFT) |
				dmic_build_channel_map(4, 1, PDM_CHAN_RIGHT) |
				dmic_build_channel_map(5, 1, PDM_CHAN_LEFT) |
				dmic_build_channel_map(6, 3, PDM_CHAN_RIGHT) |
				dmic_build_channel_map(7, 3, PDM_CHAN_LEFT),
			.req_num_chan		= NUM_MIC_CHANNELS,
			.req_num_streams	= 1,
		},
	};

	k_mem_slab_init(&dmic_mem_slab, audio_buffers, MIC_FRAME_BYTES,
			MIC_IN_BUF_COUNT);
	dmic_device = device_get_binding(DMIC_DEV_NAME);
	if (!dmic_device) {
		LOG_ERR("unable to find device %s", DMIC_DEV_NAME);
		return;
	}

	ret = dmic_configure(dmic_device, &cfg);
	if (ret != 0) {
		LOG_ERR("dmic_configure failed with %d error", ret);
	}
}

static void dmic_start(void)
{
	int ret;

	LOG_DBG("starting dmic");
	ret = dmic_trigger(dmic_device, DMIC_TRIGGER_START);
	if (ret) {
		LOG_ERR("dmic_trigger failed with code %d", ret);
	}
}

static void dmic_receive(void)
{
	int frame_counter = 0;
	s32_t *mic_in_buf;
	size_t size;
	int ret;

	while (frame_counter++ < FRAMES_PER_ITERATION) {
		ret = dmic_read(dmic_device, 0, (void **)&mic_in_buf, &size,
				K_FOREVER);
		if (ret) {
			LOG_ERR("dmic_read failed %d", ret);
		} else {
			LOG_DBG("dmic_read buffer %p size %u frame %d",
					mic_in_buf, size, frame_counter);
			k_mem_slab_free(&dmic_mem_slab, (void **)&mic_in_buf);
		}
	}
}

static void dmic_stop(void)
{
	int ret;

	ret = dmic_trigger(dmic_device, DMIC_TRIGGER_STOP);
	if (ret) {
		LOG_ERR("dmic_trigger failed with code %d", ret);
	} else {
		LOG_DBG("dmic stopped");
	}
}

static void dmic_sample_app(void *p1, void *p2, void *p3)
{
	int loop_count = 0;

	dmic_init();

	LOG_INF("Starting DMIC sample app ...");
	while (loop_count++ < NUM_ITERATIONS) {
		dmic_start();
		dmic_receive();
		dmic_stop();
		k_sleep(DELAY_BTW_ITERATIONS);
		LOG_INF("Iteration %d/%d complete, %d audio frames received.",
				loop_count, NUM_ITERATIONS,
				FRAMES_PER_ITERATION);
	}
	LOG_INF("Exiting DMIC sample app ...");
}

K_THREAD_DEFINE(dmic_sample, 1024, dmic_sample_app, NULL, NULL, NULL, 10, 0,
		K_NO_WAIT);
