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

PWM Delay Generation Circuit (PDG) driver public API. More...

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

Go to the source code of this file.

Data Structures

struct  ra8_pdg_config_t
 Driver configuration descriptor for ra8_pdg_init. More...
struct  ra8_pdg_status_full_t
 Decoded snapshot of GTDLYCR / GTDLYCR2 returned by ra8_pdg_get_status_full. More...
struct  ra8_pdg_delay_entry_t
 Single-edge descriptor for the batch update API. More...

Typedefs

typedef void(* ra8_pdg_event_fn_t) (void *ctx)
 PDG event callback (DLL lock event, etc.).

Enumerations

enum  ra8_pdg_edge_t : uint8_t {
  k_ra8_pdg_edge_rising = 0U ,
  k_ra8_pdg_edge_falling = 1U
}
 Selects which delay register family is targeted. More...
enum  ra8_pdg_pin_t : uint8_t {
  k_ra8_pdg_pin_a = 0U ,
  k_ra8_pdg_pin_b = 1U
}
 Picks the A or B pin within a PDG channel. More...
enum  ra8_pdg_status_t : uint16_t {
  k_ra8_pdg_status_dll_locked = 0x0001U ,
  k_ra8_pdg_status_in_reset = 0x0002U ,
  k_ra8_pdg_status_frange_msk = 0x0300U
}
 Bits surfaced by ra8_pdg_get_status (legacy compact form). More...
enum  ra8_pdg_count_dir_t : uint8_t {
  k_ra8_pdg_dir_up = 0U ,
  k_ra8_pdg_dir_down = 1U
}
 Counter direction passed to ra8_pdg_check_constraints. More...
enum  ra8_pdg_wave_mode_t : uint8_t {
  k_ra8_pdg_wave_saw = 0U ,
  k_ra8_pdg_wave_triangle = 1U
}
 PWM waveform shape – selects which Table 23.4 row applies. More...

Functions

ra8_err_t ra8_pdg_init (const ra8_pdg_config_t *cfg)
 Initialise the PDG block per HUM Figure 23.2 (p 1160).
ra8_err_t ra8_pdg_deinit (void)
 Tear down the PDG block (reset + module-stop).
ra8_err_t ra8_pdg_set_delay (uint8_t channel, ra8_pdg_pin_t pin, ra8_pdg_edge_t edge, uint8_t code)
 Set the per-edge fine delay for one PDG channel/pin/edge.
ra8_err_t ra8_pdg_get_delay (uint8_t channel, ra8_pdg_pin_t pin, ra8_pdg_edge_t edge, uint8_t *out_code)
 Read back the last-programmed delay code.
ra8_err_t ra8_pdg_set_delay_batch (const ra8_pdg_delay_entry_t *entries, uint8_t count)
 Atomically program a batch of (channel, pin, edge, code) delay updates.
ra8_err_t ra8_pdg_delay_ns_to_code (uint32_t delay_ns, uint32_t gptclk_hz, ra8_pdg_frange_t frange, uint8_t *out_code)
 Convert a desired pin-to-pin delay (in nanoseconds) to a DLY[6:0] code given a measured GPTCLK frequency.
ra8_err_t ra8_pdg_exit_stop (uint8_t channel)
 Power up one PDG channel (clear the GTDLYCR2.DLYENn bit).
ra8_err_t ra8_pdg_enter_stop (uint8_t channel)
 Power down one PDG channel (set GTDLYCR2.DLYENn).
ra8_err_t ra8_pdg_channel_bypass_set (uint8_t channel, uint8_t bypass)
 Set or clear the bypass bit for a channel.
ra8_err_t ra8_pdg_pin_disable (uint8_t channel, ra8_pdg_pin_t pin)
 Force a single A or B pin's delay to zero (per-pin disable) without touching the channel-level bypass / power bits.
ra8_err_t ra8_pdg_get_status (uint16_t *out)
 Read GTDLYCR packed into a status mask.
ra8_err_t ra8_pdg_get_status_full (ra8_pdg_status_full_t *out)
 Read a fully-decoded snapshot of GTDLYCR + GTDLYCR2.
ra8_err_t ra8_pdg_clear_status (uint16_t mask)
 Clear the soft-reset bit (DLYRST -> 0) and re-enable the DLL.
ra8_err_t ra8_pdg_attach_handler (ra8_pdg_event_fn_t fn, void *ctx)
 Attach an asynchronous PDG event callback.
void ra8_pdg_dispatch (void)
 Fire the registered handler.
ra8_err_t ra8_pdg_pick_frange (uint32_t gptclk_hz, ra8_pdg_frange_t *out)
 Auto-pick a FRANGE value from a measured GPTCLK frequency.
ra8_err_t ra8_pdg_set_frange (ra8_pdg_frange_t new_frange)
 Switch FRANGE at runtime, re-running the DLL re-lock sequence with the new band.
