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
34
35#include <stdint.h>
36
37#include "ra8_board_ek_ra8d2.h"
38#include "ra8_boot_entry.h"
39#include "ra8_cgc.h"
40#include "ra8_err.h"
41#include "ra8_isr.h"
42#include "ra8_mstp.h"
43#include "ra8_sdramc.h"
44#include "ra8_sdramc_regs.h"
45#include "ra8_time.h"
46
55
68
77typedef struct {
78 uint32_t count;
79 uint32_t first_idx;
80 uint32_t expected;
81 uint32_t got;
83
85typedef enum : uint32_t {
88
92static const uint8_t k_sdram_demo_pass_msg[] = "sdram: bench OK\r\n";
93
100static void sdram_demo_panic_halt(void)
101{
102 while (1) {
103 __asm__ volatile("wfi");
104 }
105}
106
113{
114 uint32_t cpuclk0_hz = 0U;
115
116 if (ra8_cgc_init() != k_ra8_ok) {
118 }
121 }
122 if (ra8_mstp_init() != k_ra8_ok) {
124 }
125 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
127 }
130 }
131 if (ra8_sdramc_init() != k_ra8_ok) {
133 }
136 }
139 }
140}
141
159static uint32_t sdram_demo_mbps(uint32_t bytes, uint32_t ms)
160{
161 const uint32_t ms_clamped = (ms == 0U) ? 1U : ms;
162 return bytes / (ms_clamped * (uint32_t)k_sdram_demo_us_per_ms);
163}
164
175static uint32_t sdram_demo_write_pass(uint32_t base)
176{
177 volatile uint32_t* mem = (volatile uint32_t*)k_ra8_sdram_base_addr;
178 const uint32_t start_ms = ra8_time_ms();
179 for (uint32_t i = 0U; i < (uint32_t)k_sdram_demo_block_words; i++) {
180 mem[i] = base + i;
181 }
182 return ra8_time_ms() - start_ms;
183}
184
198static bool sdram_demo_read_check(uint32_t base, uint32_t* elapsed, sdram_demo_diag_t* diag)
199{
200 const volatile uint32_t* mem = (const volatile uint32_t*)k_ra8_sdram_base_addr;
201 const uint32_t start_ms = ra8_time_ms();
202 diag->count = 0U;
203 for (uint32_t i = 0U; i < (uint32_t)k_sdram_demo_block_words; i++) {
204 const uint32_t got = mem[i];
205 if (got != base + i) {
206 if (diag->count == 0U) {
207 diag->first_idx = i;
208 diag->expected = base + i;
209 diag->got = got;
210 }
211 diag->count++;
212 }
213 }
214 *elapsed = ra8_time_ms() - start_ms;
215 return diag->count == 0U;
216}
217
229static uint8_t sdram_demo_uint_to_hex(uint8_t* buf, uint32_t v)
230{
231 for (uint8_t i = 0U; i < (uint8_t)k_sdram_demo_hex_digits; i++) {
232 const uint8_t shift =
233 (uint8_t)(((uint8_t)k_sdram_demo_hex_digits - 1U - i) * (uint8_t)k_sdram_demo_nyb_bits);
234 const uint8_t nyb = (uint8_t)((v >> shift) & (uint32_t)k_sdram_demo_nyb_mask);
235 buf[i] = (nyb < (uint8_t)k_sdram_demo_dec_base)
236 ? (uint8_t)((uint8_t)k_sdram_demo_ascii_zero + nyb)
237 : (uint8_t)((uint8_t)k_sdram_demo_ascii_a +
238 (uint8_t)(nyb - (uint8_t)k_sdram_demo_dec_base));
239 }
240 return (uint8_t)k_sdram_demo_hex_digits;
241}
242
254static uint8_t sdram_demo_uint_to_dec(uint8_t* buf, uint32_t v)
255{
256 uint8_t tmp[k_sdram_demo_uint_dec_max];
257 uint8_t n = 0U;
258 uint32_t r = v;
259 if (r == 0U) {
260 buf[0] = (uint8_t)k_sdram_demo_ascii_zero;
261 return 1U;
262 }
263 while ((r > 0U) && (n < (uint8_t)k_sdram_demo_uint_dec_max)) {
264 tmp[n] =
265 (uint8_t)((uint8_t)k_sdram_demo_ascii_zero + (uint8_t)(r % (uint32_t)k_sdram_demo_dec_base));
266 r = r / (uint32_t)k_sdram_demo_dec_base;
267 n++;
268 }
269 for (uint8_t i = 0U; i < n; i++) {
270 buf[i] = tmp[(uint8_t)(n - 1U - i)];
271 }
272 return n;
273}
274
288static uint32_t sdram_demo_format_line(uint8_t* out, uint32_t w_mbps, uint32_t r_mbps)
289{
290 uint32_t off = 0U;
291 const uint8_t prefix[] = "sdram: w=";
292 const uint8_t mid[] = " MB/s r=";
293 const uint8_t suffix[] = " MB/s\r\n";
294 for (uint32_t i = 0U; i < sizeof(prefix) - 1U; i++) {
295 out[off++] = prefix[i];
296 }
297 off += sdram_demo_uint_to_dec(&out[off], w_mbps);
298 for (uint32_t i = 0U; i < sizeof(mid) - 1U; i++) {
299 out[off++] = mid[i];
300 }
301 off += sdram_demo_uint_to_dec(&out[off], r_mbps);
302 for (uint32_t i = 0U; i < sizeof(suffix) - 1U; i++) {
303 out[off++] = suffix[i];
304 }
305 return off;
306}
307
324static uint32_t sdram_demo_format_fail(uint8_t* out, const sdram_demo_diag_t* diag)
325{
326 uint32_t off = 0U;
327 const uint8_t prefix[] = "sdram: FAIL idx=";
328 const uint8_t exp_tag[] = " exp=";
329 const uint8_t got_tag[] = " got=";
330 const uint8_t n_tag[] = " n=";
331 const uint8_t suffix[] = "\r\n";
332 for (uint32_t i = 0U; i < sizeof(prefix) - 1U; i++) {
333 out[off++] = prefix[i];
334 }
335 off += sdram_demo_uint_to_dec(&out[off], diag->first_idx);
336 for (uint32_t i = 0U; i < sizeof(exp_tag) - 1U; i++) {
337 out[off++] = exp_tag[i];
338 }
339 off += sdram_demo_uint_to_hex(&out[off], diag->expected);
340 for (uint32_t i = 0U; i < sizeof(got_tag) - 1U; i++) {
341 out[off++] = got_tag[i];
342 }
343 off += sdram_demo_uint_to_hex(&out[off], diag->got);
344 for (uint32_t i = 0U; i < sizeof(n_tag) - 1U; i++) {
345 out[off++] = n_tag[i];
346 }
347 off += sdram_demo_uint_to_dec(&out[off], diag->count);
348 for (uint32_t i = 0U; i < sizeof(suffix) - 1U; i++) {
349 out[off++] = suffix[i];
350 }
351 return off;
352}
353
365void main(void)
366{
369
370 uint32_t base = (uint32_t)k_sdram_demo_pattern_seed;
371 while (1) {
372 const uint32_t w_ms = sdram_demo_write_pass(base);
373 uint32_t r_ms = 0U;
374 sdram_demo_diag_t diag = {};
375 const bool match = sdram_demo_read_check(base, &r_ms, &diag);
376 const uint32_t w_mbps = sdram_demo_mbps((uint32_t)k_sdram_demo_block_bytes, w_ms);
377 const uint32_t r_mbps = sdram_demo_mbps((uint32_t)k_sdram_demo_block_bytes, r_ms);
378
379 uint8_t out[k_sdram_demo_print_buf] = {};
380 const uint32_t off = sdram_demo_format_line(out, w_mbps, r_mbps);
381 if (!match) {
383 /* Emit a FAIL diagnostic so the HIL negative regex catches a
384 * read-back mismatch and a log reader sees the corruption
385 * signature (first index, expected vs got, total count). */
386 uint8_t fail[k_sdram_demo_fail_buf] = {};
387 const uint32_t fail_off = sdram_demo_format_fail(fail, &diag);
388 (void)ra8_board_uart_console_write(fail, (size_t)fail_off);
389 }
390 if (ra8_board_uart_console_write(out, (size_t)off) != k_ra8_ok) {
391 break;
392 }
393 /* Success-only verdict for the HIL scrape: a clean read-back pass. */
394 if (match) {
396 (size_t)(sizeof(k_sdram_demo_pass_msg) - 1U));
397 }
399 break;
400 }
401 base += 1U;
403 }
404
406}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static uint32_t sdram_demo_format_line(uint8_t *out, uint32_t w_mbps, uint32_t r_mbps)
Format the per-cycle MB/s line into out, return its length.
Definition main.c:288
static const uint8_t k_sdram_demo_pass_msg[]
Verdict line emitted only when a read-back pass matched every word (never on a "sdram: FAIL idx=" pat...
Definition main.c:92
static uint32_t sdram_demo_write_pass(uint32_t base)
Write base + i into every word of the SDRAM block.
Definition main.c:175
static uint8_t sdram_demo_uint_to_dec(uint8_t *buf, uint32_t v)
Write a decimal uint32 into buf; returns bytes written.
Definition main.c:254
sdram_demo_seed_t
Pattern seed – recognisable hex word for SWD inspection.
Definition main.c:85
@ k_sdram_demo_pattern_seed
SDRAM demo pattern seed.
Definition main.c:86
static void sdram_demo_panic_halt(void)
Park forever after a fatal init failure.
Definition main.c:100
static void sdram_demo_setup_or_halt(void)
Bring CGC + SysTick + console + SDRAM up.
Definition main.c:112
static uint32_t sdram_demo_mbps(uint32_t bytes, uint32_t ms)
Compute throughput in MB/s given a byte count and millisecond span.
Definition main.c:159
sdram_demo_byte_t
Single-byte ASCII conversion constants.
Definition main.c:57
@ k_sdram_demo_uint_dec_max
Max digits in a uint32 base-10.
Definition main.c:61
@ k_sdram_demo_ascii_a
SDRAM demo ascii a.
Definition main.c:59
@ k_sdram_demo_nyb_bits
Bits per hex nibble.
Definition main.c:65
@ k_sdram_demo_print_buf
Max bytes in one throughput line.
Definition main.c:62
@ k_sdram_demo_nyb_mask
Mask for one nibble.
Definition main.c:66
@ k_sdram_demo_fail_buf
Max bytes in the FAIL diag line.
Definition main.c:63
@ k_sdram_demo_dec_base
SDRAM demo dec base.
Definition main.c:60
@ k_sdram_demo_ascii_zero
SDRAM demo ascii zero.
Definition main.c:58
@ k_sdram_demo_hex_digits
Hex digits in a uint32.
Definition main.c:64
sdram_demo_const_t
App-wide tunables.
Definition main.c:48
@ k_sdram_demo_block_bytes
64 KB window per pass.
Definition main.c:51
@ k_sdram_demo_period_ms
SDRAM demo period ms.
Definition main.c:50
@ k_sdram_demo_block_words
65536 / sizeof(uint32_t).
Definition main.c:52
@ k_sdram_demo_baud
SDRAM demo baud.
Definition main.c:49
@ k_sdram_demo_us_per_ms
Conversion factor used in mbps.
Definition main.c:53
static uint8_t sdram_demo_uint_to_hex(uint8_t *buf, uint32_t v)
Render v as exactly 8 lowercase hex digits into buf.
Definition main.c:229
static uint32_t sdram_demo_format_fail(uint8_t *out, const sdram_demo_diag_t *diag)
Format the read-back FAIL diagnostic line into out.
Definition main.c:324
static bool sdram_demo_read_check(uint32_t base, uint32_t *elapsed, sdram_demo_diag_t *diag)
Read every word back and check it matches base + i.
Definition main.c:198
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).
ra8_err_t ra8_board_led_on(ra8_board_led_id_t led)
Drive led HIGH (light it).
@ 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
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
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
External SDRAM controller driver (framework).
ra8_err_t ra8_sdramc_init(void)
Initialise the external SDRAM at k_ra8_sdram_base_addr.
Definition ra8_sdramc.c:257
External SDRAM controller register layout for the Renesas RA8D2.
@ k_ra8_sdram_base_addr
External SDRAM window.
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
uint32_t ra8_time_ms(void)
Get the current 1 kHz tick count.
Definition ra8_time.c:108
First-mismatch diagnostic captured by sdram_demo_read_check.
Definition main.c:77
uint32_t expected
Value that should have been read back.
Definition main.c:80
uint32_t got
Value actually read back at first_idx.
Definition main.c:81
uint32_t first_idx
Word index of the first mismatch.
Definition main.c:79
uint32_t count
Total mismatched words in the pass.
Definition main.c:78