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
63
64#include <stdint.h>
65
66#include "ra8_attributes.h"
67#include "ra8_board_ek_ra8d2.h"
68#include "ra8_boot_entry.h"
69#include "ra8_cache.h"
70#include "ra8_cgc.h"
71#include "ra8_dmac.h"
72#include "ra8_dmac_regs.h"
73#include "ra8_err.h"
74#include "ra8_isr.h"
75#include "ra8_log.h"
76#include "ra8_mstp.h"
77
79typedef enum : uint32_t {
80 k_dma_coh_baud = 115200U,
83 k_dma_coh_sentinel = 0xA5A5A5A5U,
85
87typedef enum : uint8_t {
92
94static const uint8_t s_dma_coh_pass_banner[] = "dma_coherency_hil: dma coherent PASS\r\n";
95
97static const uint8_t s_dma_coh_fail_banner[] = "dma_coherency_hil: dma coherent FAIL\r\n";
98
110alignas(k_dma_coh_align) static uint32_t s_src[k_dma_coh_buf_words];
111
123alignas(k_dma_coh_align) static uint32_t s_dst[k_dma_coh_buf_words];
124
140[[noreturn]] RA8_INTERNAL static void internal_park(void)
141{
142 while (1) {
143 __asm__ volatile("wfi");
144 }
145}
146
164{
165 if (ra8_cgc_init() != k_ra8_ok) {
167 }
168 if (ra8_mstp_init() != k_ra8_ok) {
170 }
173 }
176 }
179 }
180}
181
202{
203 for (uint32_t i = 0U; i < (uint32_t)k_dma_coh_buf_words; ++i) {
204 s_src[i] = i ^ (i >> (uint32_t)k_dma_coh_byte_sh);
205 s_dst[i] = (uint32_t)k_dma_coh_sentinel;
206 }
207}
208
233[[nodiscard]] RA8_INTERNAL static uint8_t internal_verify(void)
234{
235 for (uint32_t i = 0U; i < (uint32_t)k_dma_coh_buf_words; ++i) {
236 if (s_dst[i] != s_src[i]) {
237 return 0U;
238 }
239 }
240 return 1U;
241}
242
277[[nodiscard]] RA8_INTERNAL static ra8_err_t internal_run_copy(void)
278{
279 /* clean-before: dirty src lines -> SRAM so the DMAC reads fresh bytes. */
280 if (ra8_cache_dcache_clean_by_addr(s_src, (uint32_t)sizeof(s_src)) != k_ra8_ok) {
281 return k_ra8_err_hw_error;
282 }
283
284 const ra8_dmac_config_t cfg = {
285 .src = (uint32_t)(uintptr_t)s_src,
286 .dst = (uint32_t)(uintptr_t)s_dst,
287 .count = (uint16_t)k_dma_coh_buf_words,
288 .block_count = 1U,
289 .width = k_ra8_dmac_width_word,
290 .src_inc = true,
291 .dst_inc = true,
292 };
294 if (err != k_ra8_ok) {
295 return err;
296 }
297
298 volatile r_dmac_channel_regs_t* reg = ra8_dmac((uint8_t)k_dma_coh_channel);
299 if (reg == nullptr) {
300 (void)ra8_dmac_stop((uint8_t)k_dma_coh_channel);
301 return k_ra8_err_hw_error;
302 }
303
304 /* Software trigger: assert DMREQ.SWREQ to request the block transfer.
305 * HUM Ch 17.2.15 p 744: write SWREQ=1; the bit auto-clears when the
306 * controller accepts the request (CLRS=0 is the reset default). */
307 reg->DMREQ = (uint8_t)k_ra8_dmreq_swreq_mask;
308
309 /* Poll DMSTS.ACT until the controller goes idle.
310 * HUM Ch 17.2.16 p 745: ACT clears when the transfer completes. */
311 bool done = false;
312 for (uint32_t i = 0U; i < (uint32_t)k_dma_coh_poll_limit; ++i) {
313 if ((reg->DMSTS & (uint8_t)k_ra8_dmsts_act_mask) == 0U) {
314 done = true;
315 break;
316 }
317 }
318 err = ra8_dmac_stop((uint8_t)k_dma_coh_channel);
319 if (!done) {
321 }
322 if (err != k_ra8_ok) {
323 return err;
324 }
325
326 /* invalidate-after: drop stale dst lines so the verify reads SRAM. */
327 if (ra8_cache_dcache_invalidate_by_addr(s_dst, (uint32_t)sizeof(s_dst)) != k_ra8_ok) {
328 return k_ra8_err_hw_error;
329 }
330 return k_ra8_ok;
331}
332
350RA8_INTERNAL static void internal_report(uint8_t ok)
351{
352 if (ok != 0U) {
354 (size_t)(sizeof(s_dma_coh_pass_banner) - 1U));
356 ra8_log_info("dma_coherency_hil", "dma coherent PASS");
358 } else {
360 (size_t)(sizeof(s_dma_coh_fail_banner) - 1U));
362 ra8_log_info("dma_coherency_hil", "dma coherent FAIL");
364 }
365}
366
377void main(void)
378{
381
383 const ra8_err_t err = internal_run_copy();
384 const uint8_t ok = (err == k_ra8_ok && internal_verify() != 0U) ? 1U : 0U;
385 internal_report(ok);
386
388}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static uint32_t s_src[k_dtc_arm_buf_words]
Source / destination buffers (32-bit aligned by element type).
Definition main.c:181
static uint32_t s_dst[k_dtc_arm_buf_words]
Definition main.c:182
static void internal_setup_or_halt(void)
Bring up clocks, MSTP, delay timing, and the board console.
Definition main.c:211
static void internal_report(uint8_t ok)
Emit the PASS/FAIL result over VCOM and ITM, toggle an LED.
Definition main.c:350
dma_coh_byte_t
Single-byte constants.
Definition main.c:87
@ k_dma_coh_align
D-cache line size (bytes).
Definition main.c:90
@ k_dma_coh_channel
DMAC0 channel index.
Definition main.c:88
@ k_dma_coh_byte_sh
Pattern xor shift.
Definition main.c:89
dma_coh_config_t
Compile-time settings.
Definition main.c:79
@ k_dma_coh_buf_words
Words per buffer (256 x 4 = 1 KiB).
Definition main.c:81
@ k_dma_coh_poll_limit
DMSTS.ACT poll bound.
Definition main.c:82
@ k_dma_coh_baud
J-Link OB VCOM baud rate.
Definition main.c:80
@ k_dma_coh_sentinel
Pre-fill so a no-op copy fails.
Definition main.c:83
static ra8_err_t internal_run_copy(void)
Clean src, run the DMAC block copy, then invalidate dst.
Definition main.c:277
static const uint8_t s_dma_coh_pass_banner[]
VCOM success banner.
Definition main.c:94
static void internal_fill_buffers(void)
Fill s_src with a deterministic pattern; prime s_dst.
Definition main.c:201
static uint8_t internal_verify(void)
Verify s_dst matches s_src element-by-element.
Definition main.c:233
static const uint8_t s_dma_coh_fail_banner[]
VCOM failure banner (caught by hil.conf HIL_EXPECT_NEGATIVE).
Definition main.c:97
static void internal_park(void)
Halt forever in WFI – panic stop on a fatal init failure.
Definition main.c:140
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
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.
ra8_err_t ra8_board_uart_console_flush(void)
Block until every byte queued on the J-Link OB VCOM console has finished clocking out on the wire.
Boot entry points shared between a vector table and its startup code.
Cortex-M85 L1 cache maintenance, enable/disable, and I-cache invalidate.
ra8_err_t ra8_cache_dcache_invalidate_by_addr(const void *addr, uint32_t size)
Invalidate (drop) the D-cache lines covering a byte range.
Definition ra8_cache.c:185
ra8_err_t ra8_cache_dcache_clean_by_addr(const void *addr, uint32_t size)
Clean (write back) the D-cache lines covering a byte range.
Definition ra8_cache.c:180
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
8-channel DMA controller (DMAC0) driver
@ k_ra8_dmac_width_word
32-bit transfers (DMTMD.SZ = 10b).
Definition ra8_dmac.h:53
ra8_err_t ra8_dmac_stop(uint8_t channel)
Disable a DMAC0 channel and drop its MSTP reference.
Definition ra8_dmac.c:432
ra8_err_t ra8_dmac_start_block(uint8_t channel, const ra8_dmac_config_t *cfg)
Programme a DMAC channel in block-transfer mode.
Definition ra8_dmac.c:483
DMAC (Direct Memory Access Controller) register layout for the RA8D2.
static volatile r_dmac_channel_regs_t * ra8_dmac(uint8_t channel)
Pointer to DMAC channel channel (0..7), or NULL on error.
@ k_ra8_dmreq_swreq_mask
RA8 dmreq swreq mask.
@ k_ra8_dmsts_act_mask
RA8 dmsts act mask.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
Definition ra8_err.h:304
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_hw_error
Generic hardware fault detected (error flag set, fault interrupt).
Definition ra8_err.h:310
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
Lightweight Logging Interface for ra8-firmware.
#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_init(void)
Re-establish the ra8_mstp ref-count table from current hardware state.
Definition ra8_mstp.c:291
Per-channel DMAC register window.
volatile uint8_t DMSTS
+0x1E Status (ESIF/DTIF/ACT).
volatile uint8_t DMREQ
+0x1D Software Start (SWREQ/CLRS).
DMAC channel configuration.
Definition ra8_dmac.h:121