ra8_err_t ra8_pdg_bind_gpt_channel (uint8_t channel)
 Bind PDG channel n to its host GPT32n channel.
ra8_err_t ra8_pdg_unbind_gpt_channel (uint8_t channel)
 Reverse ra8_pdg_bind_gpt_channel, restoring write-protect.
ra8_err_t ra8_pdg_check_constraints (ra8_pdg_wave_mode_t mode, ra8_pdg_count_dir_t dir, uint32_t compare_match, uint32_t gtpr)
 Check Table 23.4 constraints before writing a delay register.
ra8_err_t ra8_pdg_required_write_ns (uint32_t pclka_hz, uint32_t gptclk_hz, uint32_t *out_ns)
 Compute the minimum register-write interval (HUM 23.4.3 p 1163).
ra8_err_t ra8_pdg_capture_start (const ra8_pdg_delay_entry_t *buf, uint8_t len)
 Stage a buffer of ra8_pdg_delay_entry_t records and arm them.
ra8_err_t ra8_pdg_capture_stop (void)
 Cancel any pending buffered apply and clear the completion latch.

Detailed Description

PWM Delay Generation Circuit (PDG) driver public API.

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

The PDG (HUM Ch 23 "PWM Delay Generation Circuit (PDG)", p 1152-1163) is a per-edge fine-delay sub-block that sits in line with the GPT320..GPT323 PWM outputs and shifts each rising or falling edge by an integer fraction of the GPT core clock period (1/128 in the 80..160 MHz range, 1/64 in the 155..300 MHz range).

Hardware binding:

  • PDG channel 0 -> GPT320 -> GTIOC0A / GTIOC0B
  • PDG channel 1 -> GPT321 -> GTIOC1A / GTIOC1B
  • PDG channel 2 -> GPT322 -> GTIOC2A / GTIOC2B
  • PDG channel 3 -> GPT323 -> GTIOC3A / GTIOC3B

GPT324..GPT329 are not delayed – they bypass the PDG entirely (HUM Figure 23.1 p 1153). The driver therefore caps the channel argument at 4.

Initialization sequence implemented by ra8_pdg_init follows Figure 23.2 (p 1160):

  1. Clear DLLEN, set DLYRST = 1, all DLYBSn = 0, set FRANGE.
  2. Set DLLEN = 1 (start the DLL).
  3. Wait >= 20 us for the DLL to lock.
  4. Clear DLYRST (release the delay generation circuit).
  5. Wait >= 5 GTCLK cycles.
  6. Set DLYBSn = 1 for the channels in use (turn off bypass).

Note: PDG is bound to GPT0/1/2/3 channels; you must also configure the matching GPT timer through the GPT driver. Use this driver solely for the per-edge fine delay overlay.

Round-3 additions (full Ch 23 coverage):

  • Auto-tune calibration: pick FRANGE from a measured GPTCLK Hz.
  • Multi-edge atomic batch updates: ra8_pdg_set_delay_batch.
  • Runtime FRANGE switch: ra8_pdg_set_frange re-runs the DLL re-lock sequence with the new band, preserving channel state.
  • Full GPT0/1/2/3 binding helpers: ra8_pdg_bind_gpt_channel cracks open GTWP for the matching GPT channel before letting delay-register writes through (HUM 23.2.3 p 1156).
  • Per-pin enable/disable helpers ra8_pdg_pin_bypass_set so a single pin can stay bypassed while its sibling is delayed.
  • Full status reporting: ra8_pdg_get_status_full returns a structured snapshot of every PDG bit.
  • Compare-match constraint check: ra8_pdg_check_constraints implements HUM Ch 23.4.2 Table 23.4 (p 1162).
  • Register-write-interval helper ra8_pdg_required_write_ns implements HUM Ch 23.4.3 (p 1163).
See also
ra8_gpt.h GPT timer driver – you must configure GPT320..323 output channels before the PDG delays take effect.

Definition in file ra8_pdg.h.

Typedef Documentation

◆ ra8_pdg_event_fn_t

typedef void(* ra8_pdg_event_fn_t) (void *ctx)

PDG event callback (DLL lock event, etc.).

Parameters
[in]ctxCaller context forwarded from ra8_pdg_attach_handler.

The PDG itself does not raise its own NVIC vector – delay transfers happen on GPT timer overflow / underflow / trough (HUM Ch 23.3.2 p 1161). The callback hook is exposed so a host test (or a future "DLL lost lock" watchdog wired through ELC) has a single entry point to deliver async notifications.

Definition at line 231 of file ra8_pdg.h.

Enumeration Type Documentation

◆ ra8_pdg_count_dir_t

enum ra8_pdg_count_dir_t : uint8_t

Counter direction passed to ra8_pdg_check_constraints.

