ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_gpt.c
Go to the documentation of this file.
1
13
14#include "ra8_gpt.h"
15
16#include <stdint.h>
17
18#include "ra8_attributes.h"
19#include "ra8_check.h"
20#include "ra8_dma.h"
21#include "ra8_dmac.h"
22#include "ra8_err.h"
23#include "ra8_gpt_capture.h"
24#include "ra8_gpt_regs.h"
25#include "ra8_log.h"
26#include "ra8_mstp.h"
27
28static const char* s_tag = "GPT";
29
53
58typedef enum : uint32_t {
62
83typedef enum : uint32_t {
84 k_ra8_gptclkcr_bpen = 0x00000001UL,
86
116{
117 static bool s_gpt_clock_inited = false;
118 if (s_gpt_clock_inited) {
119 return;
120 }
121 /* Enable GTCLK source for the GPT block. */
122 /* HUM Ch 22.2.47 "GTCLKCR : Clock Control Register" p 975 */
123 /* HUM Ch 22.10.1 "Clock and Pin Setup" p 1146 */
124 volatile uint32_t* gtclkcr = (volatile uint32_t*)k_ra8_gpt_gtclk_addr;
125 *gtclkcr = (uint32_t)k_ra8_gptclkcr_bpen;
126 s_gpt_clock_inited = true;
127}
128
140typedef enum : uint32_t {
141 k_ra8_gpt_gtcr_cst_set = 0x00000001UL,
144 k_ra8_gpt_gtstr_start = 0x00000001UL,
145 k_ra8_gpt_gtstp_stop = 0x00000001UL,
146 k_ra8_gpt_gtst_mask = 0x000000C3UL,
148
191
207typedef enum : uint32_t {
210 k_ra8_gpt_gtdtcr_tde = 0x00000001UL,
211 k_ra8_gpt_gtcr_cst_mask = 0x00000001UL,
213
231
265
267
268/* internal_gtcr -- see header for full description. */
270{
271 return ((uint32_t)mode << k_ra8_gpt_gtcr_md_shift) | ((uint32_t)ps << k_ra8_gpt_gtcr_tpcs_shift);
272}
273
274ra8_err_t ra8_gpt_start_free_run(uint8_t channel, uint32_t period)
275{
276 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
277 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
278 if (channel >= (uint8_t)k_ra8_gpt_channel_count) {
280 }
281 /* HUM Ch 22.10.1 "Module-Stop Function Setting" p 1146: GTCLKCR
282 * must be programmed BEFORE MSTPCR is cleared, or per-channel
283 * writes silently drop. */
285 /* HUM Ch 11.2.10 "MSTPCRE : Module Stop Control Register E", p 449 */
286 const ra8_err_t mst_err = ra8_mstp_enable(s_gpt_mstp_table[channel]);
287 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
288 RA8_RETURN_ON_ERROR(mst_err, s_tag, "gpt_start: mstp enable");
289 /* GCOVR_EXCL_BR_STOP */
290
292 reg->GTSTP = 1UL; /* Stop if running. */
293 reg->GTCR = 0x00000001UL; /* Saw-wave PWM mode. */
294 reg->GTPR = period;
295 reg->GTCNT = 0U;
296 reg->GTSTR = 1UL; /* Start. */
298
299 ra8_log_info_val(s_tag, "start channel", (uint32_t)channel);
300 return k_ra8_ok;
301}
302
303ra8_err_t ra8_gpt_stop(uint8_t channel)
304{
305 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
306 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
307
309 reg->GTSTP = 1UL;
311 return k_ra8_ok;
312}
313
314ra8_err_t ra8_gpt_read(uint8_t channel, uint32_t* out)
315{
316 RA8_CHECK_NULL_PTR(out, s_tag, "out must not be nullptr");
317 volatile const r_gpt_channel_regs_t* reg = ra8_gpt(channel);
318 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
319
320 *out = reg->GTCNT;
321 return k_ra8_ok;
322}
323
324/* =============================================================================
325 * full build-out
326 * =============================================================================
327 */
328
329ra8_err_t ra8_gpt_init(uint8_t channel, const ra8_gpt_cfg_t* cfg)
330{
331 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
332 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
333 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
334
335 /* HUM Ch 22.10.1 "Module-Stop Function Setting" p 1146: GTCLKCR
336 * must be programmed BEFORE MSTPCR is cleared, or per-channel
337 * writes silently drop. */
339 /* HUM Ch 11.2.10 "MSTPCRE : Module Stop Control Register E", p 449 */
340 const ra8_err_t mst_err = ra8_mstp_enable(s_gpt_mstp_table[channel]);
341 RA8_RETURN_ON_ERROR(mst_err, s_tag, "gpt_init: mstp enable");
342
345 reg->GTCR = internal_gtcr(cfg->mode, cfg->prescaler);
346 reg->GTPR = cfg->period;
347 reg->GTPBR = cfg->period;
348 /* GTCCRA / GTCCRB are PWM compare values for GTIOCnA / GTIOCnB
349 outputs in saw-wave PWM mode. */
350 /* HUM Ch 22.2.20 "GTCCRA..F : General PWM Timer Compare Capture Register" p 938 */
351 reg->GTCCR[0] = cfg->duty_a;
352 reg->GTCCR[1] = cfg->duty_b;
353 reg->GTCNT = 0U;
354 if (cfg->auto_start) {
357 }
359
360 s_gpt_state[channel].configured = true;
361 ra8_log_info_val(s_tag, "init channel", (uint32_t)channel);
362 return k_ra8_ok;
363}
364
365ra8_err_t ra8_gpt_deinit(uint8_t channel)
366{
367 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
368 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
369
372 reg->GTCR = 0U;
374
375 s_gpt_state[channel].fn = nullptr;
376 s_gpt_state[channel].ctx = nullptr;
377 s_gpt_state[channel].configured = false;
378 (void)ra8_mstp_disable(s_gpt_mstp_table[channel]);
379 return k_ra8_ok;
380}
381
382ra8_err_t ra8_gpt_set_period(uint8_t channel, uint32_t period)
383{
384 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
385 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
386
388 reg->GTPR = period;
389 reg->GTPBR = period;
391 return k_ra8_ok;
392}
393
394ra8_err_t ra8_gpt_set_duty(uint8_t channel, ra8_gpt_ccr_sel_t which, uint32_t value)
395{
396 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
397 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
398 if ((uint8_t)which > k_ra8_gpt_ccr_b) {
400 }
401
403 reg->GTCCR[(uint8_t)which] = value;
405 return k_ra8_ok;
406}
407
408ra8_err_t ra8_gpt_get_status(uint8_t channel, uint32_t* out_mask)
409{
410 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
411 volatile const r_gpt_channel_regs_t* reg = ra8_gpt(channel);
412 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
413
414 *out_mask = reg->GTST & k_ra8_gpt_gtst_mask;
415 return k_ra8_ok;
416}
417
418ra8_err_t ra8_gpt_clear_status(uint8_t channel, uint32_t mask)
419{
420 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
421 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
422
423 /* GTST bits are cleared by writing the current value with target bits zero. */
424 const uint32_t current = reg->GTST;
425 reg->GTST = current & ~(mask & k_ra8_gpt_gtst_mask);
426 return k_ra8_ok;
427}
428
430{
431 if (channel >= (uint8_t)k_ra8_gpt_channel_count) {
433 }
434 s_gpt_state[channel].fn = fn;
435 s_gpt_state[channel].ctx = ctx;
436 return k_ra8_ok;
437}
438
440{
441 if (channel >= (uint8_t)k_ra8_gpt_channel_count) {
443 }
444 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
445 if (reg != nullptr) {
449 }
450 return ra8_mstp_disable(s_gpt_mstp_table[channel]);
451}
452
454{
455 if (channel >= (uint8_t)k_ra8_gpt_channel_count) {
457 }
458 return ra8_mstp_enable(s_gpt_mstp_table[channel]);
459}
460
461/* ---- DMA TX / RX ----------------------------------------- */
462
464 const uint32_t* periods,
465 uint16_t count,
466 ra8_dma_complete_fn_t on_complete,
467 void* ctx,
468 uint8_t* out_dma_channel)
469{
470 RA8_CHECK_NULL_PTR(periods, s_tag, "gpt_write_dma: periods");
471 RA8_CHECK_NULL_PTR(out_dma_channel, s_tag, "gpt_write_dma: out_dma_channel");
472 if ((channel >= (uint8_t)k_ra8_gpt_channel_count) || (count == 0U)) {
474 }
475 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
476 /* Word-wide DMA writes stream period values into GTPR;
477 dst_inc=false so every element lands at the same MMIO address. */
478 /* HUM Ch 22.2.21 "GTPR : General PWM Timer Cycle Setting Register" p 938 */
479 ra8_dma_request_t req = {};
480 req.src_addr = (uintptr_t)periods;
481 req.dst_addr = (uintptr_t)&reg->GTPR;
482 req.count = count;
484 req.src_inc = true;
485 req.dst_inc = false;
486 req.trigger = (ra8_elc_event_t)0;
487 req.on_complete = on_complete;
488 req.ctx = ctx;
489 return ra8_dma_request(&req, out_dma_channel);
490}
491
492/* out_counts is written by the DMAC engine. */
494 uint8_t channel,
495 uint32_t*
496 out_counts, // NOLINT(readability-non-const-parameter) -- written by the DMAC engine via dst_addr, never through the pointer.
497 uint16_t count,
498 ra8_dma_complete_fn_t on_complete,
499 void* ctx,
500 uint8_t* out_dma_channel)
501{
502 RA8_CHECK_NULL_PTR(out_counts, s_tag, "gpt_read_dma: out_counts");
503 RA8_CHECK_NULL_PTR(out_dma_channel, s_tag, "gpt_read_dma: out_dma_channel");
504 if ((channel >= (uint8_t)k_ra8_gpt_channel_count) || (count == 0U)) {
506 }
507 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
508 /* Word-wide DMA reads stream GTCNT snapshots into out_counts[]. */
509 /* HUM Ch 22.2.19 "GTCNT : General PWM Timer Counter" p 938 */
510 ra8_dma_request_t req = {};
511 req.src_addr = (uintptr_t)&reg->GTCNT;
512 req.dst_addr = (uintptr_t)out_counts;
513 req.count = count;
515 req.src_inc = false;
516 req.dst_inc = true;
517 req.trigger = (ra8_elc_event_t)0;
518 req.on_complete = on_complete;
519 req.ctx = ctx;
520 return ra8_dma_request(&req, out_dma_channel);
521}
522
523/* =============================================================================
524 * Input capture & external event counting
525 * =============================================================================
526 */
527
528ra8_err_t ra8_gpt_capture_configure(uint8_t channel, ra8_gpt_ccr_sel_t which, uint32_t source_mask)
529{
530 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
531 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
532 if (((uint8_t)which > (uint8_t)k_ra8_gpt_ccr_b) ||
533 ((source_mask & ~(uint32_t)k_ra8_gpt_cap_src_valid_mask) != 0U)) {
535 }
536
537 /* HUM Ch 22.2.1 "GTWP : General PWM Timer Write Protection Register" p 883-884 */
539 if (which == k_ra8_gpt_ccr_a) {
540 /* HUM Ch 22.2.10 "GTICASR : General PWM Timer Input Capture Source Select Register A" p 906-908
541 */
542 reg->GTICASR = source_mask;
543 } else {
544 /* HUM Ch 22.2.11 "GTICBSR : General PWM Timer Input Capture Source Select Register B" p 909-912
545 */
546 reg->GTICBSR = source_mask;
547 }
548 /* HUM Ch 22.2.1 "GTWP : General PWM Timer Write Protection Register" p 883-884 */
550 return k_ra8_ok;
551}
552
553ra8_err_t ra8_gpt_capture_read(uint8_t channel, ra8_gpt_ccr_sel_t which, uint32_t* out_value)
554{
555 RA8_CHECK_NULL_PTR(out_value, s_tag, "out_value must not be nullptr");
556 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
557 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
558 if ((uint8_t)which > (uint8_t)k_ra8_gpt_ccr_b) {
560 }
561
562 /* GTCCRA (index A) and GTCCRB (index B) hold the GTCNT value latched on the
563 last capture edge while GTICASR / GTICBSR is armed. */
564 /* HUM Ch 22.2.20 "GTCCRk : General PWM Timer Compare Capture Register k (k = A to F)" p 938 */
565 *out_value = reg->GTCCR[(uint8_t)which];
566 return k_ra8_ok;
567}
568
569ra8_err_t ra8_gpt_event_count_configure(uint8_t channel, uint32_t up_source, uint32_t down_source)
570{
571 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
572 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
573 if (((up_source & ~(uint32_t)k_ra8_gpt_cnt_src_valid_mask) != 0U) ||
574 ((down_source & ~(uint32_t)k_ra8_gpt_cnt_src_valid_mask) != 0U)) {
576 }
577
578 /* HUM Ch 22.2.1 "GTWP : General PWM Timer Write Protection Register" p 883-884 */
580 /* HUM Ch 22.2.8 "GTUPSR : General PWM Timer Up Count Source Select Register" p 898-901 */
581 reg->GTUPSR = up_source;
582 /* HUM Ch 22.2.9 "GTDNSR : General PWM Timer Down Count Source Select Register" p 902-905 */
583 reg->GTDNSR = down_source;
584 /* HUM Ch 22.2.1 "GTWP : General PWM Timer Write Protection Register" p 883-884 */
586 return k_ra8_ok;
587}
588
589/* =============================================================================
590 * Sweep 3 Task 2 -- runtime PWM duty / period / counter / dead-time / 3-phase
591 * Mirrors FSP r_gpt + r_gpt_three_phase.
592 * =============================================================================
593 */
594
595ra8_err_t ra8_gpt_period_set(uint8_t channel, uint32_t period_counts)
596{
597 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
598 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
599
601 reg->GTPBR = period_counts;
602 /* Per FSP R_GPT_PeriodSet: if the counter is currently stopped,
603 the new period is also written into the live register so the
604 next start has the correct GTPR. */
605 if ((reg->GTCR & k_ra8_gpt_gtcr_cst_mask) == 0U) {
606 reg->GTPR = period_counts;
607 reg->GTCNT = 0U;
608 }
610 return k_ra8_ok;
611}
612
613ra8_err_t ra8_gpt_duty_cycle_set(uint8_t channel, ra8_gpt_pwm_pin_t pin, uint32_t compare_counts)
614{
615 if (pin > k_ra8_gpt_pin_b) {
617 }
618 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
619 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
620
621 /* HUM Ch 22.2.20 "GTCCRA..F" p 938 */ /* + Ch 22.2.17 "GTBER" p 932:
622 write compare into GTCCRC (shadow for A) or GTCCRE (shadow for
623 B), then assert the matching GTBER buffer-enable bit so the
624 next cycle-end reloads GTCCRA / GTCCRB. */
626 if (pin == k_ra8_gpt_pin_a) {
627 reg->GTCCR[k_ra8_gpt_ccr_idx_c] = compare_counts;
629 } else {
630 reg->GTCCR[k_ra8_gpt_ccr_idx_e] = compare_counts;
632 }
634 return k_ra8_ok;
635}
636
637ra8_err_t ra8_gpt_counter_set(uint8_t channel, uint32_t value)
638{
639 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
640 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
641 /* FSP R_GPT_CounterSet rejects writes while the timer is running. */
642 if ((reg->GTCR & k_ra8_gpt_gtcr_cst_mask) != 0U) {
644 }
645
647 reg->GTCNT = value;
649 return k_ra8_ok;
650}
651
670{
671 if (polarity == k_ra8_gpt_pol_active_low) {
673 }
675}
676
679{
680 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
681 if (pin > k_ra8_gpt_pin_b) {
683 }
684 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
685 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
686
687 const uint32_t pattern = internal_gtio_pattern(cfg->polarity);
689 uint32_t gtior = reg->GTIOR;
690
691 if (pin == k_ra8_gpt_pin_a) {
692 /* Clear and re-pack the A-side fields only -- preserve B-side. */
693 gtior &=
695 gtior |= (pattern & k_ra8_gpt_gtioa_mask) << k_ra8_gpt_gtioa_shift;
696 gtior |= ((uint32_t)cfg->stop_level << k_ra8_gpt_oadflt_shift) & k_ra8_gpt_oadflt_mask;
697 if (cfg->output_enable) {
698 gtior |= k_ra8_gpt_oae_mask;
699 }
700 gtior |= ((uint32_t)cfg->disable_on_fault << k_ra8_gpt_oadf_shift) & k_ra8_gpt_oadf_mask;
701 } else {
702 gtior &=
705 gtior |= ((uint32_t)cfg->stop_level << k_ra8_gpt_obdflt_shift) & k_ra8_gpt_obdflt_mask;
706 if (cfg->output_enable) {
707 gtior |= k_ra8_gpt_obe_mask;
708 }
709 gtior |= ((uint32_t)cfg->disable_on_fault << k_ra8_gpt_obdf_shift) & k_ra8_gpt_obdf_mask;
710 }
711 reg->GTIOR = gtior;
713 return k_ra8_ok;
714}
715
716ra8_err_t ra8_gpt_dead_time_set(uint8_t channel, uint32_t rising_dt, uint32_t falling_dt)
717{
718 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
719 RA8_CHECK_NULL_PTR(reg, s_tag, "channel out of range");
720
722 reg->GTDVU = rising_dt;
723 reg->GTDVD = falling_dt;
724 reg->GTDTCR = ((rising_dt != 0U) || (falling_dt != 0U)) ? k_ra8_gpt_gtdtcr_tde : 0U;
726 return k_ra8_ok;
727}
728
729/* ---- Three-phase synchronized PWM ----------------------------------- */
730
745
747
768 uint32_t* out_mask)
769{
770 const uint32_t initial_duties[k_ra8_gpt_three_phase_count] = {
771 cfg->initial_duty_u,
772 cfg->initial_duty_v,
773 cfg->initial_duty_w,
774 };
775 uint32_t mask = 0U;
776 for (uint8_t i = 0U; i < k_ra8_gpt_three_phase_count; ++i) {
777 const ra8_gpt_cfg_t per_ch_cfg = {
778 .mode = cfg->mode,
779 .prescaler = cfg->prescaler,
780 .period = cfg->period_counts,
781 .duty_a = initial_duties[i],
782 .duty_b = initial_duties[i],
783 .auto_start = false,
784 };
785 const ra8_err_t err = ra8_gpt_init(cfg->channels[i], &per_ch_cfg);
786 if (err != k_ra8_ok) {
787 for (uint8_t j = 0U; j < i; ++j) {
788 (void)ra8_gpt_deinit(cfg->channels[j]);
789 }
790 return err;
791 }
792 mask |= (uint32_t)(1UL << cfg->channels[i]);
793 s_three_phase.channels[i] = cfg->channels[i];
794 }
795 *out_mask = mask;
796 return k_ra8_ok;
797}
798
800{
801 RA8_CHECK_NULL_PTR(cfg, s_tag, "three_phase cfg must not be nullptr");
802 if (s_three_phase.open) {
804 }
805 for (uint8_t i = 0U; i < k_ra8_gpt_three_phase_count; ++i) {
806 if (cfg->channels[i] >= (uint8_t)k_ra8_gpt_channel_count) {
808 }
809 }
810
811 uint32_t mask = 0U;
812 const ra8_err_t err = internal_three_phase_init_subs(cfg, &mask);
813 if (err != k_ra8_ok) {
814 return err;
815 }
816
817 /* Synchronous start: a single GTSTR write to the U-channel slot
818 with all three CSTRTn bits set kicks all three counters on the
819 same PCLKD edge. HUM Ch 22.2.2 "GTSTR" p 886. */
820 volatile r_gpt_channel_regs_t* u_reg = ra8_gpt(cfg->channels[0]);
821 if (u_reg != nullptr) {
823 u_reg->GTSTR = mask;
824 u_reg->GTWP = k_ra8_gtwp_key_lock;
825 }
826
827 s_three_phase.channel_mask = mask;
828 s_three_phase.open = true;
829 ra8_log_info_val(s_tag, "three_phase open mask", mask);
830 return k_ra8_ok;
831}
832
833ra8_err_t ra8_gpt_three_phase_set_duty(uint32_t u_duty, uint32_t v_duty, uint32_t w_duty)
834{
835 if (!s_three_phase.open) {
837 }
838 const uint32_t duties[k_ra8_gpt_three_phase_count] = {u_duty, v_duty, w_duty};
839
840 /* Range check against the shared GTPR (read once from U). */
841 volatile const r_gpt_channel_regs_t* u_reg = ra8_gpt(s_three_phase.channels[0]);
842 const uint32_t period = u_reg->GTPR;
843 for (uint8_t i = 0U; i < k_ra8_gpt_three_phase_count; ++i) {
844 if (duties[i] > period) {
846 }
847 }
848
849 for (uint8_t i = 0U; i < k_ra8_gpt_three_phase_count; ++i) {
850 volatile r_gpt_channel_regs_t* reg = ra8_gpt(s_three_phase.channels[i]);
852 reg->GTCCR[k_ra8_gpt_ccr_idx_c] = duties[i];
853 reg->GTCCR[k_ra8_gpt_ccr_idx_e] = duties[i];
856 }
857 return k_ra8_ok;
858}
859
861{
862 if (!s_three_phase.open) {
864 }
865 /* Synchronous stop: single GTSTP write covers all three channels. */
866 volatile r_gpt_channel_regs_t* u_reg = ra8_gpt(s_three_phase.channels[0]);
867 if (u_reg != nullptr) {
869 u_reg->GTSTP = s_three_phase.channel_mask;
870 u_reg->GTWP = k_ra8_gtwp_key_lock;
871 }
872 for (uint8_t i = 0U; i < k_ra8_gpt_three_phase_count; ++i) {
873 (void)ra8_gpt_deinit(s_three_phase.channels[i]);
874 }
875 s_three_phase.channel_mask = 0U;
876 s_three_phase.open = false;
877 return k_ra8_ok;
878}
879
880/* ---- ISR dispatch ---------------------------------------------------- */
881
882/* internal_dispatch -- see header for full description. */
883RA8_INTERNAL static void internal_dispatch(uint8_t channel, uint32_t status_mask)
884{
885 if (channel >= (uint8_t)k_ra8_gpt_channel_count) {
886 return;
887 }
888 volatile r_gpt_channel_regs_t* reg = ra8_gpt(channel);
889 if (reg != nullptr) {
890 const uint32_t current = reg->GTST;
891 reg->GTST = current & ~status_mask;
892 }
893 const ra8_gpt_event_fn_t fn = s_gpt_state[channel].fn;
894 void* const ctx = s_gpt_state[channel].ctx;
895 if (fn != nullptr) {
896 fn(ctx, status_mask);
897 }
898}
899
901void ra8_gpt_dispatch_ovf(uint8_t channel)
902{
904}
905
907void ra8_gpt_dispatch_und(uint8_t channel)
908{
910}
911
913void ra8_gpt_dispatch_ccra(uint8_t channel)
914{
916}
917
919void ra8_gpt_dispatch_ccrb(uint8_t channel)
920{
922}
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).
ra8_board_eth_pin_t pin
Pin.
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
Generic DMA transfer substrate (DMAC engine).
ra8_err_t ra8_dma_request(const ra8_dma_request_t *req, uint8_t *out_channel)
Allocate a DMAC channel, programme it, and start the trigger wiring.
Definition ra8_dma.c:308
void(* ra8_dma_complete_fn_t)(void *ctx)
Caller-supplied completion callback.
Definition ra8_dma.h:88
8-channel DMA controller (DMAC0) driver
@ k_ra8_dmac_width_word
32-bit transfers (DMTMD.SZ = 10b).
Definition ra8_dmac.h:53
ra8_elc_event_t
Partial list of ELC events (populate as drivers need them).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ 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
void ra8_gpt_dispatch_ccrb(uint8_t channel)
Dispatch GPT compare-match B (GTCIB) – clear + fire callback.
Definition ra8_gpt.c:919
ra8_err_t ra8_gpt_pwm_pin_configure(uint8_t channel, ra8_gpt_pwm_pin_t pin, const ra8_gpt_pwm_pin_cfg_t *cfg)
Configure GTIOR for one PWM output pin.
Definition ra8_gpt.c:678
ra8_err_t ra8_gpt_capture_read(uint8_t channel, ra8_gpt_ccr_sel_t which, uint32_t *out_value)
Read the value latched by the last input capture.
Definition ra8_gpt.c:553
ra8_gpt_ccr_idx_t
Index positions inside GTCCR[6] used by the buffer-based duty cycle setter.
Definition ra8_gpt.c:225
@ k_ra8_gpt_ccr_idx_b
RA8 GPT ccr index b.
Definition ra8_gpt.c:227
@ k_ra8_gpt_ccr_idx_c
RA8 GPT ccr index c.
Definition ra8_gpt.c:228
@ k_ra8_gpt_ccr_idx_e
RA8 GPT ccr index e.
Definition ra8_gpt.c:229
@ k_ra8_gpt_ccr_idx_a
RA8 GPT ccr index a.
Definition ra8_gpt.c:226
ra8_err_t ra8_gpt_dead_time_set(uint8_t channel, uint32_t rising_dt, uint32_t falling_dt)
Programme the dead-time value pair for complementary PWM.
Definition ra8_gpt.c:716
static uint32_t internal_gtio_pattern(ra8_gpt_pwm_polarity_t polarity)
Build the GTIO[A/B] sub-field encoding for the requested polarity.
Definition ra8_gpt.c:669
static void internal_dispatch(uint8_t channel, uint32_t status_mask)
Definition ra8_gpt.c:883
ra8_err_t ra8_gpt_start_free_run(uint8_t channel, uint32_t period)
Configure a GPT channel as a free-running up-counter.
Definition ra8_gpt.c:274
static ra8_gpt_state_t s_gpt_state[k_ra8_gpt_channel_count]
Definition ra8_gpt.c:266
static ra8_err_t internal_three_phase_init_subs(const ra8_gpt_three_phase_cfg_t *cfg, uint32_t *out_mask)
Bring up the three GPT submodules and build the start mask.
Definition ra8_gpt.c:767
ra8_err_t ra8_gpt_stop(uint8_t channel)
Stop a GPT channel.
Definition ra8_gpt.c:303
ra8_gtwp_t
GTWP write-protect key.
Definition ra8_gpt.c:58
@ k_ra8_gtwp_key_unlock
Password in upper byte, WP=0.
Definition ra8_gpt.c:59
@ k_ra8_gtwp_key_lock
Password in upper byte, WP=1.
Definition ra8_gpt.c:60
ra8_err_t ra8_gpt_attach_handler(uint8_t channel, ra8_gpt_event_fn_t fn, void *ctx)
Attach a GPT event callback for a channel.
Definition ra8_gpt.c:429
ra8_err_t ra8_gpt_set_period(uint8_t channel, uint32_t period)
Change the GPT period (GTPR / GTPBR) at runtime.
Definition ra8_gpt.c:382
void ra8_gpt_dispatch_und(uint8_t channel)
Dispatch GPT underflow (GTCIU) – clear + fire callback.
Definition ra8_gpt.c:907
ra8_err_t ra8_gpt_set_duty(uint8_t channel, ra8_gpt_ccr_sel_t which, uint32_t value)
Change one compare register (GTCCRA / GTCCRB) at runtime.
Definition ra8_gpt.c:394
ra8_gpt_buffer_bits_t
GTBER bits and GTDTCR bits used by the runtime PWM API.
Definition ra8_gpt.c:207
@ k_ra8_gpt_gtber_ccra_single
RA8 GPT gtber ccra single.
Definition ra8_gpt.c:208
@ k_ra8_gpt_gtdtcr_tde
RA8 GPT gtdtcr tde.
Definition ra8_gpt.c:210
@ k_ra8_gpt_gtber_ccrb_single
RA8 GPT gtber ccrb single.
Definition ra8_gpt.c:209
@ k_ra8_gpt_gtcr_cst_mask
RA8 GPT gtcr cst mask.
Definition ra8_gpt.c:211
ra8_err_t ra8_gpt_write_dma(uint8_t channel, const uint32_t *periods, uint16_t count, ra8_dma_complete_fn_t on_complete, void *ctx, uint8_t *out_dma_channel)
Stream a buffer of period values into GPT GTPR via DMA.
Definition ra8_gpt.c:463
ra8_err_t ra8_gpt_three_phase_set_duty(uint32_t u_duty, uint32_t v_duty, uint32_t w_duty)
Atomically update U/V/W compare values via the shadow buffer.
Definition ra8_gpt.c:833
ra8_err_t ra8_gpt_duty_cycle_set(uint8_t channel, ra8_gpt_pwm_pin_t pin, uint32_t compare_counts)
Update one PWM compare value via the shadow buffer.
Definition ra8_gpt.c:613
ra8_err_t ra8_gpt_read_dma(uint8_t channel, uint32_t *out_counts, uint16_t count, ra8_dma_complete_fn_t on_complete, void *ctx, uint8_t *out_dma_channel)
Capture a stream of GTCNT values into a buffer via DMA.
Definition ra8_gpt.c:493
static const ra8_mstp_t s_gpt_mstp_table[k_ra8_gpt_channel_count]
Channel-index -> MSTP id lookup.
Definition ra8_gpt.c:37
ra8_err_t ra8_gpt_clear_status(uint8_t channel, uint32_t mask)
Clear GTST flag bits (write-0 to clear).
Definition ra8_gpt.c:418
ra8_err_t ra8_gpt_exit_stop(uint8_t channel)
Exit MSTP-gated stop.
Definition ra8_gpt.c:453
ra8_err_t ra8_gpt_three_phase_close(void)
Stop and tear down the three U/V/W channels.
Definition ra8_gpt.c:860
ra8_err_t ra8_gpt_capture_configure(uint8_t channel, ra8_gpt_ccr_sel_t which, uint32_t source_mask)
Arm a GPT channel for input capture on GTCCRA or GTCCRB.
Definition ra8_gpt.c:528
ra8_gpt_bits_t
GTCR / GTSTR / GTSTP / GTST bit positions.
Definition ra8_gpt.c:140
@ k_ra8_gpt_gtst_mask
TCFPU|TCFPO|TCFB|TCFA.
Definition ra8_gpt.c:146
@ k_ra8_gpt_gtcr_cst_set
GTCR.CST start.
Definition ra8_gpt.c:141
@ k_ra8_gpt_gtstp_stop
GTSTP.CSTOP0 write.
Definition ra8_gpt.c:145
@ k_ra8_gpt_gtcr_md_shift
GTCR.MD bit0.
Definition ra8_gpt.c:142
@ k_ra8_gpt_gtstr_start
GTSTR.CSTRT0 write.
Definition ra8_gpt.c:144
@ k_ra8_gpt_gtcr_tpcs_shift
GTCR.TPCS bit0.
Definition ra8_gpt.c:143
ra8_err_t ra8_gpt_three_phase_open(const ra8_gpt_three_phase_cfg_t *cfg)
Open three GPT channels as a phase-synchronized U/V/W triple.
Definition ra8_gpt.c:799
static void internal_gpt_clock_block_init(void)
Block-level GPT clock-control init (one-shot, MSTP-stopped).
Definition ra8_gpt.c:115
ra8_gptclkcr_bits_t
GTCLKCR block-level clock-control bits.
Definition ra8_gpt.c:83
@ k_ra8_gptclkcr_bpen
BPEN: PCLKA <-> GTCLK sync.
Definition ra8_gpt.c:84
void ra8_gpt_dispatch_ccra(uint8_t channel)
Dispatch GPT compare-match A (GTCIA) – clear + fire callback.
Definition ra8_gpt.c:913
void ra8_gpt_dispatch_ovf(uint8_t channel)
Dispatch GPT overflow (GTCIV) – clear + fire callback.
Definition ra8_gpt.c:901
static ra8_gpt_three_phase_state_t s_three_phase
Definition ra8_gpt.c:746
ra8_err_t ra8_gpt_init(uint8_t channel, const ra8_gpt_cfg_t *cfg)
Initialise a GPT channel with a full config descriptor.
Definition ra8_gpt.c:329
ra8_err_t ra8_gpt_counter_set(uint8_t channel, uint32_t value)
Force GTCNT to value (timer must be stopped).
Definition ra8_gpt.c:637
ra8_err_t ra8_gpt_deinit(uint8_t channel)
Tear down a channel (stop + MSTP release).
Definition ra8_gpt.c:365
ra8_gpt_gtior_bits_t
GTIOR field positions and masks.
Definition ra8_gpt.c:173
@ k_ra8_gpt_gtiob_mask
RA8 GPT gtiob mask.
Definition ra8_gpt.c:181
@ k_ra8_gpt_gtio_active_high
RA8 GPT gtio active high.
Definition ra8_gpt.c:188
@ k_ra8_gpt_oadf_shift
RA8 GPT oadf shift.
Definition ra8_gpt.c:180
@ k_ra8_gpt_oadf_mask
RA8 GPT oadf mask.
Definition ra8_gpt.c:179
@ k_ra8_gpt_oadflt_shift
RA8 GPT oadflt shift.
Definition ra8_gpt.c:177
@ k_ra8_gpt_obdflt_mask
RA8 GPT obdflt mask.
Definition ra8_gpt.c:183
@ k_ra8_gpt_gtio_active_low
RA8 GPT gtio active low.
Definition ra8_gpt.c:189
@ k_ra8_gpt_oae_mask
RA8 GPT oae mask.
Definition ra8_gpt.c:178
@ k_ra8_gpt_oadflt_mask
RA8 GPT oadflt mask.
Definition ra8_gpt.c:176
@ k_ra8_gpt_obdflt_shift
RA8 GPT obdflt shift.
Definition ra8_gpt.c:184
@ k_ra8_gpt_gtioa_shift
RA8 GPT gtioa shift.
Definition ra8_gpt.c:175
@ k_ra8_gpt_obdf_shift
RA8 GPT obdf shift.
Definition ra8_gpt.c:187
@ k_ra8_gpt_obdf_mask
RA8 GPT obdf mask.
Definition ra8_gpt.c:186
@ k_ra8_gpt_gtiob_shift
RA8 GPT gtiob shift.
Definition ra8_gpt.c:182
@ k_ra8_gpt_obe_mask
RA8 GPT obe mask.
Definition ra8_gpt.c:185
@ k_ra8_gpt_gtioa_mask
RA8 GPT gtioa mask.
Definition ra8_gpt.c:174
ra8_err_t ra8_gpt_get_status(uint8_t channel, uint32_t *out_mask)
Read GTST overflow / underflow / compare flags.
Definition ra8_gpt.c:408
ra8_err_t ra8_gpt_read(uint8_t channel, uint32_t *out)
Read the current counter value.
Definition ra8_gpt.c:314
static uint32_t internal_gtcr(ra8_gpt_mode_t mode, ra8_gpt_prescaler_t ps)
Definition ra8_gpt.c:269
ra8_err_t ra8_gpt_enter_stop(uint8_t channel)
Put a channel into MSTP-gated stop.
Definition ra8_gpt.c:439
ra8_err_t ra8_gpt_period_set(uint8_t channel, uint32_t period_counts)
Update the GPT period via the shadow buffer (GTPBR).
Definition ra8_gpt.c:595
ra8_err_t ra8_gpt_event_count_configure(uint8_t channel, uint32_t up_source, uint32_t down_source)
Configure external event (edge) counting on GTCNT.
Definition ra8_gpt.c:569
Full-featured General PWM Timer (GPT) driver.
@ k_ra8_gpt_three_phase_count
Number of phases.
Definition ra8_gpt.h:219
ra8_gpt_pwm_pin_t
Selector for the GTIOCnA / GTIOCnB PWM output pins.
Definition ra8_gpt.h:145
@ k_ra8_gpt_pin_b
GTIOCnB – compare register B path.
Definition ra8_gpt.h:147
@ k_ra8_gpt_pin_a
GTIOCnA – compare register A path.
Definition ra8_gpt.h:146
ra8_gpt_ccr_sel_t
Selector for ra8_gpt_set_duty.
Definition ra8_gpt.h:113
@ k_ra8_gpt_ccr_a
GTCCRA.
Definition ra8_gpt.h:114
@ k_ra8_gpt_ccr_b
GTCCRB.
Definition ra8_gpt.h:115
@ k_ra8_gpt_status_ccrb
GTST.TCFB (bit 1).
Definition ra8_gpt.h:104
@ k_ra8_gpt_status_ccra
GTST.TCFA (bit 0).
Definition ra8_gpt.h:103
@ k_ra8_gpt_status_overflow
GTST.TCFPO (bit 6).
Definition ra8_gpt.h:105
@ k_ra8_gpt_status_underflow
GTST.TCFPU (bit 7).
Definition ra8_gpt.h:106
void(* ra8_gpt_event_fn_t)(void *ctx, uint32_t status_mask)
GPT IRQ event callback signature.
Definition ra8_gpt.h:125
ra8_gpt_mode_t
GPT counter-mode selection (GTCR.MD field).
Definition ra8_gpt.h:53
ra8_gpt_pwm_polarity_t
Output polarity for ra8_gpt_pwm_pin_configure.
Definition ra8_gpt.h:159
@ k_ra8_gpt_pol_active_low
Output is low while duty < count.
Definition ra8_gpt.h:161
ra8_gpt_prescaler_t
GTCR.TPCS clock prescaler.
Definition ra8_gpt.h:65
GPT input-capture + external event / pulse-count extension.
@ k_ra8_gpt_cnt_src_valid_mask
bits 0..23: all legal bits.
@ k_ra8_gpt_cap_src_valid_mask
bits 0..24: all legal bits.
General PWM Timer (GPT) register layout for the Renesas RA8D2.
@ k_ra8_gpt_channel_count
RA8 GPT channel count.
@ k_ra8_gpt_gtclk_addr
Shared GTCLK regs.
static volatile r_gpt_channel_regs_t * ra8_gpt(uint8_t channel)
Get pointer to GPT channel N.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
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_gpt2
MSTPE29 GPT2.
@ k_ra8_mstp_gpt11
MSTPE20 GPT11.
@ k_ra8_mstp_gpt3
MSTPE28 GPT3.
@ k_ra8_mstp_gpt10
MSTPE21 GPT10.
@ k_ra8_mstp_gpt4_9
MSTPE27 GPT4..GPT9.
@ k_ra8_mstp_gpt1
MSTPE30 GPT1.
@ k_ra8_mstp_gpt13
MSTPE18 GPT13.
@ k_ra8_mstp_gpt0
MSTPE31 GPT0.
@ k_ra8_mstp_gpt12
MSTPE19 GPT12.
Per-channel GPT register window.
volatile uint32_t GTICBSR
+0x28 Input capture B source select.
volatile uint32_t GTBER
+0x40 Buffer Enable.
volatile uint32_t GTICASR
+0x24 Input capture A source select.
volatile uint32_t GTDNSR
+0x20 Down-count source select.
volatile uint32_t GTPR
+0x64 Period.
volatile uint32_t GTSTP
+0x08 Software Stop.
volatile uint32_t GTPBR
+0x68 Period buffer.
volatile uint32_t GTDVD
+0x90 Dead Time Value D.
volatile uint32_t GTCNT
+0x48 Counter.
volatile uint32_t GTCCR[6]
+0x4C..+0x60 Compare/Capture A..F.
volatile uint32_t GTUPSR
+0x1C Up-count source select.
volatile uint32_t GTIOR
+0x34 I/O Control.
volatile uint32_t GTSTR
+0x04 Software Start.
volatile uint32_t GTWP
+0x00 Write-Protection.
volatile uint32_t GTDTCR
+0x88 Dead Time Control.
volatile uint32_t GTCR
+0x2C Timer Control.
volatile uint32_t GTDVU
+0x8C Dead Time Value U.
volatile uint32_t GTST
+0x3C Status.
Descriptor for a single DMA transfer.
Definition ra8_dma.h:115
ra8_dma_complete_fn_t on_complete
On complete.
Definition ra8_dma.h:123
uintptr_t dst_addr
Dst address.
Definition ra8_dma.h:117
bool dst_inc
Dst inc.
Definition ra8_dma.h:121
ra8_dmac_width_t width
Width.
Definition ra8_dma.h:119
bool src_inc
Src inc.
Definition ra8_dma.h:120
uint16_t count
Count.
Definition ra8_dma.h:118
uintptr_t src_addr
Src address.
Definition ra8_dma.h:116
void * ctx
Ctx.
Definition ra8_dma.h:124
ra8_elc_event_t trigger
Trigger.
Definition ra8_dma.h:122
Configuration descriptor for ra8_gpt_init.
Definition ra8_gpt.h:83
ra8_gpt_prescaler_t prescaler
Clock divider.
Definition ra8_gpt.h:85
uint32_t duty_b
GTCCRB compare/duty (PWM B).
Definition ra8_gpt.h:88
bool auto_start
True -> start after init.
Definition ra8_gpt.h:89
ra8_gpt_mode_t mode
Counter mode.
Definition ra8_gpt.h:84
uint32_t duty_a
GTCCRA compare/duty (PWM A).
Definition ra8_gpt.h:87
uint32_t period
GTPR period.
Definition ra8_gpt.h:86
Configuration descriptor for ra8_gpt_pwm_pin_configure.
Definition ra8_gpt.h:199
ra8_gpt_pwm_polarity_t polarity
Active-high vs active-low.
Definition ra8_gpt.h:201
bool output_enable
OAE / OBE – enable pin.
Definition ra8_gpt.h:200
ra8_gpt_pwm_disable_t disable_on_fault
OADF / OBDF (POEG).
Definition ra8_gpt.h:203
ra8_gpt_pwm_stop_level_t stop_level
OADFLT / OBDFLT.
Definition ra8_gpt.h:202
Per-channel runtime state (callback, configured flag).
Definition ra8_gpt.c:260
bool configured
True after ra8_gpt_init.
Definition ra8_gpt.c:263
ra8_gpt_event_fn_t fn
Registered callback.
Definition ra8_gpt.c:261
void * ctx
Callback context.
Definition ra8_gpt.c:262
Configuration descriptor for ra8_gpt_three_phase_open.
Definition ra8_gpt.h:238
ra8_gpt_mode_t mode
Triangle/saw.
Definition ra8_gpt.h:240
uint32_t initial_duty_u
Initial duty U.
Definition ra8_gpt.h:243
uint32_t period_counts
Shared GTPR.
Definition ra8_gpt.h:242
ra8_gpt_prescaler_t prescaler
Clock div.
Definition ra8_gpt.h:241
uint32_t initial_duty_w
Initial duty W.
Definition ra8_gpt.h:245
uint8_t channels[k_ra8_gpt_three_phase_count]
U/V/W ch ids.
Definition ra8_gpt.h:239
uint32_t initial_duty_v
Initial duty V.
Definition ra8_gpt.h:244
Driver-internal three-phase tracking state.
Definition ra8_gpt.c:740
uint32_t channel_mask
OR of (1<<ch) bits.
Definition ra8_gpt.c:742
uint8_t channels[k_ra8_gpt_three_phase_count]
Channel ids.
Definition ra8_gpt.c:741