/*
 * Copyright (c) 2020 Stephanos Ioannidis <root@stephanos.io>
 * Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <zephyr/zephyr.h>
#include <stdlib.h>
#include <arm_math.h>
#include "../../common/test_common.h"

#include "fir_q31.pat"

#define SNR_ERROR_THRESH	((float32_t)100)
#define ABS_ERROR_THRESH_Q31	((q31_t)2)

#define COEFF_PADDING		(4)

static void test_arm_fir_q31(void)
{
	size_t sample_index, block_index;
	size_t block_size, tap_count;
	size_t sample_count = ARRAY_SIZE(in_config) / 2;
	size_t length = ARRAY_SIZE(ref_val);
	const uint16_t *config = in_config;
	const q31_t *input = (const q31_t *)in_val;
	const q31_t *coeff = (const q31_t *)in_coeff;
	const q31_t *ref = (const q31_t *)ref_val;
	q31_t *state, *output_buf, *output;
	arm_fir_instance_q31 inst;
#if defined(CONFIG_ARMV8_1_M_MVEI) && defined(CONFIG_FPU)
	q31_t coeff_padded[32];
	int round;
#endif

	/* Allocate buffers */
	state = malloc(3 * 47 * sizeof(q31_t));
	zassert_not_null(state, ASSERT_MSG_BUFFER_ALLOC_FAILED);

	output_buf = malloc(length * sizeof(q31_t));
	zassert_not_null(output_buf, ASSERT_MSG_BUFFER_ALLOC_FAILED);

	output = output_buf;

	/* Enumerate samples */
	for (sample_index = 0; sample_index < sample_count; sample_index++) {
		/* Resolve sample configurations */
		block_size = config[0];
		tap_count = config[1];

#if defined(CONFIG_ARMV8_1_M_MVEI) && defined(CONFIG_FPU)
		/* Copy coefficients and pad to zero */
		memset(coeff_padded, 127, sizeof(coeff_padded));
		round = tap_count / COEFF_PADDING;
		if ((round * COEFF_PADDING) < tap_count) {
			round++;
		}
		round = round * COEFF_PADDING;
		memset(coeff_padded, 0, round * sizeof(q31_t));
		memcpy(coeff_padded, coeff, tap_count * sizeof(q31_t));
#endif

		/* Initialise instance */
#if defined(CONFIG_ARMV8_1_M_MVEI) && defined(CONFIG_FPU)
		arm_fir_init_q31(&inst, tap_count, coeff_padded, state, block_size);
#else
		arm_fir_init_q31(&inst, tap_count, coeff, state, block_size);
#endif

		/* Reset input pointer */
		input = (const q31_t *)in_val;

		/* Enumerate blocks */
		for (block_index = 0; block_index < 2; block_index++) {
			/* Run test function */
			arm_fir_q31(&inst, input, output, block_size);

			/* Increment pointers */
			input += block_size;
			output += block_size;
		}

		/* Increment pointers */
		coeff += tap_count;
		config += 2;
	}

	/* Validate output */
	zassert_true(
		test_snr_error_q31(length, output_buf, ref, SNR_ERROR_THRESH),
		ASSERT_MSG_SNR_LIMIT_EXCEED);

	zassert_true(
		test_near_equal_q31(length, output_buf, ref,
			ABS_ERROR_THRESH_Q31),
		ASSERT_MSG_ABS_ERROR_LIMIT_EXCEED);

	/* Free buffers */
	free(state);
	free(output_buf);
}

void test_filtering_fir_q31(void)
{
	ztest_test_suite(filtering_fir_q31,
		ztest_unit_test(test_arm_fir_q31)
		);

	ztest_run_test_suite(filtering_fir_q31);
}
