ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
adc.c
Go to the documentation of this file.
1
38
39#include <stdint.h>
40
41#include "adc_internal.h"
42#include "ra8_adc.h"
43#include "ra8_adc_b_regs.h"
44#include "ra8_attributes.h"
45#include "ra8_check.h"
46#include "ra8_err.h"
47#include "ra8_log.h"
48#include "ra8_mstp.h"
49
50static const char* s_tag = "ADC";
51
56typedef enum : uint8_t {
59
73
86
88
113 uint32_t* out_adprc)
114{
115 switch (resolution) {
117 *out_adprc = (uint32_t)k_ra8_addopcrc_adprc_16bit;
118 return true;
120 *out_adprc = (uint32_t)k_ra8_addopcrc_adprc_14bit;
121 return true;
123 *out_adprc = (uint32_t)k_ra8_addopcrc_adprc_12bit;
124 return true;
126 *out_adprc = (uint32_t)k_ra8_addopcrc_adprc_10bit;
127 return true;
128 default:
129 return false;
130 }
131}
132
151RA8_INTERNAL static void internal_write_adprc(uint8_t vch, uint32_t adprc)
152{
153 volatile uint32_t* reg = ra8_adc_b_addopcrc(vch);
154 if (reg == nullptr) {
155 return;
156 }
157 const uint32_t adprc_field =
159 /* HUM Ch 53.2.3.4 "ADDOPCRCn : A/D Conversion Data Operation Control C Register n" p 3339 */
160 *reg = (*reg & ~k_ra8_addopcrc_mask_adprc) | adprc_field;
161}
162
183{
184 for (uint8_t ch = 0U; ch < k_ra8_adc_b_result_regs; ++ch) {
185 internal_write_adprc(ch, adprc);
186 }
187}
188
208RA8_INTERNAL static void internal_wait_clksr(uint32_t desired)
209{
210 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
211 for (uint32_t i = 0U; i < k_ra8_adc_clk_wait_limit; ++i) {
212 if ((*ra8_adc_b_adclksr() & k_ra8_adclksr_mask_clksr) == desired) {
213 return;
214 }
215 }
216}
217
231RA8_INTERNAL static void internal_clock_bring_up(uint32_t clkcr_value)
232{
233 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
234 *ra8_adc_b_adclkenr() = 0U;
236 *ra8_adc_b_adclkcr() = clkcr_value;
239}
240
258{
259 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
260 for (uint8_t ch = 0U; ch < k_ra8_adc_b_max_channels; ++ch) {
261 volatile uint32_t* reg = ra8_adc_b_adchcr(ch);
262 if (reg != nullptr) {
263 *reg = 0U;
264 }
265 }
266}
267
283RA8_INTERNAL static void internal_program_channel(uint8_t virtual_ch, uint8_t physical_ch)
284{
285 volatile uint32_t* reg = ra8_adc_b_adchcr(virtual_ch);
286 if (reg == nullptr) {
287 return;
288 }
289 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
290 const uint32_t cnvcs =
291 ((uint32_t)physical_ch << (uint32_t)k_ra8_adchcr_bit_cnvcs) & k_ra8_adchcr_mask_cnvcs;
292 const uint32_t sgsel = ((uint32_t)k_ra8_adc_default_group << (uint32_t)k_ra8_adchcr_bit_sgsel) &
294 *reg = (cnvcs | sgsel);
295}
296
316RA8_INTERNAL static uint32_t internal_build_admdr(bool scan_mode)
317{
318 const uint32_t admd0_code =
319 scan_mode ? (uint32_t)k_ra8_admdr_mode_continuous : (uint32_t)k_ra8_admdr_mode_one_cycle;
320 return (admd0_code << (uint32_t)k_ra8_admdr_bit_admd0) & k_ra8_admdr_mask_admd0;
321}
322
324{
325 /* HUM Ch 11.2.9 "MSTPCRD : Module Stop Control Register D" p 449 */
327 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
328 RA8_RETURN_ON_ERROR(mst_err, s_tag, "adc_init: mstp enable");
329 /* GCOVR_EXCL_BR_STOP */
330
332
333 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
335 *ra8_adc_b_adintcr() = 0U;
336 *ra8_adc_b_adsger() = (uint32_t)(1UL << (uint32_t)k_ra8_adc_default_group);
337
340
341 for (uint8_t g = 0U; g < k_ra8_adc_b_scan_groups; ++g) {
342 s_adc_state.groups[g].num_channels = 0U;
343 }
344
345 s_adc_state.resolution = k_ra8_adc_res_14bit;
346 s_adc_state.configured = true;
347 ra8_log_info(s_tag, "adc_init ready");
348 return k_ra8_ok;
349}
350
351ra8_err_t ra8_adc_read_channel(uint8_t channel, uint16_t* out_raw)
352{
353 RA8_CHECK_NULL_PTR(out_raw, s_tag, "out_raw must not be nullptr");
354
355 volatile const uint32_t* chcr = ra8_adc_b_adchcr(channel);
356 volatile const uint32_t* addr = ra8_adc_b_addr(channel);
357 if ((chcr == nullptr) || (addr == nullptr)) {
359 }
360
361 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
362 /* Map this slot onto physical channel == ``channel`` in the
363 * default scan group (driver convention: virtual_ch == physical_ch). */
364 internal_program_channel(channel, channel);
365
366 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
367 /* Kick the conversion via per-group ADSTR[default_group].ADST. */
368 volatile uint32_t* adstr = ra8_adc_b_adstr(k_ra8_adc_default_group);
369 if (adstr != nullptr) {
370 *adstr = k_ra8_adstr_mask_adst;
371 }
372
373 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
374 /* Poll ADSR.ADACT0 -- hardware clears it when the unit becomes idle. */
375 for (uint32_t i = 0U; i < k_ra8_adc_busy_wait_limit; ++i) {
376 if ((*ra8_adc_b_adsr() & k_ra8_adsr_mask_adact0) == 0U) {
377 *out_raw = (uint16_t)(*addr & k_ra8_addr_mask_data);
378 return k_ra8_ok;
379 }
380 }
381
382 *out_raw = 0U;
383 ra8_log_error(s_tag, "ADACT0 poll timeout");
385}
386
388{
389 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
390
391 /* Validate the resolution -> ADPRC translation before touching hardware so
392 * a bad descriptor cannot leave the module half-configured. */
393 uint32_t adprc = 0U;
394 if (!internal_adprc_for_resolution(cfg->resolution, &adprc)) {
396 }
397
399 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
400 RA8_RETURN_ON_ERROR(mst_err, s_tag, "adc_init_cfg: mstp enable");
401 /* GCOVR_EXCL_BR_STOP */
402
404
405 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
407 *ra8_adc_b_adintcr() = 0U;
408 *ra8_adc_b_adsger() = (uint32_t)(1UL << (uint32_t)k_ra8_adc_default_group);
409
412
413 for (uint8_t g = 0U; g < k_ra8_adc_b_scan_groups; ++g) {
414 s_adc_state.groups[g].num_channels = 0U;
415 }
416
417 s_adc_state.resolution = cfg->resolution;
418 s_adc_state.configured = true;
419 ra8_log_info(s_tag, "adc_init_configured ready");
420 return k_ra8_ok;
421}
422
424{
425 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
427 *ra8_adc_b_admdr() = 0U;
428 *ra8_adc_b_adsger() = 0U;
429 *ra8_adc_b_adintcr() = 0U;
430 *ra8_adc_b_adtrgenr() = 0U;
431 *ra8_adc_b_adcmpenr() = 0U;
432 *ra8_adc_b_adcmpintcr() = 0U;
433 *ra8_adc_b_adclkenr() = 0U;
434 s_adc_state.fn = nullptr;
435 s_adc_state.ctx = nullptr;
436 s_adc_state.configured = false;
437 for (uint8_t g = 0U; g < k_ra8_adc_b_scan_groups; ++g) {
438 s_adc_state.groups[g].num_channels = 0U;
439 }
441}
442
444{
445 uint32_t adprc = 0U;
446 if (!internal_adprc_for_resolution(resolution, &adprc)) {
448 }
449 s_adc_state.resolution = resolution;
450 /* Resolution is the per-channel ADDOPCRC.ADPRC data-format, not an ADMDR
451 * mode: install it on every result-producing virtual channel so the next
452 * conversion reports in the requested precision. */
454 return k_ra8_ok;
455}
456
457ra8_err_t ra8_adc_get_status(uint16_t* out_mask)
458{
459 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
460 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
461 const uint32_t adsr_now = *ra8_adc_b_adsr();
462 uint16_t out = 0U;
463 if ((adsr_now & k_ra8_adsr_mask_adact) != 0U) {
465 }
466 if (*ra8_adc_b_adintcr() != 0U) {
467 out |= k_ra8_adc_status_ie;
468 }
469 *out_mask = out;
470 return k_ra8_ok;
471}
472
474{
475 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
476 /* ADSR.ADACT0/1 are read-only on silicon -- to clear "busy" you
477 * write the matching ADSTOP bit in ADSTOPR. The host mock window
478 * is anonymous RAM, so we also write 0 to ADSR so the test can
479 * observe the busy bit drop after this call. */
481 *ra8_adc_b_adsr() = 0U;
482 return k_ra8_ok;
483}
484
486{
487 s_adc_state.fn = fn;
488 s_adc_state.ctx = ctx;
489 return k_ra8_ok;
490}
491
493{
494 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
495 *ra8_adc_b_admdr() = 0U;
497}
498
503
505void ra8_adc_dispatch_cnv_end(uint8_t channel)
506{
507 volatile const uint32_t* addr = ra8_adc_b_addr(channel);
508 if (addr == nullptr) {
509 return;
510 }
511 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
512 const uint16_t result = (uint16_t)(*addr & k_ra8_addr_mask_data);
514 void* const ctx = s_adc_state.ctx;
515 if (fn != nullptr) {
516 fn(ctx, result);
517 }
518}
519
520/* =============================================================================
521 * Scan-group / trigger / window-comparator / oversampling
522 * ----------------------------------------------------------------------------
523 * The following functions bring the ADC_B driver to FSP r_adc_b parity for
524 * scan-group orchestration. Implementation mirrors
525 * /opt/fsp/ra/fsp/src/r_adc_b/r_adc_b.c::R_ADC_B_ScanCfg
526 * /opt/fsp/ra/fsp/src/r_adc_b/r_adc_b.c::R_ADC_B_ScanStart
527 * /opt/fsp/ra/fsp/src/r_adc_b/r_adc_b.c::R_ADC_B_ScanStop
528 * /opt/fsp/ra/fsp/src/r_adc_b/r_adc_b.c::R_ADC_B_Read
529 * /opt/fsp/ra/fsp/src/r_adc_b/r_adc_b.c::R_ADC_B_WindowCfg
530 * =============================================================================
531 */
532
550 const ra8_adc_scan_group_cfg_t* cfg)
551{
552 if (group >= k_ra8_adc_b_scan_groups) {
554 }
555 if ((cfg->num_channels == 0U) || (cfg->num_channels > k_ra8_adc_scan_group_max_channels)) {
557 }
558 for (uint8_t i = 0U; i < cfg->num_channels; ++i) {
559 if (cfg->channels[i] >= k_ra8_adc_b_max_channels) {
561 }
562 }
563 return k_ra8_ok;
564}
565
584internal_oversample_encode(ra8_adc_oversample_t mode, uint32_t* out_avemd, uint32_t* out_adc)
585{
586 switch (mode) {
588 *out_avemd = (uint32_t)k_ra8_avemd_off;
589 *out_adc = (uint32_t)k_ra8_adc_avg_1x;
590 return k_ra8_ok;
592 *out_avemd = (uint32_t)k_ra8_avemd_average;
593 *out_adc = (uint32_t)k_ra8_adc_avg_4x;
594 return k_ra8_ok;
596 *out_avemd = (uint32_t)k_ra8_avemd_average;
597 *out_adc = (uint32_t)k_ra8_adc_avg_16x;
598 return k_ra8_ok;
600 *out_avemd = (uint32_t)k_ra8_avemd_average;
601 *out_adc = (uint32_t)k_ra8_adc_avg_64x;
602 return k_ra8_ok;
603 default:
605 }
606}
607
626 const ra8_adc_scan_group_cfg_t* cfg)
627{
628 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
629 for (uint8_t i = 0U; i < cfg->num_channels; ++i) {
630 const uint8_t ch = cfg->channels[i];
631 volatile uint32_t* reg = ra8_adc_b_adchcr(ch);
632 if (reg == nullptr) {
634 }
635 const uint32_t cnvcs =
636 ((uint32_t)ch << (uint32_t)k_ra8_adchcr_bit_cnvcs) & k_ra8_adchcr_mask_cnvcs;
637 const uint32_t sgsel =
638 ((uint32_t)group << (uint32_t)k_ra8_adchcr_bit_sgsel) & k_ra8_adchcr_mask_sgsel;
639 *reg = (cnvcs | sgsel);
640 }
641 return k_ra8_ok;
642}
643
658 const ra8_adc_scan_group_cfg_t* cfg)
659{
660 s_adc_state.groups[group].num_channels = cfg->num_channels;
661 for (uint8_t i = 0U; i < cfg->num_channels; ++i) {
662 s_adc_state.groups[group].channels[i] = cfg->channels[i];
663 }
664}
665
680{
681 const uint32_t group_bit = (uint32_t)(1UL << (uint32_t)group);
682 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
683 *ra8_adc_b_adsger() |= group_bit;
684 if (trigger == k_ra8_adc_trig_src_software) {
685 *ra8_adc_b_adtrgenr() &= ~group_bit;
686 } else {
687 *ra8_adc_b_adtrgenr() |= group_bit;
688 }
689}
690
692{
693 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
694
695 const ra8_err_t v_err = internal_validate_group_cfg(group, cfg);
696 RA8_RETURN_ON_ERROR(v_err, s_tag, "configure_scan_group: validation");
697
698 const ra8_err_t prog_err = internal_program_group_channels(group, cfg);
699 RA8_RETURN_ON_ERROR(prog_err, s_tag, "configure_scan_group: program channels");
700
703
704 (void)cfg->priority; /* Cached for future scan_group_priority register. */
705 return k_ra8_ok;
706}
707
709{
710 volatile uint32_t* adstr = ra8_adc_b_adstr(group);
711 if (adstr == nullptr) {
713 }
714 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
715 *adstr = k_ra8_adstr_mask_adst;
716 return k_ra8_ok;
717}
718
720{
721 volatile uint32_t* adstr = ra8_adc_b_adstr(group);
722 if (adstr == nullptr) {
724 }
725 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
726 *adstr = 0U;
728 return k_ra8_ok;
729}
730
731ra8_err_t ra8_adc_read_group_results(uint8_t group, uint16_t* out_buf, uint8_t* out_count)
732{
733 RA8_CHECK_NULL_PTR(out_buf, s_tag, "out_buf must not be nullptr");
734 RA8_CHECK_NULL_PTR(out_count, s_tag, "out_count must not be nullptr");
735 *out_count = 0U;
736
737 if (group >= k_ra8_adc_b_scan_groups) {
739 }
740 const ra8_adc_group_cache_t* cache = &s_adc_state.groups[group];
741 if (cache->num_channels == 0U) {
743 }
744
745 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
746 for (uint8_t i = 0U; i < cache->num_channels; ++i) {
747 volatile const uint32_t* addr = ra8_adc_b_addr(cache->channels[i]);
748 if (addr == nullptr) {
750 }
751 out_buf[i] = (uint16_t)(*addr & k_ra8_addr_mask_data);
752 }
753 *out_count = cache->num_channels;
754 return k_ra8_ok;
755}
756
757ra8_err_t ra8_adc_set_continuous_scan(uint8_t group, bool enable)
758{
759 if (group >= k_ra8_adc_b_scan_groups) {
761 }
762 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
763 /* ADMDR.ADMD0 holds the unit-level mode; we map continuous-scan to
764 * the matching code. The group argument is held for forward
765 * compatibility with a per-group mode register. */
766 const uint32_t mdr_now = *ra8_adc_b_admdr() & ~k_ra8_admdr_mask_admd0;
767 const uint32_t code =
768 enable ? (uint32_t)k_ra8_admdr_mode_continuous : (uint32_t)k_ra8_admdr_mode_one_cycle;
769 const uint32_t admd0 = (code << (uint32_t)k_ra8_admdr_bit_admd0) & k_ra8_admdr_mask_admd0;
770 *ra8_adc_b_admdr() = mdr_now | admd0;
771 return k_ra8_ok;
772}
773
774ra8_err_t ra8_adc_set_compare_window(uint8_t channel, uint16_t low, uint16_t high)
775{
776 if (channel >= k_ra8_adc_b_cmp_tables) {
778 }
779 if (high < low) {
781 }
782 volatile uint32_t* tbl = ra8_adc_b_adcmptbr(channel);
783 if (tbl == nullptr) {
785 }
786 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
787 /* Pack (low,high) into a single 32-bit ADCMPTBRn slot. */
788 *tbl = ((uint32_t)low << (uint32_t)k_ra8_adcmptbr_bit_low) |
789 ((uint32_t)high << (uint32_t)k_ra8_adcmptbr_bit_high);
790
791 /* CMPMDn -> "inside-window" mode. ADCMPMDR0 carries CMPMD0..3,
792 * ADCMPMDR1 carries CMPMD4..7. Each field is 2 bits at byte stride. */
793 const uint8_t which = (uint8_t)((channel < k_ra8_adcmpmd_per_reg) ? 0U : 1U);
794 volatile uint32_t* mdr = ra8_adc_b_adcmpmdr(which);
795 if (mdr != nullptr) {
796 const uint8_t local_idx = (uint8_t)(channel % k_ra8_adcmpmd_per_reg);
797 const uint8_t shift = (uint8_t)(local_idx * k_ra8_adcmpmd_field_step);
798 const uint32_t mask = ((uint32_t)0x3UL) << shift;
799 const uint32_t code = ((uint32_t)k_ra8_adcmpmd_inside) << shift;
800 *mdr = (*mdr & ~mask) | code;
801 }
802
803 /* ADCMPENR.CMPENn is the main enable for table N. */
804 const uint32_t enable_bit = (uint32_t)(1UL << channel);
805 *ra8_adc_b_adcmpenr() |= enable_bit;
806
807 /* Per-channel CMPTBLEm in ADDOPCRB enables table N for this channel. */
808 volatile uint32_t* opcrb = ra8_adc_b_addopcrb(channel);
809 if (opcrb != nullptr) {
810 const uint32_t cmptble_bit =
811 ((uint32_t)(1UL << channel) << (uint32_t)k_ra8_addopcrb_bit_cmptblem) &
813 *opcrb =
815 }
816 return k_ra8_ok;
817}
818
820{
821 uint32_t avemd = 0U;
822 uint32_t adc = 0U;
823 const ra8_err_t enc_err = internal_oversample_encode(mode, &avemd, &adc);
824 RA8_RETURN_ON_ERROR(enc_err, s_tag, "set_oversampling: invalid mode");
825
826 volatile uint32_t* opcrb = ra8_adc_b_addopcrb(channel);
827 if (opcrb == nullptr) {
829 }
830 /* HUM Ch 53 "16-bit A/D Converter (ADC16H)" p 3308 */
831 const uint32_t avemd_field =
833 const uint32_t adc_field = (adc << (uint32_t)k_ra8_addopcrb_bit_adc) & k_ra8_addopcrb_mask_adc;
834 const uint32_t cleared = *opcrb & ~(k_ra8_addopcrb_mask_avemd | k_ra8_addopcrb_mask_adc);
835 *opcrb = cleared | avemd_field | adc_field;
836 return k_ra8_ok;
837}
static void internal_wait_clksr(uint32_t desired)
Best-effort wait for ADCLKSR.CLKSR to match the requested level.
Definition adc.c:208
static uint32_t internal_build_admdr(bool scan_mode)
Build the ADMDR value (ADMD0 only – ADC1 stays disabled).
Definition adc.c:316
static bool internal_adprc_for_resolution(ra8_adc_resolution_t resolution, uint32_t *out_adprc)
Translate a public resolution selector into its ADDOPCRC.ADPRC code.
Definition adc.c:112
ra8_err_t ra8_adc_read_group_results(uint8_t group, uint16_t *out_buf, uint8_t *out_count)
Drain conversion results for every channel mapped to a group.
Definition adc.c:731
ra8_err_t ra8_adc_start_group(uint8_t group)
Kick a scan group via the per-group ADSTR register.
Definition adc.c:708
ra8_err_t ra8_adc_init_configured(const ra8_adc_cfg_t *cfg)
Initialise ADC_B with a full config descriptor.
Definition adc.c:387
ra8_err_t ra8_adc_attach_handler(ra8_adc_complete_fn_t fn, void *ctx)
Attach a conversion-complete callback.
Definition adc.c:485
ra8_err_t ra8_adc_set_oversampling(uint8_t channel, ra8_adc_oversample_t mode)
Programme ADDOPCRB[ch].AVEMD/ADC for a per-channel averaging mode.
Definition adc.c:819
ra8_adc_default_group_t
Scan-group used by the legacy single-channel polling API.
Definition adc.c:56
@ k_ra8_adc_default_group
Group 0 owns SW-trigger conversions.
Definition adc.c:57
static void internal_apply_group_enable(uint8_t group, ra8_adc_trigger_src_t trigger)
Apply the per-group enable bit (ADSGER) and trigger source (ADTRGENR).
Definition adc.c:679
static void internal_zero_channel_table(void)
Default-zero every per-channel ADCHCRn slot.
Definition adc.c:257
static void internal_apply_resolution_code(uint32_t adprc)
Install one ADPRC data-format code on every result-producing channel.
Definition adc.c:182
ra8_err_t ra8_adc_read_channel(uint8_t channel, uint16_t *out_raw)
Blocking single-channel sample.
Definition adc.c:351
ra8_err_t ra8_adc_configure_scan_group(uint8_t group, const ra8_adc_scan_group_cfg_t *cfg)
Configure scan group group with a list of channels + trigger.
Definition adc.c:691
ra8_err_t ra8_adc_set_resolution(ra8_adc_resolution_t resolution)
Change the ADC conversion resolution at runtime.
Definition adc.c:443
ra8_err_t ra8_adc_exit_stop(void)
Exit MSTP-gated stop.
Definition adc.c:499
static ra8_adc_state_t s_adc_state
Definition adc.c:87
ra8_err_t ra8_adc_get_status(uint16_t *out_mask)
Read the ADC status bits (ADCSR.ADST / ADIE).
Definition adc.c:457
ra8_err_t ra8_adc_enter_stop(void)
Put ADC_B into MSTP-gated stop.
Definition adc.c:492
static ra8_err_t internal_program_group_channels(uint8_t group, const ra8_adc_scan_group_cfg_t *cfg)
Walk the channel list and program ADCHCR[ch] = (SGSEL, CNVCS).
Definition adc.c:625
static ra8_err_t internal_oversample_encode(ra8_adc_oversample_t mode, uint32_t *out_avemd, uint32_t *out_adc)
Translate the public oversampling enum into ADDOPCRB AVEMD/ADC.
Definition adc.c:584
static ra8_err_t internal_validate_group_cfg(uint8_t group, const ra8_adc_scan_group_cfg_t *cfg)
Validate a scan-group configuration descriptor.
Definition adc.c:549
ra8_err_t ra8_adc_set_compare_window(uint8_t channel, uint16_t low, uint16_t high)
Programme a window comparator for a single channel.
Definition adc.c:774
ra8_err_t ra8_adc_init(void)
Legacy init – 14-bit right-aligned, software trigger.
Definition adc.c:323
ra8_err_t ra8_adc_deinit(void)
Tear down the ADC_B peripheral.
Definition adc.c:423
static void internal_write_adprc(uint8_t vch, uint32_t adprc)
Write the ADPRC data-format field of one ADDOPCRCn slot (RMW).
Definition adc.c:151
ra8_err_t ra8_adc_clear_status(void)
Clear the ADCSR.ADST busy bit (abort in-flight conversion).
Definition adc.c:473
static void internal_program_channel(uint8_t virtual_ch, uint8_t physical_ch)
Programme an ADCHCRn slot to map a physical channel into the default scan group with no special sampl...
Definition adc.c:283
ra8_err_t ra8_adc_set_continuous_scan(uint8_t group, bool enable)
Switch a scan group between one-shot and continuous (free-running).
Definition adc.c:757
static void internal_cache_group_channels(uint8_t group, const ra8_adc_scan_group_cfg_t *cfg)
Cache a group's channel list into s_adc_state.groups.
Definition adc.c:657
void ra8_adc_dispatch_cnv_end(uint8_t channel)
Dispatch conversion-complete – read result + fire callback.
Definition adc.c:505
ra8_err_t ra8_adc_stop_group(uint8_t group)
Stop a scan group: clear ADSTR[group] and write ADSTOPR.
Definition adc.c:719
static void internal_clock_bring_up(uint32_t clkcr_value)
Bring ADCLK up: ENR=0 -> wait CLKSR=0 -> CR=src -> ENR=1 -> CLKSR=1.
Definition adc.c:231
Cross-TU constants shared by the ADC_B driver split.
@ k_ra8_adc_busy_wait_limit
ADSR.ADACT busy-poll budget.
@ k_ra8_adc_clk_wait_limit
ADCLKSR settle-poll budget.
Full-featured ADC_B driver.
void(* ra8_adc_complete_fn_t)(void *ctx, uint16_t result)
Conversion-complete callback.
Definition ra8_adc.h:98
ra8_adc_resolution_t
ADDOPCRCn.ADPRC per-channel conversion-resolution (data-format) selector.
Definition ra8_adc.h:49
@ k_ra8_adc_res_12bit
12-bit conversion result (ADPRC = 0b10).
Definition ra8_adc.h:52
@ k_ra8_adc_res_14bit
14-bit conversion result (ADPRC = 0b01).
Definition ra8_adc.h:51
@ k_ra8_adc_res_10bit
10-bit conversion result (ADPRC = 0b11).
Definition ra8_adc.h:53
@ k_ra8_adc_res_16bit
16-bit conversion result (ADPRC = 0b00).
Definition ra8_adc.h:50
ra8_adc_oversample_t
Per-channel ADADC.AVEMD/ADC oversampling configuration.
Definition ra8_adc.h:150
@ k_ra8_adc_oversample_off
Single sample, no averaging.
Definition ra8_adc.h:151
@ k_ra8_adc_oversample_64x
64-sample average.
Definition ra8_adc.h:154
@ k_ra8_adc_oversample_4x
4-sample average.
Definition ra8_adc.h:152
@ k_ra8_adc_oversample_16x
16-sample average.
Definition ra8_adc.h:153
@ k_ra8_adc_status_ie
ADCSR.ADIE.
Definition ra8_adc.h:89
@ k_ra8_adc_status_busy
ADCSR.ADST (conversion in flight).
Definition ra8_adc.h:88
ra8_adc_trigger_src_t
Per-scan-group trigger source.
Definition ra8_adc.h:113
@ k_ra8_adc_trig_src_software
SW kick (default).
Definition ra8_adc.h:114
@ k_ra8_adc_scan_group_max_channels
Maximum channels per scan group.
Definition ra8_adc.h:162
ADC16H (16-bit SAR) register layout for the Renesas RA8D2 / RA8P1.
static volatile uint32_t * ra8_adc_b_adcmpmdr(uint8_t which)
Pointer to ADCMPMDR0 / ADCMPMDR1 (compare-table mode select).
@ k_ra8_addopcrc_adprc_12bit
12-bit data.
@ k_ra8_addopcrc_adprc_16bit
16-bit data.
@ k_ra8_addopcrc_adprc_14bit
14-bit data.
@ k_ra8_addopcrc_adprc_10bit
10-bit data.
static volatile uint32_t * ra8_adc_b_addopcrc(uint8_t ch)
Pointer to the per-virtual-channel ADDOPCRC[n] register.
static volatile uint32_t * ra8_adc_b_adclkenr(void)
Pointer to the 32-bit ADCLKENR register.
@ k_ra8_adchcr_mask_cnvcs
[14:8]
@ k_ra8_adchcr_mask_sgsel
[4:0]
static volatile uint32_t * ra8_adc_b_admdr(void)
Pointer to the 32-bit ADMDR register.
@ k_ra8_adstopr_mask_adstop1
[8]
@ k_ra8_adstopr_mask_adstop0
[0]
@ k_ra8_adc_avg_16x
RA8 ADC avg 16x.
@ k_ra8_adc_avg_4x
RA8 ADC avg 4x.
@ k_ra8_adc_avg_64x
RA8 ADC avg 64x.
@ k_ra8_adc_avg_1x
RA8 ADC avg 1x.
@ k_ra8_admdr_mode_continuous
Continuous-scan repeating.
@ k_ra8_admdr_mode_one_cycle
Single-shot scan, one cycle.
static volatile uint32_t * ra8_adc_b_adcmpenr(void)
Pointer to the 32-bit ADCMPENR register (compare-table enable).
@ k_ra8_adchcr_bit_sgsel
Scan group selection.
@ k_ra8_adchcr_bit_cnvcs
Physical channel selection.
static volatile uint32_t * ra8_adc_b_adclkcr(void)
Pointer to the 32-bit ADCLKCR register.
static volatile uint32_t * ra8_adc_b_addopcrb(uint8_t ch)
Pointer to the per-virtual-channel ADDOPCRB[n] register.
@ k_ra8_adcmpmd_inside
Match when low <= data <= high.
@ k_ra8_adclksr_mask_clksr
RA8 adclksr mask clksr.
static volatile uint32_t * ra8_adc_b_adintcr(void)
Pointer to the 32-bit ADINTCR register (per-group scan-end IE).
@ k_ra8_admdr_bit_admd0
ADC0 mode select [3:0].
static volatile uint32_t * ra8_adc_b_addr(uint8_t ch)
Pointer to the per-virtual-channel ADDR[n] result register.
@ k_ra8_adcmpmd_per_reg
Four CMPMDn per ADCMPMDR.
@ k_ra8_adcmpmd_field_step
Stride between CMPMDn fields.
@ k_ra8_adc_b_scan_groups
ADSGER / ADTRGENR / ADSYSTR width [8:0].
@ k_ra8_adc_b_result_regs
ADDR[0..22] result slots.
@ k_ra8_adc_b_max_channels
ADCHCR0..23 virtual-channel config slots.
@ k_ra8_adc_b_cmp_tables
ADCMPTBR0..7 / CMPMD0..7 / CMPENn[7:0].
@ k_ra8_addopcrc_mask_adprc
ADPRC[1:0].
@ k_ra8_addopcrb_bit_cmptblem
RA8 addopcrb bit cmptblem.
@ k_ra8_addopcrb_bit_avemd
RA8 addopcrb bit avemd.
@ k_ra8_addopcrb_bit_adc
RA8 addopcrb bit ADC.
@ k_ra8_addopcrb_mask_adc
[11:8]
@ k_ra8_addopcrb_mask_cmptblem
[23:16]
@ k_ra8_addopcrb_mask_avemd
[1:0]
@ k_ra8_addr_mask_data
[15:0] conversion data.
static volatile uint32_t * ra8_adc_b_adstr(uint8_t group)
Pointer to the per-scan-group ADSTR[n] register.
@ k_ra8_adstr_mask_adst
RA8 adstr mask adst.
@ k_ra8_avemd_off
Disabled (single-sample).
@ k_ra8_avemd_average
Sum then divide by N.
@ k_ra8_adclkenr_mask_clken
RA8 adclkenr mask clken.
static volatile uint32_t * ra8_adc_b_adchcr(uint8_t ch)
Pointer to the per-virtual-channel ADCHCR register.
@ k_ra8_adcmptbr_bit_high
High-side window level [31:16].
@ k_ra8_adcmptbr_bit_low
Low-side window level [15:0].
@ k_ra8_adsr_mask_adact0
RA8 adsr mask adact0.
@ k_ra8_adsr_mask_adact
Either unit busy.
static volatile uint32_t * ra8_adc_b_adtrgenr(void)
Pointer to the 32-bit ADTRGENR register (per-group HW trigger enable).
static volatile uint32_t * ra8_adc_b_adcmptbr(uint8_t table)
Pointer to a per-table ADCMPTBR[n] register (low/high pair).
static volatile uint32_t * ra8_adc_b_adclksr(void)
Pointer to the 32-bit ADCLKSR register.
@ k_ra8_admdr_mask_admd0
ADMD0 [3:0].
@ k_ra8_addopcrc_bit_adprc
Data-format select [17:16].
static volatile uint32_t * ra8_adc_b_adstopr(void)
Pointer to the 32-bit ADSTOPR register (force-stop).
static volatile uint32_t * ra8_adc_b_adsger(void)
Pointer to the 32-bit ADSGER register (scan-group enable).
static volatile uint32_t * ra8_adc_b_adcmpintcr(void)
Pointer to the 32-bit ADCMPINTCR register (compare-match IE).
static volatile uint32_t * ra8_adc_b_adsr(void)
Pointer to the 32-bit ADSR register (status).
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
Error Code Definitions for ra8-firmware.
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
Definition ra8_err.h:304
@ 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(tag, message)
RA8 log info.
Definition ra8_log.h:364
#define ra8_log_error(tag, message)
RA8 log error.
Definition ra8_log.h:335
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_adc16h
MSTPD21 ADC16H.
Configuration descriptor for ra8_adc_init_configured.
Definition ra8_adc.h:75
bool scan_mode
True -> continuous scan.
Definition ra8_adc.h:79
ra8_adc_resolution_t resolution
16 / 14 / 12 / 10 bit.
Definition ra8_adc.h:76
Per-scan-group channel-list cache.
Definition adc.c:69
uint8_t channels[k_ra8_adc_scan_group_max_channels]
Physical channel list.
Definition adc.c:71
uint8_t num_channels
0 means group unconfigured.
Definition adc.c:70
Configuration for a single scan group.
Definition ra8_adc.h:178
uint8_t num_channels
1..8.
Definition ra8_adc.h:179
uint8_t channels[k_ra8_adc_scan_group_max_channels]
Physical-channel list.
Definition ra8_adc.h:180
ra8_adc_trigger_src_t trigger
Trigger source.
Definition ra8_adc.h:181
ra8_adc_priority_t priority
Priority class.
Definition ra8_adc.h:182
Driver-wide runtime state.
Definition adc.c:78
bool configured
True after first successful init.
Definition adc.c:82
void * ctx
Callback context.
Definition adc.c:80
ra8_adc_complete_fn_t fn
Conversion-complete callback or nullptr.
Definition adc.c:79
ra8_adc_resolution_t resolution
Last-applied resolution selection.
Definition adc.c:81
ra8_adc_group_cache_t groups[k_ra8_adc_b_scan_groups]
Per-group channel cache.
Definition adc.c:84