HUM Ch 23.4.2 Table 23.4 (p 1162) restricts when a delay register may be updated, depending on whether the host GPT counter is counting up or down. The two values match the GPT GTST.TUCF bit semantics so callers can pass GTST.TUCF directly.

Enumerator
k_ra8_pdg_dir_up 

Counter is up-counting (TUCF == 0).

k_ra8_pdg_dir_down 

Counter is down-counting (TUCF == 1).

Definition at line 130 of file ra8_pdg.h.

◆ ra8_pdg_edge_t

enum ra8_pdg_edge_t : uint8_t

Selects which delay register family is targeted.

Maps directly to the HUM split between GTDLYRn (rising) and GTDLYFn (falling) registers. Used by ra8_pdg_set_delay / ra8_pdg_get_delay.

Enumerator
k_ra8_pdg_edge_rising 

GTDLYRnA / GTDLYRnB.

k_ra8_pdg_edge_falling 

GTDLYFnA / GTDLYFnB.

Definition at line 86 of file ra8_pdg.h.

◆ ra8_pdg_pin_t

enum ra8_pdg_pin_t : uint8_t

Picks the A or B pin within a PDG channel.

Each PDG channel feeds two GPT outputs: the A pin is GTIOCnA, the B pin is GTIOCnB. The two delay codes are independent.

Enumerator
k_ra8_pdg_pin_a 

GTIOCnA – "A" output of GPT32n.

k_ra8_pdg_pin_b 

GTIOCnB – "B" output of GPT32n.

Definition at line 99 of file ra8_pdg.h.

◆ ra8_pdg_status_t

enum ra8_pdg_status_t : uint16_t

Bits surfaced by ra8_pdg_get_status (legacy compact form).

The PDG has no dedicated status register – "status" here is a snapshot of GTDLYCR (DLLEN / DLYRST / FRANGE) packed into a caller-friendly mask. ra8_pdg_get_status reads GTDLYCR directly per HUM Ch 23.2.1 p 1154.

Enumerator
k_ra8_pdg_status_dll_locked 

DLLEN = 1 (DLL running).

k_ra8_pdg_status_in_reset 

DLYRST = 1 (held in reset).

k_ra8_pdg_status_frange_msk 

Live FRANGE[1:0] bits.

Definition at line 114 of file ra8_pdg.h.

◆ ra8_pdg_wave_mode_t

enum ra8_pdg_wave_mode_t : uint8_t

PWM waveform shape – selects which Table 23.4 row applies.

The constraint table in HUM Ch 23.4.2 (p 1162) lists two rows: saw-wave mode and triangle-wave mode. Triangle mode is identified here so that ra8_pdg_check_constraints selects the right row.

Enumerator
k_ra8_pdg_wave_saw 

Saw-wave PWM (count up or down).

k_ra8_pdg_wave_triangle 

Triangle-wave PWM.

Definition at line 144 of file ra8_pdg.h.

Function Documentation

◆ ra8_pdg_attach_handler()

ra8_err_t ra8_pdg_attach_handler ( ra8_pdg_event_fn_t fn,
void * ctx )
nodiscard

Attach an asynchronous PDG event callback.

The PDG itself does not raise an NVIC vector – this hook is available for higher-level code that wants to forward GPT compare-match events (e.g. "delay updated") through a single registration point.

Parameters
[in]fnCallback invoked from ra8_pdg_dispatch.
[in]ctxForwarded to fn.
Returns
k_ra8_ok – the registration cannot fail.
Precondition
None.
Postcondition
Subsequent ra8_pdg_dispatch calls invoke fn.
Since
0.1.0

Definition at line 707 of file ra8_pdg.c.

References k_ra8_ok, s_pdg_event_ctx, and s_pdg_event_fn.

◆ ra8_pdg_bind_gpt_channel()

ra8_err_t ra8_pdg_bind_gpt_channel ( uint8_t channel)
nodiscard

Bind PDG channel n to its host GPT32n channel.

HUM Ch 23.2.3 (p 1156) requires that GTWP write-protect is cleared on the matching GPT channel before the PDG delay registers can be written. This helper performs that GTWP unlock (and stores the prior value so the caller can re-arm protection later via ra8_pdg_unbind_gpt_channel).

Parameters
[in]channel0..3 (GPT320..GPT323).
Returns
ra8_err_t error code.
Return values
k_ra8_okGTWP cleared, binding active.
k_ra8_err_invalid_argchannel out of range.
Precondition
PDG init has run.
Postcondition
GPT32n.GTWP write-protect bits cleared.
Subsequent ra8_pdg_set_delay writes are accepted.
Since
0.1.0

Definition at line 839 of file ra8_pdg.c.

References r_gpt_channel_regs_t::GTWP, internal_pdg_is_initialized(), k_ra8_err_hw_unmapped, k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_gtwp_unlock, and ra8_gpt().

