ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c File Reference

SPI-mode SD card round-trip HIL demo for the EK-RA8D2. More...

#include <stdint.h>
#include <string.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_cgc.h"
#include "ra8_err.h"
#include "ra8_fs.h"
#include "ra8_gpio_constants.h"
#include "ra8_isr.h"
#include "ra8_log.h"
#include "ra8_port_constants.h"
#include "ra8_port_utils.h"
#include "ra8_sci_spi.h"
#include "ra8_sdmmc_spi.h"
#include "ra8_spi.h"
#include "ra8_time.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  sd_demo_config_t : uint32_t {
  k_sd_decimal_base = 10U ,
  k_sd_spi_idle_byte = 0xFFU ,
  k_sd_prng_byte_shift = 16U ,
  k_sd_byte_mask = 0xFFU ,
  k_sd_demo_uart_baud = 115200U ,
  k_sd_demo_spi_channel = 0U ,
  k_sd_demo_payload_bytes = 4096U ,
  k_sd_demo_prng_seed = 0x5EEDC0DEUL ,
  k_sd_demo_prng_mul = 1664525UL ,
  k_sd_demo_prng_add = 1013904223UL
}
 Compile-time settings for the SD round-trip demo. More...
enum  sd_demo_mb_t : uint32_t { k_sd_demo_blocks_per_mib = 2048U }
 Conversion factor 512-byte blocks -> MiB. More...

Functions

static void sd_demo_print (const uint8_t *msg, uint32_t len)
 Write a NUL-terminated ASCII byte run on the BSP console (SCI8).
static void sd_demo_print_u32 (uint32_t value)
 Write the decimal expansion of value on SCI8.
static void sd_demo_panic_halt (void)
 Halt forever in WFI – panic stop on irrecoverable boot failure.
static ra8_err_t sd_demo_spi_set_clock (void *ctx, uint32_t hz)
 ra8_sdmmc_spi_transport_t::set_clock shim over ra8_spi.
static ra8_err_t sd_demo_spi_cs (void *ctx, bool asserted)
 ra8_sdmmc_spi_transport_t::cs shim over ra8_gpio.
static ra8_err_t sd_demo_spi_xfer (void *ctx, const uint8_t *tx, uint8_t *rx, uint32_t len)
 ra8_sdmmc_spi_transport_t::xfer shim over ra8_sci_spi_xfer.
static ra8_err_t sd_demo_spi_pins_init (void)
 Route Pmod2 pins to SCI0 Simple-SPI and claim CS as a GPIO output.
static void sd_demo_setup_or_halt (uint32_t *out_pclka_hz)
 Bring up CGC + SysTick + console SCI + SPI + CS GPIO.
static void sd_demo_fill_payload (uint8_t *buf, uint32_t len)
 Fill buf with a fixed-seed LCG pseudo-random sequence.
static ra8_err_t sd_demo_write_payload (ra8_fs_mount_t *mount, const uint8_t *payload, uint32_t len)
 Write the payload to TEST.TXT on the mounted volume.
static ra8_err_t sd_demo_read_payload (ra8_fs_mount_t *mount, uint8_t *buf, uint32_t cap, uint32_t *out_len)
 Read the payload back into buf and report bytes copied.
static void sd_demo_print_capacity (void)
 Print the detected card capacity in MiB on SCI8.
static void sd_demo_compare_and_report (const uint8_t *a, const uint8_t *b, uint32_t got)
 Compare payload buffers and print "ok" or first-mismatch offset.
static void sd_demo_init_card_or_halt (uint32_t *pclka_hz)
 Init the SD driver and panic-halt with a diagnostic on failure.
static ra8_fs_mount_tsd_demo_mount_or_halt (void)
 Bind the SD backend, mount the FAT volume, panic-halt on failure.
void main (void)
 Application entry: bring up the bus, probe the SD card, write a payload, read it back, compare, print result.

Variables

static const ra8_port_pin_t k_sd_demo_pin_sck = (ra8_port_pin_t)k_ra8_board_pmod2_spi_sck
 Pmod2 SPI pins (J25) – SCI0 Simple-SPI per HUM Table 20.13.
static const ra8_port_pin_t k_sd_demo_pin_cipo = (ra8_port_pin_t)k_ra8_board_pmod2_spi_cipo
static const ra8_port_pin_t k_sd_demo_pin_copi = (ra8_port_pin_t)k_ra8_board_pmod2_spi_copi
static const ra8_port_pin_t k_sd_demo_pin_cs = (ra8_port_pin_t)k_ra8_board_pmod2_spi_cs
static const uint8_t k_sd_demo_msg_boot [] = "sd: boot\r\n"
 Static message strings – ASCII-only per project policy.
