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

Ethernet Generic PTP Timer (GPTP) driver – HUM Ch 35. More...

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

Go to the source code of this file.

Data Structures

struct  ra8_eth_gptp_cfg_t
 Static configuration for ra8_eth_gptp_init. More...

Enumerations

enum  ra8_eth_gptp_limit_t : uint32_t {
  k_ra8_gptp_ns_per_sec = 1000000000UL ,
  k_ra8_gptp_nsec_max = 999999999UL
}
 Field limits taken from the HUM register descriptions. More...
enum  ra8_eth_gptp_sec_limit_t : uint64_t { k_ra8_gptp_sec_max = 0xFFFFFFFFFFFFULL }
 Upper bound of the GPTP seconds field. More...

Functions

ra8_err_t ra8_eth_gptp_init (const ra8_eth_gptp_cfg_t *cfg)
 Power up the GPTP block and programme both timers' increment.
ra8_err_t ra8_eth_gptp_deinit (void)
 Stop both timers, clear their configuration and gate the block off.
ra8_err_t ra8_eth_gptp_ip_version (uint32_t *out_version)
 Read the read-only PTPIPV IP-version word.
ra8_err_t ra8_eth_gptp_tiv_from_hz (uint32_t clk_hz, uint32_t *out_tiv)
 Derive PTPTIVCt.TIV from a clk frequency.
ra8_err_t ra8_eth_gptp_timer_enable (ra8_gptp_timer_idx_t timer)
 Start one timer unit (PTPTMEC.TEq).
ra8_err_t ra8_eth_gptp_timer_disable (ra8_gptp_timer_idx_t timer)
 Stop one timer unit (PTPTMDC.TDq).
ra8_err_t ra8_eth_gptp_timer_is_enabled (ra8_gptp_timer_idx_t timer, bool *out_enabled)
 Report whether one timer unit is enabled.
ra8_err_t ra8_eth_gptp_set_increment (ra8_gptp_timer_idx_t timer, uint32_t tiv)
 Write one timer unit's increment register PTPTIVCt.
ra8_err_t ra8_eth_gptp_get_increment (ra8_gptp_timer_idx_t timer, uint32_t *out_tiv)
 Read one timer unit's increment register PTPTIVCt.
ra8_err_t ra8_eth_gptp_set_offset (ra8_gptp_timer_idx_t timer, uint64_t sec, uint32_t nsec)
 Load one timer unit's additive 78-bit offset.
ra8_err_t ra8_eth_gptp_get_time (ra8_gptp_timer_idx_t timer, uint64_t *out_sec, uint32_t *out_nsec)
 Read one timer unit's 78-bit GPTP time.
ra8_err_t ra8_eth_gptp_get_avtp_ns (ra8_gptp_timer_idx_t timer, uint64_t *out_ns)
 Read one timer unit's 64-bit AVTP nanosecond counter.
ra8_err_t ra8_eth_gptp_enter_stop (void)
 Stop both timers and assert the ESWM module-stop gate.
ra8_err_t ra8_eth_gptp_exit_stop (void)
 Release the ESWM module-stop gate again.

Detailed Description

Ethernet Generic PTP Timer (GPTP) driver – HUM Ch 35.

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

Drives the RA8D2 GPTP block described by HUM Ch 35 "Ethernet Generic PTP Timer (GPTP)" p 1925-1964. That block is a timer, and this driver exposes exactly what the timer does:

  • enable / disable each of the two timer units (PTPTMEC / PTPTMDC);
  • program the per-clk increment PTPTIVCt (nanoseconds per clk cycle, 5.27 fixed point) from the ESWCLK frequency;
  • load the additive 78-bit offset {PTPTOVCtU, PTPTOVCtM, PTPTOVCtL};
  • read the 78-bit GPTP time {PTPGPTPTMtU, PTPGPTPTMtM, PTPGPTPTMtL} (48-bit seconds + 30-bit nanoseconds);
  • read the 64-bit AVTP nanosecond view {PTPAVTPTMtU, PTPAVTPTMtL};
  • read the read-only PTPIPV IP-version word, which is the only reset-nonzero register in the window and therefore the one honest "is this aperture really the GPTP block?" probe.
