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

IIC_B (I3C block in I2C-compat mode) facade controller + peripheral demo. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_cgc.h"
#include "ra8_err.h"
#include "ra8_i2c_bus_ops.h"
#include "ra8_i3c.h"
#include "ra8_io_i2c_bus.h"
#include "ra8_io_i2c_bus_i3c_compat.h"
#include "ra8_isr.h"
#include "ra8_mstp.h"
#include "ra8_time.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  iic_facade_tunable_t : uint32_t {
  k_iic_baud = 115200U ,
  k_iic_bus_hz = 100000U ,
  k_iic_period_ms = 1000U
}
 Console / bus / loop knobs (no magic numbers). More...
enum  iic_facade_layout_t : uint8_t {
  k_iic_channel = 0U ,
  k_iic_ctrl_addr_7b = 0x5DU ,
  k_iic_periph_addr_7b = 0x42U ,
  k_iic_prod_ptr_hi = 0x81U ,
  k_iic_prod_ptr_lo = 0x40U ,
  k_iic_ptr_len = 2U ,
  k_iic_prod_len = 4U
}
 Channel + on-bus addresses + register map. More...
enum  iic_facade_periph_t : uint16_t {
  k_iic_periph_rounds = 4U ,
  k_iic_periph_poll_max = 4000U
}
 Target-mode round-trip + poll budget. More...
enum  iic_facade_fmt_t : uint8_t {
  k_iic_nib_shift = 4U ,
  k_iic_nib_mask = 0x0FU ,
  k_iic_dec_ten = 10U ,
  k_iic_dec_digits = 5U
}
 Console number-formatting constants. More...
enum  iic_facade_ctrl_result_t : uint8_t {
  k_iic_ctrl_ok = 0U ,
  k_iic_ctrl_nak = 1U ,
  k_iic_ctrl_idle = 2U
}
 Outcome classification of the facade controller transfer. More...
enum  iic_facade_svc_t : uint8_t {
  k_iic_svc_none = 0U ,
  k_iic_svc_rx = 1U ,
  k_iic_svc_tx = 2U
}
 What one target-mode service poll did. More...

Functions

static void iic_print (const uint8_t *msg, uint32_t len)
 Emit a byte run on the SCI8 console (best-effort).
static void iic_panic_halt (const uint8_t *msg, uint32_t len)
 Print the fail banner then trap (ra8_emulator halts on the BKPT).
static void iic_print_hex_byte (uint8_t value)
 Print a byte as two uppercase hex nibbles.
static void iic_print_dec (uint32_t value)
 Print a small unsigned integer (0..9999) in decimal.
static iic_facade_ctrl_result_t iic_facade_classify_ctrl (ra8_err_t err)
 Classify the facade controller transfer return code into a banner token.
static bool iic_facade_periph_acted (uint8_t mask)
 Did the target-mode status mask flag anything to service this poll?
static ra8_err_t iic_facade_service (uint8_t *last_byte, iic_facade_svc_t *out_svc)
 Service one target-mode event: drain a written byte or echo it back.
static iic_facade_ctrl_result_t iic_facade_controller_phase (uint8_t *out_id0)
 Run the facade CONTROLLER phase: read the GT911 PRODUCT_ID.
static uint32_t iic_facade_peripheral_phase (void)
 Run the PERIPHERAL (target) phase and count completed round-trips.
static void iic_print_ctrl_token (iic_facade_ctrl_result_t result)
 Print one controller-result token for result.
static void iic_print_banner (iic_facade_ctrl_result_t result, uint8_t id0, uint32_t rounds)
 Print the once-per-period summary banner.
static void iic_setup_or_halt (uint32_t *out_pclka_hz)
 Bring up clocks / MSTP / SysTick + the SCI8 console; halt on failure.
void main (void)
 App entry: facade controller round-trip, then target-mode responder.

Variables

static ra8_io_i2c_bus_t s_iic_bus
 Facade handle bound to IIC_B channel 0 in I2C-compat controller mode.
static const uint8_t k_msg_boot [] = "iic_b facade: boot\r\n"
static const uint8_t k_msg_fail [] = "iic_b facade: FAIL init\r\n"
static const uint8_t k_msg_open [] = "iic_b facade: FAIL open\r\n"
static const uint8_t k_msg_up [] = "iic_b facade: up ctrl="
static const uint8_t k_msg_id0 [] = " id0=0x"
static const uint8_t k_msg_peri [] = " periph="
static const uint8_t k_msg_eol [] = "\r\n"
static const uint8_t k_tok_ok [] = "OK"
static const uint8_t k_tok_nak [] = "NAK"
static const uint8_t k_tok_idle [] = "IDLE"

