ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c File Reference

PDM MEMS microphone capture + plausibility demo (SPH0690 / ch 2). More...

#include <stdint.h>
#include "ra8_audio.h"
#include "ra8_audio_source_pdm.h"
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_err.h"
#include "ra8_mstp.h"
#include "ra8_time.h"
Include dependency graph for main.c:

Go to the source code of this file.

Data Structures

struct  pdm_metrics_t
 Statistics for one captured PCM window. More...
struct  pdm_mic_result_t
 Debugger-probable capture result. More...

Enumerations

enum  pdm_demo_const_t : uint32_t {
  k_pdm_demo_baud = 115200U ,
  k_pdm_demo_decimal = 10U ,
  k_pdm_demo_settle_ms = 300U ,
  k_pdm_demo_window = 256U ,
  k_pdm_demo_discard = 1024U ,
  k_pdm_demo_report_win = 8U ,
  k_pdm_demo_poll_max = 500000U
}
 App-wide tunables. More...
enum  pdm_demo_threshold_t : int32_t {
  k_pdm_demo_min_span = 8 ,
  k_pdm_demo_rms_floor = 16
}
 Plausibility thresholds (20-bit signed full scale = +-524288). More...
enum  pdm_demo_str_cap_t : uint32_t { k_pdm_demo_int_str_cap = 12U }
 Sizing for the decimal serialiser buffer ("-2147483648" + NUL). More...
enum  pdm_isqrt_const_t : uint32_t {
  k_pdm_isqrt_steps = 32U ,
  k_pdm_isqrt_top2 = 62U
}
 Integer-sqrt bit-window constants (64-bit radicand). More...
enum  pdm_demo_magic_t : uint32_t { k_pdm_demo_magic = 0x50444D31U }
 Result magic marker ('PDM1'). More...

Functions

static void pdm_demo_panic_halt (void)
 Park forever after a fatal error.
static uint32_t pdm_demo_i32_to_dec (int32_t value, uint8_t *out)
 Convert a signed 32-bit int into a decimal ASCII string.
static uint32_t pdm_demo_isqrt (uint64_t value)
 Integer square root of a 64-bit value (floor).
static void pdm_demo_tx (const uint8_t *bytes, uint32_t len)
 Emit a byte run over the SCI8 console.
static void pdm_demo_emit_kv (const uint8_t *label, uint32_t label_len, int32_t value)
 Emit "<label><value>" with a decimal integer.
static void pdm_demo_clocks_or_halt (void)
 Bring CGC + MSTP + SysTick up; halts on any failure.
static void pdm_demo_io_or_halt (void)
 Route P812/P502 to the PDM function and open the console.
static void pdm_demo_pdm_or_halt (void)
 Bind the on-board MIC1 through the reusable PDM audio source.
static void pdm_demo_analyze (const int32_t *buf, uint32_t n, pdm_metrics_t *m)
 Compute min/max/mean/peak/RMS for a captured window.
static bool pdm_demo_is_active (const pdm_metrics_t *m)
 Decide whether a window carries plausible live audio.
static void pdm_demo_publish (const pdm_metrics_t *m, int32_t vary, bool active)
 Print a per-window detail line and latch g_pdm_mic_result.
static bool pdm_demo_run_window (int32_t vary, pdm_metrics_t *out_m)
 Capture one window, analyse it and publish it.
void main (void)
 Application entry: bring up the PDM mic and report plausibility.

Variables

volatile pdm_mic_result_t g_pdm_mic_result
 J-Link-probable capture result (read at &g_pdm_mic_result).
static int32_t s_pdm_demo_buf [k_pdm_demo_window]
 Static capture buffer (kept off the stack).
static ra8_audio_source_t s_pdm_demo_source
 Generic caller-owned audio source handle.
static ra8_audio_source_pdm_state_t s_pdm_demo_source_state
 Caller-owned PDM backend state.
static const uint8_t k_pdm_demo_banner_init [] = "pdm: init ch=2 clk=4mhz fs=16khz\r\n"
static const uint8_t k_pdm_demo_banner_fail [] = "pdm: init FAIL\r\n"
static const uint8_t k_pdm_demo_banner_nodat [] = "pdm: no data (FIFO empty) -- clock/mic?\r\n"
static const uint8_t k_pdm_demo_banner_pass [] = "pdm: verdict=PASS active=Y\r\n"
static const uint8_t k_pdm_demo_banner_inactive [] = "pdm: verdict=FAIL active=N\r\n"