Warning
There is no PTP message engine on this part. HUM Ch 35 defines no Sync / Announce / Follow_Up generator, no domain register, no clockIdentity, no port role and no BMCA – so no such call exists here, and none can. An IEEE 1588-2019 / IEEE 802.1AS implementation on RA8D2 is software layered above this HAL: it disciplines this counter through ra8_eth_gptp_set_offset and ra8_eth_gptp_set_increment, and takes its receive timestamps from the RMAC capture path (MTRC / MPFCt, HUM Ch 33) rather than from this block.

The media-clock capture / recovery, cyclic-compare and pulse-output-timer parts of the same register window need the MEDIA_IN / MEDIA_OUT / CYCLIC_COMP pins, which the EK-RA8D2 board layer does not route, so this driver does not address them.

Definition in file ra8_eth_gptp.h.

Enumeration Type Documentation

◆ ra8_eth_gptp_limit_t

enum ra8_eth_gptp_limit_t : uint32_t

Field limits taken from the HUM register descriptions.

PTPTOVCtL.TOVL accepts only 0x0000_0000..0x3B9A_C9FF (HUM 35.3.2.4 p 1929), i.e. a nanosecond value strictly below one second, and PTPTIVCt.TIV is a 5.27 fixed-point nanoseconds-per-clk value (HUM 35.3.2.3 p 1928).

Invariant
k_ra8_gptp_nsec_max is exactly k_ra8_gptp_ns_per_sec - 1.
Example:
if (nsec > (uint32_t)k_ra8_gptp_nsec_max) { return k_ra8_err_invalid_arg; }
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_gptp_nsec_max
Largest legal PTPTOVCtL.TOVL.
See also
ra8_eth_gptp_set_offset
Enumerator
k_ra8_gptp_ns_per_sec 

Nanoseconds in one second.

k_ra8_gptp_nsec_max 

Largest legal PTPTOVCtL.TOVL.

Definition at line 73 of file ra8_eth_gptp.h.

◆ ra8_eth_gptp_sec_limit_t

enum ra8_eth_gptp_sec_limit_t : uint64_t

Upper bound of the GPTP seconds field.

The GPTP time is 78 bits with the second part in GPTP[t][77:30] (HUM 35.1 Table 35.1 p 1925), so seconds are 48 bits wide: {PTPTOVCtU.TOVU[15:0], PTPTOVCtM.TOVM[31:0]}.

Invariant
Equals 2^48 - 1.
Example:
if (sec > (uint64_t)k_ra8_gptp_sec_max) { return k_ra8_err_invalid_arg; }
@ k_ra8_gptp_sec_max
Largest 48-bit seconds value.
See also
ra8_eth_gptp_set_offset
Enumerator
k_ra8_gptp_sec_max 

Largest 48-bit seconds value.

Definition at line 96 of file ra8_eth_gptp.h.

Function Documentation

◆ ra8_eth_gptp_deinit()

ra8_err_t ra8_eth_gptp_deinit ( void )
nodiscard

Stop both timers, clear their configuration and gate the block off.

The full teardown: writes both PTPTMDC.TD bits, restores the reset value of PTPTIVCt and of the 78-bit offset for both units, then re-asserts the ESWM module stop. Use ra8_eth_gptp_enter_stop instead when the configuration should survive the power transition.

Returns
ra8_err_t Error code.
Return values
k_ra8_okTimers stopped and the gate re-asserted.
k_ra8_err_hw_timeoutThe module-stop assert did not settle.
k_ra8_err_invalid_stateThe ESWM module-stop refcount was already 0 (no matching ra8_eth_gptp_init).
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has run (otherwise the write faults).
No consumer is mid-read of the timer.
Postcondition
Both timer units are stopped with PTPTIVCt and the offset at 0.
The ESWM module-stop bit is set once this driver is the last holder of the shared, reference-counted ESWM gate – ra8_etha_init takes the same gate, so with ETHA up the clock stays on.
Note
Not thread-safe; caller must provide synchronisation.
See also
ra8_eth_gptp_init The matching bring-up call
Since
0.1.0