Detailed Description

IIC_B (I3C block in I2C-compat mode) facade controller + peripheral demo.

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

Exercises the ra8_io_i2c_bus facade over the I3C block's legacy I2C-compatibility mode (IIC_B, the twin of the RIIC ra8_i2c path) on channel 0, in BOTH roles the peripheral supports:

  1. Controller – binds the facade with ra8_io_i2c_bus_bind_i3c_compat and runs the classic write-register-pointer / repeated-START / read pattern via ra8_io_i2c_bus_transfer against the on-board GoodIX GT911 touch controller (7-bit 0x5D). It reads the 4-byte PRODUCT_ID (register 0x8140 -> "911\0"), the exact bring-up probe ra8_touch performs – so a real device answers on a stock EK-RA8D2 (see touch_demo). The facade makes the physical peripheral (IIC_B vs RIIC) a bind-time choice, not a call-site rewrite.
  2. Peripheral (target) – reprograms the same channel as an addressed I2C target (own address 0x42) via ra8_i3c_peripheral_open and then services controller write-then-read round-trips: it drains a byte the bus controller wrote (NTST.RDBFF0) and echoes it back on the following controller-read (NTST.TDBEF0).

Each second the SCI8 J-Link console prints one banner that always leads with the gate substring iic_b facade: up (reaching the loop proves ra8_i3c_init + facade bind succeeded on silicon – a bring-up failure BKPT-halts first), followed by the informational controller outcome and the completed peripheral round-trip count:

iic_b facade: up ctrl=OK id0=0x39 periph=4

Note
EIL vs bench. tools/ra8_emulator models the IIC_B controller bus (GT911 answers PRODUCT_ID) AND plays the EXTERNAL I2C controller that drives the firmware's target role (board_periph_i2c.c), so both halves run headless and the peripheral count is non-zero in EIL. On a bare bench the controller half still ACKs the real GT911, but the target half needs an external I2C controller wired to the bus (the stock rig has none), so periph=0 there – informational, never gated. See README.md.
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ iic_facade_ctrl_result_t

enum iic_facade_ctrl_result_t : uint8_t

Outcome classification of the facade controller transfer.

Maps the ra8_io_i2c_bus_transfer return code to a banner token. A completed-but-unacknowledged bus transaction (NAK) is distinguished from a bus that never clocked (idle / floated), matching how i3c_loopback reports a bare bus.

Invariant
k_iic_ctrl_ok is the only value that carries valid id bytes.
See also
iic_facade_classify_ctrl
Since
0.1.0
Enumerator
k_iic_ctrl_ok 

Device ACKed; PRODUCT_ID bytes are valid.

k_iic_ctrl_nak 

Bus clocked but no device acknowledged.

k_iic_ctrl_idle 

No transaction completed (bus fault/float).

Definition at line 109 of file main.c.

◆ iic_facade_fmt_t

enum iic_facade_fmt_t : uint8_t

Console number-formatting constants.

Enumerator
k_iic_nib_shift 

High-nibble shift for a hex byte.

k_iic_nib_mask 

Low-nibble mask.

k_iic_dec_ten 

Decimal radix.

k_iic_dec_digits 

Decimal digit-buffer capacity.

Definition at line 89 of file main.c.

◆ iic_facade_layout_t

enum iic_facade_layout_t : uint8_t

Channel + on-bus addresses + register map.

Enumerator
k_iic_channel 

I3C/IIC_B channel (only 0 on RA8D2).

k_iic_ctrl_addr_7b 

On-board GT911 touch 7-bit address.

k_iic_periph_addr_7b 

Own 7-bit address in target mode.

k_iic_prod_ptr_hi 

GT911 PRODUCT_ID pointer MSB (0x8140).

k_iic_prod_ptr_lo 

GT911 PRODUCT_ID pointer LSB.

k_iic_ptr_len 

16-bit register-pointer width.

k_iic_prod_len 

PRODUCT_ID payload length ("911\0").

Definition at line 72 of file main.c.