static const uint8_t k_sd_demo_msg_init_ok [] = "sd: card ready\r\n"
static const uint8_t k_sd_demo_msg_mount_ok [] = "sd: fs mounted\r\n"
static const uint8_t k_sd_demo_msg_ok [] = "sd: roundtrip ok\r\n"
static const uint8_t k_sd_demo_msg_card_pre [] = "sd: card="
static const uint8_t k_sd_demo_msg_mb_suf [] = " MB\r\n"
static const uint8_t k_sd_demo_msg_init_fail [] = "sd: FAIL init\r\n"
static const uint8_t k_sd_demo_msg_mount_fail [] = "sd: FAIL mount\r\n"
static const uint8_t k_sd_demo_msg_write_fail [] = "sd: FAIL write\r\n"
static const uint8_t k_sd_demo_msg_read_fail [] = "sd: FAIL read\r\n"
static const uint8_t k_sd_demo_msg_cmp_pre [] = "sd: FAIL @ offset "
static const uint8_t k_sd_demo_msg_eol [] = "\r\n"

Detailed Description

SPI-mode SD card round-trip HIL demo for the EK-RA8D2.

Tag
[Ring 6 / APP] {World: S}

Standalone EVM-tier app that exercises the ra8_sdmmc_spi driver against a Digilent PMOD MicroSD (part 410-380, Digikey 1286-1200-ND) plugged into Pmod2 (J25) on the EK-RA8D2. The flow:

  1. ra8_cgc_init – CPUCLK0 = 1 GHz, PCLKA = 125 MHz, SCICLK = 100 MHz.
  2. Route SCI8 (TXD8 = PD02, RXD8 = PD03) for the J-Link OB CDC console at 115200 8N1 – this is the same console as uart_hello and is what the HIL runner scrapes.
  3. Route Pmod2 SPI pins (P601 RSPCKB, P602 MISOB, P603 MOSIB, P604 SSLB0) per EK-RA8D2 v1 User's Manual Table 19 p 27. The chip-select line is claimed as a plain GPIO so the SD driver can hold it asserted across multi-byte command frames (the SCI hardware CS pulses per byte, which the SD SPI mode protocol cannot tolerate – SD spec PHY v9 section 7.2.4).
  4. ra8_sci_spi_init channel 0 (SCI0 Simple-SPI) at 400 kHz, mode 0, MSB-first – the SD spec mandates the bus opens at <=400 kHz for the identification phase.
  5. ra8_sdmmc_spi_init runs the standard SPI-mode SD bring-up (CMD0 / CMD8 / ACMD41 / CMD58 / CMD9 / CMD16) and escalates the bus to 25 MHz default-speed on success.
  6. Mount a FAT volume via ra8_fs_mount using the backend adapter shipped with ra8_sdmmc_spi.
  7. Write a fixed-seed pseudo-random payload to /test.txt, seek back to 0, read it into a second buffer, byte-compare.
  8. Print the round-trip result over SCI8. The HIL runner scrapes for the literal sd: roundtrip ok line and treats it as proof the SD path works end-to-end.

Required external hardware: Digilent PMOD MicroSD plugged into J25, with a FAT-formatted (FAT16 or FAT32) microSD card inserted. The demo does NOT format the card.

Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ sd_demo_config_t

enum sd_demo_config_t : uint32_t

Compile-time settings for the SD round-trip demo.

Enumerator
k_sd_decimal_base 

Radix for integer-to-ASCII.

k_sd_spi_idle_byte 

Byte clocked out on read-only SPI xfers.

k_sd_prng_byte_shift 

Bit shift selecting the PRNG output byte.

k_sd_byte_mask 

Low-byte mask.

k_sd_demo_uart_baud 

SD demo UART baud.

k_sd_demo_spi_channel 

Pmod2 / J25 is SCI0 Simple-SPI (HUM Table 20.13).

k_sd_demo_payload_bytes 

SD demo payload bytes.

k_sd_demo_prng_seed 

SD demo prng seed.

k_sd_demo_prng_mul 

Numerical Recipes LCG.

k_sd_demo_prng_add 

SD demo prng add.

Definition at line 74 of file main.c.

◆ sd_demo_mb_t

enum sd_demo_mb_t : uint32_t

Conversion factor 512-byte blocks -> MiB.

Enumerator
k_sd_demo_blocks_per_mib 