Detailed Description

PDM MEMS microphone capture + plausibility demo (SPH0690 / ch 2).

Tag
[Ring 6 / APP] {World: S}

Stand-alone EK-RA8D2 application that brings up the on-board SPH0690 PDM MEMS microphones and reports whether they produce plausible audio.

Board wiring (EK-RA8D2 v1 UM Table 31 p 37): two SPH0690 mics (MIC1, MIC2) on the PCB underside share one clock and one data line ->

  • PDMCLK2 = P812 (MIC pin 4, CLOCK)
  • PDMDAT2 = P502 (MIC pin 1, DATA) MIC1 SELECT = GND (rise-edge data), MIC2 SELECT = +3.3V (fall-edge). Both are on PDM-IF channel 2, so this demo captures MIC1 (rise edge).

Signal path (all in hardware, HUM Ch 49): 4 MHz PDM_CLK2 (PDMIFCLK = MOCO 8 MHz / 2) -> 4th-order sinc decimation (M=125) -> compensation FIR -> high-pass (DC block) -> half-band decimation -> 16 kHz, 20-bit signed PCM read out of PDDRRCH2. Filter coefficients are the RA8D2 reset-default SPH0690 set (HUM Ch 49.2 register reset values).

Flow:

  1. Board clocks / ra8_mstp_init / ra8_time_init.
  2. Route P812/P502 to the PDM function; bring up the SCI8 console.
  3. Query board-owned SPH0690 policy and bind ra8_audio_source_pdm.
  4. The backend starts PDM-IF, settles, and discards the filter transient.
  5. Capture caller-owned fixed-size PCM frames through ra8_audio.
  6. Compute AC RMS / peak / span and a plausibility verdict, print the banner pdm: rms=NNN peak=NNN active=Y (scraped by hil.conf) and publish it in the J-Link-probable g_pdm_mic_result.
  7. Latch the PASS verdict and park in a low-power wait loop.
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ pdm_demo_const_t

enum pdm_demo_const_t : uint32_t

App-wide tunables.

Enumerator
k_pdm_demo_baud 

SCI8 console baud.

k_pdm_demo_decimal 

Radix for integer-to-ASCII.

k_pdm_demo_settle_ms 

Mic wake-up + filter settle delay.

k_pdm_demo_window 

PCM samples per analysis window.

k_pdm_demo_discard 

Transient samples discarded up front.

k_pdm_demo_report_win 

Windows swept for the verdict banner.

k_pdm_demo_poll_max 

Bounded capture poll retries (dead-mic).

Definition at line 57 of file main.c.

◆ pdm_demo_magic_t

enum pdm_demo_magic_t : uint32_t

Result magic marker ('PDM1').

Enumerator
k_pdm_demo_magic 

Pdm demo magic.

Definition at line 135 of file main.c.

◆ pdm_demo_str_cap_t

enum pdm_demo_str_cap_t : uint32_t

Sizing for the decimal serialiser buffer ("-2147483648" + NUL).

Enumerator
k_pdm_demo_int_str_cap 

Pdm demo int str cap.

Definition at line 74 of file main.c.

◆ pdm_demo_threshold_t

enum pdm_demo_threshold_t : int32_t

Plausibility thresholds (20-bit signed full scale = +-524288).

Enumerator
k_pdm_demo_min_span 

Min peak-to-peak to be non-degenerate.

k_pdm_demo_rms_floor 

Min AC RMS to count as live audio.

Definition at line 68 of file main.c.

◆ pdm_isqrt_const_t

enum pdm_isqrt_const_t : uint32_t

Integer-sqrt bit-window constants (64-bit radicand).

Enumerator
k_pdm_isqrt_steps 

32 two-bit steps span a 64-bit radicand.

k_pdm_isqrt_top2 

Shift to the top 2 bits of a 64-bit word.

Definition at line 79 of file main.c.

Function Documentation

◆ main()

void main ( void )

Application entry: bring up the PDM mic and report plausibility.

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU and priority grouping.
Postcondition
The verdict banner is printed and remains the terminal UART line.
g_pdm_mic_result carries the validated capture result.
Since
0.1.0

Definition at line 610 of file main.c.

References g_pdm_mic_result, k_pdm_demo_banner_inactive, k_pdm_demo_banner_pass, k_pdm_demo_report_win, pdm_demo_clocks_or_halt(), pdm_demo_io_or_halt(), pdm_demo_panic_halt(), pdm_demo_pdm_or_halt(), pdm_demo_run_window(), pdm_demo_tx(), and pdm_metrics_t::rms.

