ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_ulpt.c
Go to the documentation of this file.
1
23
24#include "ra8_ulpt.h"
25
26#include <stdint.h>
27
28#include "ra8_attributes.h"
29#include "ra8_check.h"
30#include "ra8_err.h"
31#include "ra8_hw_err.h"
32#include "ra8_log.h"
33#include "ra8_mstp.h"
34#include "ra8_ulpt_regs.h"
35
36static const char* s_tag = "ULPT";
37
50typedef enum : uint32_t {
53
63
64[[nodiscard]] ra8_err_t ra8_ulpt_init(void)
65{
66 for (uint8_t ch = 0U; ch < (uint8_t)k_ra8_ulpt_channel_count; ++ch) {
67 volatile r_ulpt_regs_t* reg = ra8_ulpt(ch);
68 if (reg == nullptr) {
70 }
71 /* HUM Ch 11.2.10 "MSTPCRE : Module Stop Control Register E" p 449 */
72 const ra8_err_t mst_err = ra8_mstp_enable(s_ulpt_mstp_table[ch]);
73 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
74 RA8_RETURN_ON_ERROR(mst_err, s_tag, "ulpt_init: mstp enable");
75 /* GCOVR_EXCL_BR_STOP */
76 /* HUM Ch 25.2.1 "ULPTCR : ULPT Control Register" p 1190 */
77 reg->ULPTCR = 0U;
78 /* HUM Ch 25.2.2 "ULPTMR1 : ULPT Mode Register 1" p 1192 */
79 reg->ULPTMR1 = 0U;
80 /* HUM Ch 25.2.3 "ULPTMR2 : ULPT Mode Register 2" p 1192 */
81 reg->ULPTMR2 = 0U;
82 /* HUM Ch 25.2.4 "ULPTMR3 : ULPT Mode Register 3" p 1195 */
83 reg->ULPTMR3 = 0U;
84 /* HUM Ch 25.2.5 "ULPTIOC : ULPT I/O Control Register" p 1195 */
85 reg->ULPTIOC = 0U;
86 /* HUM Ch 25.2.6 "ULPT : ULPT Counter Register" p 1198 */
87 reg->ULPTCNT = 0U;
88 }
89 ra8_log_info(s_tag, "ulpt_init");
90 return k_ra8_ok;
91}
92
93[[nodiscard]] ra8_err_t ra8_ulpt_start(uint8_t channel, uint32_t period)
94{
95 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
97 }
98 volatile r_ulpt_regs_t* reg = ra8_ulpt(channel);
99 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
100
101 /* HUM Ch 25.2.1 "ULPTCR : ULPT Control Register" p 1190 */
102 reg->ULPTCR = 0U;
103 /* HUM Ch 25.2.2 "ULPTMR1 : ULPT Mode Register 1" p 1192 -- timer mode,
104 * TCK1 = 0 selects ULPTLCLK (LOCO-derived 32.768 kHz, HUM Table 9.2
105 * p 320), which survives Software Standby. */
106 reg->ULPTMR1 = 0U;
107 /* HUM Ch 25.2.3 "ULPTMR2 : ULPT Mode Register 2" p 1192 */
108 reg->ULPTMR2 = 0U;
109 /* HUM Ch 25.2.4 "ULPTMR3 : ULPT Mode Register 3" p 1195 */
110 reg->ULPTMR3 = 0U;
111 /* HUM Ch 25.2.6 "ULPT : ULPT Counter Register" p 1198 */
112 reg->ULPTCNT = period;
113 /* HUM Ch 25.2.1 "ULPTCR : ULPT Control Register" p 1190 */
114 /* TSTART = 1. */
116
117 ra8_log_info_val(s_tag, "start channel", (uint32_t)channel);
118 return k_ra8_ok;
119}
120
121[[nodiscard]] ra8_err_t ra8_ulpt_stop(uint8_t channel)
122{
123 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
125 }
126 volatile r_ulpt_regs_t* reg = ra8_ulpt(channel);
127 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
128
129 /* HUM Ch 25.2.1 "ULPTCR : ULPT Control Register" p 1190 */
130 /* TSTOP toggle. */
132 reg->ULPTCR = 0U;
133
134 /* Confirm the down-counter actually halted before returning. ULPTCR.TCSTF
135 * (count-status flag) lags the TSTOP request by a few ULPTLCLK (32.768 kHz)
136 * cycles; a caller that re-arms for Software Standby while TCSTF is still
137 * set hangs on the second wake. Poll TCSTF low under a bounded budget
138 * (NASA Power of 10 Rule 2) -- k_ra8_ok when it clears, k_ra8_err_hw_timeout
139 * if the counter never stops. */
140 /* HUM Ch 25.2.1 "ULPTCR : ULPT Control Register" p 1190 */
141 return ra8_hw_wait_flag_clear8(&reg->ULPTCR,
142 (uint8_t)k_ra8_ulpt_mask_tcstf,
143 (uint32_t)k_ra8_ulpt_stop_poll_max);
144}
145
146/* =============================================================================
147 * full build-out
148 * =============================================================================
149 */
150
152static void* s_ulpt_ctx;
153
178{
179 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
181 }
182 volatile r_ulpt_regs_t* reg = ra8_ulpt(channel);
183 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
184
185 reg->ULPTCR = 0U;
186 return ra8_mstp_disable(s_ulpt_mstp_table[channel]);
187}
188
213ra8_err_t ra8_ulpt_set_period(uint8_t channel, uint32_t period)
214{
215 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
217 }
218 volatile r_ulpt_regs_t* reg = ra8_ulpt(channel);
219 RA8_CHECK_NULL_PTR(reg, s_tag, "channel mapping failed");
220 reg->ULPTCNT = period;
221 return k_ra8_ok;
222}
223
249ra8_err_t ra8_ulpt_get_status(uint8_t channel, uint8_t* out_mask)
250{
251 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
252 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
254 }
255 *out_mask = ra8_ulpt(channel)->ULPTCR;
256 return k_ra8_ok;
257}
258
283{
284 s_ulpt_fn = fn;
285 s_ulpt_ctx = ctx;
286 return k_ra8_ok;
287}
288
308void ra8_ulpt_dispatch(uint8_t channel)
309{
310 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
311 return;
312 }
314 void* const ctx = s_ulpt_ctx;
315 if (fn != nullptr) {
316 fn(ctx, channel);
317 }
318}
319
345{
346 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
348 }
349 return ra8_mstp_disable(s_ulpt_mstp_table[channel]);
350}
351
376{
377 if ((uint16_t)channel >= k_ra8_ulpt_channel_count) {
379 }
380 return ra8_mstp_enable(s_ulpt_mstp_table[channel]);
381}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
Definition ra8_err.h:290
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Bounded wait-flag primitives for RA8D2 HAL drivers.
static ra8_err_t ra8_hw_wait_flag_clear8(volatile const uint8_t *reg, uint8_t mask, uint32_t budget)
Spin until (*reg & mask) == 0 or budget runs out.
Definition ra8_hw_err.h:262
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
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.
Definition ra8_mstp.c:343
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_ulpt1
MSTPE8 ULPT1.
@ k_ra8_mstp_ulpt0
MSTPE9 ULPT0.
ra8_err_t ra8_ulpt_enter_stop(uint8_t channel)
Drop the MSTP reference for one ULPT channel (low-power gate).
Definition ra8_ulpt.c:344
ra8_err_t ra8_ulpt_deinit(uint8_t channel)
Tear down one ULPT channel and drop its MSTP reference.
Definition ra8_ulpt.c:177
ra8_ulpt_poll_t
Bounded poll budget for the ra8_ulpt_stop halt confirmation.
Definition ra8_ulpt.c:50
@ k_ra8_ulpt_stop_poll_max
Max TCSTF-low poll iterations.
Definition ra8_ulpt.c:51
void ra8_ulpt_dispatch(uint8_t channel)
Fire the registered ULPT callback for channel (ISR helper).
Definition ra8_ulpt.c:308
ra8_err_t ra8_ulpt_set_period(uint8_t channel, uint32_t period)
Update the 32-bit reload value for a running ULPT channel.
Definition ra8_ulpt.c:213
static ra8_ulpt_event_fn_t s_ulpt_fn
Definition ra8_ulpt.c:151
static const ra8_mstp_t s_ulpt_mstp_table[]
Channel-index -> MSTP id lookup.
Definition ra8_ulpt.c:59
ra8_err_t ra8_ulpt_attach_handler(ra8_ulpt_event_fn_t fn, void *ctx)
Register the global ULPT ISR callback (NULL detaches).
Definition ra8_ulpt.c:282
ra8_err_t ra8_ulpt_get_status(uint8_t channel, uint8_t *out_mask)
Read the ULPTCR control / status register for channel.
Definition ra8_ulpt.c:249
ra8_err_t ra8_ulpt_stop(uint8_t channel)
Stop a ULPT channel and confirm the counter has halted.
Definition ra8_ulpt.c:121
static void * s_ulpt_ctx
Definition ra8_ulpt.c:152
ra8_err_t ra8_ulpt_exit_stop(uint8_t channel)
Re-enable the MSTP gate for one ULPT channel after stop.
Definition ra8_ulpt.c:375
ra8_err_t ra8_ulpt_init(void)
Reset both ULPT channels to their power-on state.
Definition ra8_ulpt.c:64
ra8_err_t ra8_ulpt_start(uint8_t channel, uint32_t period)
Start a ULPT channel counting down from period.
Definition ra8_ulpt.c:93
Ultra-Low-Power Timer (ULPT) driver header.
void(* ra8_ulpt_event_fn_t)(void *ctx, uint8_t channel)
ULPT event callback.
Definition ra8_ulpt.h:75
Ultra-Low-Power Timer (ULPT) register layout for the Renesas RA8D2.
@ k_ra8_ulpt_mask_tstart
TSTART bit.
@ k_ra8_ulpt_mask_tstop
TSTOP bit.
@ k_ra8_ulpt_mask_tcstf
TCSTF count-status flag (RO).
@ k_ra8_ulpt_channel_count
ULPT0 and ULPT1.
static volatile r_ulpt_regs_t * ra8_ulpt(uint8_t channel)
Get pointer to ULPT channel channel.
Per-channel ULPT register window.
volatile uint8_t ULPTMR1
+0x0D Mode register 1.
volatile uint8_t ULPTIOC
+0x10 I/O control.
volatile uint8_t ULPTMR2
+0x0E Mode register 2.
volatile uint32_t ULPTCNT
+0x00 Counter / reload (32-bit).
volatile uint8_t ULPTMR3
+0x0F Mode register 3.
volatile uint8_t ULPTCR
+0x0C Control register.