# FFT HAL Sample

## Overview

This sample is a basic regression test program for the FFT HAL. It focuses on verifying FFT and IFFT round-trip accuracy together with runtime measurements at different point counts.

The sample tests the following point counts in order:

- 64
- 128
- 256
- 512
- 1024
- 2048
- 4096

For each point count, the program:

1. generates a fixed test signal
1. runs one FFT
1. runs one IFFT
1. compares the recovered data with the original input and records the maximum error
1. prints timing statistics for FFT and IFFT

## Source Location

Source path: `src/rtsmart/examples/peripheral/fft/test_fft.c`

## Key Interfaces

- `drv_fft_open()`
- `drv_fft_get_input_alloc_size()`
- `drv_fft_get_output_alloc_size()`
- `drv_fft_set_input_alloc_size()`
- `drv_fft_set_output_alloc_size()`
- `drv_fft_fft()`
- `drv_fft_ifft()`
- `drv_fft_close()`

## Current HAL Behavior

In the current version, the FFT HAL pre-allocates input and output MMZ buffers during `drv_fft_open()`. The default allocation covers the maximum `4096`-point FFT case, so the regression sample does not need to allocate DMA space manually before each run.

If your application needs tighter memory control, you can query or adjust the internal buffer sizes manually:

```c
printf("in=%u out=%u\n",
  drv_fft_get_input_alloc_size(inst),
  drv_fft_get_output_alloc_size(inst));
```

```c
drv_fft_set_input_alloc_size(inst, 4096);
drv_fft_set_output_alloc_size(inst, 8192);
```

If a later run requires a larger buffer than the currently allocated size, the FFT HAL returns `-ENOMEM`.

## Build and Run

### Build

```shell
cd src/rtsmart/examples/peripheral/fft
make
```

### Run

After the board starts, enter `/sdcard/app/examples/peripheral` and run:

```shell
./fft.elf [verbose]
```

## Parameter Description

| Parameter | Description | Default |
| --- | --- | --- |
| `verbose` | log verbosity: `0` summary only, `1` per-point summary, `2` point-by-point differences | `1` |

## Sample Output

```shell
./fft.elf 1
main start verbose=1
before drv_fft_open
after drv_fft_open inst=0x7f9f2030
start point=64
  point   64  fft 133 us  ifft 121 us  max_diff(real=3@45, imag=1@3)  PASS
start point=128
  point  128  fft 121 us  ifft 118 us  max_diff(real=3@15, imag=2@31)  PASS
...
start point=4096
  point 4096  fft 1099 us  ifft 1067 us  max_diff(real=5@4094, imag=2@122)  PASS
before drv_fft_close
done failures=0

7/7 tests passed
```

## Notes

- The sample uses `shift = 0x555` for FFT by default.
- The sample uses `shift = 0xaaa` for IFFT by default.
- The current pass threshold requires both the real-part and imaginary-part maximum errors to be no greater than `5`.
- The sample reuses the MMZ buffers pre-allocated by `drv_fft_open()` and does not call the manual resize interface itself.

```{admonition} Tip
For the FFT HAL interface definitions, refer to the [FFT API documentation](../../api_reference/peripheral/fft.md). If you want to see the real-time audio spectrum display sample, refer to the [FFT spectrum display demo](../media/fft.md) in the media chapter.
```