◆ pdm_demo_analyze()

void pdm_demo_analyze ( const int32_t * buf,
uint32_t n,
pdm_metrics_t * m )
static

Compute min/max/mean/peak/RMS for a captured window.

Two bounded passes: pass 1 accumulates min/max/mean; pass 2 accumulates the AC peak and mean-square about that mean. A zero-sample window is rejected before either pass runs, so a source that reports an empty capture cannot divide by zero.

Parameters
[in]bufSample buffer (non-NULL).
[in]nSample count.
[out]mMetrics output (non-NULL).
Returns
Nothing.
Precondition
buf holds n valid samples.
m is non-NULL.
Postcondition
n == 0 leaves *m entirely zeroed.
n > 0 leaves m->rms and m->peak non-negative.
Note
Not thread-safe.
Since
0.1.0

Definition at line 439 of file main.c.

References pdm_metrics_t::max, pdm_metrics_t::mean, pdm_metrics_t::min, pdm_metrics_t::n, pdm_demo_isqrt(), pdm_metrics_t::peak, and pdm_metrics_t::rms.

Referenced by pdm_demo_run_window().

◆ pdm_demo_clocks_or_halt()

void pdm_demo_clocks_or_halt ( void )
static

Bring CGC + MSTP + SysTick up; halts on any failure.

Runs on MOCO (~8 MHz), which also sources PDMIFCLK (8 MHz).

Returns
Nothing.
Precondition
Reset_Handler prepared .data/.bss.
Single-threaded init context.
Postcondition
CGC, MSTP and the delay timer are live on success.
The CPU is parked on any failure.
Note
Not thread-safe.
Since
0.1.0

Definition at line 331 of file main.c.

References ra8_board_clock_rates_t::cpuclk0_hz, k_ra8_ok, pdm_demo_panic_halt(), ra8_board_clocks_init(), ra8_mstp_init(), and ra8_time_init().

Referenced by main().

◆ pdm_demo_emit_kv()

void pdm_demo_emit_kv ( const uint8_t * label,
uint32_t label_len,
int32_t value )
static

Emit "<label><value>" with a decimal integer.

Serializes the signed value into fixed stack storage after the label.

Parameters
[in]labelLabel bytes (non-NULL).
[in]label_lenLabel length.
[in]valueSigned integer to print.
Returns
Nothing.
Precondition
The console was initialised.
label is non-NULL.
Postcondition
The label and value were queued for transmit.
No application state changed.
Note
Not thread-safe.
Since
0.1.0

Definition at line 303 of file main.c.

References k_pdm_demo_int_str_cap, pdm_demo_i32_to_dec(), and pdm_demo_tx().

Referenced by pdm_demo_publish().

◆ pdm_demo_i32_to_dec()

uint32_t pdm_demo_i32_to_dec ( int32_t value,
uint8_t * out )
static

Convert a signed 32-bit int into a decimal ASCII string.

Avoids newlib printf. Buffer must hold k_pdm_demo_int_str_cap.

Parameters
[in]valueInteger to convert.
[out]outDestination buffer (>= 12 bytes, non-NULL).
Returns
Number of bytes written (excluding the NUL).
Return values
uint32_tDecimal character count excluding the terminator.
Precondition
out is non-NULL.
out has at least k_pdm_demo_int_str_cap bytes.
Postcondition
out holds a NUL-terminated decimal string.
The return value is in [1, 11].
Note
Pure helper; thread-safe.
Since
0.1.0

Definition at line 196 of file main.c.

References k_pdm_demo_decimal, and k_pdm_demo_int_str_cap.

Referenced by pdm_demo_emit_kv().

◆ pdm_demo_io_or_halt()

void pdm_demo_io_or_halt ( void )
static

Route P812/P502 to the PDM function and open the console.

Both pins take PSEL k_ra8_psel_pdm; the console is SCI8.

Returns
Nothing.
Precondition
pdm_demo_clocks_or_halt already ran.
Single-threaded init context.
Postcondition
PDMCLK2/PDMDAT2 are routed and the console is live on success.
The CPU is parked on any failure.
Note
Not thread-safe.
Since
0.1.0

Definition at line 360 of file main.c.

References k_pdm_demo_baud, k_ra8_board_led1, k_ra8_ok, pdm_demo_panic_halt(), ra8_board_led_init(), ra8_board_pdm_mic_route(), and ra8_board_uart_console_init().