Definition at line 227 of file ra8_eth_gptp.c.

References internal_stop(), internal_timer(), internal_write_offset(), k_ra8_gptp_timer_count, k_ra8_mstp_eswm, r_gptp_timer_regs_t::PTPTIVC, ra8_mstp_disable(), RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_enter_stop()

ra8_err_t ra8_eth_gptp_enter_stop ( void )
nodiscard

Stop both timers and assert the ESWM module-stop gate.

The low-power entry path. Unlike ra8_eth_gptp_deinit this leaves PTPTIVCt and the 78-bit offset intact – a module stop is a clock gate, not a reset – so ra8_eth_gptp_exit_stop followed by ra8_eth_gptp_timer_enable resumes on the same configuration.

Returns
ra8_err_t Error code.
Return values
k_ra8_okTimers stopped, gate asserted.
k_ra8_err_hw_timeoutThe module-stop assert did not settle.
k_ra8_err_invalid_stateThe ESWM module-stop refcount was already 0 (no matching ra8_eth_gptp_init).
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
No consumer is mid-read of either timer.
Postcondition
Both timer units are stopped, with their configuration retained.
The ESWM module-stop bit is set once this driver is the last holder of the shared, reference-counted ESWM gate – ra8_etha_init takes the same gate, so with ETHA up the clock stays on.
Note
Not thread-safe; caller must provide synchronisation.
See also
ra8_eth_gptp_exit_stop The matching resume call
Since
0.1.0

Definition at line 372 of file ra8_eth_gptp.c.

References internal_stop_all(), k_ra8_mstp_eswm, ra8_mstp_disable(), RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_exit_stop()

ra8_err_t ra8_eth_gptp_exit_stop ( void )
nodiscard

Release the ESWM module-stop gate again.

Leaves both timers stopped and their configuration as ra8_eth_gptp_enter_stop left it; call ra8_eth_gptp_timer_enable to resume counting.

Returns
ra8_err_t Error code.
Return values
k_ra8_okGate released.
k_ra8_err_hw_timeoutThe module-stop release did not settle.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_enter_stop asserted the gate.
The ESWCLK is running and stable.
Postcondition
The GPTP register window is addressable again (the ESWM gate is reference-counted, so it may already have been released by another holder such as ra8_etha_init).
Both timer units remain stopped.
Note
Not thread-safe; caller must provide synchronisation.
See also
ra8_eth_gptp_enter_stop The matching suspend call
Since
0.1.0

Definition at line 379 of file ra8_eth_gptp.c.

References k_ra8_mstp_eswm, ra8_mstp_enable(), RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_get_avtp_ns()

ra8_err_t ra8_eth_gptp_get_avtp_ns ( ra8_gptp_timer_idx_t timer,
uint64_t * out_ns )
nodiscard

Read one timer unit's 64-bit AVTP nanosecond counter.

Reads PTPAVTPTMtL first, which latches PTPAVTPTMtU (HUM 35.4.1.3.3 Figure 35.6 p 1945-1946). The AVTP view is the same clock as ra8_eth_gptp_get_time flattened to nanoseconds modulo 2^64 (HUM 35.5.1.2 p 1952) and is what an AVB talker stamps into presentation times.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
[out]out_nsReceives the 64-bit nanosecond count. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okCounter copied out.
k_ra8_err_null_ptrout_ns == nullptr.
k_ra8_err_invalid_argtimer out of range.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
out_ns points at writable storage.
Postcondition
*out_ns describes one latched instant.
No GPTP state was mutated beyond the U latch.
Note
Not re-entrant: a concurrent reader would steal the U latch.
See also
ra8_eth_gptp_get_time The 78-bit view of the same counter
Since
0.1.0

Definition at line 354 of file ra8_eth_gptp.c.

References internal_timer(), k_gptp_shift_sec_u, k_ra8_err_invalid_arg, k_ra8_gptp_timer_count, k_ra8_ok, r_gptp_timer_regs_t::PTPAVTPTML, r_gptp_timer_regs_t::PTPAVTPTMU, RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_get_increment()

