ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_vin.c
Go to the documentation of this file.
1
33
34#include "ra8_vin.h"
35
36#include <stdint.h>
37
38#include "ra8_attributes.h"
39#include "ra8_check.h"
40#include "ra8_err.h"
41#include "ra8_hw_err.h"
42#include "ra8_log.h"
43#include "ra8_mstp.h"
44#include "ra8_vin_regs.h"
45
57static const char* s_tag = "VIN";
58
76
88static void* s_vin_ctx;
89
96
102static void* s_vin_frame_ctx;
103
109static void* s_vin_frame_buf;
110
116static uint32_t s_vin_frame_len;
117
139
158
183static uint32_t internal_compose_mc(const ra8_vin_config_t* cfg)
184{
185 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
186 uint32_t mc = 0UL;
187 if (cfg->bypass_csc) {
188 mc |= k_ra8_vin_mc_bps;
189 }
190 if (cfg->big_endian) {
191 mc |= k_ra8_vin_mc_en;
192 }
193 /* IM[4:3] -- interlace mode. */
194 mc |= ((uint32_t)cfg->interlace_mode << k_ra8_vin_mc_shift_im) & k_ra8_vin_mc_im;
195 /* INF[18:16] -- input format. */
196 mc |= ((uint32_t)cfg->input_fmt << k_ra8_vin_mc_shift_inf) & k_ra8_vin_mc_inf;
197 /* CLP[29:28] -- pixel data clipping. */
198 mc |= ((uint32_t)cfg->pixel_clip_mode << k_ra8_vin_mc_shift_clp) & k_ra8_vin_mc_clp;
199 return mc;
200}
201
221static void internal_pulse_st(uint32_t mc_now)
222{
223 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975
224 * Pulse MC.ST = 1 then absorb >= 10 ICLK by reading MC back. */
225 volatile uint32_t* mc_reg = ra8_vin_reg32(k_ra8_vin_off_mc);
226 *mc_reg = mc_now | k_ra8_vin_mc_st;
227 for (uint8_t i = 0U; i < k_ra8_vin_st_settle_reads; ++i) {
228 (void)*mc_reg;
229 }
230}
231
253static void internal_mc_rmw(uint32_t clear_mask, uint32_t set_bits)
254{
255 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
256 volatile uint32_t* mc_reg = ra8_vin_reg32(k_ra8_vin_off_mc);
257 *mc_reg = (*mc_reg & ~clear_mask) | set_bits;
258}
259
260[[nodiscard]] ra8_err_t ra8_vin_init(const ra8_vin_config_t* cfg)
261{
262 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
263 if (cfg->image_stride_px == 0U) {
265 }
266 if (cfg->interlace_mode > k_ra8_vin_max_im) {
268 }
271 }
272
273 /* HUM Ch 11.2.8 "MSTPCRC: Module Stop Control Register C", p 446
274 * VIN shares its module-stop bit with MIPI CSI on the RA8D2. */
276 /* GCOVR_EXCL_BR_START -- MSTP HW readback */
277 RA8_RETURN_ON_ERROR(mst_err, s_tag, "vin_init: mstp enable");
278 /* GCOVR_EXCL_BR_STOP */
279
280 const uint32_t mc_clean = internal_compose_mc(cfg);
281
282 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
283 *ra8_vin_reg32(k_ra8_vin_off_mc) = mc_clean;
284 /* HUM Ch 67.2.3 "FC: Frame Capture Register" p 3979 */
286
287 /* HUM Ch 67.2.13 "IS: Image Stride Register" p 3984 */
289 /* HUM Ch 67.2.10 "MB1: Memory Base 1 Register" p 3985 */
291 /* HUM Ch 67.2.11 "MB2: Memory Base 2 Register" p 3986 */
293 /* HUM Ch 67.2.12 "MB3: Memory Base 3 Register" p 3987 */
295
296 /* HUM Ch 67.2.15 "IE: Interrupt Enable Register" p 3987 */
298 /* HUM Ch 67.2.17 "SI: Scanline Interrupt Register" p 3991 */
300 /* HUM Ch 67.2.16 "INTS: Interrupt Status Register" p 3989
301 * Clear all latched W1C bits left over from a previous run. */
303
304 ra8_log_info_val(s_tag, "vin_init mb1", cfg->framebuffer_addr_1);
305 return k_ra8_ok;
306}
307
308[[nodiscard]] ra8_err_t ra8_vin_deinit(void)
309{
310 /* HUM Ch 67.2.3 "FC: Frame Capture Register" p 3979 */
312 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
314 /* HUM Ch 67.2.15 "IE: Interrupt Enable Register" p 3987 */
316 /* HUM Ch 67.2.16 "INTS: Interrupt Status Register" p 3989 */
318
319 s_vin_fn = nullptr;
320 s_vin_ctx = nullptr;
321 s_vin_frame_fn = nullptr;
322 s_vin_frame_ctx = nullptr;
323 s_vin_frame_buf = nullptr;
324 s_vin_frame_len = 0U;
325
326 /* HUM Ch 11.2.8 "MSTPCRC: Module Stop Control Register C", p 446 */
328}
329
330[[nodiscard]] ra8_err_t ra8_vin_reset(void)
331{
332 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975
333 * Clear ME first so the ST pulse re-initialises a stopped pipeline. */
334 volatile uint32_t* mc_reg = ra8_vin_reg32(k_ra8_vin_off_mc);
335 const uint32_t mc_now = *mc_reg & ~k_ra8_vin_mc_me;
336 *mc_reg = mc_now;
337 internal_pulse_st(mc_now);
338 ra8_log_info(s_tag, "vin_reset");
339 return k_ra8_ok;
340}
341
343{
344 if ((mode != k_ra8_vin_capture_single) && (mode != k_ra8_vin_capture_continuous) &&
347 }
348 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
349 volatile uint32_t* mc_reg = ra8_vin_reg32(k_ra8_vin_off_mc);
350 /* HUM Ch 67.2.3 "FC: Frame Capture Register" p 3979 */
351 volatile uint32_t* fc_reg = ra8_vin_reg32(k_ra8_vin_off_fc);
352
353 const uint32_t mc_now = *mc_reg;
354 const uint32_t fc_now = *fc_reg;
355 // mcdc-deactivated: ra8_vin idle-state guard; MC.ME (module enable) and FC.CC (capture continuous) are set together by the public-API ra8_vin_capture_start sequence and cleared together by ra8_vin_capture_stop, so the two condition bits are co-dependent in normal operation -- no MC/DC vector can flip one without the other on a quiescent capture controller.
356 if (((mc_now & k_ra8_vin_mc_me) != 0UL) || ((fc_now & k_ra8_vin_fc_cc) != 0UL)) {
358 }
359
360 /* HUM Ch 67.3.1 "Initialization Procedure" p 3995 */
361 internal_pulse_st(mc_now);
362
363 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975
364 * Set ME = 1 (and re-clear ST -- it is write-only). */
365 *mc_reg = mc_now | k_ra8_vin_mc_me;
366
368 /* HUM Ch 67.2.3 "FC: Frame Capture Register" p 3979 */
369 *fc_reg = k_ra8_vin_fc_cc;
370 }
371
372 ra8_log_info_val(s_tag, "vin_capture_start mode", (uint32_t)mode);
373 return k_ra8_ok;
374}
375
377{
378 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
379 volatile uint32_t* mc_reg = ra8_vin_reg32(k_ra8_vin_off_mc);
380 /* HUM Ch 67.2.3 "FC: Frame Capture Register" p 3979 */
381 volatile uint32_t* fc_reg = ra8_vin_reg32(k_ra8_vin_off_fc);
382
383 const uint32_t mc_now = *mc_reg;
384 if ((mc_now & k_ra8_vin_mc_me) == 0UL) {
386 }
387
388 /* HUM Ch 67.2.3 "FC: Frame Capture Register" p 3979 */
389 *fc_reg = 0UL;
390 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
391 *mc_reg = mc_now & ~k_ra8_vin_mc_me;
392
393 /* HUM Ch 67.2.18 "MTCSTOP: AXI Transfer Stop Control Register" p 3991
394 * Force any outstanding AXI writes to drain so the caller can safely
395 * recycle the frame buffer once OUTSTAND reaches 0. */
396 volatile uint32_t* mtc_reg = ra8_vin_reg32(k_ra8_vin_off_mtcstop);
397 *mtc_reg = k_ra8_vin_mtcstop_req;
398
399 /* Bounded poll for OUTSTAND -> 0 (NASA Rule 2). */
400 const ra8_err_t err = ra8_hw_wait_flag_clear32(mtc_reg,
402 (uint32_t)k_ra8_vin_stop_drain_max);
403 ra8_log_info(s_tag, "vin_capture_stop");
404 return err;
405}
406
408{
409 RA8_CHECK_NULL_PTR(window, s_tag, "preclip must not be nullptr");
410 if ((window->line_end < window->line_start) || (window->pixel_end < window->pixel_start)) {
412 }
413 if ((((uint32_t)window->line_end | (uint32_t)window->line_start | (uint32_t)window->pixel_end |
414 (uint32_t)window->pixel_start) &
415 ~k_ra8_vin_preclip_mask) != 0UL) {
417 }
418 /* HUM Ch 67.2.4 "SLPRC: Pre-Clip Start Line Register" p 3980 */
419 *ra8_vin_reg32(k_ra8_vin_off_slprc) = (uint32_t)window->line_start;
420 /* HUM Ch 67.2.5 "ELPRC: Pre-Clip End Line Register" p 3980 */
421 *ra8_vin_reg32(k_ra8_vin_off_elprc) = (uint32_t)window->line_end;
422 /* HUM Ch 67.2.6 "SPPRC: Pre-Clip Start Pixel Register" p 3981 */
423 *ra8_vin_reg32(k_ra8_vin_off_spprc) = (uint32_t)window->pixel_start;
424 /* HUM Ch 67.2.7 "EPPRC: Pre-Clip End Pixel Register" p 3981 */
425 *ra8_vin_reg32(k_ra8_vin_off_epprc) = (uint32_t)window->pixel_end;
426 return k_ra8_ok;
427}
428
430{
431 RA8_CHECK_NULL_PTR(scale, s_tag, "scale must not be nullptr");
432 if ((scale->v_mantissa > (uint8_t)k_ra8_vin_uds_max_mant) ||
433 (scale->h_mantissa > (uint8_t)k_ra8_vin_uds_max_mant) ||
437 }
438 /* HUM Ch 67.2.22 "UDS_SCALE: Scaling Factor Register" p 3998 */
439 uint32_t v =
445 return k_ra8_ok;
446}
447
448[[nodiscard]] ra8_err_t ra8_vin_set_uds_passband(uint8_t v_bwidth, uint8_t h_bwidth)
449{
450 if ((v_bwidth > (uint8_t)k_ra8_vin_uds_max_bw) || (h_bwidth > (uint8_t)k_ra8_vin_uds_max_bw)) {
452 }
453 /* HUM Ch 67.2.23 "UDS_PASS_BWIDTH: Passband Register" p 4001 */
454 uint32_t v = ((uint32_t)v_bwidth << k_ra8_vin_uds_bwidth_shift_v) & k_ra8_vin_uds_bwidth_v;
455 v |= ((uint32_t)h_bwidth << k_ra8_vin_uds_bwidth_shift_h) & k_ra8_vin_uds_bwidth_h;
457 return k_ra8_ok;
458}
459
460[[nodiscard]] ra8_err_t ra8_vin_set_uds_clip(uint16_t v_size, uint16_t h_size)
461{
462 if ((v_size > k_ra8_vin_uds_max_clip) || (h_size > k_ra8_vin_uds_max_clip)) {
464 }
465 /* HUM Ch 67.2.24 "UDS_CLIP_SIZE: Output Size Clipping Register" p 4002 */
466 uint32_t v = ((uint32_t)v_size << k_ra8_vin_uds_clip_shift_v) & k_ra8_vin_uds_clip_v;
467 v |= ((uint32_t)h_size << k_ra8_vin_uds_clip_shift_h) & k_ra8_vin_uds_clip_h;
469 return k_ra8_ok;
470}
471
473{
474 RA8_CHECK_NULL_PTR(ctrl, s_tag, "ctrl must not be nullptr");
475 /* HUM Ch 67.2.21 "UDS_CTRL: Scaling Control Register" p 3997 */
476 uint32_t v = 0UL;
477 if (ctrl->b_cb_nearest) {
479 }
480 if (ctrl->g_y_nearest) {
482 }
483 if (ctrl->r_cr_nearest) {
485 }
486 if (ctrl->multitap) {
488 }
489 if (ctrl->advanced_bl) {
491 }
492 if (ctrl->advanced_amd) {
494 }
496 return k_ra8_ok;
497}
498
499[[nodiscard]] ra8_err_t ra8_vin_enable_scaling(bool enable)
500{
501 uint32_t scle_bits = 0UL;
502 if (enable) {
503 scle_bits = k_ra8_vin_mc_scle;
504 }
506 return k_ra8_ok;
507}
508
509[[nodiscard]] ra8_err_t ra8_vin_lut_program(const uint8_t* y_table,
510 const uint8_t* cb_table,
511 const uint8_t* cr_table,
512 bool enable)
513{
514 RA8_CHECK_NULL_PTR(y_table, s_tag, "y_table must not be nullptr");
515 const uint8_t* cb = (cb_table != nullptr) ? cb_table : y_table;
516 const uint8_t* cr = (cr_table != nullptr) ? cr_table : y_table;
517
518 for (uint16_t i = 0U; i < k_ra8_vin_lut_entries; ++i) {
519 /* HUM Ch 67.2.25 "LUTP: Look Up Table Pointer Register" p 4003 */
520 uint32_t lutp = ((uint32_t)i << k_ra8_vin_lutp_shift_ltypr) & k_ra8_vin_lutp_ltypr;
521 lutp |= ((uint32_t)i << k_ra8_vin_lutp_shift_ltcbpr) & k_ra8_vin_lutp_ltcbpr;
522 lutp |= ((uint32_t)i << k_ra8_vin_lutp_shift_ltcrpr) & k_ra8_vin_lutp_ltcrpr;
524
525 /* HUM Ch 67.2.26 "LUTD: Look Up Table Data Register" p 4004 */
526 uint32_t lutd = ((uint32_t)y_table[i] << k_ra8_vin_lutd_shift_ltydt) & k_ra8_vin_lutd_ltydt;
527 lutd |= ((uint32_t)cb[i] << k_ra8_vin_lutd_shift_ltcbdt) & k_ra8_vin_lutd_ltcbdt;
528 lutd |= ((uint32_t)cr[i] << k_ra8_vin_lutd_shift_ltcrdt) & k_ra8_vin_lutd_ltcrdt;
530 }
531 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
532 uint32_t lute_bits = 0UL;
533 if (enable) {
534 lute_bits = k_ra8_vin_mc_lute;
535 }
537 return k_ra8_ok;
538}
539
541{
542 RA8_CHECK_NULL_PTR(coeffs, s_tag, "coeffs must not be nullptr");
543 /* HUM Ch 67.2.36 "CSCE1" p 3995 */
544 uint32_t csce1 = (uint32_t)coeffs->y_multiplier & k_ra8_vin_csce1_ymul2;
545 if (coeffs->enable_round) {
546 csce1 |= k_ra8_vin_csce1_round;
547 }
549
550 /* HUM Ch 67.2.37 "CSCE2" p 3995 */
551 uint32_t csce2 = (uint32_t)coeffs->cbcr_sub & k_ra8_vin_csce2_csub2;
552 csce2 |= ((uint32_t)coeffs->y_sub << k_ra8_vin_csce2_shift_ysub2) & k_ra8_vin_csce2_ysub2;
554
555 /* HUM Ch 67.2.38 "CSCE3" p 3996 */
556 uint32_t csce3 = (uint32_t)coeffs->cr_mul_lo & k_ra8_vin_csce_mul_lo;
557 csce3 |= ((uint32_t)coeffs->cr_mul_hi << k_ra8_vin_csce_shift_mul_hi) & k_ra8_vin_csce_mul_hi;
559
560 /* HUM Ch 67.2.39 "CSCE4" p 3996 */
561 uint32_t csce4 = (uint32_t)coeffs->cb_mul_lo & k_ra8_vin_csce_mul_lo;
562 csce4 |= ((uint32_t)coeffs->cb_mul_hi << k_ra8_vin_csce_shift_mul_hi) & k_ra8_vin_csce_mul_hi;
564 return k_ra8_ok;
565}
566
590static void
592{
593 /* HUM Ch 67.2.27 "YCCR1: RGB-to-Y Coefficient R" p 4002-4011 */
594 if (channel == 0U) {
595 *off1 = k_ra8_vin_off_yccr1;
596 *off2 = k_ra8_vin_off_yccr2;
597 *off3 = k_ra8_vin_off_yccr3;
598 } else if (channel == 1U) {
599 *off1 = k_ra8_vin_off_cbccr1;
600 *off2 = k_ra8_vin_off_cbccr2;
601 *off3 = k_ra8_vin_off_cbccr3;
602 } else {
603 *off1 = k_ra8_vin_off_crccr1;
604 *off2 = k_ra8_vin_off_crccr2;
605 *off3 = k_ra8_vin_off_crccr3;
606 }
607}
608
609[[nodiscard]] ra8_err_t ra8_vin_set_rgb_to_yc(uint8_t channel, const ra8_vin_rgb_to_yc_chan_t* row)
610{
611 RA8_CHECK_NULL_PTR(row, s_tag, "row must not be nullptr");
612 if (channel > k_ra8_vin_yc_chan_max) {
614 }
615 if (row->shift_down > k_ra8_vin_max_lsft) {
617 }
621 internal_yc_offsets(channel, &off1, &off2, &off3);
622
623 /* HUM Ch 67.2.27 "YCCR1: RGB-to-Y Coefficient R" p 4002-4010 */
624 *ra8_vin_reg32(off1) = (uint32_t)row->r_coeff & k_ra8_vin_yc1_rp;
625
626 /* HUM Ch 67.2.28 "YCCR2: RGB-to-Y Coefficient G+B" p 4003-4010 */
627 uint32_t s2 = (uint32_t)row->g_coeff & k_ra8_vin_yc2_gp;
628 s2 |= ((uint32_t)row->b_coeff << k_ra8_vin_yccr_shift_bp) & k_ra8_vin_yc2_bp;
629 *ra8_vin_reg32(off2) = s2;
630
631 /* HUM Ch 67.2.29 "YCCR3: RGB-to-Y Normalization" p 4004-4011 */
632 uint32_t s3 = (uint32_t)row->add_offset & k_ra8_vin_yc3_ap;
633 if (row->enable_hen) {
634 s3 |= k_ra8_vin_yc3_hen;
635 }
636 s3 |= ((uint32_t)row->shift_down << k_ra8_vin_yccr_shift_sft) & k_ra8_vin_yc3_sft;
637 *ra8_vin_reg32(off3) = s3;
638 return k_ra8_ok;
639}
640
641[[nodiscard]] ra8_err_t ra8_vin_set_dithering(uint8_t mode, bool direction)
642{
643 if (mode > k_ra8_vin_max_dc) {
645 }
646 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975
647 * DC[15:14] dithering mode + DC2[24] direction. */
648 const uint32_t dc_bits = ((uint32_t)mode << k_ra8_vin_mc_shift_dc) & k_ra8_vin_mc_dc;
649 uint32_t dc2_bits = 0UL;
650 if (direction) {
651 dc2_bits = k_ra8_vin_mc_dc2;
652 }
653 internal_mc_rmw(k_ra8_vin_mc_dc | k_ra8_vin_mc_dc2, dc_bits | dc2_bits);
654 return k_ra8_ok;
655}
656
657[[nodiscard]] ra8_err_t ra8_vin_set_yuv444_mode(uint8_t mode)
658{
659 if (mode > k_ra8_vin_max_yuv444) {
661 }
662 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
664 return k_ra8_ok;
665}
666
667[[nodiscard]] ra8_err_t ra8_vin_set_interlace_mode(uint8_t mode)
668{
669 if (mode > k_ra8_vin_max_im) {
671 }
672 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
674 return k_ra8_ok;
675}
676
678{
679 RA8_CHECK_NULL_PTR(mode, s_tag, "mode must not be nullptr");
680 if ((mode->conv_mode > k_ra8_vin_max_dtmd) || (mode->y_mode > k_ra8_vin_max_ymode)) {
682 }
683 /* HUM Ch 67.2.19 "DMR: Data Mode Register" p 3992 */
684 uint32_t v = ((uint32_t)mode->conv_mode << k_ra8_vin_dmr_shift_dtmd) & k_ra8_vin_dmr_dtmd;
685 if (mode->alpha_bit) {
687 }
688 if (mode->byte_swap) {
690 }
691 if (mode->extend_rgb) {
693 }
694 if (mode->yc_through) {
696 }
697 v |= ((uint32_t)mode->y_mode << k_ra8_vin_dmr_shift_ymode) & k_ra8_vin_dmr_ymode;
698 v |= ((uint32_t)mode->alpha_byte << k_ra8_vin_dmr_shift_a8bit) & k_ra8_vin_dmr_a8bit;
700 return k_ra8_ok;
701}
702
704{
705 RA8_CHECK_NULL_PTR(input, s_tag, "input must not be nullptr");
706 if ((input->virtual_channel > k_ra8_vin_max_vc_sel) || (input->data_type > k_ra8_vin_max_dt)) {
708 }
709 /* HUM Ch 67.2.8 "CSI_IFMD: CSI2 Interface Mode Register" p 3982 */
710 uint32_t v = ((uint32_t)input->virtual_channel << k_ra8_vin_csi_ifmd_shift_vc_sel) &
713 if (input->zero_extend) {
715 }
717 return k_ra8_ok;
718}
719
721{
722 RA8_CHECK_NULL_PTR(detect, s_tag, "detect must not be nullptr");
725 }
726 /* HUM Ch 67.2.9 "CSIFLD: Field Detection Control Register" p 3983 */
727 uint32_t v = 0UL;
728 if (detect->enable) {
730 }
731 if (detect->even_field_sel) {
733 }
734 if (detect->even_field_num != 0U) {
736 }
738 return k_ra8_ok;
739}
740
741[[nodiscard]] ra8_err_t ra8_vin_set_framebuffers(uint32_t mb1, uint32_t mb2, uint32_t mb3)
742{
743 if ((mb1 == 0U) && (mb2 == 0U) && (mb3 == 0U)) {
745 }
746 if (((mb1 & k_ra8_vin_mb_align_mask) != 0UL) || ((mb2 & k_ra8_vin_mb_align_mask) != 0UL) ||
747 ((mb3 & k_ra8_vin_mb_align_mask) != 0UL)) {
749 }
750 if (mb1 != 0U) {
751 /* HUM Ch 67.2.10 "MB1: Memory Base 1 Register" p 3985 */
753 }
754 if (mb2 != 0U) {
755 /* HUM Ch 67.2.11 "MB2: Memory Base 2 Register" p 3986 */
757 }
758 if (mb3 != 0U) {
759 /* HUM Ch 67.2.12 "MB3: Memory Base 3 Register" p 3987 */
761 }
762 return k_ra8_ok;
763}
764
765[[nodiscard]] ra8_err_t ra8_vin_set_uv_offset(uint32_t uv_addr)
766{
767 if ((uv_addr & k_ra8_vin_mb_align_mask) != 0UL) {
769 }
770 /* HUM Ch 67.2.20 "UVAOF: UV Address Offset Register" p 3994 */
772 return k_ra8_ok;
773}
774
775[[nodiscard]] ra8_err_t ra8_vin_get_status(uint32_t* out_mask)
776{
777 RA8_CHECK_NULL_PTR(out_mask, s_tag, "out_mask must not be nullptr");
778 /* HUM Ch 67.2.16 "INTS: Interrupt Status Register" p 3989 */
779 *out_mask = *ra8_vin_reg32(k_ra8_vin_off_ints);
780 return k_ra8_ok;
781}
782
783[[nodiscard]] ra8_err_t ra8_vin_clear_status(uint32_t mask)
784{
785 /* HUM Ch 67.2.16 "INTS: Interrupt Status Register" p 3989
786 * Only FOS / ARES / FIS2 are W1C; gate other bits to avoid
787 * accidentally toggling state bits the hardware owns. */
788 const uint32_t w1c = mask & k_ra8_vin_int_w1c_mask;
790 return k_ra8_ok;
791}
792
794{
795 RA8_CHECK_NULL_PTR(out_status, s_tag, "out_status must not be nullptr");
796 /* HUM Ch 67.2.2 "MS: Module Status Register" p 3978 */
797 const uint32_t v = *ra8_vin_reg32(k_ra8_vin_off_ms);
798 out_status->capture_active = ((v & k_ra8_vin_ms_ca) != 0UL);
799 out_status->active_video = ((v & k_ra8_vin_ms_av) != 0UL);
800 out_status->even_field = ((v & k_ra8_vin_ms_fs) != 0UL);
801 out_status->frame_buffer_id = (uint8_t)((v & k_ra8_vin_ms_fbs) >> k_ra8_vin_ms_shift_fbs);
802 out_status->memory_active = ((v & k_ra8_vin_ms_ma) != 0UL);
803 out_status->latest_frame_buffer = (uint8_t)((v & k_ra8_vin_ms_fms) >> k_ra8_vin_ms_shift_fms);
804 return k_ra8_ok;
805}
806
807[[nodiscard]] ra8_err_t ra8_vin_get_line_count(uint16_t* out_count)
808{
809 RA8_CHECK_NULL_PTR(out_count, s_tag, "out_count must not be nullptr");
810 /* HUM Ch 67.2.14 "LC: Line Count Register" p 3987 */
811 *out_count = (uint16_t)(*ra8_vin_reg32(k_ra8_vin_off_lc) & k_ra8_vin_lc_mask);
812 return k_ra8_ok;
813}
814
815[[nodiscard]] ra8_err_t ra8_vin_get_active_buffer(uint8_t* out_id)
816{
817 RA8_CHECK_NULL_PTR(out_id, s_tag, "out_id must not be nullptr");
818 /* HUM Ch 67.2.2 "MS: Module Status Register" p 3978 */
819 const uint32_t v = *ra8_vin_reg32(k_ra8_vin_off_ms);
820 *out_id = (uint8_t)((v & k_ra8_vin_ms_fbs) >> k_ra8_vin_ms_shift_fbs);
821 return k_ra8_ok;
822}
823
824[[nodiscard]] ra8_err_t ra8_vin_set_interrupt_enable(uint32_t mask)
825{
826 /* HUM Ch 67.2.15 "IE: Interrupt Enable Register" p 3987 */
828 return k_ra8_ok;
829}
830
831[[nodiscard]] ra8_err_t ra8_vin_set_scanline_compare(uint16_t line)
832{
833 if (line > (uint16_t)k_ra8_vin_si_mask) {
835 }
836 /* HUM Ch 67.2.17 "SI: Scanline Interrupt Register" p 3991 */
837 *ra8_vin_reg32(k_ra8_vin_off_si) = (uint32_t)line;
838 return k_ra8_ok;
839}
840
842{
843 s_vin_fn = fn;
844 s_vin_ctx = ctx;
845 return k_ra8_ok;
846}
847
850{
851 /* HUM Ch 67.2.16 "INTS: Interrupt Status Register" p 3989 */
852 volatile uint32_t* reg = ra8_vin_reg32(k_ra8_vin_off_ints);
853 const uint32_t mask = *reg;
854
855 const ra8_vin_event_fn_t fn = s_vin_fn;
856 void* const ctx = s_vin_ctx;
857 if (fn != nullptr) {
858 fn(ctx, mask);
859 }
860
861 /* Sweep 17: route FME (frame memory complete) into the frame-end
862 * callback registered via `ra8_vin_attach_frame_handler`. */
863 if ((mask & k_ra8_vin_int_fme) != 0UL) {
864 const ra8_vin_frame_fn_t frame_fn = s_vin_frame_fn;
865 void* const frame_ctx = s_vin_frame_ctx;
866 if (frame_fn != nullptr) {
867 frame_fn(frame_ctx, s_vin_frame_buf, s_vin_frame_len);
868 }
869 }
870
871 /* HUM Ch 67.2.16 "INTS: Interrupt Status Register" p 3989
872 * Acknowledge the W1C subset (FOS / ARES / FIS2). */
873 *reg = mask & k_ra8_vin_int_w1c_mask;
874}
875
876[[nodiscard]] ra8_err_t ra8_vin_enter_stop(void)
877{
878 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */
879 volatile uint32_t* mc_reg = ra8_vin_reg32(k_ra8_vin_off_mc);
880 *mc_reg = *mc_reg & ~k_ra8_vin_mc_me;
881 /* HUM Ch 67.2.3 "FC: Frame Capture Register" p 3979 */
883
884 /* HUM Ch 11.2.8 "MSTPCRC: Module Stop Control Register C", p 446 */
886}
887
888[[nodiscard]] ra8_err_t ra8_vin_exit_stop(void)
889{
890 /* HUM Ch 11.2.8 "MSTPCRC: Module Stop Control Register C", p 446 */
892}
893
894/* =============================================================================
895 * Sweep 17: dynamic capture window + frame-end IRQ
896 * =============================================================================
897 */
898
903typedef enum : uint16_t {
906
916
917/* Resolve bytes-per-pixel for a given input format -- see implementation for details. */
920{
921 uint8_t bpp = k_ra8_vin_bpp_ycbcr422;
922 if (format == k_ra8_vin_input_raw8) {
923 bpp = k_ra8_vin_bpp_raw8;
924 } else if (format == k_ra8_vin_input_rgb888) {
926 } else {
928 }
929 return bpp;
930}
931
932[[nodiscard]] ra8_err_t
933ra8_vin_capture_start(void* buf, uint16_t w, uint16_t h, ra8_vin_input_fmt_t format)
934{
935 RA8_CHECK_NULL_PTR(buf, s_tag, "buf must not be nullptr");
936 if ((w == 0U) || (h == 0U) || (w > k_ra8_vin_geom_max_dim) || (h > k_ra8_vin_geom_max_dim)) {
938 }
939 if (((uintptr_t)buf & k_ra8_vin_mb_align_mask) != 0U) {
941 }
942
943 /* HUM Ch 67.2.10 "MB1: Memory Base 1 Register" p 3985 */
944 *ra8_vin_reg32(k_ra8_vin_off_mb1) = (uint32_t)(uintptr_t)buf;
945 /* HUM Ch 67.2.13 "IS: Image Stride Register" p 3984 */
946 *ra8_vin_reg32(k_ra8_vin_off_is) = (uint32_t)w;
947
948 /* HUM Ch 67.2.1 "MC: Main Control Register" p 3975 */ /* update INF only. */
950 ((uint32_t)format << k_ra8_vin_mc_shift_inf) & k_ra8_vin_mc_inf);
951
952 /* Cache geometry for the frame-end callback. */
953 s_vin_frame_buf = buf;
954 s_vin_frame_len = (uint32_t)w * (uint32_t)h * (uint32_t)internal_format_bpp(format);
955
957}
958
960{
961 return ra8_vin_capture_disarm();
962}
963
964[[nodiscard]] ra8_err_t ra8_vin_set_window(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
965{
966 if ((w == 0U) || (h == 0U)) {
968 }
969 const uint32_t pixel_end = (uint32_t)x + (uint32_t)w - 1U;
970 const uint32_t line_end = (uint32_t)y + (uint32_t)h - 1U;
971 if ((pixel_end > k_ra8_vin_preclip_mask) || (line_end > k_ra8_vin_preclip_mask)) {
973 }
974 const ra8_vin_preclip_t window = {
975 .line_start = y,
976 .line_end = (uint16_t)line_end,
977 .pixel_start = x,
978 .pixel_end = (uint16_t)pixel_end,
979 };
980 return ra8_vin_set_preclip(&window);
981}
982
984{
985 s_vin_frame_fn = fn;
986 s_vin_frame_ctx = ctx;
987 return k_ra8_ok;
988}
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_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
Bounded wait-flag primitives for RA8D2 HAL drivers.
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
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_mipi_csi
MSTPC17 MIPI CSI.
ra8_err_t ra8_vin_set_window(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
Programme a region-of-interest pre-clip window.
Definition ra8_vin.c:964
ra8_vin_local_t
File-scope magic-free constants.
Definition ra8_vin.c:126
@ k_ra8_vin_max_ymode
DMR.YMODE legal max (0..3).
Definition ra8_vin.c:132
@ k_ra8_vin_max_lsft
Setting 3 LSFT 5-bit max.
Definition ra8_vin.c:136
@ k_ra8_vin_max_yuv444
MC.YUV444 legal max.
Definition ra8_vin.c:130
@ k_ra8_vin_max_im
MC.IM legal max (0..2).
Definition ra8_vin.c:127
@ k_ra8_vin_max_vc_sel
CSI_IFMD.VC_SEL 4-bit max.
Definition ra8_vin.c:133
@ k_ra8_vin_max_dt
CSI_IFMD.DT 6-bit max.
Definition ra8_vin.c:134
@ k_ra8_vin_max_field_no
CSIFLD.FLD_NUM legal max.
Definition ra8_vin.c:135
@ k_ra8_vin_max_dtmd
DMR.DTMD legal max (0..2).
Definition ra8_vin.c:131
@ k_ra8_vin_max_clp
MC.CLP legal max (0..3 with 2 reserved).
Definition ra8_vin.c:129
@ k_ra8_vin_yc_chan_max
RGB-to-YC channel index max (0..2).
Definition ra8_vin.c:137
@ k_ra8_vin_max_dc
MC.DC legal max (0..2).
Definition ra8_vin.c:128
ra8_err_t ra8_vin_set_data_mode(const ra8_vin_data_mode_t *mode)
Programme the DMR (Data Mode Register).
Definition ra8_vin.c:677
ra8_err_t ra8_vin_set_yc_to_rgb(const ra8_vin_yc_to_rgb_t *coeffs)
Programme the YC -> RGB matrix coefficients (CSCE1..4).
Definition ra8_vin.c:540
static void * s_vin_frame_ctx
Context forwarded to s_vin_frame_fn.
Definition ra8_vin.c:102
ra8_err_t ra8_vin_deinit(void)
Tear down VIN: stop capture, mask interrupts, drop MSTP.
Definition ra8_vin.c:308
void ra8_vin_dispatch(void)
Snapshot INTS, fire callback, then W1C the latched bits.
Definition ra8_vin.c:849
static ra8_vin_frame_fn_t s_vin_frame_fn
Frame-end callback registered via ra8_vin_attach_frame_handler.
Definition ra8_vin.c:95
ra8_err_t ra8_vin_init(const ra8_vin_config_t *cfg)
Initialise VIN with the supplied descriptor.
Definition ra8_vin.c:260
static void * s_vin_frame_buf
Buffer base of the most recent ra8_vin_capture_start call.
Definition ra8_vin.c:109
static void internal_mc_rmw(uint32_t clear_mask, uint32_t set_bits)
Read-modify-write a single bit-field within MC.
Definition ra8_vin.c:253
ra8_err_t ra8_vin_enable_scaling(bool enable)
Toggle the MC.SCLE main scaling-enable bit.
Definition ra8_vin.c:499
static uint32_t s_vin_frame_len
Cached length (in bytes) of the most recent capture geometry.
Definition ra8_vin.c:116
ra8_err_t ra8_vin_set_uds_ctrl(const ra8_vin_uds_ctrl_t *ctrl)
Programme UDS interpolation control (UDS_CTRL).
Definition ra8_vin.c:472
ra8_err_t ra8_vin_set_scanline_compare(uint16_t line)
Programme the SI (Scanline Interrupt) compare register.
Definition ra8_vin.c:831
ra8_err_t ra8_vin_lut_program(const uint8_t *y_table, const uint8_t *cb_table, const uint8_t *cr_table, bool enable)
Programme all 256 entries of the Y / Cb / Cr conversion LUT.
Definition ra8_vin.c:509
ra8_vin_chan_offsets_t
Register offsets for one row of the RGB-to-YC matrix.
Definition ra8_vin.c:147
@ k_ra8_vin_yc_y_set3
RA8 vin yc y set3.
Definition ra8_vin.c:150
@ k_ra8_vin_yc_y_set1
RA8 vin yc y set1.
Definition ra8_vin.c:148
@ k_ra8_vin_yc_cb_set2
RA8 vin yc cb set2.
Definition ra8_vin.c:152
@ k_ra8_vin_yc_cr_set2
RA8 vin yc cr set2.
Definition ra8_vin.c:155
@ k_ra8_vin_yc_cb_set1
RA8 vin yc cb set1.
Definition ra8_vin.c:151
@ k_ra8_vin_yc_cb_set3
RA8 vin yc cb set3.
Definition ra8_vin.c:153
@ k_ra8_vin_yc_y_set2
RA8 vin yc y set2.
Definition ra8_vin.c:149
@ k_ra8_vin_yc_cr_set1
RA8 vin yc cr set1.
Definition ra8_vin.c:154
@ k_ra8_vin_yc_cr_set3
RA8 vin yc cr set3.
Definition ra8_vin.c:156
ra8_err_t ra8_vin_set_csi_input(const ra8_vin_csi_input_t *input)
Programme CSI_IFMD (virtual channel + data type + extension).
Definition ra8_vin.c:703
ra8_err_t ra8_vin_exit_stop(void)
Re-enable the VIN clock gate after ra8_vin_enter_stop.
Definition ra8_vin.c:888
ra8_err_t ra8_vin_set_preclip(const ra8_vin_preclip_t *window)
Programme the pre-clip window (SLPRC / ELPRC / SPPRC / EPPRC).
Definition ra8_vin.c:407
static void internal_yc_offsets(uint8_t channel, ra8_vin_off_t *off1, ra8_vin_off_t *off2, ra8_vin_off_t *off3)
Resolve the (set1, set2, set3) offset triple for one row.
Definition ra8_vin.c:591
ra8_err_t ra8_vin_set_interrupt_enable(uint32_t mask)
Update the IE (Interrupt Enable) mask at runtime.
Definition ra8_vin.c:824
ra8_err_t ra8_vin_set_field_detect(const ra8_vin_field_detect_t *detect)
Programme CSIFLD (field detection).
Definition ra8_vin.c:720
ra8_err_t ra8_vin_set_yuv444_mode(uint8_t mode)
Configure the YUV-444 conversion mode (MC.YUV444).
Definition ra8_vin.c:657
ra8_err_t ra8_vin_set_uds_scale(const ra8_vin_uds_scale_t *scale)
Programme the UDS scaling factor (UDS_SCALE).
Definition ra8_vin.c:429
ra8_err_t ra8_vin_enter_stop(void)
Quiesce VIN and disable its module-stop clock gate.
Definition ra8_vin.c:876
ra8_vin_capture_geom_t
Bounded geometry constants used by ra8_vin_capture_start.
Definition ra8_vin.c:903
@ k_ra8_vin_geom_max_dim
Hardware caps both axes at 4096.
Definition ra8_vin.c:904
static void * s_vin_ctx
Context value forwarded to s_vin_fn.
Definition ra8_vin.c:88
ra8_err_t ra8_vin_set_rgb_to_yc(uint8_t channel, const ra8_vin_rgb_to_yc_chan_t *row)
Programme one row of the RGB -> YC matrix.
Definition ra8_vin.c:609
ra8_err_t ra8_vin_capture_arm(ra8_vin_capture_mode_t mode)
Start a capture operation.
Definition ra8_vin.c:342
static uint32_t internal_compose_mc(const ra8_vin_config_t *cfg)
Encode a ra8_vin_config_t into the MC register value.
Definition ra8_vin.c:183
ra8_err_t ra8_vin_capture_start(void *buf, uint16_t w, uint16_t h, ra8_vin_input_fmt_t format)
Start a single-frame capture into buf with the supplied geometry.
Definition ra8_vin.c:933
ra8_err_t ra8_vin_capture_disarm(void)
Stop the current capture and drain outstanding AXI traffic.
Definition ra8_vin.c:376
static void internal_pulse_st(uint32_t mc_now)
Pulse MC.ST then absorb the >= 10 ICLK settling time.
Definition ra8_vin.c:221
static uint8_t internal_format_bpp(ra8_vin_input_fmt_t format)
Definition ra8_vin.c:919
ra8_err_t ra8_vin_get_line_count(uint16_t *out_count)
Read the LC (line count) register.
Definition ra8_vin.c:807
ra8_err_t ra8_vin_attach_handler(ra8_vin_event_fn_t fn, void *ctx)
Attach a VIN event callback (shared between status + error IRQs).
Definition ra8_vin.c:841
ra8_err_t ra8_vin_set_framebuffers(uint32_t mb1, uint32_t mb2, uint32_t mb3)
Re-programme MB1 / MB2 / MB3 (ping-pong framebuffers).
Definition ra8_vin.c:741
ra8_err_t ra8_vin_clear_status(uint32_t mask)
Clear write-1-to-clear bits in the INTS register.
Definition ra8_vin.c:783
ra8_vin_format_bpp_t
Bytes-per-pixel lookup for ra8_vin_input_fmt_t.
Definition ra8_vin.c:911
@ k_ra8_vin_bpp_rgb888
RGB888 packed in 32-bit cells.
Definition ra8_vin.c:914
@ k_ra8_vin_bpp_ycbcr422
4:2:2 packs to 2 bytes / pixel.
Definition ra8_vin.c:912
@ k_ra8_vin_bpp_raw8
RAW8 = 1 byte / pixel.
Definition ra8_vin.c:913
ra8_err_t ra8_vin_get_active_buffer(uint8_t *out_id)
Return the active framebuffer index from MS.FBS.
Definition ra8_vin.c:815
ra8_err_t ra8_vin_set_uv_offset(uint32_t uv_addr)
Programme UVAOF (UV plane address offset for YC-separated mode).
Definition ra8_vin.c:765
ra8_err_t ra8_vin_attach_frame_handler(ra8_vin_frame_fn_t fn, void *ctx)
Register the frame-end IRQ callback.
Definition ra8_vin.c:983
static ra8_vin_event_fn_t s_vin_fn
Registered VIN event callback (set by ra8_vin_attach_handler).
Definition ra8_vin.c:75
ra8_err_t ra8_vin_get_status(uint32_t *out_mask)
Snapshot the INTS register.
Definition ra8_vin.c:775
ra8_err_t ra8_vin_capture_stop(void)
Stop the in-flight capture started via ra8_vin_capture_start.
Definition ra8_vin.c:959
ra8_err_t ra8_vin_set_dithering(uint8_t mode, bool direction)
Configure the dithering mode (MC.DC + MC.DC2).
Definition ra8_vin.c:641
ra8_err_t ra8_vin_set_uds_passband(uint8_t v_bwidth, uint8_t h_bwidth)
Programme the UDS pass-band bandwidth (UDS_PASS_BWIDTH).
Definition ra8_vin.c:448
ra8_err_t ra8_vin_set_interlace_mode(uint8_t mode)
Set the interlace mode (MC.IM).
Definition ra8_vin.c:667
ra8_err_t ra8_vin_reset(void)
Issue a soft reset by re-running the MC.ST settle sequence.
Definition ra8_vin.c:330
ra8_err_t ra8_vin_set_uds_clip(uint16_t v_size, uint16_t h_size)
Programme the UDS output clipping (UDS_CLIP_SIZE).
Definition ra8_vin.c:460
ra8_err_t ra8_vin_get_module_status(ra8_vin_module_status_t *out_status)
Decode the MS register into a typed snapshot.
Definition ra8_vin.c:793
Video Input Module (VIN) driver – public API.
Video Input Module (VIN) register layout for the RA8D2.
@ k_ra8_vin_st_settle_reads
MC.ST settle read-backs.
@ k_ra8_vin_fc_cc
CC [1] Continuous frame capture mode.
@ k_ra8_vin_lutd_shift_ltydt
Y data byte shift.
@ k_ra8_vin_lutd_shift_ltcbdt
Cb data byte shift.
@ k_ra8_vin_lutd_shift_ltcrdt
Cr data byte shift.
@ k_ra8_vin_mtcstop_outstand
OUTSTAND[21:16] (R).
@ k_ra8_vin_mtcstop_req
STOPREQ [0].
@ k_ra8_vin_csce_mul_hi
High multiplier [29:16].
@ k_ra8_vin_csce_mul_lo
Low multiplier [13:0].
@ k_ra8_vin_dmr_shift_dtmd
DTMD[1:0] shift.
@ k_ra8_vin_dmr_shift_a8bit
A8BIT[31:24] shift.
@ k_ra8_vin_dmr_shift_ymode
YMODE[14:12] shift.
@ k_ra8_vin_uds_ctrl_amd
AMD [30] Advanced pixel cnt.
@ k_ra8_vin_uds_ctrl_bladv
BLADV [28] Advanced bilinear.
@ k_ra8_vin_uds_ctrl_bc
BC [20] Bilinear vs multi.
@ k_ra8_vin_uds_ctrl_ne_bcb
NE_BCB [16] B/Cb interp method.
@ k_ra8_vin_uds_ctrl_ne_gy
NE_GY [17] G/Y interp method.
@ k_ra8_vin_uds_ctrl_ne_rcr
NE_RCR [18] R/Cr interp method.
@ k_ra8_vin_csi_ifmd_shift_vc_sel
VC_SEL[3:0] shift.
@ k_ra8_vin_csi_ifmd_shift_dt
DT[13:8] shift.
@ k_ra8_vin_uds_scale_shift_vmant
VMANT[15:12] shift.
@ k_ra8_vin_uds_scale_shift_hmant
HMANT[31:28] shift.
@ k_ra8_vin_uds_scale_shift_hfrac
HFRAC[27:16] shift.
@ k_ra8_vin_uds_scale_shift_vfrac
VFRAC[11:0] shift.
@ k_ra8_vin_si_mask
SI[11:0] scanline match value.
@ k_ra8_vin_lc_mask
LC[11:0] line count.
@ k_ra8_vin_uds_bwidth_h
BWIDTH_H [22:16].
@ k_ra8_vin_uds_bwidth_v
BWIDTH_V [6:0].
ra8_vin_off_t
32-bit register offsets inside the VIN window.
@ k_ra8_vin_off_csifld
CSIFLD Field detect control.
@ k_ra8_vin_off_uvaof
UVAOF UV data address offset.
@ k_ra8_vin_off_lutp
LUTP LUT pointer (Y/Cb/Cr).
@ k_ra8_vin_off_csi_ifmd
CSI_IFMD CSI-2 interface mode.
@ k_ra8_vin_off_slprc
SLPRC Pre-clip start line.
@ k_ra8_vin_off_csce2
CSCE2 YC-to-RGB Y/CbCr subtraction.
@ k_ra8_vin_off_mb1
MB1 Memory base 1 (frame addr).
@ k_ra8_vin_off_crccr2
CRCCR2 RGB-to-Cr coeff G+B.
@ k_ra8_vin_off_lutd
LUTD LUT data (Y/Cb/Cr).
@ k_ra8_vin_off_fc
FC Frame capture register.
@ k_ra8_vin_off_cbccr2
CBCCR2 RGB-to-Cb coeff G+B.
@ k_ra8_vin_off_ints
INTS Interrupt status (W1C).
@ k_ra8_vin_off_uds_pass_bwidth
UDS_PASS_BWIDTH passband bandwidth.
@ k_ra8_vin_off_ie
IE Interrupt enable.
@ k_ra8_vin_off_epprc
EPPRC Pre-clip end pixel.
@ k_ra8_vin_off_csce4
CSCE4 YC-to-RGB Cb multiplication.
@ k_ra8_vin_off_mtcstop
MTCSTOP AXI transfer stop control.
@ k_ra8_vin_off_lc
LC Line count (R).
@ k_ra8_vin_off_mb2
MB2 Memory base 2 (frame addr).
@ k_ra8_vin_off_elprc
ELPRC Pre-clip end line.
@ k_ra8_vin_off_cbccr1
CBCCR1 RGB-to-Cb coeff R.
@ k_ra8_vin_off_mb3
MB3 Memory base 3 (frame addr).
@ k_ra8_vin_off_mc
MC Main control register.
@ k_ra8_vin_off_crccr1
CRCCR1 RGB-to-Cr coeff R.
@ k_ra8_vin_off_si
SI Scanline interrupt compare.
@ k_ra8_vin_off_ms
MS Module status (R).
@ k_ra8_vin_off_dmr
DMR Data mode register.
@ k_ra8_vin_off_uds_clip_size
UDS_CLIP_SIZE output clip size.
@ k_ra8_vin_off_yccr1
YCCR1 RGB-to-Y coeff R.
@ k_ra8_vin_off_yccr2
YCCR2 RGB-to-Y coeff G+B.
@ k_ra8_vin_off_is
IS Image stride.
@ k_ra8_vin_off_cbccr3
CBCCR3 RGB-to-Cb norm/shift.
@ k_ra8_vin_off_yccr3
YCCR3 RGB-to-Y norm/shift.
@ k_ra8_vin_off_csce1
CSCE1 YC-to-RGB Y multiplication.
@ k_ra8_vin_off_spprc
SPPRC Pre-clip start pixel.
@ k_ra8_vin_off_uds_ctrl
UDS_CTRL Scaling interpolation ctrl.
@ k_ra8_vin_off_csce3
CSCE3 YC-to-RGB Cr multiplication.
@ k_ra8_vin_off_crccr3
CRCCR3 RGB-to-Cr norm/shift.
@ k_ra8_vin_off_uds_scale
UDS_SCALE Scaling factor V/H.
@ k_ra8_vin_mb_align_mask
Reserved low bits (must be zero).
@ k_ra8_vin_lutd_ltydt
LTYDT [23:16] Y data byte.
@ k_ra8_vin_lutd_ltcbdt
LTCBDT [15:8] Cb data byte.
@ k_ra8_vin_lutd_ltcrdt
LTCRDT [7:0] Cr data byte.
@ k_ra8_vin_csce2_shift_ysub2
YSUB2[27:16] shift.
@ k_ra8_vin_lut_entries
LUT entry count for Y, Cb, and Cr.
@ k_ra8_vin_yc2_gp
Setting 2: G coeff [12:0].
@ k_ra8_vin_yc3_sft
Setting 3: shift-down volume [28:24].
@ k_ra8_vin_yc1_rp
Setting 1: R coeff [12:0].
@ k_ra8_vin_yc3_ap
Setting 3: additive offset [11:0].
@ k_ra8_vin_yc2_bp
Setting 2: B coeff [28:16].
@ k_ra8_vin_yc3_hen
Setting 3: round-off enable [23].
@ k_ra8_vin_csce2_csub2
CSUB2 [11:0].
@ k_ra8_vin_csce2_ysub2
YSUB2 [27:16].
@ k_ra8_vin_dmr_a8bit
A8BIT [31:24] ARGB-8888 alpha.
@ k_ra8_vin_dmr_bpsm
BPSM [4] Byte-swap mode.
@ k_ra8_vin_dmr_exrgb
EXRGB [8] Extend RGB to 32-bit.
@ k_ra8_vin_dmr_abit
ABIT [2] ARGB-1555 alpha bit.
@ k_ra8_vin_dmr_ymode
YMODE [14:12] YC transfer mode.
@ k_ra8_vin_dmr_dtmd
DTMD [1:0] Data conversion mode.
@ k_ra8_vin_dmr_yc_thr
YC_THR [11] YC data through mode.
@ k_ra8_vin_yccr_shift_sft
Setting 3 shift-down shift.
@ k_ra8_vin_yccr_shift_bp
Setting 2 B coeff shift.
@ k_ra8_vin_csi_ifmd_dt
DT [13:8] Data type.
@ k_ra8_vin_csi_ifmd_vc_sel
VC_SEL [3:0] Virtual channel.
@ k_ra8_vin_csi_ifmd_des0
DES0 [25] Data extension.
@ k_ra8_vin_uds_max_clip
12-bit clip-size max.
@ k_ra8_vin_uds_max_bw
7-bit pass-band width max.
@ k_ra8_vin_uds_max_mant
4-bit mantissa max value.
@ k_ra8_vin_uds_max_frac
12-bit fractional max value.
@ k_ra8_vin_preclip_mask
12-bit pre-clip count.
@ k_ra8_vin_uds_scale_hfrac
HFRAC [27:16] H scale frac.
@ k_ra8_vin_uds_scale_hmant
HMANT [31:28] H scale int.
@ k_ra8_vin_uds_scale_vfrac
VFRAC [11:0] V scale frac.
@ k_ra8_vin_uds_scale_vmant
VMANT [15:12] V scale int.
@ k_ra8_vin_lutp_ltypr
LTYPR [29:20] Y pointer.
@ k_ra8_vin_lutp_ltcrpr
LTCRPR [9:0] Cr pointer.
@ k_ra8_vin_lutp_ltcbpr
LTCBPR [19:10] Cb pointer.
@ k_ra8_vin_int_w1c_mask
FOS | ARES | FIS2.
@ k_ra8_vin_ms_ma
MA [16] Memory capture active.
@ k_ra8_vin_ms_av
AV [1] Active video.
@ k_ra8_vin_ms_fs
FS [2] Field status (0=odd,1=even).
@ k_ra8_vin_ms_ca
CA [0] Capture active.
@ k_ra8_vin_ms_fbs
FBS [4:3] Latest frame buffer id.
@ k_ra8_vin_ms_fms
FMS [20:19] External MB buffer status.
static volatile uint32_t * ra8_vin_reg32(ra8_vin_off_t off)
Pointer to a 32-bit register inside the VIN block.
@ k_ra8_vin_mc_shift_inf
INF[18:16] shift.
@ k_ra8_vin_mc_shift_im
IM[4:3] shift.
@ k_ra8_vin_mc_shift_clp
CLP[29:28] shift.
@ k_ra8_vin_mc_shift_dc
DC[15:14] shift.
@ k_ra8_vin_uds_bwidth_shift_v
BWIDTH_V[6:0] shift.
@ k_ra8_vin_uds_bwidth_shift_h
BWIDTH_H[22:16] shift.
@ k_ra8_vin_csce_shift_mul_hi
High multiplier shift.
@ k_ra8_vin_int_fme
[5] Frame memory write complete.
@ k_ra8_vin_ms_shift_fbs
FBS[4:3] shift.
@ k_ra8_vin_ms_shift_fms
FMS[20:19] shift.
@ k_ra8_vin_uds_clip_v
CL_VSIZE [11:0] .
@ k_ra8_vin_uds_clip_h
CL_HSIZE [27:16].
@ k_ra8_vin_csce1_ymul2
YMUL2 [13:0].
@ k_ra8_vin_csce1_round
ROUND [16].
@ k_ra8_vin_uds_clip_shift_v
CL_VSIZE shift.
@ k_ra8_vin_uds_clip_shift_h
CL_HSIZE shift.
@ k_ra8_vin_mc_lute
LUTE [20] LUT enable.
@ k_ra8_vin_mc_clp
CLP [29:28] Pixel data clipping.
@ k_ra8_vin_mc_dc2
DC2 [24] Dithering direction.
@ k_ra8_vin_mc_im
IM [4:3] Interlace mode.
@ k_ra8_vin_mc_yuv444
YUV444[25] YUV444 conversion.
@ k_ra8_vin_mc_bps
BPS [1] Colour-space bypass.
@ k_ra8_vin_mc_en
EN [6] Endian (1 = big).
@ k_ra8_vin_mc_st
ST [22] Init at startup (W).
@ k_ra8_vin_mc_scle
SCLE [26] UDS scaling enable.
@ k_ra8_vin_mc_inf
INF [18:16] Input interface format.
@ k_ra8_vin_mc_dc
DC [15:14] Dithering mode.
@ k_ra8_vin_mc_me
ME [0] Module Enable.
@ k_ra8_vin_stop_drain_max
Max OUTSTAND poll iterations.
@ k_ra8_vin_csifld_fld_num
FLD_NUM [16] Even-field number.
@ k_ra8_vin_csifld_fld_sel
FLD_SEL [5:4] Even-field select.
@ k_ra8_vin_csifld_fld_en
FLD_EN [0] Field detect.
@ k_ra8_vin_lutp_shift_ltcbpr
Cb pointer shift.
@ k_ra8_vin_lutp_shift_ltcrpr
Cr pointer shift.
@ k_ra8_vin_lutp_shift_ltypr
Y pointer shift.
void(* ra8_vin_frame_fn_t)(void *ctx, void *buf, uint32_t len)
Frame-end callback registered via ra8_vin_attach_frame_handler.
ra8_vin_capture_mode_t
Single frame vs.
@ k_ra8_vin_capture_continuous_field_skip
Continuous, honour IM mode.
@ k_ra8_vin_capture_continuous
Roll MB1 -> MB2 -> MB3 ->.
@ k_ra8_vin_capture_single
Capture one frame into MB1.
ra8_vin_input_fmt_t
Camera input format for the MC.INF[2:0] field.
@ k_ra8_vin_input_raw8
RAW8 user-defined data.
@ k_ra8_vin_input_rgb888
24-bit RGB888.
void(* ra8_vin_event_fn_t)(void *ctx, uint32_t status_mask)
VIN event callback (frame complete / overflow / VSYNC).
Initial configuration for ra8_vin_init.
bool bypass_csc
MC.BPS: skip colour conversion.
uint32_t framebuffer_addr_1
MB1 (must be 64-byte aligned).
uint8_t pixel_clip_mode
MC.CLP (ra8_vin_clp_value_t).
uint32_t interrupt_enable
IE register mask.
uint8_t interlace_mode
MC.IM (ra8_vin_im_value_t).
bool big_endian
MC.EN: pack big-endian to memory.
uint32_t framebuffer_addr_2
MB2 (continuous mode only).
uint16_t scanline_compare
SI register; 0 disables.
ra8_vin_input_fmt_t input_fmt
MC.INF: input format.
uint32_t framebuffer_addr_3
MB3 (continuous mode only).
uint16_t image_stride_px
IS register, in pixels.
CSI_IFMD parameter view.
uint8_t virtual_channel
VC_SEL (0..15).
uint8_t data_type
DT (ra8_vin_csi_dt_value_t).
bool zero_extend
DES0: 1 = zero-extend, 0 = sign-extend.
Decoded view of the DMR (Data Mode) register.
bool alpha_bit
ABIT for ARGB-1555 alpha.
uint8_t alpha_byte
A8BIT ARGB-8888 alpha byte.
uint8_t y_mode
YMODE (ra8_vin_ymode_value_t).
bool extend_rgb
EXRGB pad RGB to 32 bits.
bool byte_swap
BPSM swap output bytes.
uint8_t conv_mode
DTMD (ra8_vin_dtmd_value_t).
bool yc_through
YC_THR YC pass-through mode.
CSIFLD parameter view.
uint8_t even_field_num
FLD_NUM (ra8_vin_field_polarity_t).
bool even_field_sel
FLD_SEL (bit-4 of FLD_SEL[5:4]).
Decoded snapshot of the MS (Module Status) register.
bool even_field
MS.FS (1 -> even).
uint8_t latest_frame_buffer
MS.FMS.
uint8_t frame_buffer_id
MS.FBS.
Pre-clip window (SLPRC / ELPRC / SPPRC / EPPRC).
uint16_t pixel_start
SPPRC: first pixel within each line.
uint16_t line_end
ELPRC: last line that survives the clip.
uint16_t pixel_end
EPPRC: last pixel within each line.
uint16_t line_start
SLPRC: first line that survives the clip.
One RGB-to-YC matrix row (Y, Cb, or Cr).
uint16_t b_coeff
Setting 2 B coefficient.
uint16_t r_coeff
Setting 1 R coefficient.
uint16_t add_offset
Setting 3 additive offset (LAP).
uint16_t g_coeff
Setting 2 G coefficient.
uint8_t shift_down
Setting 3 shift-down volume (LSFT, 5-bit).
bool enable_hen
Setting 3 round-off enable (LHEN).
UDS interpolation control bits.
bool r_cr_nearest
NE_RCR: 1 = nearest-neighbour for R/Cr.
bool advanced_bl
BLADV: advanced bilinear-mode tweak.
bool b_cb_nearest
NE_BCB: 1 = nearest-neighbour for B/Cb.
bool multitap
BC: 1 = multi-tap, 0 = bilinear/nearest.
bool advanced_amd
AMD: advanced pixel-count formula.
bool g_y_nearest
NE_GY: 1 = nearest-neighbour for G/Y.
UDS scaling factors for the V and H axes.
uint8_t v_mantissa
VMANT[3:0].
uint8_t h_mantissa
HMANT[3:0].
uint16_t v_fraction
VFRAC[11:0].
uint16_t h_fraction
HFRAC[11:0].
Coefficients for the YC -> RGB matrix (CSCEn).
uint16_t cb_mul_lo
CSCE4 low [13:0].
uint16_t cb_mul_hi
CSCE4 high[29:16].
bool enable_round
ROUND[16].
uint16_t cr_mul_hi
CSCE3 high[29:16].
uint16_t cr_mul_lo
CSCE3 low [13:0].
uint16_t y_multiplier
YMUL2[13:0].
uint16_t cbcr_sub
CSUB2[11:0].
uint16_t y_sub
YSUB2[27:16].