Referenced by main().

◆ pdm_demo_is_active()

bool pdm_demo_is_active ( const pdm_metrics_t * m)
static

Decide whether a window carries plausible live audio.

Non-degenerate (span >= k_pdm_demo_min_span) AND carrying AC energy (rms >= k_pdm_demo_rms_floor). Written as nested single-condition tests (no compound decision).

Parameters
[in]mWindow metrics (non-NULL).
Returns
true if the window is plausible live audio.
Return values
trueThe span and RMS meet their configured floors.
falseAt least one activity threshold was not met.
Precondition
m was filled by pdm_demo_analyze.
m->n is greater than zero.
Postcondition
No state is modified.
The result reflects only m.
Note
Pure helper; thread-safe.
Since
0.1.0

Definition at line 493 of file main.c.

References k_pdm_demo_min_span, k_pdm_demo_rms_floor, pdm_metrics_t::max, pdm_metrics_t::min, and pdm_metrics_t::rms.

Referenced by pdm_demo_run_window().

◆ pdm_demo_isqrt()

uint32_t pdm_demo_isqrt ( uint64_t value)
static

Integer square root of a 64-bit value (floor).

Bit-by-bit restoring algorithm; 32 fixed iterations, no FPU.

Parameters
[in]valueRadicand.
Returns
floor(sqrt(value)).
Return values
uint32_tGreatest integer whose square does not exceed value.
Precondition
value is a mean-square accumulation.
No FPU dependency is required.
Postcondition
The result squared does not exceed value.
(result + 1) squared exceeds value.
Note
Pure helper; thread-safe.
Since
0.1.0

Definition at line 244 of file main.c.

References k_pdm_isqrt_steps, and k_pdm_isqrt_top2.

Referenced by pdm_demo_analyze().

◆ pdm_demo_panic_halt()

void pdm_demo_panic_halt ( void )
static

Park forever after a fatal error.

Waits in a low-power spin; only a debugger or reset wakes it.

Returns
Never returns.
Precondition
Called only after a fatal init failure.
The console banner (if any) has been flushed.
Postcondition
The CPU is parked.
No further application code runs.
Note
Not callable from ISR context.
Since
0.1.0

Definition at line 170 of file main.c.

Referenced by main(), pdm_demo_clocks_or_halt(), pdm_demo_io_or_halt(), and pdm_demo_pdm_or_halt().

◆ pdm_demo_pdm_or_halt()

void pdm_demo_pdm_or_halt ( void )
static

Bind the on-board MIC1 through the reusable PDM audio source.

Runs the HUM Ch 49.4.1 start flow with the settling delay. Prints k_pdm_demo_banner_fail and parks on any error.

Returns
Nothing.
Precondition
The console and clocks are live.
The PDM pins are routed.
Postcondition
Channel 2 is capturing on success.
The CPU is parked on any failure.
Note
Not thread-safe.
Since
0.1.0

Definition at line 387 of file main.c.

References ra8_board_pdm_mic_config_t::channel, k_pdm_demo_banner_fail, k_pdm_demo_banner_init, k_pdm_demo_discard, k_pdm_demo_poll_max, k_pdm_demo_settle_ms, k_pdm_demo_window, k_ra8_board_pdm_mic1, k_ra8_ok, ra8_board_pdm_mic_config_t::pdm, pdm_demo_panic_halt(), pdm_demo_tx(), ra8_audio_source_pdm_init(), ra8_board_pdm_mic_get_config(), s_pdm_demo_source, s_pdm_demo_source_state, ra8_board_pdm_mic_config_t::sample_rate_hz, and ra8_board_pdm_mic_config_t::valid_bits.

Referenced by main().

◆ pdm_demo_publish()

void pdm_demo_publish ( const pdm_metrics_t * m,
int32_t vary,
bool active )
static

Print a per-window detail line and latch g_pdm_mic_result.

Emits each metric as a bounded decimal field before updating the SWD result object.

Parameters
[in]mWindow metrics (non-NULL).
[in]varyRMS spread across the report sweep so far.
[in]activePlausibility verdict for this window.
Returns
Nothing.
Precondition
The console is live.
m was filled by pdm_demo_analyze.
Postcondition
One pdm: ... detail line was emitted.
g_pdm_mic_result mirrors m.
Note
Not thread-safe.
Since
0.1.0

Definition at line 522 of file main.c.

