1 /*
2  * Copyright (c) 2024 Benjamin Cabé <benjamin@zephyrproject.org>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <zephyr/kernel.h>
9 
10 #include "arm_math.h"
11 
12 #define NUM_TAPS   10 /* Number of taps in the FIR filter (length of the moving average window) */
13 #define BLOCK_SIZE 32 /* Number of samples processed per block */
14 
15 /*
16  * Filter coefficients are all equal for a moving average filter. Here, 1/NUM_TAPS = 0.1f.
17  */
18 q31_t firCoeffs[NUM_TAPS] = {0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD,
19 			     0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD, 0x0CCCCCCD};
20 
21 arm_fir_instance_q31 sFIR;
22 q31_t firState[NUM_TAPS + BLOCK_SIZE - 1];
23 
main(void)24 int main(void)
25 {
26 	q31_t input[BLOCK_SIZE];
27 	q31_t output[BLOCK_SIZE];
28 	uint32_t start, end;
29 
30 	/* Initialize input data with a ramp from 0 to 31 */
31 	for (int i = 0; i < BLOCK_SIZE; i++) {
32 		input[i] = i << 24; /* Convert to Q31 format */
33 	}
34 
35 	/* Initialize the FIR filter */
36 	arm_fir_init_q31(&sFIR, NUM_TAPS, firCoeffs, firState, BLOCK_SIZE);
37 
38 	/* Apply the FIR filter to the input data and measure how many cycles this takes */
39 	start = k_cycle_get_32();
40 	arm_fir_q31(&sFIR, input, output, BLOCK_SIZE);
41 	end = k_cycle_get_32();
42 
43 	printf("Time: %u us (%u cycles)\n", k_cyc_to_us_floor32(end - start), end - start);
44 
45 	for (int i = 0; i < BLOCK_SIZE; i++) {
46 		printf("Input[%02d]: ", i);
47 		for (int j = NUM_TAPS - 1; j >= 0; j--) {
48 			if (j <= i) {
49 				printf("%2d ", (int)(input[i - j] >> 24));
50 			} else {
51 				printf("%2d ", 0);
52 			}
53 		}
54 		printf("| Output[%02d]: %6.2f\n", i, (double)output[i] / (1 << 24));
55 	}
56 
57 	return 0;
58 }
59