ra8_err_t ra8_eth_gptp_get_increment ( ra8_gptp_timer_idx_t timer,
uint32_t * out_tiv )
nodiscard

Read one timer unit's increment register PTPTIVCt.

Reads back whatever ra8_eth_gptp_set_increment last wrote, or the value ra8_eth_gptp_init derived from clk_hz, in the 5.27 fixed-point encoding of HUM 35.3.2.3 p 1928. A software servo reads its current correction through this call before computing the next one.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
[out]out_tivReceives PTPTIVCt.TIV. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okIncrement copied out.
k_ra8_err_null_ptrout_tiv == nullptr.
k_ra8_err_invalid_argtimer out of range.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
out_tiv points at writable storage.
Postcondition
*out_tiv holds the live register value on success.
No GPTP state was mutated.
Note
Performs one MMIO read; safe from any context.
See also
ra8_eth_gptp_set_increment Write the value this reports
Since
0.1.0

Definition at line 302 of file ra8_eth_gptp.c.

References internal_timer(), k_ra8_err_invalid_arg, k_ra8_gptp_timer_count, k_ra8_ok, r_gptp_timer_regs_t::PTPTIVC, RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_get_time()

ra8_err_t ra8_eth_gptp_get_time ( ra8_gptp_timer_idx_t timer,
uint64_t * out_sec,
uint32_t * out_nsec )
nodiscard

Read one timer unit's 78-bit GPTP time.

Reads PTPGPTPTMtL first: that read latches PTPGPTPTMtM and PTPGPTPTMtU, so the following two reads belong to the same instant (HUM 35.4.1.3.4 Figure 35.7 p 1946). While the unit is disabled every field reads 0 (HUM 35.3.2.1 p 1927), so a stopped timer is reported as time zero rather than as an error.

*out_nsec is masked to the register's 30 bits, which is wider than the one-second range the counter should ever hold. A value at or above 1e9 is therefore passed through rather than rejected: on a healthy block it cannot occur, and on a faulted one the caller is better served seeing the raw reading than a synthesised error.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
[out]out_secReceives the 48-bit seconds part. Must not be nullptr.
[out]out_nsecReceives the 30-bit nanoseconds part. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okTime copied out.
k_ra8_err_null_ptrEither output pointer is nullptr.
k_ra8_err_invalid_argtimer out of range.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
Both output pointers address writable storage.
Postcondition
*out_sec and *out_nsec describe one latched instant.
No GPTP state was mutated beyond the M/U latch.
Note
Not re-entrant: a concurrent reader would steal the M/U latch.
Example:
uint64_t sec = 0U;
uint32_t nsec = 0U;
ra8_err_t ra8_eth_gptp_get_time(ra8_gptp_timer_idx_t timer, uint64_t *out_sec, uint32_t *out_nsec)
Read one timer unit's 78-bit GPTP time.
@ k_ra8_gptp_timer_0
Timer unit 0 (registers at +0x0020).
See also
ra8_eth_gptp_set_offset Move the reported time
Since
0.1.0

Definition at line 331 of file ra8_eth_gptp.c.

References internal_timer(), k_gptp_mask_nsec, k_gptp_mask_sec_u, k_gptp_shift_sec_u, k_ra8_err_invalid_arg, k_ra8_gptp_timer_count, k_ra8_ok, r_gptp_timer_regs_t::PTPGPTPTML, r_gptp_timer_regs_t::PTPGPTPTMM, r_gptp_timer_regs_t::PTPGPTPTMU, RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

Referenced by gptp_measure(), and tsn_check_time_base().

◆ ra8_eth_gptp_init()

ra8_err_t ra8_eth_gptp_init ( const ra8_eth_gptp_cfg_t * cfg)
nodiscard

Power up the GPTP block and programme both timers' increment.

Releases the ESWM module-stop gate (the GPTP window is inside the Layer-3 Ethernet Switch domain, MSTPC30), then for each of the two timer units: stops it via PTPTMDC, writes the derived PTPTIVCt and clears the 78-bit offset. Timers are left stopped; call ra8_eth_gptp_timer_enable to start counting.

