ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_canfd.c
Go to the documentation of this file.
1
34
35#include "ra8_canfd.h"
36
37#include <stdint.h>
38
39#include "ra8_attributes.h"
40#include "ra8_canfd_regs.h"
41#include "ra8_cgc.h"
42#include "ra8_check.h"
43#include "ra8_err.h"
44#include "ra8_hal_internal.h"
45#include "ra8_hw_err.h"
46#include "ra8_log.h"
47#include "ra8_mstp.h"
49#include "ra8_system_regs.h"
50
51static const char* s_tag = "CANFD";
52
70typedef enum : uint32_t {
74
96static ra8_err_t internal_wait_status_bit(volatile r_canfd_t* reg, uint8_t status_bit)
97{
98 /* HUM Ch 41 p 2766 "CFDCnSTS" -- wait for the requested mode-ack bit
99 * (CRSTSTS / CHLTSTS / ...) to latch. The host unit-test build runs this
100 * same loop through the ra8_fake_mmio seam (ra8_hw_err.h), so a stuck
101 * channel surfaces here as an hw_timeout instead of short-circuiting. */
102 return ra8_hw_wait_flag_set32(&reg->CFDC[0].STS,
103 (uint32_t)(1UL << status_bit),
104 (uint32_t)k_ra8_canfd_spin);
105}
106
116
139{
140 /* Read-modify-write the CTR register, mask CHMDC to bits [1:0],
141 * stamp the requested mode. Also clear CSLPR (bit 2): the channel
142 * comes out of reset with CSLPR=1 (sleep request), and CHMDC
143 * writes are silently ignored while the channel is asleep -- the
144 * state machine stays in CH_RESET, status bits never flip, and
145 * the next mode write times out. JTAG dump after the original
146 * init showed CTR=0x05 / STS=0x05 (CHMDC=01 RESET + CSLPR=1 +
147 * CRSTSTS=1 + CSLPSTS=1) confirming the channel never woke.
148 * Mirrors the GSLPR clear in internal_set_global_mode.
149 * HUM Ch 41 p 2762 "CFDCnCTR.CHMDC" + "CFDCnCTR.CSLPR" */
150 uint32_t ctr = reg->CFDC[0].CTR;
152 ctr |= ((uint32_t)mode & k_ra8_cnctr_mask_chmdc);
153 reg->CFDC[0].CTR = ctr;
154
155 /* HUM Ch 41 p 2766 "CFDCnSTS" -- the channel state machine reflects
156 * the requested mode by latching CHLTSTS (halt), CRSTSTS (reset), or
157 * by clearing BOTH (operation). Returning before the chip latches the
158 * new state lets a subsequent CHMDC write race against the in-flight
159 * transition and the chip silently ignores it (FSP r_canfd
160 * mode_transition does the matching three-mode poll). Symptom seen on
161 * HIL prior to this wait: ra8_canfd_set_test_mode -> set CHMDC=halt
162 * times out on CHLTSTS because the channel state machine was still
163 * completing the GL/CH operation handshake from ra8_canfd_init. */
164 if (mode == k_ra8_chmdc_halt) {
166 }
167 if (mode == k_ra8_chmdc_reset) {
169 }
170 /* Operation: poll for (CRSTSTS|CHLTSTS) == 0 so a subsequent CHMDC
171 * write does not race the in-flight transition. Real silicon
172 * converges within a handful of CANFDCLK ticks; the host unit-test
173 * build drives this same loop through the ra8_fake_mmio seam
174 * (ra8_hw_err.h) so a stuck channel surfaces here as an hw_timeout
175 * rather than at the next mode write, which is what made
176 * canfd_loopback report a phantom test_mode failure with the real
177 * problem being "channel never reached operation". */
178 const uint32_t reset_or_halt =
179 (uint32_t)((1UL << k_ra8_cnsts_bit_crstst) | (1UL << k_ra8_cnsts_bit_chltst));
180 return ra8_hw_wait_flag_clear32(&reg->CFDC[0].STS, reset_or_halt, (uint32_t)k_ra8_canfd_spin);
181}
182
204static ra8_err_t internal_set_global_mode(volatile r_canfd_t* reg, uint32_t gmdc_value)
205{
206 /* HUM Ch 41 "CFDGCTR.GMDC" p 2742 */ /* "CFDGCTR.GMDC" + GSLPR clear. */
207 uint32_t gctr = reg->CFDGCTR;
209 gctr |= (gmdc_value & k_ra8_gctr_mask_gmdc);
210 reg->CFDGCTR = gctr;
211
212 if (gmdc_value == k_ra8_gctr_value_halt) {
213 return ra8_hw_wait_flag_set32(&reg->CFDGSTS,
214 (uint32_t)(1UL << k_ra8_gsts_bit_ghltsts),
215 (uint32_t)k_ra8_canfd_spin);
216 }
217 if (gmdc_value == k_ra8_gctr_value_reset) {
218 return ra8_hw_wait_flag_set32(&reg->CFDGSTS,
219 (uint32_t)(1UL << k_ra8_gsts_bit_grststs),
220 (uint32_t)k_ra8_canfd_spin);
221 }
222 /* Global OPERATION is the state where BOTH GRSTSTS and GHLTSTS
223 * read 0. The host unit-test build drives this same loop through the
224 * ra8_fake_mmio seam (ra8_hw_err.h) so a stuck global block surfaces
225 * here as an hw_timeout rather than at the next channel-mode write.
226 * HUM Ch 41 p 2746 "CFDGSTS" */
227 const uint32_t reset_or_halt =
228 (uint32_t)((1UL << k_ra8_gsts_bit_grststs) | (1UL << k_ra8_gsts_bit_ghltsts));
229 return ra8_hw_wait_flag_clear32(&reg->CFDGSTS, reset_or_halt, (uint32_t)k_ra8_canfd_spin);
230}
231
259static void internal_install_default_afl(volatile r_canfd_t* reg)
260{
261 /* HUM Ch 41 "CFDGAFLCFG0" p 2730 */ /* RNC0 = 1 -> one rule on page 0. */
262 reg->CFDGAFLCFG0 = 1UL << 16U;
263
264 /* HUM Ch 41 "CFDGAFLECTR" p 2734 */ /* page 0, AFLDAE = 1 unlocks edit. */
266
267 /* HUM Ch 41 "CFDGAFLID" p 2735 */ /* accept-id ignored: mask = 0. */
268 reg->CFDGAFL[0].ID = 0U;
269 /* HUM Ch 41 "CFDGAFLM" p 2736 */ /* mask = 0 -> accept every ID. */
270 reg->CFDGAFL[0].M = 0U;
271 /* HUM Ch 41 "CFDGAFLP0" p 2738 */ /* no RX-MB routing requested. */
272 reg->CFDGAFL[0].P0 = 0U;
273 /* HUM Ch 41 "CFDGAFLP1" p 2740 */ /* GAFLFDP0 = bit 0 -> RX FIFO 0. */
274 reg->CFDGAFL[0].P1 = 1UL << 0U;
275
276 /* Re-lock the AFL data window. */
277 reg->CFDGAFLECTR = 0U;
278}
279
305static void internal_configure_rx_fifo0(volatile r_canfd_t* reg)
306{
307 /* Programme depth + payload in GL_RESET (RFE bit left zero -- it
308 * is only writable in GL_HALT or GL_OPERATION per HUM Ch 41
309 * "CFDRFCCa" p 2741. Setting RFE here would silently no-op, the
310 * FIFO would stay disabled, and every loopback frame would land
311 * in /dev/null instead of the RX FIFO.) */
312 enum : uint32_t {
313 k_rfcc_rfdc_4msgs = 1UL << 8U,
314 k_rfcc_rfpls_64 = 7UL << 4U,
315 };
316 reg->CFDRFCC[0] = k_rfcc_rfdc_4msgs | k_rfcc_rfpls_64;
317}
318
335static void internal_enable_rx_fifo0(volatile r_canfd_t* reg)
336{
337 /* HUM Ch 41 "CFDRFCCa.RFE" p 2742 -- separate write after the rest of
338 * the CFDRFCCa register has been set, while in GL_OPERATION. */
339 reg->CFDRFCC[0] |= k_ra8_rfcc_bit_rfe;
340}
341
364static ra8_err_t internal_wait_canfdcksrdy(uint8_t expected)
365{
366 /* SRDY (clock-source ready) is bit 7 of CANFDCKCR. @p expected is
367 * always 0 or 1, so this reduces to a single-bit set/clear wait; the
368 * host unit-test build runs the same loop through the ra8_fake_mmio
369 * seam (ra8_hw_err.h) instead of faking the ack write. */
370 /* HUM Ch 9.2.46 "CANFDCKCR.CANFDCKSRDY" p 366 */
371 volatile const uint8_t* const ckcr = ra8_sys_canfdckcr();
372 const uint8_t mask = (uint8_t)(1U << k_ra8_usbckcr_bit_srdy);
373 if (expected != 0U) {
374 return ra8_hw_wait_flag_set8(ckcr, mask, (uint32_t)k_ra8_canfd_ckcr_spin);
375 }
376 return ra8_hw_wait_flag_clear8(ckcr, mask, (uint32_t)k_ra8_canfd_ckcr_spin);
377}
378
427{
428 static bool s_canfd_clock_inited = false;
429 if (s_canfd_clock_inited) {
430 return k_ra8_ok;
431 }
432 ra8_err_t err = k_ra8_ok;
434 {
435 /* HUM Ch 9.2.41 "CANFDCKDIVCR" p 357 -- /1 divider keeps MOCO at
436 * its native rate (~8 MHz nominal; PCLKA on this project is
437 * 100 MHz so MOCO < PCLKA satisfies HUM Ch 41.1.2 clock
438 * restriction CANFDCLK <= PCLKA). */
439 *ra8_sys_canfdckdivcr() = 0U;
440
441 /* HUM Ch 9.2.46 "CANFDCKCR.CANFDCKSREQ" p 366 -- assert SREQ with
442 * the reset-default source (MOCO, CANFDCKSEL = 0001b). */
443 const uint8_t sreq_mask = (uint8_t)(1U << k_ra8_usbckcr_bit_sreq);
444 const uint8_t src_moco = 0x01U;
445 *ra8_sys_canfdckcr() = (uint8_t)(src_moco | sreq_mask);
446
447 /* Step 3: wait for SRDY = 1 (chip acknowledges the request). */
449 if (err != k_ra8_ok) {
450 ra8_log_error(s_tag, "canfd: CANFDCKSRDY=1 timeout");
451 break;
452 }
453 /* Step 4: drop SREQ -- commits the (same) source selection. */
454 *ra8_sys_canfdckcr() = src_moco;
455 /* Step 5: wait for SRDY = 0 -- handshake done. */
457 if (err != k_ra8_ok) {
458 ra8_log_error(s_tag, "canfd: CANFDCKSRDY=0 timeout");
459 break;
460 }
461 }
462 if (err == k_ra8_ok) {
463 s_canfd_clock_inited = true;
464 ra8_log_info(s_tag, "canfd block clock stable");
465 }
466 return err;
467}
468
493{
496
499
501 if (gop_err != k_ra8_ok) {
502 return gop_err;
503 }
504 /* RFE is only writable in GL_HALT / GL_OPERATION, so enable RX FIFO
505 * 0 only after the global block has actually transitioned. */
508}
509
510ra8_err_t ra8_canfd_init(uint8_t channel)
511{
512 volatile r_canfd_t* reg = ra8_canfd(channel);
513 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
514 if (channel >= (uint8_t)(sizeof(s_canfd_mstp_table) / sizeof(s_canfd_mstp_table[0]))) {
516 }
517 /* MSTPC26/27 must be written AFTER CANFDCLK is stable.
518 * HUM Ch 11.2.8 "MSTPCRC" Note 4 p 446 */
520 if (clk_err != k_ra8_ok) {
521 return clk_err;
522 }
523
524 /* HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C", p 447 */
525 const ra8_err_t mst_err = ra8_mstp_enable(s_canfd_mstp_table[channel]);
526 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
527 RA8_RETURN_ON_ERROR(mst_err, s_tag, "canfd_init: mstp enable");
528 /* GCOVR_EXCL_BR_STOP */
529
530 /* Wait for RAM init done (CFDGSTS.GRAMINIT clears). */
531 /* HUM Ch 41.2 "CFDGSTS : Global Status Register" p 2730 */
532 for (uint32_t i = 0U; i < k_ra8_canfd_spin; i++) {
533 if ((reg->CFDGSTS & (uint32_t)(1UL << k_ra8_gsts_bit_graminit)) == 0U) {
534 break;
535 }
536 }
537
538 const ra8_err_t open_err = internal_canfd_open_channel(reg);
539 if (open_err != k_ra8_ok) {
540 return open_err;
541 }
542 ra8_log_info_val(s_tag, "canfd_init ch", (uint32_t)channel);
543 return k_ra8_ok;
544}
545
547{
548 volatile r_canfd_t* reg = ra8_canfd(channel);
549 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
550
551 /* HUM Ch 41 "CFDCnCTR.CHMDC" p 2762 */ /* "CFDCnCTR.CHMDC" -- park channel in reset. */
553 return k_ra8_ok;
554}
555
556/* =============================================================================
557 * status + IRQ + power transition
558 * =============================================================================
559 */
560
562static void* s_canfd_ctx;
563
564ra8_err_t ra8_canfd_get_status(uint8_t channel, uint32_t* out_mask)
565{
566 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
567 volatile r_canfd_t* reg = ra8_canfd(channel);
568 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
569 /* HUM Ch 41 "CFDCnSTS" p 2766 */ /* "CFDCnSTS". */
570 *out_mask = reg->CFDC[0].STS;
571 return k_ra8_ok;
572}
573
574ra8_err_t ra8_canfd_clear_status(uint8_t channel, uint32_t mask)
575{
576 volatile r_canfd_t* reg = ra8_canfd(channel);
577 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
578 /* HUM Ch 41 p 2772 "CFDCnERFL" -- error flags are W0C: writing 0
579 * clears, writing 1 leaves untouched. We compute the inverse mask
580 * to match the previous behaviour ("clear bits in mask"). */
581 reg->CFDC[0].ERFL = reg->CFDC[0].ERFL & ~mask;
582 return k_ra8_ok;
583}
584
586{
587 s_canfd_fn = fn;
588 s_canfd_ctx = ctx;
589 return k_ra8_ok;
590}
591
593void ra8_canfd_dispatch(uint8_t channel)
594{
595 volatile r_canfd_t* reg = ra8_canfd(channel);
596 if (reg == nullptr) {
597 return;
598 }
599 /* HUM Ch 41 "CFDCnERFL" p 2772 */ /* "CFDCnERFL" snapshot then ack. */
600 const uint32_t mask = reg->CFDC[0].ERFL;
602 void* const ctx = s_canfd_ctx;
603 reg->CFDC[0].ERFL = 0U;
604 if (fn != nullptr) {
605 fn(ctx, channel, mask);
606 }
607}
608
610enum : uint16_t {
612};
613
628static void internal_bump_rnc0_locked(volatile r_canfd_t* reg, uint16_t filter_id)
629{
630 if (filter_id >= (uint16_t)k_ra8_canfd_afl_per_page) {
631 return;
632 }
633 const uint32_t cur_rnc =
635 const uint32_t new_rnc = ((uint32_t)filter_id + 1U) & k_ra8_gaflcfg0_mask_rnc0;
636 if (cur_rnc < new_rnc) {
637 const uint32_t cfg0 = reg->CFDGAFLCFG0;
640 }
641}
642
664static void internal_write_afl_slot(volatile r_canfd_t* reg,
665 uint16_t slot,
666 uint32_t accept_id,
667 uint32_t mask,
668 uint8_t dlc)
669{
670 reg->CFDGAFL[slot].ID = accept_id;
671 reg->CFDGAFL[slot].M = mask | (uint32_t)k_ra8_gaflm_bit_gafllb;
672 reg->CFDGAFL[slot].P0 = 0U;
673 reg->CFDGAFL[slot].P1 =
676}
677
678/* ra8_canfd_filter_set -- see header for full description.
679 *
680 * HUM Ch 41.2.18 / 41.2.20 / 41.2.22 p 2735-2742: CFDGAFLCFG0.RNC0
681 * and the per-slot CFDGAFL.{ID,M,P0,P1} registers are only writable
682 * while the global block is in GL_RESET. Writing them in
683 * GL_OPERATION lands the bits in the register file but the AFL
684 * lookup engine never resamples them, so live filtering keeps using
685 * the snapshot taken at the most recent GL_RESET -> GL_OPERATION
686 * transition. install_default_afl in internal_canfd_open_channel
687 * runs in GL_RESET for that reason; we mirror the same RESET ->
688 * write -> OPERATION transaction here so updates take effect. */
689ra8_err_t ra8_canfd_filter_set(uint16_t filter_id, uint32_t accept_id, uint32_t mask, uint8_t dlc)
690{
691 if (filter_id >= k_ra8_canfd_afl_total) {
693 }
694 if (dlc > k_ra8_canfd_dlc_max) {
696 }
697 if ((accept_id & ~k_ra8_canfd_id_ext_mask) != 0U) {
699 }
700
701 const uint16_t page = (uint16_t)(filter_id / k_ra8_canfd_afl_per_page);
702 const uint16_t slot = (uint16_t)(filter_id % k_ra8_canfd_afl_per_page);
703
704 /* AFL is global across instances; access via channel 0. */
705 volatile r_canfd_t* reg = ra8_canfd(0U);
706 RA8_CHECK_NULL_PTR(reg, s_tag, "filter_set: channel0 unavailable");
707
709 if (reset_err != k_ra8_ok) {
710 return reset_err;
711 }
712
713 internal_bump_rnc0_locked(reg, filter_id);
714
715 /* Unlock AFL data window via AFLDAE bit. */
716 /* HUM Ch 41.2 "CFDGAFLECTR : AFL Entry Control Register" p 2734 */
718 internal_write_afl_slot(reg, slot, accept_id, mask, dlc);
719 reg->CFDGAFLECTR = 0U;
720
722 if (op_err != k_ra8_ok) {
723 return op_err;
724 }
725 /* GL_RESET cleared CFDRFCCa.RFE (HUM Ch 41 p 2742); re-enable so
726 * matched frames have a landing FIFO once we resume operation. */
728 return k_ra8_ok;
729}
730
732{
733 volatile r_canfd_t* reg = ra8_canfd(channel);
734 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
735 if ((uint8_t)mode > (uint8_t)k_ra8_ctms_self_test_1) {
737 }
738
739 /* HUM Ch 41 "CFDCnCTR" p 2710 -- CTME (bit 24) and CTMS (bits
740 * [26:25]) are only writable in CH_HALT mode. ra8_canfd_init parks
741 * the channel in CH_OPERATION so we transition through CH_HALT to
742 * land the test-mode select, then return to CH_OPERATION. */
744 if (halt_err != k_ra8_ok) {
745 /* Best-effort recover the channel before reporting the error. */
747 return halt_err;
748 }
749
750 /* Read-modify-write CTR: clear any prior CTME/CTMS, then OR in the
751 * requested selector with CTME = 1. */
752 uint32_t ctr = reg->CFDC[0].CTR;
755 ctr |= ((uint32_t)mode << (uint32_t)k_ra8_cnctr_bit_ctms) & k_ra8_cnctr_mask_ctms;
756 reg->CFDC[0].CTR = ctr;
757
759}
760
762{
763 volatile r_canfd_t* reg = ra8_canfd(0U);
764 RA8_CHECK_NULL_PTR(reg, s_tag, "set_iso_mode: channel0 unavailable");
765 /* HUM Ch 41 "CFDGFDCFG" pp 2702-2867 -- bit 0 (NISO) is set for ISO
766 * mode (default) and cleared for non-ISO Bosch framing. */
767 uint32_t v = reg->CFDGFDCFG;
768 if (enable) {
770 } else {
772 }
773 reg->CFDGFDCFG = v;
774 return k_ra8_ok;
775}
776
778{
779 if (channel >= k_ra8_canfd_instance_count) {
781 }
782 /* HUM Ch 11.2.8 "MSTPCRC" p 447 */ /* gate channel clock back off. */
783 return ra8_mstp_disable(s_canfd_mstp_table[channel]);
784}
785
787{
788 if (channel >= k_ra8_canfd_instance_count) {
790 }
791 /* HUM Ch 11.2.8 "MSTPCRC" p 447 */ /* ungate channel clock. */
792 return ra8_mstp_enable(s_canfd_mstp_table[channel]);
793}
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).
static ra8_err_t internal_wait_canfdcksrdy(uint8_t expected)
Bounded wait on CANFDCKCR.CANFDCKSRDY reaching expected.
Definition ra8_canfd.c:364
ra8_err_t ra8_canfd_enter_stop(uint8_t channel)
Put the CANFD channel into MSTP-gated stop.
Definition ra8_canfd.c:777
ra8_err_t ra8_canfd_deinit(uint8_t channel)
Put the CANFD channel back into reset.
Definition ra8_canfd.c:546
ra8_err_t ra8_canfd_filter_set(uint16_t filter_id, uint32_t accept_id, uint32_t mask, uint8_t dlc)
Programme one Global Acceptance-Filter-List (GAFL) entry.
Definition ra8_canfd.c:689
static const ra8_mstp_t s_canfd_mstp_table[]
Channel-index -> MSTP id lookup.
Definition ra8_canfd.c:112
static void internal_configure_rx_fifo0(volatile r_canfd_t *reg)
Enable RX FIFO 0 with a sensible default depth and payload.
Definition ra8_canfd.c:305
static ra8_err_t internal_canfd_open_channel(volatile r_canfd_t *reg)
Push the CANFD global+channel state machines into OPERATION.
Definition ra8_canfd.c:492
static void internal_enable_rx_fifo0(volatile r_canfd_t *reg)
Enable RX FIFO 0 (RFE=1) – must run in GL_HALT or GL_OPERATION.
Definition ra8_canfd.c:335
static void * s_canfd_ctx
Definition ra8_canfd.c:562
static void internal_bump_rnc0_locked(volatile r_canfd_t *reg, uint16_t filter_id)
Bump CFDGAFLCFG0.RNC0 to cover filter_id rules on page 0.
Definition ra8_canfd.c:628
void ra8_canfd_dispatch(uint8_t channel)
Dispatch a CANFD event for a channel – snapshot + fire callback.
Definition ra8_canfd.c:593
ra8_err_t ra8_canfd_clear_status(uint8_t channel, uint32_t mask)
Clear error flags in CFDCnERFL.
Definition ra8_canfd.c:574
static ra8_err_t internal_canfd_clock_block_init(void)
Block-level CANFD clock init – run BEFORE the first MSTP release.
Definition ra8_canfd.c:426
static ra8_canfd_event_fn_t s_canfd_fn
Definition ra8_canfd.c:561
static void internal_write_afl_slot(volatile r_canfd_t *reg, uint16_t slot, uint32_t accept_id, uint32_t mask, uint8_t dlc)
Write one CFDGAFL slot (ID/M/P0/P1) with the loopback + FIFO-0 routing bits set.
Definition ra8_canfd.c:664
ra8_canfd_internal_t
Internal tunables (mode-transition + clock-handshake spin budgets).
Definition ra8_canfd.c:70
@ k_ra8_canfd_ckcr_spin
CANFDCKCR SREQ/SRDY budget.
Definition ra8_canfd.c:72
@ k_ra8_canfd_spin
Bounded poll budget in iterations.
Definition ra8_canfd.c:71
static ra8_err_t internal_set_global_mode(volatile r_canfd_t *reg, uint32_t gmdc_value)
Drive CFDGCTR.GMDC and wait for matching CFDGSTS bit.
Definition ra8_canfd.c:204
ra8_err_t priv_ra8_canfd_internal_set_channel_mode(volatile r_canfd_t *reg, ra8_chmdc_mode_t mode)
Drive CFDC[0].CTR.CHMDC and wait for the matching status bit.
Definition ra8_canfd.c:138
static ra8_err_t internal_wait_status_bit(volatile r_canfd_t *reg, uint8_t status_bit)
Bounded wait on a CFDC[0].STS flag (reset/halt/operation ack).
Definition ra8_canfd.c:96
ra8_err_t ra8_canfd_init(uint8_t channel)
Take a CANFD channel out of reset into operation mode.
Definition ra8_canfd.c:510
static void internal_install_default_afl(volatile r_canfd_t *reg)
Program a default pass-all AFL rule routed into RX FIFO 0.
Definition ra8_canfd.c:259
ra8_err_t ra8_canfd_set_test_mode(uint8_t channel, ra8_ctms_mode_t mode)
Enable a CFDC[0].CTR test mode (basic / listen-only / loopback).
Definition ra8_canfd.c:731
ra8_err_t ra8_canfd_exit_stop(uint8_t channel)
Exit MSTP-gated stop.
Definition ra8_canfd.c:786
ra8_err_t ra8_canfd_get_status(uint8_t channel, uint32_t *out_mask)
Read the channel status register (CFDCnSTS).
Definition ra8_canfd.c:564
@ k_ra8_canfd_afl_per_page
RA8 CANFD afl per page.
Definition ra8_canfd.c:611
ra8_err_t ra8_canfd_attach_handler(ra8_canfd_event_fn_t fn, void *ctx)
Attach a callback for CANFD events (shared across channels).
Definition ra8_canfd.c:585
ra8_err_t ra8_canfd_set_iso_mode(bool enable)
Select ISO 11898-1 vs non-ISO CAN-FD framing.
Definition ra8_canfd.c:761
CANFD Lite driver (bit-timing, TX, RX, error state).
void(* ra8_canfd_event_fn_t)(void *ctx, uint8_t channel, uint32_t status_mask)
CANFD event callback.
Definition ra8_canfd.h:155
CANFD controller register layout for the Renesas RA8D2.
@ k_ra8_gaflp1_bit_gaflfdp0
Route to RX FIFO 0.
@ k_ra8_canfd_dlc_max
4-bit DLC max value (64 bytes).
ra8_chmdc_mode_t
Channel Mode Control (CFDC[0].CTR.CHMDC[1:0]) values.
@ k_ra8_chmdc_operation
Bus operation mode.
@ k_ra8_chmdc_reset
Reset mode.
@ k_ra8_chmdc_halt
Halt mode.
@ k_ra8_canfd_instance_count
Number of CANFD channels.
@ k_ra8_canfd_ptr_mask_dlc
4-bit DLC mask.
@ k_ra8_canfd_ptr_shift_dlc
DLC field shift.
@ k_ra8_gctr_mask_gmdc
2-bit GMDC mask.
@ k_ra8_gctr_value_operation
GMDC = 0: operation.
@ k_ra8_gctr_mask_gslpr
RA8 gctr mask gslpr.
@ k_ra8_gctr_value_halt
GMDC = 2: halt.
@ k_ra8_gctr_value_reset
GMDC = 1: reset.
@ k_ra8_canfd_id_ext_mask
29-bit extended ID.
@ k_ra8_gaflectr_mask_aflpn
RA8 gaflectr mask aflpn.
@ k_ra8_gaflectr_bit_afldae
RA8 gaflectr bit afldae.
@ k_ra8_cnsts_bit_crstst
Channel Reset Status.
@ k_ra8_cnsts_bit_chltst
Channel Halt Status.
@ k_ra8_rfcc_bit_rfe
RFE: enable FIFO.
ra8_ctms_mode_t
Channel Test Mode Select values (CFDC[0].CTR.CTMS[1:0]).
@ k_ra8_ctms_self_test_1
11b: Self-test 1 (internal loopback).
@ k_ra8_cnctr_bit_ctms
Channel Test Mode Select [26:25].
static volatile r_canfd_t * ra8_canfd(uint8_t channel)
Get pointer to CANFD instance N (0..1).
@ k_ra8_gfdcfg_bit_niso
NISO: ISO mode select.
@ k_ra8_gaflcfg0_mask_rnc0
RNC0 field is 5 bits.
@ k_ra8_gaflcfg0_shift_rnc0
Position of RNC0[4:0].
@ k_ra8_canfd_afl_total
16 pages x 16 entries.
@ k_ra8_gaflm_bit_gafllb
Loopback Configuration bit.
@ k_ra8_cnctr_mask_ctme
CTME bit 24.
@ k_ra8_cnctr_mask_ctms
CTMS[1:0] at bits [26:25].
@ k_ra8_cnctr_mask_cslpr
CSLPR (bit 2).
@ k_ra8_cnctr_mask_chmdc
2-bit CHMDC mask.
@ k_ra8_gsts_bit_ghltsts
Global Halt Status.
@ k_ra8_gsts_bit_graminit
Global RAM Initialisation.
@ k_ra8_gsts_bit_grststs
Global Reset Status.
High-level Clock Generation Circuit driver.
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_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
Cross-translation-unit private helpers shared inside ra8_hal.
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
static ra8_err_t ra8_hw_wait_flag_set32(volatile const uint32_t *reg, uint32_t mask, uint32_t budget)
Spin until (*reg & mask) != 0 or budget runs out.
Definition ra8_hw_err.h:309
static ra8_err_t ra8_hw_wait_flag_set8(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:219
static ra8_err_t ra8_hw_wait_flag_clear32(volatile const uint32_t *reg, uint32_t mask, uint32_t budget)
Spin until (*reg & mask) == 0 or budget runs out.
Definition ra8_hw_err.h:351
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
#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
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_canfd1
MSTPC26 CANFD1.
@ k_ra8_mstp_canfd0
MSTPC27 CANFD0.
Scoped PRCR unlock helper.
#define RA8_PROTECTED_WRITE(unlock_val)
Scoped PRCR unlock block.
System Control (SYSC) register layout for the Renesas RA8D2.
@ k_ra8_prcr_unlock_cgc
RA8 prcr unlock cgc.
static volatile uint8_t * ra8_sys_canfdckcr(void)
Get pointer to the 8-bit CANFDCKCR (CANFD core clock source select).
@ k_ra8_usbckcr_bit_srdy
USBCKSRDY – handshake ready.
@ k_ra8_usbckcr_bit_sreq
USBCKSREQ – request switch.
static volatile uint8_t * ra8_sys_canfdckdivcr(void)
Get pointer to the 8-bit CANFDCKDIVCR (CANFD core clock divider).
volatile uint32_t ERFL
+0x00C Channel Error Flag.
volatile uint32_t CTR
+0x004 Channel Control.
volatile uint32_t STS
+0x008 Channel Status.
volatile uint32_t P1
+0x00C GAFLFDP.
volatile uint32_t M
+0x004 GAFLIDM + GAFLIFL1 + GAFLRTRM + IDEM.
volatile uint32_t P0
+0x008 GAFLDLC + GAFLIFL0 + GAFLRMDP + ...
volatile uint32_t ID
+0x000 GAFLID + GAFLLB + GAFLRTR + GAFLIDE.
volatile uint32_t CFDGAFLECTR
CFDGAFLECTR register (offset 0x028).
volatile uint32_t CFDGSTS
CFDGSTS register (offset 0x01C).
volatile uint32_t CFDGFDCFG
CFDGFDCFG register (offset 0x0B0).
volatile uint32_t CFDGCTR
CFDGCTR register (offset 0x018).
r_canfd_cfdgafl_t CFDGAFL[k_ra8_canfd_afl_page_size]
CFDGAFL register (offset 0x120 (0x100)).
volatile uint32_t CFDRFCC[k_ra8_canfd_rx_fifo_count]
CFDRFCC register (offset 0x03C..0x043).
r_canfd_cfdc_t CFDC[1]
CFDC register.
volatile uint32_t CFDGAFLCFG0
CFDGAFLCFG0 register (offset 0x02C).