◆ ra8_pdg_capture_start()

ra8_err_t ra8_pdg_capture_start ( const ra8_pdg_delay_entry_t * buf,
uint8_t len )
nodiscard

Stage a buffer of ra8_pdg_delay_entry_t records and arm them.

The PDG itself does not "capture" data – this entry-point exists so the camera/data-capture orchestrator can stream a buffer of fine-delay updates through the same *_capture_start(buf, len) shape that the VIN / CEU drivers expose. Each ra8_pdg_delay_entry_t in buf is forwarded to ra8_pdg_set_delay_batch after a NULL / range check, and the registered completion callback (see ra8_pdg_attach_handler) fires via ra8_pdg_dispatch once all entries land.

Parameters
[in]bufPointer to an array of ra8_pdg_delay_entry_t records.
[in]lenElement count (must be > 0 and <= k_ra8_pdg_slot_count).
Returns
ra8_err_t
Return values
k_ra8_okEntries staged + dispatch fired.
k_ra8_err_null_ptrbuf was NULL.
k_ra8_err_invalid_arglen out of range or bad entry.
k_ra8_err_not_initializedPDG init has not run.
Precondition
PDG init has run.
buf is non-NULL and points to len valid entries.
Postcondition
All entries are written to their PDG temporary registers.
The registered completion callback fires once.
Note
Not thread-safe.
See also
ra8_pdg_set_delay_batch
ra8_pdg_capture_stop
Since
0.1.0

Definition at line 738 of file ra8_pdg.c.

References k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_pdg_dispatch(), ra8_pdg_set_delay_batch(), s_pdg_capture_in_flight, and s_tag.

◆ ra8_pdg_capture_stop()

ra8_err_t ra8_pdg_capture_stop ( void )
nodiscard

Cancel any pending buffered apply and clear the completion latch.

Mirrors the VIN / CEU *_capture_stop shape. Implementation simply clears the internal "in flight" flag so a subsequent ra8_pdg_dispatch does not double-fire the callback.

Returns
ra8_err_t
Return values
k_ra8_okAlways.
Precondition
PDG init has run.
Postcondition
Pending in-flight latch is cleared.
Note
Not thread-safe.
See also
ra8_pdg_capture_start
Since
0.1.0

Definition at line 754 of file ra8_pdg.c.

References k_ra8_ok, and s_pdg_capture_in_flight.

◆ ra8_pdg_channel_bypass_set()

ra8_err_t ra8_pdg_channel_bypass_set ( uint8_t channel,
uint8_t bypass )
nodiscard

Set or clear the bypass bit for a channel.

HUM Ch 23.2.2 (p 1155) describes the DLYBSn bit: 1 = delay applied, 0 = bypass. ra8_pdg_init already sets the bit for every channel in cfg->channel_mask; this helper exists so a caller can flip the bypass on the fly without a full re-init.

Parameters
[in]channel0..3.
[in]bypassNon-zero sets bypass-off (delay applied); zero sets bypass-on (delay skipped).
Returns
ra8_err_t error code.
Precondition
PDG init has run.
Postcondition
DLYBSn matches bypass.
Since
0.1.0

Definition at line 616 of file ra8_pdg.c.

