47static const char*
s_tag =
"SSIE";
77 .dma_attached =
false},
81 .dma_attached =
false},
392 uint32_t ssifcr = 0U;
421 const uint32_t scr_tdes =
423 const uint32_t scr_rdfs =
425 return scr_tdes | scr_rdfs;
450 reg->
SSIFCR = ssifcr_base;
614 if (reg ==
nullptr) {
641 if (reg ==
nullptr) {
662 if (reg ==
nullptr) {
669 uint32_t ssicr = reg->
SSICR;
671 const uint32_t desired_ren_ten = (uint32_t)dir;
672 if (desired_ren_ten == (current_ren_ten & desired_ren_ten)) {
675 if (current_ren_ten != 0U) {
684 uint32_t ssifcr = reg->
SSIFCR;
693 reg->
SSICR = ssicr | desired_ren_ten;
700 if (reg ==
nullptr) {
706 uint32_t ssicr = reg->
SSICR;
713 uint32_t ssifcr = reg->
SSIFCR;
722 if (reg ==
nullptr) {
729 reg->
SSIFCR = ssifcr_save;
735 const uint32_t ssisr = reg->
SSISR;
743 if (reg ==
nullptr) {
747 uint32_t ssicr = reg->
SSICR;
760 if (reg ==
nullptr) {
774 if (reg ==
nullptr) {
786 if (reg ==
nullptr) {
795 const uint32_t* buffer,
797 uint16_t* out_written)
802 if (reg ==
nullptr) {
806 uint16_t written = 0U;
807 for (uint16_t i = 0U; i < samples; i++) {
819 const uint32_t fsr = reg->
SSIFSR;
824 *out_written = written;
834 if (reg ==
nullptr) {
839 for (uint16_t i = 0U; i < samples; i++) {
851 const uint32_t fsr = reg->
SSIFSR;
864 if (reg ==
nullptr) {
868 const uint32_t ssisr = reg->
SSISR;
870 const uint32_t ssifsr = reg->
SSIFSR;
887 if (reg ==
nullptr) {
892 const uint32_t current = reg->
SSISR;
893 reg->
SSISR = current & ~writeable;
900 if (reg ==
nullptr) {
905 uint32_t ssicr = reg->
SSICR;
926 if (reg ==
nullptr) {
930 const uint32_t ssisr = reg->
SSISR;
932 const uint32_t ssifsr = reg->
SSIFSR;
937 fn(ctx, channel, events, ssisr);
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
8-channel DMA controller (DMAC0) driver
Error Code Definitions for ra8-firmware.
@ k_ra8_err_busy
Resource busy – blocking operation cannot proceed.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Cross-translation-unit private helpers shared inside ra8_hal.
@ k_ra8_ssie_dma_ch_unused
Sentinel: no DMA channel.
@ k_ra8_ssie_thresh_max
Max SSISCR threshold value.
ra8_ssie_runtime_t g_ssie_runtime[k_ra8_ssie_channel_count]
Per-channel SSIE runtime state, shared across the ra8_ssie split.
Bounded wait-flag primitives for RA8D2 HAL drivers.
static ra8_err_t ra8_hw_wait_flag_clear32(volatile const uint32_t *reg, uint32_t mask, uint32_t budget)
Spin until (*reg & mask) == 0 or budget runs out.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Module Stop Control (MSTP) register layout for the Renesas RA8D2.
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_ssie1
MSTPC7 SSIE1.
@ k_ra8_mstp_ssie0
MSTPC8 SSIE0.
volatile r_ssie_regs_t * priv_ra8_ssie_internal_regs(uint8_t channel)
Implementation of priv_ra8_ssie_internal_regs() – bounds-check + accessor.
ra8_err_t ra8_ssie_clear_status(uint8_t channel, uint32_t mask)
Clear sticky error flags in SSISR.
ra8_err_t ra8_ssie_write_buffer(uint8_t channel, const uint32_t *buffer, uint16_t samples, uint16_t *out_written)
Drain a host buffer into the TX FIFO until either runs out.
ra8_err_t ra8_ssie_init(uint8_t channel, const ra8_ssie_cfg_t *cfg)
Initialise an SSIE channel for I2S / TDM / monaural transfer.
void ra8_ssie_dispatch(uint8_t channel)
ISR helper: fire the registered event handler.
ra8_err_t ra8_ssie_start_recovery(uint8_t channel)
Force the channel back into a known idle state.
static ra8_err_t internal_validate_init_cfg(const ra8_ssie_cfg_t *cfg, uint8_t *out_omod, uint8_t *out_frm, uint8_t *out_pdta, uint8_t *out_sdta)
Format-decode wrapper that validates ranges before delegation.
static ra8_ssie_event_fn_t s_ssie_fn
Globally registered SSIE event callback (one slot, shared).
static void internal_apply_init_regs(volatile r_ssie_regs_t *reg, const ra8_ssie_cfg_t *cfg, uint8_t frm, uint8_t pdta, uint8_t sdta, uint8_t omod)
Stamp SSICR/SSIOFR/SSISCR/SSIFCR for a freshly reset SSIE block.
static ra8_err_t internal_wait_ssirst_clear(volatile r_ssie_regs_t *reg)
Bounded poll on SSIFCR until SSIRST clears.
static void * s_ssie_ctx
Opaque context delivered to s_ssie_fn on dispatch.
static void internal_apply_dir_irq_bits(uint32_t desired_ren_ten, uint32_t *ssicr, uint32_t *ssifcr)
Apply per-direction IRQ-enable bits to in-progress SSICR/SSIFCR.
ra8_err_t ra8_ssie_set_thresholds(uint8_t channel, uint8_t tx_threshold, uint8_t rx_threshold)
Update the FIFO trigger watermarks at runtime.
ra8_err_t ra8_ssie_read_sample(uint8_t channel, uint32_t *out)
Pop one 32-bit sample from the receive FIFO.
ra8_err_t ra8_ssie_attach_handler(ra8_ssie_event_fn_t fn, void *ctx)
Attach a shared event callback for both SSIE channels.
ra8_err_t ra8_ssie_set_fifo_threshold(uint8_t channel, uint8_t tx_threshold, uint8_t rx_threshold)
Programme SSITDMR / SSIRDMR FIFO thresholds in one call.
ra8_err_t ra8_ssie_set_irq_enable(uint8_t channel, uint32_t mask, bool enable)
Update the IRQ enable mask without rewriting SSICR fully.
ra8_err_t ra8_ssie_write_sample(uint8_t channel, uint32_t sample)
Push one 32-bit sample into the transmit FIFO.
static uint8_t internal_decode_event(uint32_t ssisr, uint32_t ssifsr)
Decode SSISR/SSIFSR into a ra8_ssie_event_t bitmap.
static ra8_err_t internal_ssie_power_up(uint8_t channel, volatile r_ssie_regs_t *reg)
Power up the SSIE block: enable MSTP then drive SSIRST low.
static ra8_err_t internal_pulse_ssi_reset(volatile r_ssie_regs_t *reg)
Drive the soft-reset sequence required before SSICR writes.
static uint32_t internal_build_ssiofr(const ra8_ssie_cfg_t *cfg, uint8_t omod)
Pack SSIOFR (audio format register) value from cfg + decoded OMOD.
static ra8_err_t internal_pulse_fifo_reset(volatile r_ssie_regs_t *reg, uint32_t ssifcr_base)
Pulse RFRST/TFRST high then low and wait for both bits to clear.
ra8_err_t ra8_ssie_deinit(uint8_t channel)
Tear down an SSIE channel and gate its clock.
static uint32_t internal_build_ssiscr(uint8_t tx_threshold, uint8_t rx_threshold)
Pack SSISCR (status control register) value from TX/RX thresholds.
ra8_err_t ra8_ssie_stop(uint8_t channel)
Disable transmission and reception.
ra8_err_t ra8_ssie_mute(uint8_t channel, bool enable)
Enable or disable mute on the next frame boundary.
ra8_err_t ra8_ssie_exit_stop(uint8_t channel)
Re-ungate the channel's MSTP bit.
ra8_err_t ra8_ssie_start(uint8_t channel, ra8_ssie_dir_t dir)
Enable transmission, reception, or full duplex.
ra8_err_t ra8_ssie_enter_stop(uint8_t channel)
Gate the channel's MSTP bit (preserve register state).
ra8_err_t ra8_ssie_read_buffer(uint8_t channel, uint32_t *buffer, uint16_t samples, uint16_t *out_read)
Empty the RX FIFO into a host buffer until either runs out.
static uint32_t internal_build_ssicr(const ra8_ssie_cfg_t *cfg, uint8_t frm, uint8_t pdta, uint8_t sdta)
Build the SSICR value from a config descriptor.
ra8_err_t ra8_ssie_get_status(uint8_t channel, ra8_ssie_status_t *out)
Snapshot SSISR + SSIFSR into a status struct.
static const ra8_mstp_t s_ssie_mstp_table[k_ra8_ssie_channel_count]
Channel-index -> MSTP id lookup.
static uint32_t internal_build_ssifcr(const ra8_ssie_cfg_t *cfg)
Pack SSIFCR (FIFO control register) value from cfg.
static bool internal_format_decode(ra8_ssie_format_t format, uint8_t *out_omod, uint8_t *out_frm, uint8_t *out_pdta, uint8_t *out_sdta)
Translate a public format enum to OMOD + FRM register fields.
static ra8_err_t internal_wait_fifo_reset_clear(volatile r_ssie_regs_t *reg)
Bounded poll on SSIFCR until both FIFO reset bits clear.
Serial Sound Interface Enhanced (SSIE / I2S audio) driver.
void(* ra8_ssie_event_fn_t)(void *ctx, uint8_t channel, uint8_t events, uint32_t ssisr)
SSIE event callback fired by ra8_ssie_dispatch.
ra8_err_t ra8_ssie_detach_dma(uint8_t channel)
Tear down DMAC channels attached to the SSIE FIFOs.
ra8_ssie_format_t
Audio frame format (drives SSIOFR.OMOD[1:0] and SSICR.FRM).
@ k_ra8_ssie_format_i2s
I2S, 2 channels per frame.
@ k_ra8_ssie_format_tdm_4
TDM 4-slot.
@ k_ra8_ssie_format_monaural
Monaural single-channel.
@ k_ra8_ssie_format_tdm_8
TDM 8-slot.
@ k_ra8_ssie_format_tdm_6
TDM 6-slot.
@ k_ra8_ssie_format_left_just
Left-justified, 2 channels.
@ k_ra8_ssie_format_right_just
Right-justified, 2 channels.
ra8_ssie_dir_t
Communication direction selector for ra8_ssie_start.
@ k_ra8_ssie_dir_tx
Transmission only (TEN).
@ k_ra8_ssie_dir_rx
Reception only (REN).
@ k_ra8_ssie_dir_tx_rx
Full duplex (TEN | REN).
@ k_ra8_ssie_role_controller
Bit clock + LR clock are outputs.
@ k_ra8_ssie_evt_tx_empty
TDE asserted (TIE on).
@ k_ra8_ssie_evt_none
No bits set.
@ k_ra8_ssie_evt_idle
IIRQ asserted.
@ k_ra8_ssie_evt_tx_over
TOIRQ.
@ k_ra8_ssie_evt_rx_under
RUIRQ.
@ k_ra8_ssie_evt_rx_over
ROIRQ.
@ k_ra8_ssie_evt_rx_full
RDF asserted (RIE on).
@ k_ra8_ssie_evt_tx_under
TUIRQ.
Serial Sound Interface Enhanced (SSIE) register layout for the RA8D2.
@ k_ra8_ssie_shift_tdc
TDC[5:0] starts at bit 24.
@ k_ra8_ssie_shift_rdc
RDC[5:0] starts at bit 8.
@ k_ra8_ssie_shift_tdes
TDES[4:0] starts at bit 8.
@ k_ra8_ssie_shift_rdfs
RDFS[4:0] starts at bit 0.
@ k_ra8_ssie_mask_rie
RIE receive full IRQ.
@ k_ra8_ssie_mask_tie
TIE transmit empty IRQ.
@ k_ra8_ssie_mask_aucke
AUCKE AUDIO_MCK enable.
@ k_ra8_ssie_mask_rie_tie
RIE | TIE.
@ k_ra8_ssie_mask_bsw
BSW byte-swap enable.
@ k_ra8_ssie_mask_ssirst
SSIRST software reset.
@ k_ra8_ssie_mask_rfrst_tfrst
Both FIFO reset bits.
@ k_ra8_ssie_channel_count
SSIE0 + SSIE1.
@ k_ra8_ssie_reset_poll_max
Bounded reset poll loops.
@ k_ra8_ssie_fifo_depth
32-stage FIFO per dir.
@ k_ra8_ssie_omod_i2s
RA8 ssie omod i2s.
@ k_ra8_ssie_omod_tdm
RA8 ssie omod tdm.
@ k_ra8_ssie_omod_monaural
RA8 ssie omod monaural.
@ k_ra8_ssie_bit_ckdv0
CKDV[3:0] @ [7:4] bit clock div.
@ k_ra8_ssie_bit_dwl0
DWL[2:0] @ [21:19] data word.
@ k_ra8_ssie_bit_frm0
FRM[1:0] @ [23:22] frame words.
@ k_ra8_ssie_bit_swl0
SWL[2:0] @ [18:16] system word.
@ k_ra8_ssie_frm_default
2 (I2S) / 1 (Mon) / – (TDM)
@ k_ra8_ssie_frm_alt3
– / – / 8 (TDM-8)
@ k_ra8_ssie_frm_alt1
– / – / 4 (TDM-4)
@ k_ra8_ssie_frm_alt2
– / – / 6 (TDM-6)
@ k_ra8_ssie_mask_err_all
ROIRQ|RUIRQ|TOIRQ|TUIRQ.
@ k_ra8_ssie_mask_ruirq
RUIRQ receive underflow.
@ k_ra8_ssie_mask_roirq
ROIRQ receive overflow.
@ k_ra8_ssie_mask_toirq
TOIRQ transmit overflow.
@ k_ra8_ssie_mask_tuirq
TUIRQ transmit underflow.
@ k_ra8_ssie_mask_iirq
IIRQ idle-mode flag (RO).
@ k_ra8_ssie_mask_err_ien
ROIEN..TUIEN tx/rx err IRQs.
@ k_ra8_ssie_mask_lrckp
LRCKP.
@ k_ra8_ssie_mask_ckdv
CKDV[3:0] @ [7:4].
@ k_ra8_ssie_mask_swl
SWL[2:0] @ [18:16].
@ k_ra8_ssie_mask_dwl
DWL[2:0] @ [21:19].
@ k_ra8_ssie_mask_sdta
SDTA.
@ k_ra8_ssie_mask_mst
MST.
@ k_ra8_ssie_mask_tuien
TUIEN.
@ k_ra8_ssie_mask_bckp
BCKP.
@ k_ra8_ssie_mask_ren
REN.
@ k_ra8_ssie_mask_del
DEL.
@ k_ra8_ssie_mask_spdp
SPDP.
@ k_ra8_ssie_mask_roien
ROIEN.
@ k_ra8_ssie_mask_muen
MUEN.
@ k_ra8_ssie_mask_ren_ten
REN | TEN.
@ k_ra8_ssie_mask_ten
TEN.
@ k_ra8_ssie_mask_iien
IIEN.
@ k_ra8_ssie_mask_frm
FRM[1:0] @ [23:22].
@ k_ra8_ssie_mask_cks
CKS audio clock select.
@ k_ra8_ssie_mask_pdta
PDTA.
@ k_ra8_ssie_mask_irq_all
IIEN..TUIEN aggregate IRQ.
@ k_ra8_ssie_mask_tde_clear
Keep RDF while clearing TDE.
@ k_ra8_ssie_mask_rdf_clear
Keep TDE while clearing RDF.
@ k_ra8_ssie_mask_rdf
RDF receive data full.
@ k_ra8_ssie_mask_tdc
TDC[5:0] @ [29:24].
@ k_ra8_ssie_mask_rdc
RDC[5:0] @ [13:8].
@ k_ra8_ssie_mask_tde
TDE transmit data empty.
@ k_ra8_ssie_mask_rdfs
RDFS[4:0] @ [4:0].
@ k_ra8_ssie_mask_tdes
TDES[4:0] @ [12:8].
static volatile r_ssie_regs_t * ra8_ssie(uint8_t channel)
Get pointer to an SSIE channel block.
@ k_ra8_ssie_mask_omod
OMOD[1:0] @ [1:0].
@ k_ra8_ssie_mask_lrcont
LRCONT continuation.
@ k_ra8_ssie_mask_bckastp
BCKASTP idle-stop BCK.
Per-channel SSIE register window.
volatile uint32_t SSISR
+0x04 Status register.
volatile uint32_t SSIFTDR
+0x18 Transmit FIFO data.
volatile uint32_t SSIOFR
+0x20 Audio format register.
volatile uint32_t SSIFSR
+0x14 FIFO status register.
volatile uint32_t SSISCR
+0x24 Status control register.
volatile uint32_t SSIFRDR
+0x1C Receive FIFO data.
volatile uint32_t SSICR
+0x00 Control register.
volatile uint32_t SSIFCR
+0x10 FIFO control register.
Configuration descriptor for ra8_ssie_init.
uint8_t rx_threshold
SSISCR.RDFS[4:0] watermark.
ra8_ssie_role_t role
Controller or peripheral.
uint8_t tx_threshold
SSISCR.TDES[4:0] watermark.
bool long_frame
true: SSICR.DEL = 0 (long).
ra8_ssie_data_word_t data_word
Significant bits per channel.
bool bckp_rising
true: SSICR.BCKP = 1.
bool byte_swap
SSIFCR.BSW.
ra8_ssie_system_word_t system_word
Total bits per channel.
bool spdp_high
true: SSICR.SPDP = 1.
bool bck_idle_stop
SSIOFR.BCKASTP (controller only).
bool lr_continue
SSIOFR.LRCONT (controller only).
bool lrckp_low
true: SSICR.LRCKP = 1.
bool enable_aucke
SSIFCR.AUCKE (controller only).
ra8_ssie_format_t format
I2S / TDM / monaural.
ra8_ssie_bclk_div_t bclk_div
CKDV divider (controller only).
bool use_gpt_clk
true: GTIOC2A; false: AUDIO_CLK.
Per-channel runtime bookkeeping.
Snapshot of FIFO levels + error flags returned by ra8_ssie_get_status.
uint32_t ssisr
Raw SSISR value.
bool rx_full
RDF flag: RX above SSISCR.RDFS.
uint8_t rx_count
RDC[5:0] – entries currently in RX.
uint32_t ssifsr
Raw SSIFSR value.
bool idle
IIRQ: SSIE in idle state.
bool error
Any of ROIRQ/RUIRQ/TOIRQ/TUIRQ set.
uint8_t tx_count
TDC[5:0] – entries currently in TX.
bool tx_empty
TDE flag: TX below SSISCR.TDES.
uint8_t events
Decoded ra8_ssie_event_t bitmap.