ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph_ceu.c
Go to the documentation of this file.
1
37
38#include <stdint.h>
39#include <stdio.h>
40
41#include "board_console.h"
42#include "board_periph_block.h"
44
46typedef enum : uint64_t {
47 k_ceu_base = 0x40348000UL,
48 k_ceu_span = 0x100UL,
49 k_ceu_words = 0x100UL / 4UL,
50 k_ceu_off_capsr = 0x00UL,
51 k_ceu_off_cmcyr = 0x0CUL,
52 k_ceu_off_capwr = 0x14UL,
53 k_ceu_off_cdwdr = 0x38UL,
54 k_ceu_off_cdayr = 0x3CUL,
55 k_ceu_off_cetcr = 0x74UL,
56 k_ceu_off_cstsr = 0x7CUL,
57 k_ceu_off_cdssr = 0x84UL,
58} ceu_map_t;
59
61typedef enum : uint32_t {
62 k_ceu_capsr_ce = 0x00000001U,
63 k_ceu_capsr_cpkil = 0x00010000U,
64 k_ceu_cetcr_cpe = 0x00000001U,
65 k_ceu_cmcyr_hcyl = 0x00003FFFU,
66 k_ceu_field_14bit = 0x00003FFFU,
67 k_ceu_capwr_hwdth = 0x00001FFFU,
68 k_ceu_field_12bit = 0x00000FFFU,
69 k_ceu_pattern_mask = 0x000000FFU,
71
73typedef enum : uint32_t {
78
80typedef enum : uint32_t {
83
85typedef struct {
86 uint32_t reg[k_ceu_words];
87 uint32_t frames;
88 uint32_t last_bytes;
89 uint32_t last_w;
90 uint32_t last_h;
92
94static uint8_t s_ceu_line[k_ceu_max_line];
95
107RA8_INTERNAL static uint32_t internal_ceu_word(uint64_t off)
108{
109 return (uint32_t)(off >> 2U);
110}
111
123{
124 const uint32_t stride =
126 if (stride != 0U) {
127 return stride;
128 }
130}
131
143{
144 const uint32_t vwdth =
146 (uint32_t)k_ceu_field_12bit;
147 if (vwdth != 0U) {
148 return vwdth;
149 }
150 return (s_ceu.reg[internal_ceu_word(k_ceu_off_cmcyr)] >> (uint32_t)k_ceu_shift_vert) &
151 (uint32_t)k_ceu_field_14bit;
152}
153
175RA8_INTERNAL static bool internal_ceu_do_capture(uc_engine* uc)
176{
177 uint32_t line_bytes = internal_ceu_line_bytes();
178 uint32_t lines = internal_ceu_line_count();
179 if ((line_bytes == 0U) || (lines == 0U)) {
180 return false; /* No geometry programmed -> no capture. */
181 }
182 if (line_bytes > (uint32_t)k_ceu_max_line) {
183 line_bytes = (uint32_t)k_ceu_max_line;
184 }
185 if (lines > (uint32_t)k_ceu_max_lines) {
186 lines = (uint32_t)k_ceu_max_lines;
187 }
188 const uint32_t dst = s_ceu.reg[internal_ceu_word(k_ceu_off_cdayr)];
189 if (dst == 0U) {
190 return false; /* No destination buffer -> no capture. */
191 }
192 for (uint32_t y = 0U; y < lines; y++) {
193 for (uint32_t x = 0U; x < line_bytes; x++) {
194 s_ceu_line[x] = (uint8_t)((x + y) & (uint32_t)k_ceu_pattern_mask);
195 }
196 (void)emu_mem_write(uc,
197 (uint64_t)dst + ((uint64_t)y * (uint64_t)line_bytes),
199 (size_t)line_bytes);
200 }
201 const uint32_t total = line_bytes * lines;
205 s_ceu.frames++;
206 s_ceu.last_bytes = total;
207 s_ceu.last_w = line_bytes;
208 s_ceu.last_h = lines;
209
210 char ln[k_ceu_console_line_cap];
211 (void)snprintf(ln,
212 sizeof(ln),
213 "CEU frame %ux%u -> %u bytes",
214 (unsigned)line_bytes,
215 (unsigned)lines,
216 (unsigned)total);
218 if (board_periph_trace()) {
219 (void)priv_emu_io_errf(" [trace] CEU capture %ux%u -> 0x%08X\n", line_bytes, lines, dst);
220 }
221 return true;
222}
223
237RA8_INTERNAL static uint64_t internal_ceu_read(uc_engine* uc, uint64_t addr, unsigned size)
238{
239 (void)uc;
240 (void)size;
241 const uint64_t off = addr - (uint64_t)k_ceu_base;
242 if (off >= (uint64_t)k_ceu_span) {
243 return 0U;
244 }
245 if (off == (uint64_t)k_ceu_off_cstsr) {
246 return 0U; /* Capture is instantaneous: CPTON always reads idle. */
247 }
248 if (off == (uint64_t)k_ceu_off_capsr) {
249 /* CPKIL self-clears (reset is instantaneous in the model). */
250 return (uint64_t)(s_ceu.reg[internal_ceu_word(off)] & ~(uint32_t)k_ceu_capsr_cpkil);
251 }
252 return (uint64_t)s_ceu.reg[internal_ceu_word(off)];
253}
254
267RA8_INTERNAL static void
268internal_ceu_write(uc_engine* uc, uint64_t addr, unsigned size, uint64_t value)
269{
270 (void)size;
271 const uint64_t off = addr - (uint64_t)k_ceu_base;
272 if (off >= (uint64_t)k_ceu_span) {
273 return;
274 }
275 s_ceu.reg[internal_ceu_word(off)] = (uint32_t)value;
276 if (off != (uint64_t)k_ceu_off_capsr) {
277 return;
278 }
279 if (((uint32_t)value & (uint32_t)k_ceu_capsr_cpkil) != 0U) {
280 /* Software reset: drop pending events and CE; CPKIL self-clears. */
283 (uint32_t)value & ~((uint32_t)k_ceu_capsr_cpkil | (uint32_t)k_ceu_capsr_ce);
284 return;
285 }
286 if (((uint32_t)value & (uint32_t)k_ceu_capsr_ce) != 0U) {
287 (void)internal_ceu_do_capture(uc); /* Arm -> synthesise a frame + latch CETCR.CPE. */
288 }
289}
290
300{
301 s_ceu = (ceu_state_t){};
302}
303
313{
314 if (s_ceu.frames == 0U) {
315 return;
316 }
317 (void)priv_emu_io_errf(" CEU : frames=%u last=%ux%u (%u bytes) synth test-pattern\n",
318 s_ceu.frames,
319 s_ceu.last_w,
320 s_ceu.last_h,
321 s_ceu.last_bytes);
322}
323
326 .base = (uint64_t)k_ceu_base,
327 .span = (uint64_t)k_ceu_span,
328 .order = (uint32_t)k_block_order_i2c, /* Synchronous on CAPSR.CE; no tick. */
329 .read = internal_ceu_read,
331 .tick = nullptr,
332 .reset = internal_ceu_reset,
333 .report = internal_ceu_report,
334 .name = "CEU",
335};
336
338[[gnu::constructor]] RA8_INTERNAL static void internal_board_periph_ceu_register(void)
339{
341}
Multi-channel console log store backing the board view's tabbed console.
void board_console_push(board_console_ch_t ch, const char *line)
Append one completed line to a channel ring and the ALL ring.
@ k_board_console_ch_dma
DMAC + DTC transfer-complete summaries.
Decentralized peripheral-block registry for the board emulator core.
void board_periph_register_block(const board_periph_block_t *block)
Register a peripheral block's descriptor with the core registry.
@ k_block_order_i2c
I3C/I2C + GT911 (no tick today).
bool board_periph_trace(void)
Whether –trace is active (blocks log transitions when true).
static RA8_INTERNAL void internal_ceu_reset(void)
Clear the CEU model to power-on state.
static RA8_INTERNAL void internal_board_periph_ceu_register(void)
Self-register the CEU block before main runs (decentralized).
static RA8_INTERNAL bool internal_ceu_do_capture(uc_engine *uc)
Synthesise one frame into the CDAYR buffer and latch CETCR.CPE.
static ceu_state_t s_ceu
ceu_bound_t
Field shift + fill bounds.
@ k_ceu_max_line
Max modelled line width (bytes) – QVGA=640.
@ k_ceu_max_lines
Max modelled line count – QVGA=240.
@ k_ceu_shift_vert
Vertical field shift (VCYL / VWDTH).
static const board_periph_block_t s_k_ceu_block
This block's descriptor (static lifetime; the core keeps the pointer).
static RA8_INTERNAL uint32_t internal_ceu_line_count(void)
Destination line count: CAPWR.VWDTH, else CMCYR.VCYL.
ceu_console_t
Console anti-flood cadence for the CEU (DMA/transfer) tab.
@ k_ceu_console_line_cap
Max chars in a "CEU frame .." line.
static RA8_INTERNAL uint32_t internal_ceu_word(uint64_t off)
Word index into the backing store for an in-window byte offset.
static RA8_INTERNAL void internal_ceu_report(void)
Print the CEU capture summary if any frame was synthesised.
static uint8_t s_ceu_line[k_ceu_max_line]
One-line fill scratch.
static RA8_INTERNAL void internal_ceu_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the CEU window: latch, then act on CAPSR.
static RA8_INTERNAL uint32_t internal_ceu_line_bytes(void)
Destination line width (bytes): CDWDR stride, else CMCYR.HCYL.
static RA8_INTERNAL uint64_t internal_ceu_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the CEU window.
ceu_map_t
CEU register-window geometry (ra8_ceu_regs.h, Plane A view).
@ k_ceu_words
Backing-store word count.
@ k_ceu_base
CEU block base (HUM Ch 60).
@ k_ceu_off_capsr
CAPSR capture start (CE / CPKIL).
@ k_ceu_off_cdwdr
CDWDR destination stride.
@ k_ceu_off_capwr
CAPWR capture width (HWDTH / VWDTH).
@ k_ceu_off_cstsr
CSTSR capture status (CPTON).
@ k_ceu_off_cetcr
CETCR event flags (CPE, ...).
@ k_ceu_off_cdayr
CDAYR destination Y address.
@ k_ceu_off_cmcyr
CMCYR interface cycle (HCYL / VCYL).
@ k_ceu_off_cdssr
CDSSR captured data byte count.
@ k_ceu_span
Plane-A register set (0x00..0x9C).
ceu_field_t
CEU register bit fields (ra8_ceu_regs.h).
@ k_ceu_field_12bit
12-bit field (CAPWR VWDTH after >>16).
@ k_ceu_capsr_cpkil
CAPSR.CPKIL: software reset.
@ k_ceu_field_14bit
14-bit field (CMCYR VCYL after >>16).
@ k_ceu_cetcr_cpe
CETCR.CPE: one-frame capture end.
@ k_ceu_capwr_hwdth
CAPWR.HWDTH[12:0] / CDWDR stride mask.
@ k_ceu_pattern_mask
Test-pattern byte modulus.
@ k_ceu_cmcyr_hcyl
CMCYR.HCYL[13:0]: byte-cycles/line.
@ k_ceu_capsr_ce
CAPSR.CE: start capture at next VD.
Bounded raw-descriptor I/O seam for the RA8 emulator.
emu_io_result_t priv_emu_io_errf(const char *format,...)
Format bounded text and write it to the injected error descriptor.
uc_err emu_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t count)
Write guest memory through the central access seam.
-proof
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
A modelled peripheral block's self-description for the core registry.
CEU model state: register backing store + capture observability.
uint32_t last_h
Last capture line count.
uint32_t reg[k_ceu_words]
Plane-A register backing store.
uint32_t last_bytes
Bytes written by the last capture.
uint32_t frames
Frames synthesised (report).
uint32_t last_w
Last capture line width (bytes).