ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_dac_b.c
Go to the documentation of this file.
1
24
25#include "ra8_dac_b.h"
26
27#include <stdint.h>
28
29#include "ra8_attributes.h"
30#include "ra8_check.h"
31#include "ra8_dac_b_regs.h"
32#include "ra8_err.h"
33#include "ra8_log.h"
34#include "ra8_mstp.h"
35
36static const char* s_tag = "DAC_B";
37
46
64RA8_INTERNAL static inline uint16_t internal_ra8_dac_b_clamp(uint16_t value)
65{
66 if ((uint32_t)value > (uint32_t)k_ra8_dac_b_max_value) {
68 }
69 return value;
70}
71
92RA8_INTERNAL static void internal_disable_channel(uint8_t channel)
93{
94 volatile r_dac_b_regs_t* reg = ra8_dac_b(channel);
95 if (reg == nullptr) {
96 return;
97 }
98 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490 */
99 reg->DACR0 = 0U;
100 reg->DADR = 0U;
101}
102
119RA8_INTERNAL static void internal_start_channel(uint8_t channel)
120{
121 volatile r_dac_b_regs_t* reg = ra8_dac_b(channel);
122 if (reg == nullptr) {
123 return;
124 }
125 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490 */
126 reg->DACR0 = reg->DACR0 | k_ra8_dacr0_mask_dacen;
127}
128
143RA8_INTERNAL static void internal_stop_channel(uint8_t channel)
144{
145 volatile r_dac_b_regs_t* reg = ra8_dac_b(channel);
146 if (reg == nullptr) {
147 return;
148 }
149 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490 */
150 reg->DACR0 = reg->DACR0 & ~k_ra8_dacr0_mask_dacen;
151}
152
153[[nodiscard]] ra8_err_t ra8_dac_b_init(void)
154{
155 /* DAC_B0 and DAC_B1 have separate MSTP bits.
156 * HUM Ch 11.2.9 "MSTPCRD : Module Stop Control Register D", p 448 */
158 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
159 RA8_RETURN_ON_ERROR(mst_err, s_tag, "dac_b_init: mstp dac0");
160 /* GCOVR_EXCL_BR_STOP */
162 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
163 RA8_RETURN_ON_ERROR(mst_err, s_tag, "dac_b_init: mstp dac1");
164 /* GCOVR_EXCL_BR_STOP */
165
168 ra8_log_info(s_tag, "dac_b_init");
169 return k_ra8_ok;
170}
171
172[[nodiscard]] ra8_err_t ra8_dac_b_write(uint8_t channel, uint16_t value)
173{
174 volatile r_dac_b_regs_t* reg = ra8_dac_b(channel);
175 if (reg == nullptr) {
177 }
178 const uint16_t clamped = internal_ra8_dac_b_clamp(value);
179 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490 -- FSP R_DAC_B_Write
180 * is a single 16-bit store to DADR; DACEN is asserted via
181 * ra8_dac_b_set_output_enable() / ra8_dac_b_init_configured(), NOT here. */
182 reg->DADR = clamped;
183 ra8_log_info_val(s_tag, "dac_b_write value", (uint32_t)clamped);
184 return k_ra8_ok;
185}
186
195
197
213RA8_INTERNAL static void internal_apply_cfg(uint8_t channel, const ra8_dac_b_cfg_t* cfg)
214{
215 volatile r_dac_b_regs_t* reg = ra8_dac_b(channel);
216 if (reg == nullptr) {
217 return;
218 }
219 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490..3496 -- mirror
220 * FSP R_DAC_B_Open: clear DACR0, set DACR1.DPSEL, DACR2.OFSSEL,
221 * zero DADR, then drive the DAOUTDIS bit per the descriptor. */
222 reg->DACR0 = 0U;
223 reg->DACR1 = ((uint32_t)cfg->data_format) << (uint32_t)k_ra8_dacr1_bit_dpsel;
224 reg->DACR2 = ((uint32_t)cfg->vref) << (uint32_t)k_ra8_dacr2_bit_ofssel;
225 reg->DADR = 0U;
226 /* internal_output_enabled == true clears DAOUTDIS (route to pin);
227 * false sets DAOUTDIS (Hi-Z). FSP encodes the same way: it writes
228 * the boolean directly into the 1-bit DAOUTDIS field. */
229 if (!cfg->internal_output_enabled) {
231 }
232}
233
235{
236 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
237
239 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
240 RA8_RETURN_ON_ERROR(mst_err, s_tag, "dac_b_init_cfg: mstp dac0");
241 /* GCOVR_EXCL_BR_STOP */
243 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
244 RA8_RETURN_ON_ERROR(mst_err, s_tag, "dac_b_init_cfg: mstp dac1");
245 /* GCOVR_EXCL_BR_STOP */
246
249
250 if (cfg->enable_channel0) {
252 }
253 if (cfg->enable_channel1) {
255 }
256 ra8_log_info(s_tag, "dac_b_init_configured");
257 return k_ra8_ok;
258}
259
261{
262 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490 -- FSP R_DAC_B_Close
263 * writes DACR0 = DAOUTDIS_Msk to fully disable output, operation,
264 * and coupled operation. We then release MSTP. */
267 if (reg0 != nullptr) {
269 reg0->DADR = 0U;
270 }
271 if (reg1 != nullptr) {
273 reg1->DADR = 0U;
274 }
275 s_dac_b_state.fn = nullptr;
276 s_dac_b_state.ctx = nullptr;
279}
280
282{
283 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490 -- DACR2.OFSSEL is
284 * a single bit at position 8; preserve all other bits. */
287 const uint32_t shifted = ((uint32_t)vref) << (uint32_t)k_ra8_dacr2_bit_ofssel;
288 reg0->DACR2 = (reg0->DACR2 & ~k_ra8_dacr2_mask_ofssel) | (shifted & k_ra8_dacr2_mask_ofssel);
289 reg1->DACR2 = (reg1->DACR2 & ~k_ra8_dacr2_mask_ofssel) | (shifted & k_ra8_dacr2_mask_ofssel);
290 return k_ra8_ok;
291}
292
293ra8_err_t ra8_dac_b_set_output_enable(uint8_t channel, bool enable)
294{
295 volatile r_dac_b_regs_t* reg = ra8_dac_b(channel);
296 if (reg == nullptr) {
298 }
299 /* HUM Ch 54 "12-Bit D/A Converter (DAC12)" p 3490 -- FSP toggles
300 * DACEN (bit 0) only; DAE (batch mode) and DAOUTDIS are managed
301 * separately. */
302 if (enable) {
303 reg->DACR0 = reg->DACR0 | k_ra8_dacr0_mask_dacen;
304 } else {
305 reg->DACR0 = reg->DACR0 & ~k_ra8_dacr0_mask_dacen;
306 }
307 return k_ra8_ok;
308}
309
311{
312 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
313 /* Build a single-byte composite status flag:
314 * bit 0 -- channel 0 DACEN
315 * bit 1 -- channel 1 DACEN
316 */
317 uint8_t flags = 0U;
318 volatile const r_dac_b_regs_t* reg0 = ra8_dac_b(k_ra8_dac_b_channel_0);
319 volatile const r_dac_b_regs_t* reg1 = ra8_dac_b(k_ra8_dac_b_channel_1);
320 if ((reg0->DACR0 & k_ra8_dacr0_mask_dacen) != 0U) {
321 flags |= 0x1U;
322 }
323 if ((reg1->DACR0 & k_ra8_dacr0_mask_dacen) != 0U) {
324 flags |= 0x2U;
325 }
326 *out_mask = flags;
327 return k_ra8_ok;
328}
329
336
338{
339 s_dac_b_state.fn = fn;
340 s_dac_b_state.ctx = ctx;
341 return k_ra8_ok;
342}
343
351
353{
355 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
356 RA8_RETURN_ON_ERROR(err0, s_tag, "dac_b_exit_stop: mstp0");
357 /* GCOVR_EXCL_BR_STOP */
359}
360
362void ra8_dac_b_dispatch_update(uint8_t channel)
363{
364 if ((uint16_t)channel >= k_ra8_dac_b_channel_count) {
365 return;
366 }
368 void* const ctx = s_dac_b_state.ctx;
369 if (fn != nullptr) {
370 fn(ctx, channel);
371 }
372}
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.
#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.
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
ra8_err_t ra8_dac_b_set_output_enable(uint8_t channel, bool enable)
Toggle output-enable for one channel at runtime.
Definition ra8_dac_b.c:293
ra8_err_t ra8_dac_b_deinit(void)
Tear down the DAC_B peripheral.
Definition ra8_dac_b.c:260
ra8_err_t ra8_dac_b_init(void)
Legacy init – zero every DAC_B register + enable MSTP.
Definition ra8_dac_b.c:153
static void internal_disable_channel(uint8_t channel)
Stop a channel and put DACR0 in the FSP "open" baseline.
Definition ra8_dac_b.c:92
ra8_err_t ra8_dac_b_write(uint8_t channel, uint16_t value)
Programme a DAC channel with a 12-bit code.
Definition ra8_dac_b.c:172
ra8_err_t ra8_dac_b_init_configured(const ra8_dac_b_cfg_t *cfg)
Initialise DAC_B with a full config descriptor.
Definition ra8_dac_b.c:234
ra8_err_t ra8_dac_b_get_status(uint8_t *out_mask)
Read the DACR output-enable / DAE mask.
Definition ra8_dac_b.c:310
static ra8_dac_b_state_t s_dac_b_state
Definition ra8_dac_b.c:196
ra8_err_t ra8_dac_b_clear_status(void)
Clear DAE + DAOE bits (disable DAC outputs).
Definition ra8_dac_b.c:330
ra8_err_t ra8_dac_b_exit_stop(void)
Exit MSTP-gated stop.
Definition ra8_dac_b.c:352
void ra8_dac_b_dispatch_update(uint8_t channel)
Dispatch a DAC-update event – fire the registered callback.
Definition ra8_dac_b.c:362
ra8_err_t ra8_dac_b_set_vref(ra8_dac_b_vref_t vref)
Change the DAC voltage reference at runtime.
Definition ra8_dac_b.c:281
ra8_err_t ra8_dac_b_enter_stop(void)
Put DAC_B into MSTP-gated stop.
Definition ra8_dac_b.c:344
static void internal_start_channel(uint8_t channel)
Set DACEN=1 on a channel (FSP R_DAC_B_Start equivalent).
Definition ra8_dac_b.c:119
ra8_err_t ra8_dac_b_attach_handler(ra8_dac_b_update_fn_t fn, void *ctx)
Attach a DAC-update callback.
Definition ra8_dac_b.c:337
static void internal_apply_cfg(uint8_t channel, const ra8_dac_b_cfg_t *cfg)
Apply cfg to one DAC_B instance (FSP R_DAC_B_Open body).
Definition ra8_dac_b.c:213
ra8_dac_b_channel_t
Named channel indices.
Definition ra8_dac_b.c:42
@ k_ra8_dac_b_channel_0
RA8 DAC b channel 0.
Definition ra8_dac_b.c:43
@ k_ra8_dac_b_channel_1
RA8 DAC b channel 1.
Definition ra8_dac_b.c:44
static uint16_t internal_ra8_dac_b_clamp(uint16_t value)
Clamp a raw value to 12-bit range.
Definition ra8_dac_b.c:64
static void internal_stop_channel(uint8_t channel)
Clear DACEN on a channel (FSP R_DAC_B_Stop equivalent).
Definition ra8_dac_b.c:143
Full-featured 12-bit DAC_B driver.
ra8_dac_b_vref_t
VREFH operating-mode selection (DACR2.OFSSEL bit 8).
Definition ra8_dac_b.h:39
void(* ra8_dac_b_update_fn_t)(void *ctx, uint8_t channel)
DAC update (conversion done) event callback.
Definition ra8_dac_b.h:82
12-bit DAC_B register layout for the Renesas RA8D2
@ k_ra8_dacr1_bit_dpsel
DPSEL: data placement select.
static volatile r_dac_b_regs_t * ra8_dac_b(uint8_t instance)
Get pointer to DAC_B instance N (0 or 1).
@ k_ra8_dac_b_channel_count
Two independent DAC_B instances.
@ k_ra8_dac_b_max_value
12-bit full-scale count.
@ k_ra8_dacr2_bit_ofssel
OFSSEL: VREFH range select.
@ k_ra8_dacr0_mask_daoutdis
Mirror of FSP DAOUTDIS_Msk.
@ k_ra8_dacr0_mask_dacen
Mirror of FSP DACEN_Msk.
@ k_ra8_dacr2_mask_ofssel
Mirror of FSP OFSSEL_Msk.
Error Code Definitions for ra8-firmware.
@ 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
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
@ k_ra8_mstp_dac12_0
MSTPD20 DAC12 ch 0.
@ k_ra8_mstp_dac12_1
MSTPD19 DAC12 ch 1.
Per-instance DAC_B register window.
volatile uint16_t DADR
+0x00 12-bit data value (low 12 bits).
volatile uint32_t DACR2
+0x0C Control 2 (OFSSEL bit 8).
volatile uint32_t DACR1
+0x08 Control 1 (DPSEL bit 16).
volatile uint32_t DACR0
+0x04 Control 0 (DACEN/DAE/DAOUTDIS).
Configuration descriptor for ra8_dac_b_init_configured.
Definition ra8_dac_b.h:68
ra8_dac_b_vref_t vref
VREFH range (DACR2.OFSSEL).
Definition ra8_dac_b.h:69
bool enable_channel1
Initial DACEN1 state.
Definition ra8_dac_b.h:73
ra8_dac_b_data_format_t data_format
Data placement (DACR1.DPSEL).
Definition ra8_dac_b.h:70
bool internal_output_enabled
Drive internal route (clears DAOUTDIS).
Definition ra8_dac_b.h:71
bool enable_channel0
Initial DACEN0 state.
Definition ra8_dac_b.h:72
Driver-wide runtime state.
Definition ra8_dac_b.c:191
ra8_dac_b_update_fn_t fn
Fn.
Definition ra8_dac_b.c:192
void * ctx
Ctx.
Definition ra8_dac_b.c:193