ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1
46
47#include <stddef.h>
48#include <stdint.h>
49
50#include "ra8_board_ek_ra8d2.h"
51#include "ra8_boot_entry.h"
52#include "ra8_cgc.h"
53#include "ra8_check.h"
54#include "ra8_drw.h"
55#include "ra8_err.h"
56#include "ra8_isr.h"
57#include "ra8_mstp.h"
58#include "ra8_time.h"
59
61static const char* s_tag = "drw_blend";
62
72typedef enum : uint32_t {
73 k_drw_blend_baud = 115200U,
77 k_drw_blend_fnv_offset = 2166136261U,
80
97
106typedef enum : uint32_t {
107 k_drw_blend_bg_argb = 0xFF202060U,
108 k_drw_blend_sp_argb = 0xFF40C040U,
109 k_drw_blend_fg_argb = 0xFFE04040U,
110 k_drw_blend_fg_a80 = 0x80E04040U,
118
136
138static const uint8_t k_drw_blend_pass_pfx[] = "drw: blit+blend crc=";
139static const uint8_t k_drw_blend_pass_sfx[] = " PASS\r\n";
140static const uint8_t k_drw_blend_fail_msg[] = "drw: blit+blend FAIL\r\n";
141
148[[gnu::aligned(4)]] volatile uint32_t
150
157volatile uint32_t g_drw_blend_crc = 0U;
158
165volatile uint32_t g_drw_blend_err = 0U;
166
173volatile uint32_t g_drw_blend_heartbeat = 0U;
174
176static void drw_blend_panic_halt(void)
177{
178 while (1) {
179 __asm__ volatile("wfi");
180 }
181}
182
184static void drw_blend_setup_or_halt(void)
185{
186 uint32_t cpuclk0_hz = 0U;
187
188 if (ra8_cgc_init() != k_ra8_ok) {
190 }
193 }
194 if (ra8_mstp_init() != k_ra8_ok) {
196 }
197 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
199 }
202 }
205 }
208 }
209}
210
227[[nodiscard]] static ra8_err_t drw_blend_configure(void)
228{
229 const ra8_drw_config_t cfg = {
230 .framebuffer_addr = (uintptr_t)g_drw_blend_fb,
231 .pitch_px = (uint16_t)k_drw_blend_fb_dim,
233 .enable_caches = false,
234 .enable_buffered_writes = false,
235 };
236 return ra8_drw_init(&cfg);
237}
238
262[[nodiscard]] static ra8_err_t
263drw_blend_fill(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t argb)
264{
265 const ra8_drw_rect_t rect = {
266 .x = x,
267 .y = y,
268 .width_px = w,
269 .height_px = h,
270 .color_argb8888 = argb,
271 };
272 const ra8_err_t ferr = ra8_drw_fill_rect(&rect);
273 if (ferr != k_ra8_ok) {
274 return ferr;
275 }
277}
278
302[[nodiscard]] static ra8_err_t drw_blend_arm(void)
303{
304 const ra8_drw_gradient_t grad = {
305 .color1_argb8888 = (uint32_t)k_drw_blend_fg_argb,
306 .color2_argb8888 = (uint32_t)k_drw_blend_bg_argb,
307 };
308 const ra8_err_t gerr = ra8_drw_set_gradient(&grad);
309 if (gerr != k_ra8_ok) {
310 return gerr;
311 }
312
313 /* True source-over: out = src*a + dst*(1-a). Source factor = alpha
314 * (BSF=1, BSI=0); destination factor = 1-alpha (BDF=1, BDI=1). The
315 * previous descriptor left dst_invert=false (dst factor = alpha, an
316 * additive mix), which is not source-over. */
317 const ra8_drw_blend_t blend = {
318 .use_alpha_channel = true,
319 .src_factor = true,
320 .dst_factor = true,
321 .src_invert = false,
322 .dst_invert = true,
323 .src_factor_alpha = true,
324 .dst_factor_alpha = true,
325 .src_invert_alpha = false,
326 .dst_invert_alpha = true,
327 .use_color2_dst = false,
328 .global_alpha = (uint8_t)k_drw_blend_alpha,
329 };
330 return ra8_drw_set_blend(&blend);
331}
332
334static uint32_t drw_blend_framebuffer_hash(void)
335{
336 const uint32_t words = (uint32_t)k_drw_blend_fb_dim * (uint32_t)k_drw_blend_fb_dim;
337 uint32_t hsh = (uint32_t)k_drw_blend_fnv_offset;
338 for (uint32_t w = 0U; w < words; ++w) {
339 const uint32_t px = g_drw_blend_fb[w];
340 for (uint32_t b = 0U; b < (uint32_t)sizeof(uint32_t); ++b) {
341 const uint8_t byte =
342 (uint8_t)((px >> (b * (uint32_t)k_drw_blend_byte_bits)) & (uint32_t)k_drw_blend_byte_mask);
343 hsh = (hsh ^ (uint32_t)byte) * (uint32_t)k_drw_blend_fnv_prime;
344 }
345 }
346 return hsh;
347}
348
370[[nodiscard]] static ra8_err_t drw_blend_render(uint32_t* out_crc)
371{
372 RA8_CHECK_NULL_PTR(out_crc, s_tag, "out_crc must not be nullptr");
373
375 (int16_t)k_drw_blend_full_org,
376 (uint16_t)k_drw_blend_fb_dim,
377 (uint16_t)k_drw_blend_fb_dim,
378 (uint32_t)k_drw_blend_bg_argb);
379 if (bg != k_ra8_ok) {
380 g_drw_blend_err = (uint32_t)bg;
381 return bg;
382 }
383
384 const ra8_err_t sp = drw_blend_fill((int16_t)k_drw_blend_sp_xy,
385 (int16_t)k_drw_blend_sp_xy,
386 (uint16_t)k_drw_blend_sp_wh,
387 (uint16_t)k_drw_blend_sp_wh,
388 (uint32_t)k_drw_blend_sp_argb);
389 if (sp != k_ra8_ok) {
390 g_drw_blend_err = (uint32_t)sp;
391 return sp;
392 }
393
394 const ra8_err_t armed = drw_blend_arm();
395 if (armed != k_ra8_ok) {
396 g_drw_blend_err = (uint32_t)armed;
397 return armed;
398 }
399
400 /* The blended fill carries the global alpha IN its colour: fill_rect
401 * writes the full COLOR1 register, so passing the opaque source colour
402 * here would clobber the armed alpha back to 0xFF and blend nothing. */
403 const ra8_err_t fg = drw_blend_fill((int16_t)k_drw_blend_fg_xy,
404 (int16_t)k_drw_blend_fg_xy,
405 (uint16_t)k_drw_blend_fg_wh,
406 (uint16_t)k_drw_blend_fg_wh,
407 (uint32_t)k_drw_blend_fg_a80);
408 if (fg != k_ra8_ok) {
409 g_drw_blend_err = (uint32_t)fg;
410 return fg;
411 }
412
413 g_drw_blend_err = 0U;
414 *out_crc = drw_blend_framebuffer_hash();
415 return k_ra8_ok;
416}
417
419static void drw_blend_print_hex(uint32_t value)
420{
421 static const uint8_t k_hex[] = "0123456789ABCDEF";
422 uint8_t out[(uint32_t)k_drw_blend_hex_digit];
423 for (uint32_t i = 0U; i < (uint32_t)k_drw_blend_hex_digit; ++i) {
424 const uint32_t shift = ((uint32_t)k_drw_blend_hi_nibble - i) * (uint32_t)k_drw_blend_nib_bits;
425 out[i] = k_hex[(value >> shift) & (uint32_t)k_drw_blend_nib_mask];
426 }
427 (void)ra8_board_uart_console_write(out, (size_t)sizeof(out));
428}
429
431static void drw_blend_print_pass(uint32_t crc)
432{
434 (size_t)(sizeof(k_drw_blend_pass_pfx) - 1U));
437 (size_t)(sizeof(k_drw_blend_pass_sfx) - 1U));
438}
439
440void main(void)
441{
443 /* Clear PRIMASK so SysTick can dispatch and ra8_delay_ms() uses the
444 * SysTick path (ra8_emulator does not advance DWT_CYCCNT). No NVIC sources
445 * are armed by this demo. */
447
448 if (drw_blend_configure() != k_ra8_ok) {
450 }
451
452 while (1) {
453 uint32_t crc = 0U;
454 const ra8_err_t err = drw_blend_render(&crc);
455 if (err == k_ra8_ok) {
456 g_drw_blend_crc = crc;
459 } else {
461 (size_t)(sizeof(k_drw_blend_fail_msg) - 1U));
463 }
466 }
468}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static ra8_err_t drw_blend_render(uint32_t *out_crc)
Render the three layers (background, sprite, blended foreground).
Definition main.c:370
static const uint8_t k_drw_blend_pass_pfx[]
Success / failure banner text.
Definition main.c:138
static void drw_blend_setup_or_halt(void)
Bring CGC + SysTick + SCI8 + LEDs + MSTP up.
Definition main.c:184
drw_blend_geom_t
Framebuffer + layer rectangle geometry, in pixels.
Definition main.c:128
@ k_drw_blend_fb_dim
32 x 32 framebuffer.
Definition main.c:129
@ k_drw_blend_fg_wh
Foreground 16 x 16.
Definition main.c:133
@ k_drw_blend_sp_xy
Sprite top-left (8, 8).
Definition main.c:130
@ k_drw_blend_sp_wh
Sprite 16 x 16.
Definition main.c:131
@ k_drw_blend_fg_xy
Foreground top-left (4, 4).
Definition main.c:132
@ k_drw_blend_full_org
Full-FB origin (0, 0).
Definition main.c:134
static ra8_err_t drw_blend_fill(int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t argb)
Issue one opaque ra8_drw_fill_rect and wait for the engine.
Definition main.c:263
static uint32_t drw_blend_framebuffer_hash(void)
FNV-1a-32 over the rendered framebuffer bytes.
Definition main.c:334
static void drw_blend_panic_halt(void)
Park forever after a fatal init failure.
Definition main.c:176
volatile uint32_t g_drw_blend_err
Non-zero if a DRW call returned an error during the last render.
Definition main.c:165
volatile uint32_t g_drw_blend_heartbeat
Bumps once per main-loop pass – liveness for headless probes.
Definition main.c:173
drw_blend_hash_t
Byte / nibble constants for the FNV hash and hex banner formatting.
Definition main.c:89
@ k_drw_blend_nib_mask
Low-nibble mask for the hex digit.
Definition main.c:95
@ k_drw_blend_hex_digit
Hex digits in a 32-bit CRC.
Definition main.c:92
@ k_drw_blend_byte_bits
Bits per byte (FNV shift step).
Definition main.c:90
@ k_drw_blend_nib_bits
Bits per hex nibble.
Definition main.c:94
@ k_drw_blend_hi_nibble
Index of the most-significant nibble.
Definition main.c:93
@ k_drw_blend_byte_mask
Low-byte mask for the FNV input.
Definition main.c:91
drw_blend_config_t
Compile-time scalar settings for the demo.
Definition main.c:72
@ k_drw_blend_alpha
Global source-over alpha (128).
Definition main.c:76
@ k_drw_blend_fnv_offset
FNV-1a-32 offset basis.
Definition main.c:77
@ k_drw_blend_idle_budget
Bounded wait_idle poll budget.
Definition main.c:75
@ k_drw_blend_fnv_prime
FNV-1a-32 prime.
Definition main.c:78
@ k_drw_blend_period_ms
Delay between renders.
Definition main.c:74
@ k_drw_blend_baud
SCI8 baud rate.
Definition main.c:73
static const uint8_t k_drw_blend_fail_msg[]
Definition main.c:140
static const uint8_t k_drw_blend_pass_sfx[]
Definition main.c:139
static ra8_err_t drw_blend_arm(void)
Arm the blend unit for opaque-over (source-over) global-alpha mixing.
Definition main.c:302
static void drw_blend_print_pass(uint32_t crc)
Emit the success banner: prefix + 8 hex CRC + " PASS\r\n".
Definition main.c:431
drw_blend_color_t
ARGB8888 colours used by the three render layers.
Definition main.c:106
@ k_drw_blend_fg_a80
Foreground at global alpha 0x80.
Definition main.c:110
@ k_drw_blend_fg_argb
Red foreground source RGB.
Definition main.c:109
@ k_drw_blend_bg_argb
Opaque dark-blue background.
Definition main.c:107
@ k_drw_blend_sp_argb
Opaque green sprite.
Definition main.c:108
volatile uint32_t g_drw_blend_crc
FNV-1a-32 hash of the last rendered framebuffer.
Definition main.c:157
static void drw_blend_print_hex(uint32_t value)
Print one hex nibble's worth of the 32-bit CRC over the console.
Definition main.c:419
static ra8_err_t drw_blend_configure(void)
Bring up the DRW engine pointed at g_drw_blend_fb.
Definition main.c:227
volatile uint32_t g_drw_blend_fb[(uint32_t) k_drw_blend_fb_dim *(uint32_t) k_drw_blend_fb_dim]
32 x 32 ARGB8888 framebuffer the DRW composites into.
Definition main.c:149
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_led_toggle(ra8_board_led_id_t led)
Toggle led's output state.
ra8_err_t ra8_board_led_init(ra8_board_led_id_t led)
Configure led as a digital output, initial level low (off).
@ k_ra8_board_led2
LED2, GREEN, P303 (jumper E26).
@ k_ra8_board_led1
LED1, BLUE, P600 (jumper E27).
ra8_err_t ra8_board_uart_console_write(const uint8_t *data, size_t len)
Polled blocking write to the J-Link OB VCOM console.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_get_clock_hz(ra8_clock_id_t id, uint32_t *out_hz)
Query the current frequency of a clock-tree domain.
Definition ra8_cgc.c:132
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
Definition ra8_cgc.h:70
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
2D Drawing Engine (DRW / D/AVE 2D) HAL driver – public API
ra8_err_t ra8_drw_fill_rect(const ra8_drw_rect_t *rect)
Issue a solid-fill rectangle blit into the framebuffer.
ra8_err_t ra8_drw_init(const ra8_drw_config_t *cfg)
Power on the DRW block, install the supplied configuration, and arm the IRQ control register.
Definition ra8_drw.c:491
ra8_err_t ra8_drw_wait_idle(uint32_t poll_budget)
Poll STATUS until all "busy" bits clear or budget runs out.
Definition ra8_drw.c:631
ra8_err_t ra8_drw_set_gradient(const ra8_drw_gradient_t *grad)
Programme the COLOR1 and COLOR2 registers from a 2-stop gradient.
Definition ra8_drw.c:713
ra8_err_t ra8_drw_set_blend(const ra8_drw_blend_t *blend)
Configure the alpha-blend unit using ra8_drw_blend_t fields.
Definition ra8_drw.c:805
@ k_ra8_drw_writefmt_argb8888
32 bpp ARGB8888.
Error Code Definitions for ra8-firmware.
@ 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
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_init(void)
Re-establish the ra8_mstp ref-count table from current hardware state.
Definition ra8_mstp.c:291
SysTick-based tick counter, delay and timestamp helpers.
ra8_err_t ra8_time_init(uint32_t cpu_hz)
Initialise SysTick for a 1 kHz tick interrupt.
Definition ra8_time.c:59
void ra8_delay_ms(uint32_t ms)
Busy-wait for at least ms milliseconds.
Definition ra8_time.c:129
Per-pixel + global alpha blending parameters.
Definition ra8_drw.h:114
Minimal DRW configuration captured by ra8_drw_init.
Definition ra8_drw.h:79
COLOR1 + COLOR2 two-stop gradient.
Definition ra8_drw.h:204
Rectangle parameters for ra8_drw_fill_rect.
Definition ra8_drw.h:96