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

Interrupt-driven SCI8 UART echo for EK-RA8D2 (RXI / TXI / TEI). More...

#include <stdint.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_cgc.h"
#include "ra8_elc.h"
#include "ra8_err.h"
#include "ra8_gpio_constants.h"
#include "ra8_isr.h"
#include "ra8_port_constants.h"
#include "ra8_port_utils.h"
#include "ra8_sci.h"
#include "ra8_time.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  uart_irq_config_t : uint32_t {
  k_uart_irq_baud = 115200U ,
  k_uart_irq_loop_ms = 100U ,
  k_uart_irq_sci_chan = 8U ,
  k_uart_irq_isr_prio = 4U
}
 Compile-time settings for the echo demo. More...
enum  uart_irq_event_t : uint16_t {
  k_uart_irq_event_rxi = 0x122U ,
  k_uart_irq_event_txi = 0x123U ,
  k_uart_irq_event_tei = 0x124U
}
 SCI8 ELC event numbers (FSP ra8d2 bsp_elc: RXI/TXI/TEI). More...

Functions

static void uart_irq_panic_halt (void)
 Halt forever in WFI – panic stop on any init failure.
static void uart_irq_rxi_isr (void *ctx)
 SCI8 RXI ISR: drive the driver's receive state machine.
static void uart_irq_txi_isr (void *ctx)
 SCI8 TXI ISR: push the next byte of an in-flight interrupt TX.
static void uart_irq_tei_isr (void *ctx)
 SCI8 TEI ISR: end-of-transmission housekeeping.
static void uart_irq_rx_cb (void *ctx, uint8_t byte)
 RX byte callback: echo the byte and re-arm the next receive.
static ra8_err_t uart_irq_pins_init (void)
 Route PD02 / PD03 to SCI8 TXD / RXD via the PFS PSEL field.
static ra8_err_t uart_irq_register_isrs (void)
 Register the SCI8 RXI / TXI / TEI events with the NVIC.
static void uart_irq_setup_or_halt (void)
 Bring CGC + SysTick + SCI8 + LED1 + the SCI ISRs up, or panic-halt.
void main (void)
 Application entry.

Variables

static const ra8_port_pin_t k_uart_irq_pin_txd = (ra8_port_pin_t)k_ra8_board_uart_console_pin_txd
 Pinout for the on-board J-Link OB CDC channel (SCI8 / PD02 + PD03).
static const ra8_port_pin_t k_uart_irq_pin_rxd = (ra8_port_pin_t)k_ra8_board_uart_console_pin_rxd
static const uint8_t k_uart_irq_banner [] = "uart_irq_echo ready\r\n"
 Banner printed once over the polled path so the host sees a prompt.
volatile uint32_t g_uart_irq_echoes = 0U
 Count of bytes echoed from interrupt context.
static uint8_t s_uart_irq_rx_byte
 One-byte RX landing pad re-armed by every receive callback.

Detailed Description

Interrupt-driven SCI8 UART echo for EK-RA8D2 (RXI / TXI / TEI).

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

Companion to uart_hello (which proves the polled SCI path): this app proves the interrupt-driven SCI path end to end – a receive byte raises RXI, the registered ISR drives ra8_sci_dispatch_rxi, the echo is queued with ra8_sci_write (which arms CCR0.TIE), and each TXI then pushes the next byte from ra8_sci_dispatch_txi until the frame drains. Nothing in the main loop touches the data path, so any byte echoed is proof the real NVIC -> ISR chain ran.

It brings the chip up exactly like uart_hello (CGC -> PLL, SCI8 TXD8 = PD02 / RXD8 = PD03 at 115200 8N1), then:

  1. ra8_isr_init + ra8_isr_register for SCI8 RXI / TXI / TEI so each event links through the ICU IELSR table and enables its NVIC line.
  2. Prints a one-line banner with ra8_sci_write_polling (so the polled path is exercised too, and the host sees a prompt).
  3. Attaches an RX byte callback and arms a 1-byte interrupt receive with ra8_sci_read; the callback re-arms the next receive and echoes the byte back over the interrupt-driven transmitter.
  4. Idles in ra8_delay_ms – every echoed byte happens in handler context.

On the EK-RA8D2 the SCI8 pins surface as the J-Link OB VCOM port; typing into a terminal at 115200 8N1 echoes each character back and toggles LED1. Under tools/ra8_emulator, --input <str> feeds the RX queue and the echo appears as captured [uart] output.

