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

Pulse Density Modulation Interface (PDM-IF) capture driver. More...

#include <stdint.h>
#include "ra8_err.h"
Include dependency graph for ra8_pdm.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_pdm_channel_cfg_t
 One PDM channel's mode + filter configuration. More...

Typedefs

typedef void(* ra8_pdm_data_callback_t) (void *ctx, const int32_t *samples, uint32_t count)
 PDM FIFO data callback invoked from ICU interrupt context.

Enumerations

enum  ra8_pdm_channel_t : uint8_t {
  k_ra8_pdm_ch0 = 0U ,
  k_ra8_pdm_ch1 = 1U ,
  k_ra8_pdm_ch2 = 2U ,
  k_ra8_pdm_ch_count = 3U
}
 PDM-IF channel selectors. More...
enum  ra8_pdm_coeff_count_t : uint8_t {
  k_ra8_pdm_hpf_h_count = 2U ,
  k_ra8_pdm_comp_h_count = 11U ,
  k_ra8_pdm_lpf_h1_count = 20U
}
 Filter-coefficient array lengths (HUM Ch 49.2.21-49.2.35). More...

Functions

ra8_err_t ra8_pdm_init (void)
 Release the PDM-IF module stop and reset its common bank.
ra8_err_t ra8_pdm_deinit (void)
 Put the PDM-IF block back into module stop.
ra8_err_t ra8_pdm_configure (uint8_t ch, const ra8_pdm_channel_cfg_t *cfg)
 Program a channel's mode, decimation and filter coefficients.
ra8_err_t ra8_pdm_start (uint8_t ch)
 Activate a configured channel's filter (start trigger).
ra8_err_t ra8_pdm_read_enable (uint8_t ch)
 Clear status, enable data read and prime the receive FIFO.
ra8_err_t ra8_pdm_read (uint8_t ch, int32_t *out, uint32_t max, uint32_t *out_count)
 Drain up to max PCM samples from a channel's FIFO.
ra8_err_t ra8_pdm_stream_enable (uint8_t ch, ra8_pdm_data_callback_t callback, void *ctx, uint8_t priority)
 Enable interrupt-driven FIFO delivery for one running channel.
ra8_err_t ra8_pdm_stream_disable (uint8_t ch)
 Disable interrupt-driven delivery for one channel.
ra8_err_t ra8_pdm_stop (uint8_t ch)
 Stop a channel and wait for its filter to halt.

Detailed Description

Pulse Density Modulation Interface (PDM-IF) capture driver.

Tag
[Ring 3 / HAL] {World: NS}

Polling-mode capture driver for the RA8D2 PDM-IF block (HUM Ch 49, p 3190-3256). A PDM MEMS microphone streams a 1-bit pulse-density bitstream on PDMDATn clocked by PDMCLKn; the peripheral's hardware filter chain (sinc decimator -> compensation FIR -> high-pass -> half-band decimation) converts it to signed PCM presented, one sample per FIFO slot, in the channel data-read register (PDDRR).

The driver is the mechanism; the filter coefficients and decimation ratio are microphone-and-rate policy supplied by the caller via ra8_pdm_channel_cfg_t (see the EK-RA8D2 pdm_mic_demo for the SPH0690 coefficient set). Sample delivery can be polled or interrupt-driven. The interrupt path drains each FIFO threshold into a bounded borrowed view; storage and scheduling policy remain above the HAL.

Bring-up order (HUM Ch 49.4.1 "Start Flow"):

  1. ra8_pdm_init – module-stop release.
  2. ra8_pdm_configure – mode + filter + coefficients.
  3. ra8_pdm_start – activate channel filtering.
  4. wait mic wake-up + filter settling (caller delay).
  5. ra8_pdm_read_enable – clear status, enable + prime FIFO.
  6. ra8_pdm_read (repeated) – drain PCM samples.
  7. ra8_pdm_stop – halt the channel.

Definition in file ra8_pdm.h.

Typedef Documentation

◆ ra8_pdm_data_callback_t

typedef void(* ra8_pdm_data_callback_t) (void *ctx, const int32_t *samples, uint32_t count)

PDM FIFO data callback invoked from ICU interrupt context.