1 MiB / 512 B = 2048 blocks.

Definition at line 91 of file main.c.

Function Documentation

◆ main()

void main ( void )

Application entry: bring up the bus, probe the SD card, write a payload, read it back, compare, print result.

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the CPU loops forever after printing the result.
On any HAL init failure the function halts in WFI.
Since
0.1.0

Definition at line 434 of file main.c.

References k_ra8_ok, k_sd_demo_msg_boot, k_sd_demo_msg_read_fail, k_sd_demo_msg_write_fail, k_sd_demo_payload_bytes, memset(), ra8_isr_globals_enable(), ra8_log_init(), s_payload, s_readback, sd_demo_compare_and_report(), sd_demo_fill_payload(), sd_demo_init_card_or_halt(), sd_demo_mount_or_halt(), sd_demo_panic_halt(), sd_demo_print(), sd_demo_print_capacity(), sd_demo_read_payload(), sd_demo_setup_or_halt(), and sd_demo_write_payload().

◆ sd_demo_compare_and_report()

void sd_demo_compare_and_report ( const uint8_t * a,
const uint8_t * b,
uint32_t got )
static

Compare payload buffers and print "ok" or first-mismatch offset.

Definition at line 363 of file main.c.

References k_sd_demo_msg_cmp_pre, k_sd_demo_msg_eol, k_sd_demo_msg_ok, k_sd_demo_payload_bytes, sd_demo_panic_halt(), sd_demo_print(), and sd_demo_print_u32().

Referenced by main().

◆ sd_demo_fill_payload()

void sd_demo_fill_payload ( uint8_t * buf,
uint32_t len )
static

Fill buf with a fixed-seed LCG pseudo-random sequence.

A 32-bit linear-congruential generator (Numerical Recipes) gives a deterministic byte sequence so the test can reseed and compare.

Definition at line 301 of file main.c.

References k_sd_byte_mask, k_sd_demo_prng_add, k_sd_demo_prng_mul, k_sd_demo_prng_seed, and k_sd_prng_byte_shift.

Referenced by main().

◆ sd_demo_init_card_or_halt()

void sd_demo_init_card_or_halt ( uint32_t * pclka_hz)
static

Init the SD driver and panic-halt with a diagnostic on failure.

Definition at line 385 of file main.c.

References k_ra8_ok, k_sd_demo_msg_init_fail, k_sd_demo_msg_init_ok, ra8_sdmmc_spi_init(), sd_demo_panic_halt(), sd_demo_print(), sd_demo_spi_cs(), sd_demo_spi_set_clock(), and sd_demo_spi_xfer().

Referenced by main().

◆ sd_demo_mount_or_halt()

ra8_fs_mount_t * sd_demo_mount_or_halt ( void )
static

Bind the SD backend, mount the FAT volume, panic-halt on failure.

Definition at line 403 of file main.c.

References k_ra8_ok, k_sd_demo_msg_mount_fail, k_sd_demo_msg_mount_ok, ra8_fs_mount(), ra8_sdmmc_spi_bind_fs_backend(), sd_demo_panic_halt(), and sd_demo_print().

Referenced by main().

◆ sd_demo_panic_halt()

void sd_demo_panic_halt ( void )
static

Halt forever in WFI – panic stop on irrecoverable boot failure.

Precondition
Called only after a fatal error in boot.
Postcondition
CPU is parked.
Since
0.1.0

Definition at line 167 of file main.c.

Referenced by main(), sd_demo_compare_and_report(), sd_demo_init_card_or_halt(), sd_demo_mount_or_halt(), and sd_demo_setup_or_halt().

◆ sd_demo_print()

void sd_demo_print ( const uint8_t * msg,
uint32_t len )
static

Write a NUL-terminated ASCII byte run on the BSP console (SCI8).

Definition at line 137 of file main.c.

References ra8_board_uart_console_write().

Referenced by main(), sd_demo_compare_and_report(), sd_demo_init_card_or_halt(), sd_demo_mount_or_halt(), sd_demo_print_capacity(), and sd_demo_print_u32().

◆ sd_demo_print_capacity()

void sd_demo_print_capacity ( void )
static

Print the detected card capacity in MiB on SCI8.

Definition at line 350 of file main.c.

References k_sd_demo_blocks_per_mib, k_sd_demo_msg_card_pre, k_sd_demo_msg_mb_suf, ra8_sdmmc_spi_get_capacity(), sd_demo_print(), and sd_demo_print_u32().

Referenced by main().

◆ sd_demo_print_u32()