Parameters
[in]cfgStatic configuration. Must not be nullptr; clk_hz must be greater than 31250000 (see ra8_eth_gptp_cfg_t).
Returns
ra8_err_t Error code.
Return values
k_ra8_okBlock powered, both timers programmed.
k_ra8_err_null_ptrcfg == nullptr.
k_ra8_err_invalid_argcfg->clk_hz == 0.
k_ra8_err_out_of_rangecfg->clk_hz too low for a 32-bit TIV.
k_ra8_err_hw_timeoutThe ESWM module-stop release did not settle.
Precondition
The ESWCLK is running and stable (HUM 11.2.8 note 6 p 447).
Single-threaded init context, or IRQs masked.
Postcondition
On success both timer units hold the derived PTPTIVCt.
On success both timer units are stopped and read time zero.
On success every other entry point in this driver is unlocked.
Note
Not thread-safe; caller must provide synchronisation.
Example:
const ra8_eth_gptp_cfg_t cfg = {.clk_hz = 125000000U};
(void)ra8_eth_gptp_init(&cfg);
ra8_err_t ra8_eth_gptp_init(const ra8_eth_gptp_cfg_t *cfg)
Power up the GPTP block and programme both timers' increment.
Static configuration for ra8_eth_gptp_init.
See also
ra8_eth_gptp_timer_enable Start a programmed timer
ra8_eth_gptp_deinit Reverse this call
Since
0.1.0

Definition at line 202 of file ra8_eth_gptp.c.

References ra8_eth_gptp_cfg_t::clk_hz, internal_stop(), internal_timer(), internal_write_offset(), k_ra8_gptp_timer_count, k_ra8_mstp_eswm, k_ra8_ok, r_gptp_timer_regs_t::PTPTIVC, RA8_CHECK_NULL_PTR, ra8_eth_gptp_tiv_from_hz(), ra8_log_info, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, s_gptp_configured, and s_tag.

Referenced by gptp_arm(), and tsn_arm_time_base().

◆ ra8_eth_gptp_ip_version()

ra8_err_t ra8_eth_gptp_ip_version ( uint32_t * out_version)
nodiscard

Read the read-only PTPIPV IP-version word.

PTPIPV (HUM 35.3.1.1 p 1927) is the only register in the GPTP window with a nonzero reset value, so a nonzero read is positive evidence that the aperture really is the GPTP block rather than a reserved region echoing back writes.

Parameters
[out]out_versionReceives PTPIPV.IPV. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okVersion word copied out.
k_ra8_err_null_ptrout_version == nullptr.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
out_version points at writable storage.
Postcondition
*out_version holds the register value on success.
No GPTP state was mutated (the register is read-only).
Note
Safe to call from any context; performs one MMIO read.
See also
ra8_eth_gptp_init Must run first
Since
0.1.0

Definition at line 242 of file ra8_eth_gptp.c.

References k_ra8_ok, r_gptp_regs_t::PTPIPV, RA8_CHECK_NULL_PTR, ra8_gptp(), RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

Referenced by gptp_probe_presence().

◆ ra8_eth_gptp_set_increment()

ra8_err_t ra8_eth_gptp_set_increment ( ra8_gptp_timer_idx_t timer,
uint32_t tiv )
nodiscard

Write one timer unit's increment register PTPTIVCt.

PTPTIVCt is writable at any time (HUM Table 35.4 p 1946-1947), which is how a software servo applies a frequency correction: nudging TIV away from ra8_eth_gptp_tiv_from_hz makes the counter run fast or slow.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
[in]tivNanoseconds per clk in 5.27 fixed point.
Returns
ra8_err_t Error code.
Return values
k_ra8_okIncrement written.
k_ra8_err_invalid_argtimer out of range, or tiv == 0.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
tiv came from ra8_eth_gptp_tiv_from_hz or a servo around it.
Postcondition
PTPTIVCt holds tiv.
The counter rate changes from the next clk edge.
Note
Not thread-safe against another writer of the same timer.
See also
ra8_eth_gptp_get_increment Read the value back
Since
0.1.0

