|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Pulse Density Modulation Interface (PDM-IF) capture driver. More...
#include "ra8_pdm.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_isr.h"#include "ra8_log.h"#include "ra8_mstp.h"#include "ra8_mstp_regs.h"#include "ra8_pdm_regs.h"Go to the source code of this file.
Data Structures | |
| struct | pdm_stream_state_t |
| Per-channel interrupt callback binding. More... | |
Enumerations | |
| enum | pdm_impl_const_t : uint32_t { k_pdm_prime_discards = 30U , k_pdm_stop_poll_max = 1000U , k_pdm_field_3bit = 0x7U } |
| Implementation-local bounds (HUM Ch 49 "Normal Processing Flow"). More... | |
Functions | |
| static void | internal_pdm_write_mode (volatile r_pdm_ch_regs_t *reg, const ra8_pdm_channel_cfg_t *cfg) |
| Write a channel's PDMDSR + PDSFCR mode/decimation words. | |
| static void | internal_pdm_write_coeffs (volatile r_pdm_ch_regs_t *reg, const ra8_pdm_channel_cfg_t *cfg) |
| Write a channel's high-pass, compensation and low-pass coefficients. | |
| static int32_t | internal_pdm_sign_extend20 (uint32_t raw) |
| Sign-extend one 20-bit PDDRR sample to a full int32_t. | |
| static void | internal_pdm_data_isr (void *ctx) |
| Drain one PDM FIFO threshold and dispatch its signed samples. | |
| 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. | |
Variables | |
| static const char * | s_tag = "PDM" |
| static pdm_stream_state_t | s_streams [k_ra8_pdm_ch_count] |
| static const ra8_elc_event_t | s_pdm_data_events [k_ra8_pdm_ch_count] |
Pulse Density Modulation Interface (PDM-IF) capture driver.
Polling-mode capture driver for the RA8D2 PDM-IF block. Implements the HUM Ch 49.4.1 "Start Flow": configure a channel's mode + decimation + FIR coefficients, activate the filter, prime the FIFO and drain 20-bit signed PCM from the data-read register. The hardware performs the PDM->PCM decimation; this driver only sequences and reads it. Every register access carries a HUM Ch 49 citation.
Definition in file ra8_pdm.c.
| enum pdm_impl_const_t : uint32_t |
|
static |
Drain one PDM FIFO threshold and dispatch its signed samples.
Bounds the hardware-reported fill level to the FIFO depth, converts each 20-bit word, and invokes the registered channel callback once.
| [in] | ctx | Encoded channel index. |
Definition at line 185 of file ra8_pdm.c.
References pdm_stream_state_t::callback, pdm_stream_state_t::ctx, internal_pdm_sign_extend20(), k_ra8_pdm_ch_count, k_ra8_pdm_fifo_depth, k_ra8_pdm_pddsr_num_mask, r_pdm_ch_regs_t::PDDRR, r_pdm_ch_regs_t::PDDSR, RA8_INTERNAL, ra8_pdm_ch(), and s_streams.
Referenced by ra8_pdm_stream_enable().
|
static |
Sign-extend one 20-bit PDDRR sample to a full int32_t.
Masks raw to its low 20 significant bits, then, if bit 19 (the two's-complement sign bit) is set, fills the upper 12 bits with ones so the value reads as a correctly-signed int32_t; otherwise returns the masked value unchanged. Pure bit manipulation, no hardware access.
| [in] | raw | Raw PDDRR read (only the low 20 bits are significant). |
| <0 | The 20-bit sign bit (bit 19) was set; upper bits filled with ones. |
| >=0 | The 20-bit sign bit was clear; the masked low-20-bit value. |
Definition at line 164 of file ra8_pdm.c.
References k_ra8_pdm_pddrr_dat_mask, k_ra8_pdm_pddrr_sign_bit, k_ra8_pdm_pddrr_sign_ext, and RA8_INTERNAL.
Referenced by internal_pdm_data_isr(), and ra8_pdm_read().
|
static |
Write a channel's high-pass, compensation and low-pass coefficients.
Loads the three FIR banks (HPF s0/k1/h[2], compensation h[11], low-pass h0/h1[20]) that the sinc chain feeds. The values are the microphone/rate filter set carried by cfg.
| [in,out] | reg | Channel register bank (non-NULL). |
| [in] | cfg | Channel configuration (non-NULL). |
Definition at line 120 of file ra8_pdm.c.
References ra8_pdm_channel_cfg_t::comp_h, ra8_pdm_channel_cfg_t::hpf_h, ra8_pdm_channel_cfg_t::hpf_k1, ra8_pdm_channel_cfg_t::hpf_s0, k_ra8_pdm_comp_h_count, k_ra8_pdm_hpf_h_count, k_ra8_pdm_lpf_h1_count, ra8_pdm_channel_cfg_t::lpf_h0, ra8_pdm_channel_cfg_t::lpf_h1, r_pdm_ch_regs_t::PDCFCHR, r_pdm_ch_regs_t::PDHFCHR, r_pdm_ch_regs_t::PDHFCK1R, r_pdm_ch_regs_t::PDHFCS0R, r_pdm_ch_regs_t::PDLFCH010R, r_pdm_ch_regs_t::PDLFCH1R, and RA8_INTERNAL.
Referenced by ra8_pdm_configure().
|
static |
Write a channel's PDMDSR + PDSFCR mode/decimation words.
Packs the mode-setting fields (sinc order, filter input shifts, data shift, input edge) into PDMDSR and the clock divider + sinc decimation
| [in,out] | reg | Channel register bank (non-NULL). |
| [in] | cfg | Channel configuration (non-NULL). |
Definition at line 80 of file ra8_pdm.c.
References ra8_pdm_channel_cfg_t::cf_shift, ra8_pdm_channel_cfg_t::clock_div, ra8_pdm_channel_cfg_t::data_shift, ra8_pdm_channel_cfg_t::edge, ra8_pdm_channel_cfg_t::hpf_shift, k_pdm_field_3bit, k_ra8_pdm_pdmdsr_cfis_pos, k_ra8_pdm_pdmdsr_dbis_pos, k_ra8_pdm_pdmdsr_hfis_pos, k_ra8_pdm_pdmdsr_inpsel, k_ra8_pdm_pdmdsr_lfis_pos, k_ra8_pdm_pdmdsr_sfmd_pos, k_ra8_pdm_pdsfcr_ckdiv_pos, k_ra8_pdm_pdsfcr_sincdec_pos, k_ra8_pdm_pdsfcr_sincrng_pos, ra8_pdm_channel_cfg_t::lpf_shift, r_pdm_ch_regs_t::PDMDSR, r_pdm_ch_regs_t::PDSFCR, RA8_INTERNAL, ra8_pdm_channel_cfg_t::sinc_dec, ra8_pdm_channel_cfg_t::sinc_order, and ra8_pdm_channel_cfg_t::sinc_range.
Referenced by ra8_pdm_configure().
|
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.
| [in] | ch | Channel index (0..2). |
| [in] | cfg | Channel configuration (non-NULL). |
| k_ra8_ok | Channel configured. |
| k_ra8_err_invalid_arg | ch out of range. |
| k_ra8_err_null_ptr | cfg was NULL. |
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().
|
nodiscard |
Put the PDM-IF block back into module stop.
| k_ra8_ok | Module stopped. |
| k_ra8_err_hw_timeout | Module-stop entry did not settle. |
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().
|
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.
| k_ra8_ok | Module clocked and common bank reset. |
| k_ra8_err_hw_timeout | Module-stop release did not settle. |
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().
|
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.
| [in] | ch | Channel index (0..2). |
| [out] | out | Destination sample buffer (non-NULL). |
| [in] | max | Capacity of out in samples (>0). |
| [out] | out_count | Number of samples written (non-NULL). |
| k_ra8_ok | Zero or more samples returned. |
| k_ra8_err_invalid_arg | ch out of range or max was 0. |
| k_ra8_err_null_ptr | out or out_count was NULL. |
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().
|
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.
| [in] | ch | Channel index (0..2). |
| k_ra8_ok | Data read enabled and FIFO primed. |
| k_ra8_err_invalid_arg | ch out of range. |
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().
|
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.
| [in] | ch | Channel index (0..2). |
| k_ra8_ok | Start trigger issued. |
| k_ra8_err_invalid_arg | ch out of range. |
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().
|
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.
| [in] | ch | Channel index (0..2). |
| k_ra8_ok | Channel stopped. |
| k_ra8_err_invalid_arg | ch out of range. |
| k_ra8_err_hw_timeout | Channel did not report stopped. |
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().
|
nodiscard |
Disable interrupt-driven delivery for one channel.
| [in] | ch | Channel index (0..2). |
| k_ra8_ok | Delivery disabled. |
| k_ra8_err_invalid_arg | Channel is invalid. |
| k_ra8_err_not_initialized | Channel was not streaming. |
| other | Propagated ISR unregister error. |
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().
|
nodiscard |
Enable interrupt-driven FIFO delivery for one running channel.
| [in] | ch | Channel index (0..2). |
| [in] | callback | Bounded data callback. |
| [in] | ctx | Opaque callback context; may be nullptr. |
| [in] | priority | NVIC priority accepted by ra8_isr_register. |
| k_ra8_ok | Interrupt delivery enabled. |
| k_ra8_err_null_ptr | callback was nullptr. |
| k_ra8_err_invalid_arg | Channel or priority is invalid. |
| k_ra8_err_exists | The channel is already streaming. |
| other | Propagated ISR registration error. |
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().
|
static |
Definition at line 43 of file ra8_pdm.c.
Referenced by ra8_pdm_stream_disable(), and ra8_pdm_stream_enable().
|
static |
Definition at line 41 of file ra8_pdm.c.
Referenced by internal_pdm_data_isr(), ra8_pdm_stop(), ra8_pdm_stream_disable(), and ra8_pdm_stream_enable().