References g_pdm_mic_result, k_pdm_demo_magic, pdm_metrics_t::max, pdm_metrics_t::mean, pdm_metrics_t::min, pdm_metrics_t::n, pdm_demo_emit_kv(), pdm_demo_tx(), pdm_metrics_t::peak, and pdm_metrics_t::rms.

Referenced by pdm_demo_run_window().

◆ pdm_demo_run_window()

bool pdm_demo_run_window ( int32_t vary,
pdm_metrics_t * out_m )
static

Capture one window, analyse it and publish it.

Reports the no-data banner and returns false if the FIFO never fills (dead clock / mic).

Parameters
[in]varyRMS spread so far (for the detail line).
[in,out]out_mReceives the window metrics (non-NULL).
Returns
true if a window was captured and analysed.
Return values
trueCapture, analysis, and publication completed.
falseThe audio source did not provide a frame.
Precondition
The PDM channel is running with data read enabled.
out_m is non-NULL.
Postcondition
On success *out_m holds the window statistics.
g_pdm_mic_result is refreshed on success.
Note
Not thread-safe.
Since
0.1.0

Definition at line 577 of file main.c.

References g_pdm_mic_result, k_pdm_demo_banner_nodat, k_ra8_ok, pdm_demo_analyze(), pdm_demo_is_active(), pdm_demo_publish(), pdm_demo_tx(), ra8_audio_source_capture(), s_pdm_demo_buf, s_pdm_demo_source, ra8_audio_frame_t::sample_count, and ra8_audio_frame_t::timestamp_ms.

Referenced by main().

◆ pdm_demo_tx()

void pdm_demo_tx ( const uint8_t * bytes,
uint32_t len )
static

Emit a byte run over the SCI8 console.

Forwards the exact caller span through the board console without formatting.

Parameters
[in]bytesByte array (non-NULL).
[in]lenByte count.
Returns
Nothing.
Precondition
The console was initialised.
bytes is non-NULL.
Postcondition
len bytes were queued for transmit.
No application state changed.
Note
Not thread-safe.
Since
0.1.0

Definition at line 280 of file main.c.

References ra8_board_uart_console_write().

Referenced by main(), pdm_demo_emit_kv(), pdm_demo_pdm_or_halt(), pdm_demo_publish(), and pdm_demo_run_window().

Variable Documentation

◆ g_pdm_mic_result

volatile pdm_mic_result_t g_pdm_mic_result

J-Link-probable capture result (read at &g_pdm_mic_result).

Definition at line 123 of file main.c.

Referenced by main(), pdm_demo_publish(), and pdm_demo_run_window().

◆ k_pdm_demo_banner_fail

const uint8_t k_pdm_demo_banner_fail[] = "pdm: init FAIL\r\n"
static

Definition at line 145 of file main.c.

Referenced by pdm_demo_pdm_or_halt().

◆ k_pdm_demo_banner_inactive

const uint8_t k_pdm_demo_banner_inactive[] = "pdm: verdict=FAIL active=N\r\n"
static

Definition at line 148 of file main.c.

Referenced by main().

◆ k_pdm_demo_banner_init

const uint8_t k_pdm_demo_banner_init[] = "pdm: init ch=2 clk=4mhz fs=16khz\r\n"
static

Definition at line 144 of file main.c.

Referenced by pdm_demo_pdm_or_halt().

◆ k_pdm_demo_banner_nodat

const uint8_t k_pdm_demo_banner_nodat[] = "pdm: no data (FIFO empty) -- clock/mic?\r\n"
static

Definition at line 146 of file main.c.

Referenced by pdm_demo_run_window().

◆ k_pdm_demo_banner_pass

const uint8_t k_pdm_demo_banner_pass[] = "pdm: verdict=PASS active=Y\r\n"
static

Definition at line 147 of file main.c.

Referenced by main().

◆ s_pdm_demo_buf

int32_t s_pdm_demo_buf[k_pdm_demo_window]
static

Static capture buffer (kept off the stack).

Definition at line 126 of file main.c.

Referenced by pdm_demo_run_window().

◆ s_pdm_demo_source

ra8_audio_source_t s_pdm_demo_source
static

Generic caller-owned audio source handle.

Definition at line 129 of file main.c.

Referenced by pdm_demo_pdm_or_halt(), and pdm_demo_run_window().

◆ s_pdm_demo_source_state

ra8_audio_source_pdm_state_t s_pdm_demo_source_state
static

Caller-owned PDM backend state.

Definition at line 132 of file main.c.

Referenced by pdm_demo_pdm_or_halt().