void sd_demo_print_u32 ( uint32_t value)
static

Write the decimal expansion of value on SCI8.

Definition at line 145 of file main.c.

References k_sd_decimal_base, and sd_demo_print().

Referenced by sd_demo_compare_and_report(), and sd_demo_print_capacity().

◆ sd_demo_read_payload()

ra8_err_t sd_demo_read_payload ( ra8_fs_mount_t * mount,
uint8_t * buf,
uint32_t cap,
uint32_t * out_len )
staticnodiscard

Read the payload back into buf and report bytes copied.

Definition at line 332 of file main.c.

References k_ra8_fs_mode_read, k_ra8_ok, ra8_fs_close(), ra8_fs_open(), and ra8_fs_read().

Referenced by main().

◆ sd_demo_setup_or_halt()

void sd_demo_setup_or_halt ( uint32_t * out_pclka_hz)
static

Bring up CGC + SysTick + console SCI + SPI + CS GPIO.

Panic on fail.

Parameters
[out]out_pclka_hzCached PCLKA rate (Hz) for the SPI clock shim.
Postcondition
On success, the console is ready to print and SCI0 Simple-SPI is configured at 400 kHz mode-0 MSB-first, CS deasserted.

Definition at line 254 of file main.c.

References k_ra8_clock_id_cpuclk0, k_ra8_clock_id_pclka, k_ra8_ok, k_ra8_sdmmc_spi_clock_init_hz, k_ra8_spi_mode_0, k_sd_demo_spi_channel, k_sd_demo_uart_baud, ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_sci_spi_init(), ra8_time_init(), sd_demo_panic_halt(), and sd_demo_spi_pins_init().

Referenced by main().

◆ sd_demo_spi_cs()

ra8_err_t sd_demo_spi_cs ( void * ctx,
bool asserted )
static

ra8_sdmmc_spi_transport_t::cs shim over ra8_gpio.

Definition at line 197 of file main.c.

References k_ra8_level_high, k_ra8_level_low, k_sd_demo_pin_cs, and ra8_gpio_write().

Referenced by sd_demo_init_card_or_halt().

◆ sd_demo_spi_pins_init()

ra8_err_t sd_demo_spi_pins_init ( void )
staticnodiscard

Route Pmod2 pins to SCI0 Simple-SPI and claim CS as a GPIO output.

Precondition
IOPORT module is reachable.
Postcondition
P601/P602/P603 are in SCI0 Simple-SPI mode; P604 is a GPIO output.

Definition at line 228 of file main.c.

References k_ra8_level_high, k_ra8_ok, k_ra8_psel_sci_async, k_sd_demo_pin_cipo, k_sd_demo_pin_copi, k_sd_demo_pin_cs, k_sd_demo_pin_sck, ra8_gpio_output_init(), and ra8_pfs_route_peripheral().

Referenced by sd_demo_setup_or_halt().

◆ sd_demo_spi_set_clock()

ra8_err_t sd_demo_spi_set_clock ( void * ctx,
uint32_t hz )
static

ra8_sdmmc_spi_transport_t::set_clock shim over ra8_spi.

The mock-friendly transport signature carries PCLKA in the ctx pointer so we can compute the SPBR divisor without reaching into a file-scope global. ctx is a uint32_t* to the cached PCLKA Hz.

Definition at line 188 of file main.c.

References k_sd_demo_spi_channel, and ra8_sci_spi_set_clock().

Referenced by sd_demo_init_card_or_halt().

◆ sd_demo_spi_xfer()

ra8_err_t sd_demo_spi_xfer ( void * ctx,
const uint8_t * tx,
uint8_t * rx,
uint32_t len )
static

ra8_sdmmc_spi_transport_t::xfer shim over ra8_sci_spi_xfer.

ra8_sci_spi_xfer is full-duplex and already handles a NULL tx (shifts idle 0xFF) or NULL rx (discards), so the transport is a thin pass-through.

Definition at line 211 of file main.c.

References k_sd_demo_spi_channel, and ra8_sci_spi_xfer().

Referenced by sd_demo_init_card_or_halt().

◆ sd_demo_write_payload()

ra8_err_t sd_demo_write_payload ( ra8_fs_mount_t * mount,
const uint8_t * payload,
uint32_t len )
staticnodiscard

Write the payload to TEST.TXT on the mounted volume.

Uses the one-shot ra8_fs_write_file so the same path works on FAT and exFAT (exFAT only supports whole-file creation). It does not overwrite: if TEST.TXT already exists from a previous run the existing file is kept, and the read-back below still validates persistence.