References r_pdg_regs_t::GTDLYCR2, internal_pdg_is_initialized(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_gtdlycr2_shift_dlybs, and ra8_pdg().

◆ ra8_pdg_check_constraints()

ra8_err_t ra8_pdg_check_constraints ( ra8_pdg_wave_mode_t mode,
ra8_pdg_count_dir_t dir,
uint32_t compare_match,
uint32_t gtpr )
nodiscard

Check Table 23.4 constraints before writing a delay register.

HUM Ch 23.4.2 Table 23.4 (p 1162) forbids changing a delay register while the host GPT is in a "no write" window:

mode direction compare-match value forbidden
Saw Up >= GTPR - 2
Saw Down <= 2
Triangle Down <= 2
Parameters
[in]modeSaw vs triangle.
[in]dirCounter direction.
[in]compare_matchCurrent GTCCRx (= compare match value).
[in]gtprGPT period register value.
Returns
ra8_err_t error code.
Return values
k_ra8_okSafe to write the delay register.
k_ra8_err_invalid_stateInside the forbidden window.
Precondition
None.
Postcondition
No side effects.
Since
0.1.0

Definition at line 881 of file ra8_pdg.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_pdg_constraint_high_pad, k_ra8_pdg_constraint_low_thresh, k_ra8_pdg_dir_down, k_ra8_pdg_dir_up, k_ra8_pdg_wave_saw, and k_ra8_pdg_wave_triangle.

◆ ra8_pdg_clear_status()

ra8_err_t ra8_pdg_clear_status ( uint16_t mask)
nodiscard

Clear the soft-reset bit (DLYRST -> 0) and re-enable the DLL.

Used to re-arm the block after a controlled park via ra8_pdg_enter_stop. The "status mask" is in fact the GTDLYCR register so this call only writes back the bit that the caller provided – DLYRST is forced low.

Parameters
[in]maskCaller-supplied bits to clear in GTDLYCR. Only k_ra8_pdg_status_in_reset is meaningful today.
Returns
ra8_err_t error code.
Precondition
PDG init has run.
Postcondition
GTDLYCR.DLYRST = 0 if mask includes k_ra8_pdg_status_in_reset.
Since
0.1.0

Definition at line 696 of file ra8_pdg.c.

References r_pdg_regs_t::GTDLYCR, k_ra8_ok, k_ra8_pdg_gtdlycr_mask_dlyrst, k_ra8_pdg_status_in_reset, and ra8_pdg().

◆ ra8_pdg_deinit()

ra8_err_t ra8_pdg_deinit ( void )
nodiscard

Tear down the PDG block (reset + module-stop).

Returns
ra8_err_t error code.
Return values
k_ra8_okBlock parked back in module-stop with all channels disabled.
Precondition
PDG was previously initialized (otherwise a no-op).
Postcondition
GTDLYCR.DLLEN = 0 and DLYRST = 1.
GTDLYCR2 = 0 (every channel bypassed and powered down).
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 464 of file ra8_pdg.c.

References r_pdg_dly_pair_t::A, r_pdg_dly_pair_t::B, r_pdg_regs_t::GTDLYCR, r_pdg_regs_t::GTDLYCR2, r_pdg_regs_t::GTDLYF, r_pdg_regs_t::GTDLYR, k_ra8_mstp_pdg, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_gtdlycr_mask_dlyrst, ra8_mstp_disable(), and ra8_pdg().

◆ ra8_pdg_delay_ns_to_code()

ra8_err_t ra8_pdg_delay_ns_to_code ( uint32_t delay_ns,
uint32_t gptclk_hz,
ra8_pdg_frange_t frange,
uint8_t * out_code )
nodiscard

Convert a desired pin-to-pin delay (in nanoseconds) to a DLY[6:0] code given a measured GPTCLK frequency.

Uses the divider table from HUM Ch 23.2.3..23.2.6 (p 1156-1158): 1/128 step at k_ra8_pdg_frange_80_160_mhz, 1/64 step at k_ra8_pdg_frange_155_300_mhz. The result is rounded to the nearest representable code and clamped to [0, 0x7F].

Parameters
[in]delay_nsDesired delay in nanoseconds.
[in]gptclk_hzGPTCLK frequency in Hz (must be > 0).
[in]frangeThe FRANGE band currently programmed.
[out]out_codeReceives the closest DLY[6:0] code.
Returns
ra8_err_t error code.
Return values
k_ra8_okCode computed.
k_ra8_err_null_ptrout_code is NULL.
k_ra8_err_invalid_arggptclk_hz is zero or frange out of range.
Precondition
out_code non-null, gptclk_hz > 0.
Postcondition
*out_code <= 0x7F.
Since
0.1.0

Definition at line 554 of file ra8_pdg.c.

References internal_frange_ok(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdg_dly_div_high, k_ra8_pdg_dly_div_low, k_ra8_pdg_dly_max, k_ra8_pdg_frange_80_160_mhz, k_ra8_pdg_ns_per_sec, RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_pdg_dispatch()

void ra8_pdg_dispatch ( void )

Fire the registered handler.

Test / ELC entry point.

Since
0.1.0

See implementation.

Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.

Definition at line 715 of file ra8_pdg.c.

References s_pdg_event_ctx, and s_pdg_event_fn.

Referenced by ra8_pdg_capture_start().

◆ ra8_pdg_enter_stop()

ra8_err_t ra8_pdg_enter_stop ( uint8_t channel)
nodiscard

Power down one PDG channel (set GTDLYCR2.DLYENn).

Parameters
[in]channel0..3.
Returns
ra8_err_t error code.
Precondition
channel < 4.
Postcondition
Channel channel is power-off; its outputs revert to the undelayed GPT signal.
Since
0.1.0

Definition at line 603 of file ra8_pdg.c.

References r_pdg_regs_t::GTDLYCR2, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_gtdlycr2_shift_dlyen, and ra8_pdg().

◆ ra8_pdg_exit_stop()

ra8_err_t ra8_pdg_exit_stop ( uint8_t channel)
nodiscard

Power up one PDG channel (clear the GTDLYCR2.DLYENn bit).

Parameters
[in]channel0..3.
Returns
ra8_err_t error code.
Precondition
PDG init has run.
Postcondition
Channel channel is power-on (HUM 23.2.2 p 1155 – DLYEN is inverted, 0 = enabled).
Since
0.1.0

Definition at line 589 of file ra8_pdg.c.

References r_pdg_regs_t::GTDLYCR2, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_gtdlycr2_shift_dlyen, and ra8_pdg().

◆ ra8_pdg_get_delay()

ra8_err_t ra8_pdg_get_delay ( uint8_t channel,
ra8_pdg_pin_t pin,
ra8_pdg_edge_t edge,
uint8_t * out_code )
nodiscard

Read back the last-programmed delay code.

Parameters
[in]channelPDG channel (0..3).
[in]pink_ra8_pdg_pin_a / k_ra8_pdg_pin_b.
[in]edgek_ra8_pdg_edge_rising / k_ra8_pdg_edge_falling.
[out]out_codeReceives the DLY[6:0] code last written.
Returns
ra8_err_t error code.
Precondition
out_code is non-null.
channel < 4.
Postcondition
*out_code is in 0..0x7F.
Note
Reads the live register, not the temporary buffer.
Since
0.1.0

Definition at line 512 of file ra8_pdg.c.

References internal_dly_cell(), internal_validate_slot(), k_ra8_ok, k_ra8_pdg_dly_mask, pin, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.

Referenced by internal_pdg_demo_sample().

◆ ra8_pdg_get_status()

ra8_err_t ra8_pdg_get_status ( uint16_t * out)
nodiscard

Read GTDLYCR packed into a status mask.

Parameters
[out]outReceives a bitmask of ra8_pdg_status_t bits.
Returns
ra8_err_t error code.
Precondition
out is non-null.
Postcondition
*out reflects the live GTDLYCR (DLLEN, DLYRST, FRANGE).
Since
0.1.0

Definition at line 663 of file ra8_pdg.c.

References r_pdg_regs_t::GTDLYCR, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_pdg(), and s_tag.

◆ ra8_pdg_get_status_full()

ra8_err_t ra8_pdg_get_status_full ( ra8_pdg_status_full_t * out)
nodiscard

Read a fully-decoded snapshot of GTDLYCR + GTDLYCR2.

Parameters
[out]outNon-null structure to fill in.
Returns
ra8_err_t error code.
Return values
k_ra8_okSnapshot stored.
k_ra8_err_null_ptrout is NULL.
Precondition
out non-null.
Postcondition
Every field in *out reflects the live registers at call time (DLLEN, DLYRST, FRANGE, DLYBSn, DLYENn).
Since
0.1.0

Definition at line 672 of file ra8_pdg.c.

References ra8_pdg_status_full_t::dll_enabled, ra8_pdg_status_full_t::frange, r_pdg_regs_t::GTDLYCR, r_pdg_regs_t::GTDLYCR2, ra8_pdg_status_full_t::in_reset, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_gtdlycr2_shift_dlybs, k_ra8_pdg_gtdlycr2_shift_dlyen, k_ra8_pdg_gtdlycr_mask_dllen, k_ra8_pdg_gtdlycr_mask_dlyrst, k_ra8_pdg_gtdlycr_mask_frange, k_ra8_pdg_gtdlycr_shift_frange, ra8_pdg_status_full_t::per_channel_bypass_off, ra8_pdg_status_full_t::per_channel_powered, RA8_CHECK_NULL_PTR, ra8_pdg(), ra8_pdg_status_full_t::raw_gtdlycr, ra8_pdg_status_full_t::raw_gtdlycr2, and s_tag.

Referenced by internal_pdg_demo_sample().

◆ ra8_pdg_init()

ra8_err_t ra8_pdg_init ( const ra8_pdg_config_t * cfg)
nodiscard

Initialise the PDG block per HUM Figure 23.2 (p 1160).

Clears the PDG module-stop bit (MSTPD6 per HUM Ch 23.4.1 p 1162), holds the circuit in reset, programs FRANGE (or auto-derives it from cfg->gptclk_hz when cfg->auto_tune == 1), enables the DLL, waits for lock, releases reset, and turns off bypass for the channels listed in cfg->channel_mask.

Parameters
[in]cfgNon-NULL driver descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okInit complete.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_invalid_argcfg->frange out of range or cfg->channel_mask selects bits outside [0..3] or auto-tune saw gptclk_hz == 0.
k_ra8_err_out_of_rangeAuto-tune saw gptclk_hz outside the 80..300 MHz range allowed by HUM Ch 23.2.1 p 1154.
k_ra8_err_hw_init_failedMSTP failed to release the block.
Precondition
IRQs masked or single-threaded init context.
ra8_mstp_init has been called.
Postcondition
GTDLYCR.DLLEN = 1 and DLYRST = 0.
GTDLYCR2.DLYBSn = 1 for every n in cfg->channel_mask.
Note
Thread safety: not thread-safe.
See also
ra8_gpt.h
ra8_pdg_set_frange Switch FRANGE at runtime without deinit.
Since
0.1.0

Definition at line 438 of file ra8_pdg.c.

References ra8_pdg_config_t::auto_tune, ra8_pdg_config_t::frange, ra8_pdg_config_t::gptclk_hz, internal_program_dll(), internal_validate_cfg(), k_ra8_mstp_pdg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_info, ra8_mstp_enable(), ra8_pdg_pick_frange(), RA8_RETURN_ON_ERROR, and s_tag.

Referenced by internal_pdg_demo_configure().

◆ ra8_pdg_pick_frange()

ra8_err_t ra8_pdg_pick_frange ( uint32_t gptclk_hz,
ra8_pdg_frange_t * out )
nodiscard

Auto-pick a FRANGE value from a measured GPTCLK frequency.

Implements the band-selection table of HUM Ch 23.2.1 (p 1154):

The two ranges overlap between 155 and 160 MHz; this helper picks the lower band when the input falls in the overlap because that gives the finer 1/128 step.

Parameters
[in]gptclk_hzGPTCLK in Hz (>0). 80..300 MHz inclusive.
[out]outReceives the chosen ra8_pdg_frange_t.
Returns
ra8_err_t error code.
Return values
k_ra8_okBand selected.
k_ra8_err_null_ptrout is NULL.
k_ra8_err_invalid_arggptclk_hz is 0.
k_ra8_err_out_of_rangegptclk_hz outside [80 MHz, 300 MHz].
Since
0.1.0

Definition at line 765 of file ra8_pdg.c.

References k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_ok, k_ra8_pdg_frange_155_300_mhz, k_ra8_pdg_frange_80_160_mhz, k_ra8_pdg_freq_high_max_hz, k_ra8_pdg_freq_low_min_hz, k_ra8_pdg_freq_overlap_top, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ra8_pdg_init().

◆ ra8_pdg_pin_disable()

ra8_err_t ra8_pdg_pin_disable ( uint8_t channel,
ra8_pdg_pin_t pin )
nodiscard

Force a single A or B pin's delay to zero (per-pin disable) without touching the channel-level bypass / power bits.

The HUM lets DLYBSn / DLYENn be flipped per channel; per-pin disable is achieved by writing 0x00 into the pin's two delay cells (rising + falling). ra8_pdg_pin_disable does that, and ra8_pdg_pin_enable restores caller-supplied codes.

Parameters
[in]channel0..3.
[in]pink_ra8_pdg_pin_a or k_ra8_pdg_pin_b.
Returns
ra8_err_t error code.
Precondition
PDG init has run.
Postcondition
Both rising and falling delay cells of the chosen pin = 0.
Since
0.1.0

Definition at line 637 of file ra8_pdg.c.

References internal_dly_cell(), internal_pdg_is_initialized(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_edge_falling, k_ra8_pdg_edge_rising, k_ra8_pdg_pin_a, k_ra8_pdg_pin_b, and pin.

◆ ra8_pdg_required_write_ns()

ra8_err_t ra8_pdg_required_write_ns ( uint32_t pclka_hz,
uint32_t gptclk_hz,
uint32_t * out_ns )
nodiscard

Compute the minimum register-write interval (HUM 23.4.3 p 1163).

Write_Interval [ns] = Period_of_PCLKA [ns] x 6

  • Period_of_GPTCLK [ns] x 4

Used by callers that issue back-to-back writes to the same delay register to size their software pacing.

Parameters
[in]pclka_hzPCLKA frequency in Hz (>0).
[in]gptclk_hzGPTCLK frequency in Hz (>0).
[out]out_nsReceives the required interval, in ns.
Returns
ra8_err_t error code.
Precondition
Both clocks > 0; out_ns non-null.
Postcondition
*out_ns >= 0.
Since
0.1.0

Definition at line 921 of file ra8_pdg.c.

References internal_freq_to_period_ns(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdg_gptclk_mult, k_ra8_pdg_pclka_mult, RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_pdg_set_delay()

ra8_err_t ra8_pdg_set_delay ( uint8_t channel,
ra8_pdg_pin_t pin,
ra8_pdg_edge_t edge,
uint8_t code )
nodiscard

Set the per-edge fine delay for one PDG channel/pin/edge.

Parameters
[in]channelPDG channel (0..3, mapped to GPT320..GPT323).
[in]pink_ra8_pdg_pin_a (GTIOCnA) or k_ra8_pdg_pin_b (GTIOCnB).
[in]edgek_ra8_pdg_edge_rising or k_ra8_pdg_edge_falling.
[in]codeDLY[6:0] code, 0..0x7F. 0 disables the delay on this edge; the meaning of non-zero codes depends on the FRANGE bit currently programmed in GTDLYCR (HUM Ch 23.2.3..23.2.6 p 1156-1158).
Returns
ra8_err_t error code.
Return values
k_ra8_okCode written.
k_ra8_err_invalid_argChannel >= 4, pin/edge invalid, or code > 0x7F.
k_ra8_err_not_initializedPDG init has not run.
Precondition
PDG is out of reset (GTDLYCR.DLYRST == 0).
Caller is not currently inside the GPT compare-match window where writes are disallowed (HUM Ch 23.4.2 p 1162, Table 23.4) – use ra8_pdg_check_constraints first.
Postcondition
The temporary register holds code; it propagates to the live delay on the next GPT overflow / underflow / trough (HUM Ch 23.3.2 p 1161).
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 494 of file ra8_pdg.c.

References internal_dly_cell(), internal_pdg_is_initialized(), internal_validate_slot(), k_ra8_err_not_initialized, k_ra8_ok, k_ra8_pdg_dly_mask, pin, RA8_RETURN_ON_ERROR, and s_tag.

Referenced by internal_pdg_demo_configure().

◆ ra8_pdg_set_delay_batch()

ra8_err_t ra8_pdg_set_delay_batch ( const ra8_pdg_delay_entry_t * entries,
uint8_t count )
nodiscard

Atomically program a batch of (channel, pin, edge, code) delay updates.

Walks entries and applies each one with IRQs nominally masked (host-test build is single-threaded). All writes land in the PDG temporary registers in the same critical section, so the next GPT overflow / underflow / trough applies them as one coherent set. This is the multi-edge atomic batch entry-point called for in HUM Ch 23.3.2 (p 1161).

Parameters
[in]entriesPointer to count entries.
[in]countNumber of entries (must be > 0 and <= k_ra8_pdg_slot_count).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll entries written.
k_ra8_err_null_ptrentries is NULL.
k_ra8_err_invalid_argCount out of range or any entry contains a bad channel / pin / edge / code.
k_ra8_err_not_initializedPDG init has not run.
Precondition
entries non-null and points to count valid entries.
PDG is out of reset.
Postcondition
Every entry's delay code is in the corresponding temporary register; it propagates on next overflow.
Since
0.1.0

Definition at line 525 of file ra8_pdg.c.

References internal_dly_cell(), internal_pdg_is_initialized(), internal_validate_slot(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_pdg_dly_mask, k_ra8_pdg_slot_count, pin, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ra8_pdg_capture_start().

◆ ra8_pdg_set_frange()

ra8_err_t ra8_pdg_set_frange ( ra8_pdg_frange_t new_frange)
nodiscard

Switch FRANGE at runtime, re-running the DLL re-lock sequence with the new band.

HUM Ch 23.2.1 (p 1154): "Set the FRANGE[1:0] bits only when the DLLEN bit is 0." This routine therefore performs:

  1. Save current DLYBSn / DLYENn from GTDLYCR2.
  2. Drop DLLEN to 0, raise DLYRST to 1.
  3. Write the new FRANGE bits.
  4. Re-enable DLLEN, wait 20 us for lock.
  5. Lower DLYRST.
  6. Restore the saved GTDLYCR2 bits.
Parameters
[in]new_frangeThe new FRANGE encoding.
Returns
ra8_err_t error code.
Return values
k_ra8_okSwitch complete.
k_ra8_err_invalid_argnew_frange not a legal band.
k_ra8_err_not_initializedPDG init has not run.
Precondition
PDG init has run.
Postcondition
GTDLYCR.FRANGE == new_frange, DLLEN = 1, DLYRST = 0.
GTDLYCR2 contents preserved across the call.
Since
0.1.0

Definition at line 787 of file ra8_pdg.c.

References r_pdg_regs_t::GTDLYCR, r_pdg_regs_t::GTDLYCR2, internal_busy_wait_us(), internal_frange_ok(), internal_pdg_is_initialized(), internal_wait_5_gtclk(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_pdg_dll_lock_us, k_ra8_pdg_gtdlycr_mask_dllen, k_ra8_pdg_gtdlycr_mask_dlyrst, k_ra8_pdg_gtdlycr_shift_frange, and ra8_pdg().

◆ ra8_pdg_unbind_gpt_channel()

ra8_err_t ra8_pdg_unbind_gpt_channel ( uint8_t channel)
nodiscard

Reverse ra8_pdg_bind_gpt_channel, restoring write-protect.

Parameters
[in]channel0..3.
Returns
ra8_err_t error code.
Precondition
channel < 4.
Postcondition
GPT32n.GTWP write-protect re-armed.
Since
0.1.0

Definition at line 860 of file ra8_pdg.c.

References r_gpt_channel_regs_t::GTWP, k_ra8_err_hw_unmapped, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pdg_channel_count, k_ra8_pdg_gtwp_lock, and ra8_gpt().