Parameters
[in]ctxCaller context supplied at stream enable.
[in]samplesBorrowed signed PCM-S32 samples.
[in]countNumber of readable samples.
Precondition
samples is readable only for the duration of the callback.
Postcondition
The callback must not retain samples.
Note
ISR context: must be bounded and non-blocking.
Since
0.1.0

Definition at line 123 of file ra8_pdm.h.

Enumeration Type Documentation

◆ ra8_pdm_channel_t

enum ra8_pdm_channel_t : uint8_t

PDM-IF channel selectors.

The RA8D2 exposes three PDM channels. The EK-RA8D2 SPH0690 MEMS microphones (MIC1/MIC2) are wired to PDMCLK2 (P812) / PDMDAT2 (P502), i.e. channel 2.

Enumerator
k_ra8_pdm_ch0 

Channel 0.

k_ra8_pdm_ch1 

Channel 1.

k_ra8_pdm_ch2 

Channel 2 (EK-RA8D2 MEMS mic).

k_ra8_pdm_ch_count 

Number of channels (bound).

Definition at line 56 of file ra8_pdm.h.

◆ ra8_pdm_coeff_count_t

enum ra8_pdm_coeff_count_t : uint8_t

Filter-coefficient array lengths (HUM Ch 49.2.21-49.2.35).

Fixed by the PDM-IF hardware filter topology; used to size the coefficient arrays in ra8_pdm_channel_cfg_t.

Enumerator
k_ra8_pdm_hpf_h_count 

High-pass filter h(0..1) coefficients.

k_ra8_pdm_comp_h_count 

Compensation filter h(0..10) coefficients.

k_ra8_pdm_lpf_h1_count 

Low-pass (half-band) h1(0..19) coefficients.

Definition at line 71 of file ra8_pdm.h.

Function Documentation

◆ ra8_pdm_configure()

ra8_err_t ra8_pdm_configure ( uint8_t ch,
const ra8_pdm_channel_cfg_t * cfg )
nodiscard

Program a channel's mode, decimation and filter coefficients.

Implements the configuration portion of HUM Ch 49.4.1 "Start Flow": writes PDMDSR (mode/shifts/edge), PDSFCR (clock divider, decimation, clip range), the high-pass/compensation/low-pass coefficient banks and PDDBCR (reception threshold). Does not start the channel.