Definition at line 287 of file ra8_eth_gptp.c.

References internal_timer(), k_ra8_err_invalid_arg, k_ra8_gptp_timer_count, k_ra8_ok, r_gptp_timer_regs_t::PTPTIVC, RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_set_offset()

ra8_err_t ra8_eth_gptp_set_offset ( ra8_gptp_timer_idx_t timer,
uint64_t sec,
uint32_t nsec )
nodiscard

Load one timer unit's additive 78-bit offset.

Writes PTPTOVCtU, then PTPTOVCtM, then PTPTOVCtL – the order is load-bearing, because writing the L register is what commits the whole offset to the timer (HUM 35.4.1.3.1 Figure 35.4 p 1944-1945). The reported time is offset + free-running counter (HUM 35.5.1.1 p 1951), so this is the coarse "step" half of a software clock servo.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
[in]secSeconds part, at most k_ra8_gptp_sec_max.
[in]nsecNanoseconds part, at most k_ra8_gptp_nsec_max.
Returns
ra8_err_t Error code.
Return values
k_ra8_okOffset committed.
k_ra8_err_invalid_argtimer, sec or nsec out of range.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
The caller accepts a discontinuity in the reported time.
Postcondition
The three offset registers hold the requested value.
The next ra8_eth_gptp_get_time reflects the new offset.
Note
Not thread-safe; the three writes are not atomic against a reader.
Example:
(void)ra8_eth_gptp_set_offset(k_ra8_gptp_timer_0, 1000000000ULL, 0U);
ra8_err_t ra8_eth_gptp_set_offset(ra8_gptp_timer_idx_t timer, uint64_t sec, uint32_t nsec)
Load one timer unit's additive 78-bit offset.
See also
ra8_eth_gptp_get_time Observe the effect
Since
0.1.0

Definition at line 315 of file ra8_eth_gptp.c.

References internal_write_offset(), k_ra8_err_invalid_arg, k_ra8_gptp_nsec_max, k_ra8_gptp_sec_max, k_ra8_gptp_timer_count, k_ra8_ok, RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

Referenced by gptp_arm().

◆ ra8_eth_gptp_timer_disable()

ra8_err_t ra8_eth_gptp_timer_disable ( ra8_gptp_timer_idx_t timer)
nodiscard

Stop one timer unit (PTPTMDC.TDq).

Per HUM 35.3.2.1 p 1927 a disabled unit's counters are fixed at 0, so a stop is also a clear.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
Returns
ra8_err_t Error code.
Return values
k_ra8_okTimer disabled.
k_ra8_err_invalid_argtimer out of range.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
No consumer is mid-read of this unit.
Postcondition
PTPTMEC.TE[timer] reads 0.
The unit's counters read 0.
Note
Not thread-safe against ra8_eth_gptp_timer_enable.
See also
ra8_eth_gptp_timer_enable Start the unit again
Since
0.1.0

Definition at line 264 of file ra8_eth_gptp.c.

References internal_stop(), k_ra8_err_invalid_arg, k_ra8_gptp_timer_count, k_ra8_ok, RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_timer_enable()

ra8_err_t ra8_eth_gptp_timer_enable ( ra8_gptp_timer_idx_t timer)
nodiscard

Start one timer unit (PTPTMEC.TEq).

Writes 1 to PTPTMEC.TEq (HUM 35.3.2.1 p 1927). The register is write-1-to-set, so the sibling unit's enable bit is untouched. Counting resumes from the next clk edge at the unit's current PTPTIVCt, on top of whatever 78-bit offset ra8_eth_gptp_set_offset last committed.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
Returns
ra8_err_t Error code.
Return values
k_ra8_okTimer enabled.
k_ra8_err_invalid_argtimer out of range.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has programmed PTPTIVCt for this timer.
The ESWCLK is running.
Postcondition
PTPTMEC.TE[timer] reads 1.
The unit's free-running counter advances by TIV per clk.
Note
Not thread-safe against ra8_eth_gptp_timer_disable.
See also
ra8_eth_gptp_timer_disable Stop the unit again
Since
0.1.0