Definition at line 319 of file main.c.

References k_ra8_fs_mode_read, k_ra8_ok, ra8_fs_close(), ra8_fs_open(), and ra8_fs_write_file().

Referenced by main().

Variable Documentation

◆ k_sd_demo_msg_boot

const uint8_t k_sd_demo_msg_boot[] = "sd: boot\r\n"
static

Static message strings – ASCII-only per project policy.

Definition at line 121 of file main.c.

Referenced by main().

◆ k_sd_demo_msg_card_pre

const uint8_t k_sd_demo_msg_card_pre[] = "sd: card="
static

Definition at line 125 of file main.c.

Referenced by sd_demo_print_capacity().

◆ k_sd_demo_msg_cmp_pre

const uint8_t k_sd_demo_msg_cmp_pre[] = "sd: FAIL @ offset "
static

Definition at line 131 of file main.c.

Referenced by sd_demo_compare_and_report().

◆ k_sd_demo_msg_eol

const uint8_t k_sd_demo_msg_eol[] = "\r\n"
static

Definition at line 132 of file main.c.

Referenced by sd_demo_compare_and_report().

◆ k_sd_demo_msg_init_fail

const uint8_t k_sd_demo_msg_init_fail[] = "sd: FAIL init\r\n"
static

Definition at line 127 of file main.c.

Referenced by sd_demo_init_card_or_halt().

◆ k_sd_demo_msg_init_ok

const uint8_t k_sd_demo_msg_init_ok[] = "sd: card ready\r\n"
static

Definition at line 122 of file main.c.

Referenced by sd_demo_init_card_or_halt().

◆ k_sd_demo_msg_mb_suf

const uint8_t k_sd_demo_msg_mb_suf[] = " MB\r\n"
static

Definition at line 126 of file main.c.

Referenced by sd_demo_print_capacity().

◆ k_sd_demo_msg_mount_fail

const uint8_t k_sd_demo_msg_mount_fail[] = "sd: FAIL mount\r\n"
static

Definition at line 128 of file main.c.

Referenced by sd_demo_mount_or_halt().

◆ k_sd_demo_msg_mount_ok

const uint8_t k_sd_demo_msg_mount_ok[] = "sd: fs mounted\r\n"
static

Definition at line 123 of file main.c.

Referenced by sd_demo_mount_or_halt().

◆ k_sd_demo_msg_ok

const uint8_t k_sd_demo_msg_ok[] = "sd: roundtrip ok\r\n"
static

Definition at line 124 of file main.c.

Referenced by sd_demo_compare_and_report().

◆ k_sd_demo_msg_read_fail

const uint8_t k_sd_demo_msg_read_fail[] = "sd: FAIL read\r\n"
static

Definition at line 130 of file main.c.

Referenced by main().

◆ k_sd_demo_msg_write_fail

const uint8_t k_sd_demo_msg_write_fail[] = "sd: FAIL write\r\n"
static

Definition at line 129 of file main.c.

Referenced by main().

◆ k_sd_demo_pin_cipo

const ra8_port_pin_t k_sd_demo_pin_cipo = (ra8_port_pin_t)k_ra8_board_pmod2_spi_cipo
static

Definition at line 111 of file main.c.

Referenced by sd_demo_spi_pins_init().

◆ k_sd_demo_pin_copi

const ra8_port_pin_t k_sd_demo_pin_copi = (ra8_port_pin_t)k_ra8_board_pmod2_spi_copi
static

Definition at line 112 of file main.c.

Referenced by sd_demo_spi_pins_init().

◆ k_sd_demo_pin_cs

const ra8_port_pin_t k_sd_demo_pin_cs = (ra8_port_pin_t)k_ra8_board_pmod2_spi_cs
static

Definition at line 113 of file main.c.

Referenced by sd_demo_spi_cs(), and sd_demo_spi_pins_init().

◆ k_sd_demo_pin_sck

const ra8_port_pin_t k_sd_demo_pin_sck = (ra8_port_pin_t)k_ra8_board_pmod2_spi_sck
static

Pmod2 SPI pins (J25) – SCI0 Simple-SPI per HUM Table 20.13.

P604 is left as a GPIO output because SD SPI-mode framing requires CS to stay asserted across the 6-byte command + payload + CRC trailer (SD spec PHY v9 section 7.2.4). The SCI hardware CS controller pulses CS between every word, which the SD protocol does not tolerate. Driving CS by hand is the standard workaround.

Definition at line 110 of file main.c.

Referenced by sd_demo_spi_pins_init().