Note
Unlike the other demos, this one drives SCI8 directly rather than the BSP ra8_board_uart_console API: the interrupt-driven SCI8 RX/TX path is the subject under test, so it must own the channel's ISRs and registers itself. (The BSP is still linked – for LED1.)
Author
Brighton Sikarskie
Date
2026-06-08
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ uart_irq_config_t

enum uart_irq_config_t : uint32_t

Compile-time settings for the echo demo.

Enumerator
k_uart_irq_baud 

UART IRQ baud.

k_uart_irq_loop_ms 

UART IRQ loop ms.

k_uart_irq_sci_chan 

Console channel: SCI8 (PD02/PD03).

k_uart_irq_isr_prio 

NVIC priority for the SCI events.

Definition at line 60 of file main.c.

◆ uart_irq_event_t

enum uart_irq_event_t : uint16_t

SCI8 ELC event numbers (FSP ra8d2 bsp_elc: RXI/TXI/TEI).

Enumerator
k_uart_irq_event_rxi 

SCI8 RXI receive-data-full event.

k_uart_irq_event_txi 

SCI8 TXI transmit-data-empty event.

k_uart_irq_event_tei 

SCI8 TEI transmit-end event.

Definition at line 68 of file main.c.

Function Documentation

◆ main()

void main ( void )

Application entry.

The application entry point Reset_Handler hands control to.

Brings up SCI8 + ISRs, prints, then echoes via IRQ.

Precondition
Reset_Handler has copied .data and zeroed .bss; SystemInit set VTOR/FPU.
Postcondition
On clean entry the CPU idles while the SCI ISRs echo received bytes.
On any HAL init failure the function halts in WFI.
Since
0.1.0

Definition at line 294 of file main.c.

References k_uart_irq_banner, k_uart_irq_loop_ms, k_uart_irq_sci_chan, ra8_delay_ms(), ra8_isr_globals_enable(), ra8_sci_attach_rx_handler(), ra8_sci_read(), ra8_sci_write_polling(), s_uart_irq_rx_byte, uart_irq_panic_halt(), uart_irq_rx_cb(), and uart_irq_setup_or_halt().

◆ uart_irq_panic_halt()

void uart_irq_panic_halt ( void )
static

Halt forever in WFI – panic stop on any init failure.

Precondition
Called only after a fatal error in boot.
Postcondition
CPU is parked; only a debugger or external reset wakes it.
Since
0.1.0

Definition at line 106 of file main.c.

Referenced by main(), and uart_irq_setup_or_halt().

◆ uart_irq_pins_init()

ra8_err_t uart_irq_pins_init ( void )
staticnodiscard

Route PD02 / PD03 to SCI8 TXD / RXD via the PFS PSEL field.

Returns
Error code from the first failing route call, or k_ra8_ok.
Return values
k_ra8_okBoth pins are SCI-routed.
Precondition
IOPORT module is reachable; single-threaded init context.
Postcondition
On success PD02 and PD03 are in SCI-async (PSEL=0x04) mode.
Since
0.1.0

Definition at line 195 of file main.c.

References k_ra8_ok, k_ra8_psel_sci_async, k_uart_irq_pin_rxd, k_uart_irq_pin_txd, and ra8_pfs_route_peripheral().

Referenced by uart_irq_setup_or_halt().

◆ uart_irq_register_isrs()

ra8_err_t uart_irq_register_isrs ( void )
staticnodiscard

Register the SCI8 RXI / TXI / TEI events with the NVIC.

Returns
k_ra8_ok on success, else the first failing registration error.
Precondition
ra8_isr_init has run; interrupts not yet globally enabled.
Postcondition
Each SCI8 event links through IELSR and its NVIC line is enabled.
Since
0.1.0

Definition at line 213 of file main.c.

References k_ra8_ok, k_uart_irq_event_rxi, k_uart_irq_event_tei, k_uart_irq_event_txi, k_uart_irq_isr_prio, ra8_isr_register(), uart_irq_rxi_isr(), uart_irq_tei_isr(), and uart_irq_txi_isr().

Referenced by uart_irq_setup_or_halt().

◆ uart_irq_rx_cb()

void uart_irq_rx_cb ( void * ctx,
uint8_t byte )
static

RX byte callback: echo the byte and re-arm the next receive.

