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
37
38#include <stddef.h>
39#include <stdint.h>
40
41#include "ra8_board_ek_ra8d2.h"
42#include "ra8_boot_entry.h"
43#include "ra8_cgc.h"
44#include "ra8_err.h"
45#include "ra8_i2c_bus_ops.h"
46#include "ra8_i3c.h"
47#include "ra8_io_i2c_bus.h"
49#include "ra8_isr.h"
50#include "ra8_mstp.h"
51#include "ra8_port_utils.h"
52#include "ra8_smbus.h"
53#include "ra8_time.h"
54
68
73
86
87static const uint8_t k_msg_boot[] = "smbus-demo: boot\r\n";
88static const uint8_t k_msg_fail[] = "smbus-demo: FAIL init\r\n";
89static const uint8_t k_msg_open[] = "smbus: FAIL open\r\n";
90static const uint8_t k_msg_nak[] = "smbus: NAK (no LSM6DSO)\r\n";
91static const uint8_t k_msg_bad[] = "smbus: mismatch\r\n";
92static const uint8_t k_msg_pre[] = "smbus: whoami=";
93static const uint8_t k_msg_mid[] = " sendrecv=";
94static const uint8_t k_msg_ok[] = " PASS\r\n";
95
97static void sd_print(const uint8_t* msg, uint32_t len)
98{
99 (void)ra8_board_uart_console_write(msg, (size_t)len);
100}
101
103static void sd_panic_halt(const uint8_t* msg, uint32_t len)
104{
105 sd_print(msg, len);
106 __asm__ volatile("bkpt #0");
107 while (1) {
108 __asm__ volatile("wfi");
109 }
110}
111
113static void sd_print_hex8(uint8_t value)
114{
115 uint8_t buf[2];
116 const uint32_t hi = ((uint32_t)value >> (uint32_t)k_sd_hex_shift) & (uint32_t)k_sd_hex_mask;
117 const uint32_t lo = (uint32_t)value & (uint32_t)k_sd_hex_mask;
118 buf[0] = (uint8_t)((hi < (uint32_t)k_sd_dec_ten) ? ('0' + hi) : ('A' + (hi - k_sd_dec_ten)));
119 buf[1] = (uint8_t)((lo < (uint32_t)k_sd_dec_ten) ? ('0' + lo) : ('A' + (lo - k_sd_dec_ten)));
120 sd_print(buf, 2U);
121}
122
124[[nodiscard]] static ra8_err_t sd_pins_init(void)
125{
128 }
130}
131
133static void sd_setup_or_halt(uint32_t* out_pclka_hz)
134{
135 uint32_t cpuclk0_hz = 0U;
136 if ((ra8_cgc_init() != k_ra8_ok) || (ra8_mstp_init() != k_ra8_ok)) {
137 sd_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
138 }
141 sd_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
142 }
143 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
144 sd_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
145 }
146 if (sd_pins_init() != k_ra8_ok) {
147 sd_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
148 }
150 sd_panic_halt(k_msg_fail, (uint32_t)sizeof(k_msg_fail) - 1U);
151 }
152}
153
166static void sd_read_whoami_or_halt(uint8_t* out_a, uint8_t* out_b)
167{
168 uint8_t a = 0U;
169 if (ra8_smbus_read_byte_data((uint8_t)k_sd_lsm_addr, (uint8_t)k_sd_reg_whoami, &a) != k_ra8_ok) {
170 sd_panic_halt(k_msg_nak, (uint32_t)sizeof(k_msg_nak) - 1U);
171 }
172 uint8_t b = 0U;
173 if (ra8_smbus_send_byte((uint8_t)k_sd_lsm_addr, (uint8_t)k_sd_reg_whoami) != k_ra8_ok) {
174 sd_panic_halt(k_msg_nak, (uint32_t)sizeof(k_msg_nak) - 1U);
175 }
176 if (ra8_smbus_receive_byte((uint8_t)k_sd_lsm_addr, &b) != k_ra8_ok) {
177 sd_panic_halt(k_msg_nak, (uint32_t)sizeof(k_msg_nak) - 1U);
178 }
179 if ((a != (uint8_t)k_sd_whoami_val) || (b != (uint8_t)k_sd_whoami_val)) {
180 sd_panic_halt(k_msg_bad, (uint32_t)sizeof(k_msg_bad) - 1U);
181 }
182 *out_a = a;
183 *out_b = b;
184}
185
194void main(void)
195{
196 uint32_t pclka_hz = 0U;
197 sd_setup_or_halt(&pclka_hz);
199 sd_print(k_msg_boot, (uint32_t)sizeof(k_msg_boot) - 1U);
200
201 /* App-owned bus bring-up: IIC_B in I2C-compat mode, bound through the
202 * ra8_io facade into the SMBus layer's injected seam. A future board
203 * revision that moves the bus onto a RIIC channel only swaps the bind. */
204 const ra8_i3c_cfg_t iic_cfg = {.mode = k_ra8_i3c_mode_i2c,
205 .bus_hz = (uint32_t)k_sd_bus_hz,
206 .pclka_hz = pclka_hz};
207 ra8_i2c_bus_ops_t bus_ops = {};
208 if (ra8_i3c_init((uint8_t)k_sd_iic_chan, &iic_cfg) != k_ra8_ok) {
209 sd_panic_halt(k_msg_open, (uint32_t)sizeof(k_msg_open) - 1U);
210 }
212 sd_panic_halt(k_msg_open, (uint32_t)sizeof(k_msg_open) - 1U);
213 }
214 if (ra8_io_i2c_bus_as_ops(&s_sd_bus, &bus_ops) != k_ra8_ok) {
215 sd_panic_halt(k_msg_open, (uint32_t)sizeof(k_msg_open) - 1U);
216 }
217
218 const ra8_smbus_cfg_t cfg = {.bus = bus_ops, .pec_enabled = false};
219 if (ra8_smbus_init(&cfg) != k_ra8_ok) {
220 sd_panic_halt(k_msg_open, (uint32_t)sizeof(k_msg_open) - 1U);
221 }
222
223 uint8_t a = 0U;
224 uint8_t b = 0U;
226
227 sd_print(k_msg_pre, (uint32_t)sizeof(k_msg_pre) - 1U);
228 sd_print_hex8(a);
229 sd_print(k_msg_mid, (uint32_t)sizeof(k_msg_mid) - 1U);
230 sd_print_hex8(b);
231 sd_print(k_msg_ok, (uint32_t)sizeof(k_msg_ok) - 1U);
232
233 while (1) {
234 __asm__ volatile("wfi");
235 }
236}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static const uint8_t k_msg_pre[]
Definition main.c:151
static const uint8_t k_msg_ok[]
Definition main.c:153
static const uint8_t k_msg_boot[]
Definition main.c:140
static const uint8_t k_msg_open[]
Definition main.c:64
static const uint8_t k_msg_fail[]
Definition main.c:63
static const uint8_t k_msg_nak[]
Definition main.c:97
static void sd_setup_or_halt(uint32_t *out_pclka_hz)
Bring up clocks/MSTP/time + the SCI8 console; halt on failure.
Definition main.c:133
static const uint8_t k_msg_mid[]
Definition main.c:93
static void sd_print(const uint8_t *msg, uint32_t len)
Emit a byte run on the SCI8 console.
Definition main.c:97
static void sd_read_whoami_or_halt(uint8_t *out_a, uint8_t *out_b)
Read WHO_AM_I two ways over SMBus; halt on any failure.
Definition main.c:166
static void sd_panic_halt(const uint8_t *msg, uint32_t len)
Print the fail banner and trap (ra8_emulator halts on the BKPT).
Definition main.c:103
static const ra8_port_pin_t k_sd_pin_sda
MikroBUS SDA routed through the Pmod1 I2C side (SDA1).
Definition main.c:72
static void sd_print_hex8(uint8_t value)
Print one byte as two upper-case hex digits.
Definition main.c:113
static ra8_io_i2c_bus_t s_sd_bus
Bound I2C bus handle the SMBus layer's injected seam points at.
Definition main.c:85
static const uint8_t k_msg_bad[]
Definition main.c:91
static const ra8_port_pin_t k_sd_pin_scl
MikroBUS SCL routed through the Pmod1 I2C side (SCL1).
Definition main.c:70
static ra8_err_t sd_pins_init(void)
Route the MikroBUS IIC SCL/SDA via PFS.
Definition main.c:124
sd_consts_t
Console / bus / device knobs (no magic numbers).
Definition main.c:56
@ k_sd_reg_whoami
WHO_AM_I register index.
Definition main.c:62
@ k_sd_whoami_val
Expected WHO_AM_I value.
Definition main.c:63
@ k_sd_hex_shift
Nibble shift for hex printing.
Definition main.c:64
@ k_sd_dec_ten
Hex digit / decimal split.
Definition main.c:66
@ k_sd_iic_chan
0.
Definition main.c:60
@ k_sd_hex_mask
Low-nibble mask.
Definition main.c:65
@ k_sd_uart_baud
Console baud.
Definition main.c:57
@ k_sd_lsm_addr
LSM6DSO 7-bit address (SA0 high).
Definition main.c:61
@ k_sd_bus_hz
IIC_B standard-mode bit rate.
Definition main.c:58
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
@ k_ra8_board_mikrobus_iic_b_channel
RA8 board mikrobus iic b channel.
@ k_ra8_board_mikrobus_i2c_scl
J22.5 SCL (SW4-5 OFF) -> P512 SCL1.
@ k_ra8_board_mikrobus_i2c_sda
J22.6 SDA (SW4-5 OFF) -> P511 SDA1.
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
@ k_ra8_clock_id_pclka
PCLKA.
Definition ra8_cgc.h:73
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_err_hw_init_failed
Hardware peripheral failed to initialise.
Definition ra8_err.h:290
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
@ k_ra8_psel_iic
00111b: IIC / I3C controller-peripheral.
Injected I2C-bus seam consumed by Ring-3 I2C device drivers.
I3C Bus Interface driver – unified native-I3C + I2C-compat modes.
@ k_ra8_i3c_mode_i2c
Legacy I2C-compatibility controller.
Definition ra8_i3c.h:69
ra8_err_t ra8_i3c_init(uint8_t channel, const ra8_i3c_cfg_t *cfg)
Initialise an I3C channel in the configured mode.
Definition ra8_i3c.c:311
ra8_io I2C-bus facade – one controller-transfer vtable over thechip's two I2C implementations.
ra8_err_t ra8_io_i2c_bus_as_ops(const ra8_io_i2c_bus_t *bus, ra8_i2c_bus_ops_t *out)
Expose a bound bus through the Ring-3 seam ra8_i2c_bus_ops_t.
I3C I2C-compatibility backend binder for the ra8_io I2C-bus facade.
ra8_err_t ra8_io_i2c_bus_bind_i3c_compat(ra8_io_i2c_bus_t *bus, uint8_t channel)
Bind bus to I3C channel channel in I2C-compatibility mode.
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
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_pfs_route_peripheral(ra8_port_pin_t pin, ra8_psel_t psel, const char *owner)
Route a pin to a non-IRQ peripheral function via PFS.PSEL.
Definition gpio.c:238
SMBus 3.2 protocol layer over an injected I2C bus seam.
ra8_err_t ra8_smbus_init(const ra8_smbus_cfg_t *cfg)
Initialise the SMBus layer over the injected bus seam.
Definition ra8_smbus.c:152
ra8_err_t ra8_smbus_send_byte(uint8_t target_7b, uint8_t data)
Send Byte transaction (SMBus 3.2 section 6.5.2).
Definition ra8_smbus.c:191
ra8_err_t ra8_smbus_receive_byte(uint8_t target_7b, uint8_t *out_data)
Receive Byte transaction (SMBus 3.2 section 6.5.3).
Definition ra8_smbus.c:210
ra8_err_t ra8_smbus_read_byte_data(uint8_t target_7b, uint8_t cmd, uint8_t *out_data)
Read Byte Data: register-indexed byte read (SMBus 3.2 sec 6.5.5).
Definition ra8_smbus.c:259
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
Caller-filled I2C controller-transfer seam (write / read / write-then-read).
Per-channel bring-up configuration for ra8_i3c_init.
Definition ra8_i3c.h:90
Caller-allocated I2C-bus handle binding a backend to its context.
Configuration descriptor for ra8_smbus_init.
Definition ra8_smbus.h:87