◆ iic_facade_periph_t

enum iic_facade_periph_t : uint16_t

Target-mode round-trip + poll budget.

Enumerator
k_iic_periph_rounds 

Controller write+read round-trips to accept.

k_iic_periph_poll_max 

Bounded target-service polls (NASA P10 R2).

Definition at line 83 of file main.c.

◆ iic_facade_svc_t

enum iic_facade_svc_t : uint8_t

What one target-mode service poll did.

Reported by iic_facade_service so the caller can count only a FULL round-trip (a received byte followed by its echo), not either half in isolation.

Invariant
k_iic_svc_none means the status poll found nothing to service.
See also
iic_facade_service
Since
0.1.0
Enumerator
k_iic_svc_none 

No RX-full / TX-empty event this poll.

k_iic_svc_rx 

Drained one controller-written byte.

k_iic_svc_tx 

Echoed one byte back (round-trip end).

Definition at line 127 of file main.c.

◆ iic_facade_tunable_t

enum iic_facade_tunable_t : uint32_t

Console / bus / loop knobs (no magic numbers).

Enumerator
k_iic_baud 

SCI8 J-Link console baud.

k_iic_bus_hz 

IIC_B bit rate (100 kHz Sm).

k_iic_period_ms 

Banner period.

Definition at line 65 of file main.c.

Function Documentation

◆ iic_facade_classify_ctrl()

iic_facade_ctrl_result_t iic_facade_classify_ctrl ( ra8_err_t err)
staticnodiscard

Classify the facade controller transfer return code into a banner token.

Pure mapping used by the controller phase and mirrored by the host test. k_ra8_ok means the target ACKed and the PRODUCT_ID bytes are valid; k_ra8_err_nack means the bus clocked but nothing answered; any other error means no transaction completed (a floated / wedged bus).

Parameters
[in]errReturn code from ra8_io_i2c_bus_transfer.
Returns
ra8_facade controller result classification.
Return values
k_iic_ctrl_okerr was k_ra8_ok.
k_iic_ctrl_nakerr was k_ra8_err_nack.
k_iic_ctrl_idleerr was any other value.
Precondition
err is a valid ra8_err_t value.
Postcondition
The return value names exactly one banner token.
Note
Thread-safe (pure function of err).
See also
iic_facade_controller_phase
Since
0.1.0

Definition at line 223 of file main.c.

References k_iic_ctrl_idle, k_iic_ctrl_nak, k_iic_ctrl_ok, k_ra8_err_nack, and k_ra8_ok.

Referenced by iic_facade_controller_phase().

◆ iic_facade_controller_phase()

iic_facade_ctrl_result_t iic_facade_controller_phase ( uint8_t * out_id0)
staticnodiscard

Run the facade CONTROLLER phase: read the GT911 PRODUCT_ID.

Issues one ra8_io_i2c_bus_transfer – write the 2-byte register pointer 0x8140, repeated START, read 4 bytes – against 0x5D and classifies the outcome. The first PRODUCT_ID byte is returned for the banner.

Parameters
[out]out_id0First PRODUCT_ID byte on ACK, else 0.
Returns
Controller-phase classification (iic_facade_ctrl_result_t).
Precondition
The facade is bound to IIC_B channel 0 (s_iic_bus).
out_id0 is non-NULL.
Postcondition
out_id0 holds the first read byte (0 unless the result is OK).
Note
Not thread-safe with respect to the channel.
See also
iic_facade_classify_ctrl
Since
0.1.0

Definition at line 328 of file main.c.

References iic_facade_classify_ctrl(), k_iic_ctrl_addr_7b, k_iic_ctrl_ok, k_iic_prod_len, k_iic_prod_ptr_hi, k_iic_prod_ptr_lo, k_iic_ptr_len, ra8_io_i2c_bus_transfer(), and s_iic_bus.

Referenced by main().

◆ iic_facade_periph_acted()

bool iic_facade_periph_acted ( uint8_t mask)
staticnodiscard

Did the target-mode status mask flag anything to service this poll?

The compound decision at the heart of the peripheral service loop: a poll has work iff the RX-buffer-full OR TX-buffer-empty event is latched. Mirrored under MC/DC by the host test.