Runs in RXI handler context (driver invokes it per received byte). Echoes the byte over the interrupt-driven transmitter (ra8_sci_write arms TIE, so the echo flows out through uart_irq_txi_isr) and re-arms a fresh 1-byte interrupt receive so the stream keeps draining.

Parameters
[in]ctxUnused callback context.
[in]byteThe received data byte.
Returns
Nothing.
Since
0.1.0

Definition at line 174 of file main.c.

References g_uart_irq_echoes, k_ra8_board_led1, k_uart_irq_sci_chan, ra8_board_led_toggle(), ra8_sci_read(), ra8_sci_write(), and s_uart_irq_rx_byte.

Referenced by main().

◆ uart_irq_rxi_isr()

void uart_irq_rxi_isr ( void * ctx)
static

SCI8 RXI ISR: drive the driver's receive state machine.

Parameters
[in]ctxUnused registration context.
Returns
Nothing.
Precondition
Registered for the SCI8 RXI event.
Postcondition
The driver has consumed one RDR byte and the RX callback has run.
Since
0.1.0

Definition at line 124 of file main.c.

References k_uart_irq_sci_chan, and ra8_sci_dispatch_rxi().

Referenced by uart_irq_register_isrs().

◆ uart_irq_setup_or_halt()

void uart_irq_setup_or_halt ( void )
static

Bring CGC + SysTick + SCI8 + LED1 + the SCI ISRs up, or panic-halt.

Returns
Nothing (halts forever on any failure).
Since
0.1.0

Definition at line 244 of file main.c.

References k_ra8_board_led1, k_ra8_clock_id_cpuclk0, k_ra8_clock_id_pclka, k_ra8_ok, k_ra8_sci_data_8, k_ra8_sci_parity_none, k_ra8_sci_stop_1, k_uart_irq_baud, k_uart_irq_sci_chan, ra8_board_led_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_isr_init(), ra8_sci_init(), ra8_time_init(), uart_irq_panic_halt(), uart_irq_pins_init(), and uart_irq_register_isrs().

Referenced by main().

◆ uart_irq_tei_isr()

void uart_irq_tei_isr ( void * ctx)
static

SCI8 TEI ISR: end-of-transmission housekeeping.

Parameters
[in]ctxUnused registration context.
Returns
Nothing.
Precondition
Registered for the SCI8 TEI event.
Postcondition
The driver's error/end path has run for the channel.
Since
0.1.0

Definition at line 154 of file main.c.

References k_uart_irq_sci_chan, and ra8_sci_dispatch_eri().

Referenced by uart_irq_register_isrs().

◆ uart_irq_txi_isr()

void uart_irq_txi_isr ( void * ctx)
static

SCI8 TXI ISR: push the next byte of an in-flight interrupt TX.

Parameters
[in]ctxUnused registration context.
Returns
Nothing.
Precondition
Registered for the SCI8 TXI event.
Postcondition
One queued TX byte has been written to TDR (or TIE cleared at end).
Since
0.1.0

Definition at line 139 of file main.c.

References k_uart_irq_sci_chan, and ra8_sci_dispatch_txi().

Referenced by uart_irq_register_isrs().

Variable Documentation

◆ g_uart_irq_echoes

volatile uint32_t g_uart_irq_echoes = 0U

Count of bytes echoed from interrupt context.

Incremented only inside uart_irq_rx_cb (reached via the real RXI -> ra8_isr_dispatch -> driver path). A non-zero value is direct evidence the interrupt-driven receive ran; read externally by J-Link (HIL) and by tools/ra8_emulator (emulator).

Note
Read externally only; the firmware main loop never reads it back.
Since
0.1.0

Definition at line 94 of file main.c.

Referenced by uart_irq_rx_cb().

◆ k_uart_irq_banner

const uint8_t k_uart_irq_banner[] = "uart_irq_echo ready\r\n"
static

Banner printed once over the polled path so the host sees a prompt.

Definition at line 79 of file main.c.

Referenced by main().

◆ k_uart_irq_pin_rxd

Definition at line 76 of file main.c.

Referenced by uart_irq_pins_init().

◆ k_uart_irq_pin_txd

Pinout for the on-board J-Link OB CDC channel (SCI8 / PD02 + PD03).

Definition at line 75 of file main.c.

Referenced by uart_irq_pins_init().

◆ s_uart_irq_rx_byte

uint8_t s_uart_irq_rx_byte
static

One-byte RX landing pad re-armed by every receive callback.

Definition at line 97 of file main.c.

Referenced by main(), and uart_irq_rx_cb().