Definition at line 252 of file ra8_eth_gptp.c.

References k_ra8_err_invalid_arg, k_ra8_gptp_timer_count, k_ra8_ok, r_gptp_regs_t::PTPTMEC, ra8_gptp(), RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

Referenced by gptp_arm(), and tsn_arm_time_base().

◆ ra8_eth_gptp_timer_is_enabled()

ra8_err_t ra8_eth_gptp_timer_is_enabled ( ra8_gptp_timer_idx_t timer,
bool * out_enabled )
nodiscard

Report whether one timer unit is enabled.

Reads PTPTMEC once and extracts bit timer (HUM 35.3.2.1 p 1927). PTPTMDC is write-only and reads as 0, so PTPTMEC is the single authority on whether a unit is running: a unit stopped through PTPTMDC reads back 0 here.

Parameters
[in]timerTimer index, below k_ra8_gptp_timer_count.
[out]out_enabledReceives PTPTMEC.TE[timer]. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okState copied out.
k_ra8_err_null_ptrout_enabled == nullptr.
k_ra8_err_invalid_argtimer out of range.
k_ra8_err_not_initializedra8_eth_gptp_init has not run.
Precondition
ra8_eth_gptp_init has released the module-stop gate.
out_enabled points at writable storage.
Postcondition
*out_enabled holds the live enable bit on success.
No GPTP state was mutated.
Note
Performs one MMIO read; safe from any context.
See also
ra8_eth_gptp_timer_enable Set the bit this reports
Since
0.1.0

Definition at line 274 of file ra8_eth_gptp.c.

References k_ra8_err_invalid_arg, k_ra8_gptp_timer_count, k_ra8_ok, r_gptp_regs_t::PTPTMEC, RA8_CHECK_NULL_PTR, ra8_gptp(), RA8_VALIDATE_INIT, s_gptp_configured, and s_tag.

◆ ra8_eth_gptp_tiv_from_hz()

ra8_err_t ra8_eth_gptp_tiv_from_hz ( uint32_t clk_hz,
uint32_t * out_tiv )
nodiscard

Derive PTPTIVCt.TIV from a clk frequency.

TIV is the nanoseconds-per-clk increment in 5.27 fixed point: TIV[31:27] is the whole-nanosecond part and TIV[26:0] the sub-nanosecond part (HUM 35.3.2.3 p 1928), so TIV = round(1e9 * 2^27 / clk_hz). The HUM's worked examples (0xA000_0000 / 0x5000_0000 / 0x2800_0000 / 0x2000_0000 for 50 / 100 / 200 / 250 MHz) fall out of that expression exactly.

This is a pure function – it touches no hardware – so an application can sanity-check its clock tree before powering the block on.

Parameters
[in]clk_hzclk frequency in Hz. Must be nonzero and above 31250000, below which TIV would not fit in 32 bits.
[out]out_tivReceives the computed increment. Must not be nullptr.
Returns
ra8_err_t Error code.
Return values
k_ra8_okIncrement computed.
k_ra8_err_null_ptrout_tiv == nullptr.
k_ra8_err_invalid_argclk_hz == 0.
k_ra8_err_out_of_rangeComputed TIV exceeds 32 bits.
Precondition
out_tiv points at writable storage.
clk_hz describes the live ESWCLK, not a nominal figure.
Postcondition
*out_tiv is unmodified unless k_ra8_ok is returned.
No hardware register was read or written.
Note
Pure and re-entrant.
Example:
uint32_t tiv = 0U;
(void)ra8_eth_gptp_tiv_from_hz(125000000U, &tiv); // tiv == 0x40000000
ra8_err_t ra8_eth_gptp_tiv_from_hz(uint32_t clk_hz, uint32_t *out_tiv)
Derive PTPTIVCt.TIV from a clk frequency.
See also
ra8_eth_gptp_set_increment Apply the value to a timer
Since
0.1.0

Definition at line 185 of file ra8_eth_gptp.c.

References k_gptp_round_half, k_gptp_subns_shift, k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_gptp_ns_per_sec, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ra8_eth_gptp_init().