Parameters
[in]chChannel index (0..2).
[in]cfgChannel configuration (non-NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okChannel configured.
k_ra8_err_invalid_argch out of range.
k_ra8_err_null_ptrcfg was NULL.
Precondition
ra8_pdm_init succeeded.
cfg describes a HUM Table 49.7 combination.
Postcondition
The channel's filter registers hold cfg.
The channel remains stopped (no data produced yet).
Note
Not thread-safe.
Since
0.1.0

Definition at line 233 of file ra8_pdm.c.

References internal_pdm_write_coeffs(), internal_pdm_write_mode(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdm_ch_count, r_pdm_ch_regs_t::PDDBCR, RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, ra8_pdm_ch(), ra8_pdm_channel_cfg_t::rx_threshold, and s_tag.

Referenced by internal_pdm_prepare_hardware().

◆ ra8_pdm_deinit()

ra8_err_t ra8_pdm_deinit ( void )
nodiscard

Put the PDM-IF block back into module stop.

Returns
ra8_err_t Error code.
Return values
k_ra8_okModule stopped.
k_ra8_err_hw_timeoutModule-stop entry did not settle.
Precondition
ra8_pdm_init previously succeeded.
No channel is mid-capture.
Postcondition
The PDM-IF block is unclocked.
Register contents are undefined until re-init.
Note
Not thread-safe.
Since
0.1.0

Definition at line 225 of file ra8_pdm.c.

References k_ra8_mstp_pdmif, r_pdm_regs_t::PDCDRCR, ra8_mstp_disable(), and ra8_pdm().

Referenced by internal_pdm_prepare_hardware(), and internal_pdm_stop().

◆ ra8_pdm_init()

ra8_err_t ra8_pdm_init ( void )
nodiscard

Release the PDM-IF module stop and reset its common bank.

Clears the PDM-IF bit in MSTPCRC so the block is clocked, then zeroes the common start/stop/status-clear triggers to a known state. Must run before any channel configuration.

Returns
ra8_err_t Error code.
Return values
k_ra8_okModule clocked and common bank reset.
k_ra8_err_hw_timeoutModule-stop release did not settle.
Precondition
PDMIFCLK (MOCO, 8 MHz) is running.
Single-threaded init context or IRQs masked.
Postcondition
The PDM-IF block is clocked out of module stop.
Common start/stop triggers read back clear.
Note
Not thread-safe.
Since
0.1.0

Definition at line 211 of file ra8_pdm.c.

References k_ra8_mstp_pdmif, k_ra8_ok, r_pdm_regs_t::PDCDRCR, r_pdm_regs_t::PDCICR, ra8_log_info, ra8_mstp_enable(), ra8_pdm(), RA8_RETURN_ON_ERROR, and s_tag.

Referenced by internal_pdm_prepare_hardware(), and ra8_nsc_pdm_init().

◆ ra8_pdm_read()

ra8_err_t ra8_pdm_read ( uint8_t ch,
int32_t * out,
uint32_t max,
uint32_t * out_count )
nodiscard

Drain up to max PCM samples from a channel's FIFO.

Reads PDDSR for the current FIFO fill count, then pops that many (capped at max) 20-bit samples from PDDRR, sign-extending each to a full int32_t. Non-blocking: returns 0 in *out_count if the FIFO is empty.

Parameters
[in]chChannel index (0..2).
[out]outDestination sample buffer (non-NULL).
[in]maxCapacity of out in samples (>0).
[out]out_countNumber of samples written (non-NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okZero or more samples returned.
k_ra8_err_invalid_argch out of range or max was 0.
k_ra8_err_null_ptrout or out_count was NULL.
Precondition
ra8_pdm_read_enable succeeded for ch.
out has room for max int32_t samples.
Postcondition
*out_count is in [0, max].
Each written sample is sign-extended from 20 bits.
Note
Not thread-safe.
Since
0.1.0

Definition at line 271 of file ra8_pdm.c.

References internal_pdm_sign_extend20(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdm_ch_count, k_ra8_pdm_pddsr_num_mask, r_pdm_ch_regs_t::PDDRR, r_pdm_ch_regs_t::PDDSR, RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, ra8_log_error, ra8_pdm_ch(), and s_tag.

Referenced by internal_pdm_fill().

◆ ra8_pdm_read_enable()

ra8_err_t ra8_pdm_read_enable ( uint8_t ch)
nodiscard

Clear status, enable data read and prime the receive FIFO.

Clears the channel status flags, sets PDDRCR.DATRE and performs the mandatory FIFO_DEPTH - 2 priming reads of PDDRR (discarded) that HUM Ch 49 "Normal Processing Flow" requires before valid samples flow. Call after the microphone wake-up delay.

Parameters
[in]chChannel index (0..2).
Returns
ra8_err_t Error code.
Return values
k_ra8_okData read enabled and FIFO primed.
k_ra8_err_invalid_argch out of range.
Precondition
ra8_pdm_start succeeded and the settling delay elapsed.
The channel filter reports running.
Postcondition
Subsequent ra8_pdm_read calls return live PCM samples.
The channel status flags are cleared.
Note
Not thread-safe.
Since
0.1.0

Definition at line 254 of file ra8_pdm.c.

References k_pdm_prime_discards, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdm_ch_count, k_ra8_pdm_pddrcr_datre, k_ra8_pdm_pdscr_clr_all, r_pdm_ch_regs_t::PDDRCR, r_pdm_ch_regs_t::PDDRR, r_pdm_ch_regs_t::PDSCR, RA8_CHECK_RANGE_TAG, ra8_pdm_ch(), and s_tag.

Referenced by internal_pdm_prepare_hardware().

◆ ra8_pdm_start()

ra8_err_t ra8_pdm_start ( uint8_t ch)
nodiscard

Activate a configured channel's filter (start trigger).

Sets the channel's common start-trigger bit (PDCSTRTR.STRTRGn), which begins clocking PDMCLKn and running the filter chain. The caller must then wait the microphone wake-up plus filter settling time before enabling data read.

Parameters
[in]chChannel index (0..2).
Returns
ra8_err_t Error code.
Return values
k_ra8_okStart trigger issued.
k_ra8_err_invalid_argch out of range.
Precondition
ra8_pdm_configure succeeded for ch.
PDMCLKn / PDMDATn pins are routed to the PDM function.
Postcondition
The channel filter is running.
PDMCLKn is toggling at the configured rate.
Note
Not thread-safe.
Since
0.1.0

Definition at line 246 of file ra8_pdm.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdm_ch_count, k_ra8_pdm_pdstrtr_strt, r_pdm_regs_t::PDCSTRTR, RA8_CHECK_RANGE_TAG, ra8_pdm(), and s_tag.

Referenced by internal_pdm_prepare_hardware().

◆ ra8_pdm_stop()

ra8_err_t ra8_pdm_stop ( uint8_t ch)
nodiscard

Stop a channel and wait for its filter to halt.

Disables data read (PDDRCR), issues the channel stop trigger (PDCSTPTR.STPTRGn) per HUM Ch 49.4.2 "Stop Flow" and polls PDCSR.STATEn until the channel reports stopped or a bounded retry budget expires.

Parameters
[in]chChannel index (0..2).
Returns
ra8_err_t Error code.
Return values
k_ra8_okChannel stopped.
k_ra8_err_invalid_argch out of range.
k_ra8_err_hw_timeoutChannel did not report stopped.
Precondition
ra8_pdm_start previously succeeded for ch.
Single-threaded context.
Postcondition
The channel filter is halted.
No further samples are produced until re-start.
Note
Not thread-safe.
Since
0.1.0

Definition at line 332 of file ra8_pdm.c.

References k_pdm_stop_poll_max, k_ra8_err_hw_timeout, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdm_ch_count, k_ra8_pdm_pdsr_state, k_ra8_pdm_pdstptr_stp, r_pdm_regs_t::PDCSTPTR, r_pdm_ch_regs_t::PDDRCR, RA8_CHECK_RANGE_TAG, ra8_log_error, ra8_pdm(), ra8_pdm_ch(), ra8_pdm_stream_disable(), RA8_RETURN_ON_ERROR, s_streams, and s_tag.

Referenced by internal_pdm_prepare_hardware(), and internal_pdm_stop().

◆ ra8_pdm_stream_disable()

ra8_err_t ra8_pdm_stream_disable ( uint8_t ch)
nodiscard

Disable interrupt-driven delivery for one channel.

Parameters
[in]chChannel index (0..2).
Returns
Error code.
Return values
k_ra8_okDelivery disabled.
k_ra8_err_invalid_argChannel is invalid.
k_ra8_err_not_initializedChannel was not streaming.
otherPropagated ISR unregister error.
Precondition
No callback for this channel is currently executing.
Postcondition
The PDM data event is unregistered and callback state cleared.
Note
Not thread-safe.
Since
0.1.0

Definition at line 316 of file ra8_pdm.c.

References k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_pdm_ch_count, k_ra8_pdm_pdicr_idre, r_pdm_ch_regs_t::PDICR, RA8_CHECK_RANGE_TAG, ra8_isr_unregister(), ra8_pdm_ch(), s_pdm_data_events, s_streams, and s_tag.

Referenced by ra8_pdm_stop().

◆ ra8_pdm_stream_enable()

ra8_err_t ra8_pdm_stream_enable ( uint8_t ch,
ra8_pdm_data_callback_t callback,
void * ctx,
uint8_t priority )
nodiscard

Enable interrupt-driven FIFO delivery for one running channel.

Parameters
[in]chChannel index (0..2).
[in]callbackBounded data callback.
[in]ctxOpaque callback context; may be nullptr.
[in]priorityNVIC priority accepted by ra8_isr_register.
Returns
Error code.
Return values
k_ra8_okInterrupt delivery enabled.
k_ra8_err_null_ptrcallback was nullptr.
k_ra8_err_invalid_argChannel or priority is invalid.
k_ra8_err_existsThe channel is already streaming.
otherPropagated ISR registration error.
Precondition
ra8_pdm_read_enable and ra8_isr_init succeeded.
Postcondition
Each FIFO threshold invokes callback from interrupt context.
Note
Not thread-safe. One stream may be active per PDM channel.
Since
0.1.0

Definition at line 294 of file ra8_pdm.c.

References internal_pdm_data_isr(), k_ra8_err_exists, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdm_ch_count, k_ra8_pdm_pdicr_idre, r_pdm_ch_regs_t::PDICR, RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, ra8_isr_register(), ra8_pdm_ch(), s_pdm_data_events, s_streams, and s_tag.

Referenced by internal_pdm_stream_start().