Parameters
[in]maskra8_i3c_peripheral_status event mask.
Returns
true when a controller-write or controller-read is pending.
Return values
trueRX-full or TX-empty (or both) is set.
falseNeither event is set (idle poll).
Precondition
mask is a valid ra8_i3c_peripheral_status_t OR-mask.
Postcondition
No state is mutated.
Note
Thread-safe (pure function of mask).
See also
iic_facade_service
Since
0.1.0

Definition at line 253 of file main.c.

References k_ra8_i3c_peripheral_status_rx_full, and k_ra8_i3c_peripheral_status_tx_empty.

Referenced by iic_facade_service().

◆ iic_facade_peripheral_phase()

uint32_t iic_facade_peripheral_phase ( void )
staticnodiscard

Run the PERIPHERAL (target) phase and count completed round-trips.

Opens the channel as an addressed I2C target (0x42) then services a bounded number of polls, counting only a full round-trip (a received byte immediately echoed back). In ra8_emulator the external-controller model drives these; on a bare bench with no external controller the count stays 0.

Returns
Completed controller write+read round-trips (0 .. k_iic_periph_rounds).
Precondition
The channel was initialised in I2C mode via ra8_i3c_init.
The controller phase has finished (no transfer is in flight).
Postcondition
The channel is left in target mode answering 0x42.
Note
Not thread-safe with respect to the channel.
See also
iic_facade_service
Since
0.1.0

Definition at line 360 of file main.c.

References iic_facade_service(), k_iic_channel, k_iic_periph_addr_7b, k_iic_periph_poll_max, k_iic_periph_rounds, k_iic_svc_none, k_iic_svc_rx, k_iic_svc_tx, k_ra8_ok, and ra8_i3c_peripheral_open().

Referenced by main().

◆ iic_facade_service()

ra8_err_t iic_facade_service ( uint8_t * last_byte,
iic_facade_svc_t * out_svc )
staticnodiscard

Service one target-mode event: drain a written byte or echo it back.

Polls ra8_i3c_peripheral_status once. On RX-full it drains one byte into last_byte; on TX-empty it re-sends last_byte (echo). The ra8_emulator external-controller model paces these so a receive is always followed by the matching echo.

Parameters
[in,out]last_byteLatched controller-write byte; echoed on the next read.
[out]out_svcWhat this poll did (iic_facade_svc_t).
Returns
ra8_err_t status of the HAL calls.
Return values
k_ra8_okPoll serviced (see out_svc).
k_ra8_err_hw_errorA HAL status / receive / send call failed.
Precondition
The channel was opened in target mode via ra8_i3c_peripheral_open.
last_byte and out_svc are non-NULL.
Postcondition
out_svc names the serviced half (or k_iic_svc_none).
On RX last_byte holds the freshly received byte.
Note
Not thread-safe with respect to the channel.
See also
iic_facade_periph_acted
Since
0.1.0

Definition at line 283 of file main.c.

References iic_facade_periph_acted(), k_iic_channel, k_iic_svc_none, k_iic_svc_rx, k_iic_svc_tx, k_ra8_err_hw_error, k_ra8_i3c_peripheral_status_rx_full, k_ra8_i3c_peripheral_status_tx_empty, k_ra8_ok, ra8_i3c_peripheral_receive(), ra8_i3c_peripheral_send(), and ra8_i3c_peripheral_status().

Referenced by iic_facade_peripheral_phase().

◆ iic_panic_halt()

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

Print the fail banner then trap (ra8_emulator halts on the BKPT).

Definition at line 164 of file main.c.

References iic_print().

Referenced by iic_setup_or_halt(), and main().

◆ iic_print()

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

Emit a byte run on the SCI8 console (best-effort).

Definition at line 158 of file main.c.

References ra8_board_uart_console_write().

Referenced by iic_panic_halt(), iic_print_banner(), iic_print_ctrl_token(), iic_print_dec(), iic_print_hex_byte(), and main().

◆ iic_print_banner()

void iic_print_banner ( iic_facade_ctrl_result_t result,
uint8_t id0,
uint32_t rounds )
static

Print the once-per-period summary banner.

Definition at line 404 of file main.c.

References iic_print(), iic_print_ctrl_token(), iic_print_dec(), iic_print_hex_byte(), k_msg_eol, k_msg_id0, k_msg_peri, and k_msg_up.

Referenced by main().

◆ iic_print_ctrl_token()

void iic_print_ctrl_token ( iic_facade_ctrl_result_t result)
static

Print one controller-result token for result.

Definition at line 392 of file main.c.

References iic_print(), k_iic_ctrl_nak, k_iic_ctrl_ok, k_tok_idle, k_tok_nak, and k_tok_ok.

Referenced by iic_print_banner().

◆ iic_print_dec()

void iic_print_dec ( uint32_t value)
static

Print a small unsigned integer (0..9999) in decimal.

Definition at line 184 of file main.c.

References iic_print(), k_iic_dec_digits, and k_iic_dec_ten.

Referenced by iic_print_banner().

◆ iic_print_hex_byte()

void iic_print_hex_byte ( uint8_t value)
static

Print a byte as two uppercase hex nibbles.

Definition at line 174 of file main.c.

References iic_print(), k_iic_nib_mask, and k_iic_nib_shift.

Referenced by iic_print_banner().

◆ iic_setup_or_halt()

void iic_setup_or_halt ( uint32_t * out_pclka_hz)
static

Bring up clocks / MSTP / SysTick + the SCI8 console; halt on failure.

Definition at line 416 of file main.c.

References iic_panic_halt(), k_iic_baud, k_msg_fail, k_ra8_board_led1, k_ra8_clock_id_cpuclk0, k_ra8_clock_id_pclka, k_ra8_ok, ra8_board_led_init(), ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_mstp_init(), and ra8_time_init().

Referenced by main().

◆ main()

void main ( void )

App entry: facade controller round-trip, then target-mode responder.

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler copied .data and zeroed .bss.
SystemInit set VTOR / FPU / priority grouping.
Postcondition
The iic_b facade: up banner is emitted every period in the loop.
On any bring-up failure the CPU BKPT-halts before the loop.
Since
0.1.0

Definition at line 446 of file main.c.

References iic_facade_controller_phase(), iic_facade_peripheral_phase(), iic_panic_halt(), iic_print(), iic_print_banner(), iic_setup_or_halt(), k_iic_bus_hz, k_iic_channel, k_iic_period_ms, k_msg_boot, k_msg_open, k_ra8_board_led1, k_ra8_i3c_mode_i2c, k_ra8_ok, ra8_board_led_toggle(), ra8_delay_ms(), ra8_i3c_init(), ra8_io_i2c_bus_bind_i3c_compat(), ra8_isr_globals_enable(), and s_iic_bus.

Variable Documentation

◆ k_msg_boot

const uint8_t k_msg_boot[] = "iic_b facade: boot\r\n"
static

Definition at line 146 of file main.c.

◆ k_msg_eol

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

Definition at line 152 of file main.c.

◆ k_msg_fail

const uint8_t k_msg_fail[] = "iic_b facade: FAIL init\r\n"
static

Definition at line 147 of file main.c.

◆ k_msg_id0

const uint8_t k_msg_id0[] = " id0=0x"
static

Definition at line 150 of file main.c.

Referenced by iic_print_banner().

◆ k_msg_open

const uint8_t k_msg_open[] = "iic_b facade: FAIL open\r\n"
static

Definition at line 148 of file main.c.

◆ k_msg_peri

const uint8_t k_msg_peri[] = " periph="
static

Definition at line 151 of file main.c.

Referenced by iic_print_banner().

◆ k_msg_up

const uint8_t k_msg_up[] = "iic_b facade: up ctrl="
static

Definition at line 149 of file main.c.

Referenced by iic_print_banner().

◆ k_tok_idle

const uint8_t k_tok_idle[] = "IDLE"
static

Definition at line 155 of file main.c.

Referenced by iic_print_ctrl_token().

◆ k_tok_nak

const uint8_t k_tok_nak[] = "NAK"
static

Definition at line 154 of file main.c.

Referenced by iic_print_ctrl_token().

◆ k_tok_ok

const uint8_t k_tok_ok[] = "OK"
static

Definition at line 153 of file main.c.

Referenced by iic_print_ctrl_token().

◆ s_iic_bus

ra8_io_i2c_bus_t s_iic_bus
static

Facade handle bound to IIC_B channel 0 in I2C-compat controller mode.

File-scope so it out-lives every facade call made through it during the controller phase.

Note
Written once during bring-up, then read-only.
Warning
Do not rebind while a transfer is in flight.
Since
0.1.0

Definition at line 144 of file main.c.

Referenced by iic_facade_controller_phase(), and main().