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
29
30#include <stdint.h>
31
32#include "c6_join.h"
33#include "nx_ether_driver_c6.h"
34#include "ra8_board_ek_ra8d2.h"
35#include "ra8_boot_entry.h"
36#include "ra8_c6link.h"
37#include "ra8_c6link_wifi.h"
38#include "ra8_cgc.h"
39#include "ra8_err.h"
41#include "ra8_esp_hosted_port.h"
42#include "ra8_isr.h"
43#include "ra8_mstp.h"
44#include "ra8_net_provision.h"
45#include "ra8_secure.h"
46#include "ra8_time.h"
47#include "tx_api.h"
48
50static uint32_t s_cpuclk_hz;
52static uint32_t s_pclka_hz;
58static CHAR s_worker_name[] = "c6_wifi_join";
66static volatile uint32_t s_events;
68static volatile uint8_t s_connected;
70static volatile uint8_t s_disconnected;
72static volatile uint16_t s_reason;
79
92static void c6_join_panic_halt(void)
93{
94 while (true) {
95 __asm volatile("wfi");
96 }
97}
98
132
147static void c6_join_on_event(void* ctx, const ra8_c6link_event_t* ev)
148{
149 (void)ctx;
150 if (ev == nullptr) {
151 return;
152 }
153 s_events++;
155 s_connected = 1U;
156 } else if (ev->kind == k_ra8_c6link_event_sta_disconnected) {
157 s_disconnected = 1U;
158 s_reason = ev->reason;
159 } else {
160 /* boot / bare wifi events: counted above, nothing else to latch. */
161 }
162}
163
178static void c6_join_report_fault(const char* what, ra8_err_t err)
179{
180 ra8_c6link_fault_t fault = {};
181 (void)ra8_c6link_last_fault(&s_link, &fault);
182 c6_join_puts("c6_join: FAIL ");
183 c6_join_puts(what);
184 c6_join_puts(" err=");
186 c6_join_puts("\r\n");
187}
188
204{
205 ra8_c6link_cfg_t cfg = {};
207 if (seam != k_ra8_ok) {
208 return seam;
209 }
210 cfg.arena = s_arena;
211 cfg.arena_bytes = (uint32_t)sizeof(s_arena);
214 cfg.cb_ctx = nullptr;
215 return ra8_c6link_open(&s_link, &cfg);
216}
217
234{
235 const ra8_err_t opened = c6_join_open_link();
236 c6_join_puts("c6_join: link_open=");
238 c6_join_puts("\r\n");
239 if (opened != k_ra8_ok) {
240 return false;
241 }
242 const ra8_err_t ready =
244 if (ready != k_ra8_ok) {
245 c6_join_report_fault("await_ready", ready);
246 return false;
247 }
248 c6_join_puts("c6_join: coprocessor fw=");
250 c6_join_puts(".");
252 c6_join_puts(".");
254 c6_join_puts(" chip_id=");
256 c6_join_puts("\r\n");
257 return true;
258}
259
274static bool c6_join_wait_connected(void)
275{
276 for (uint32_t i = 0U; i < (uint32_t)k_c6_join_assoc_tries; i++) {
277 ra8_c6link_stats_t stats = {};
278 (void)ra8_c6link_poll(&s_link, (uint16_t)k_ra8_c6link_announce_transfers, &stats);
279 if (s_connected != 0U) {
280 return true;
281 }
282 if (s_disconnected != 0U) {
283 return false;
284 }
286 }
287 return false;
288}
289
308 const ra8_net_credentials_t* credentials)
309{
310 const ra8_err_t started = ra8_c6link_wifi_start(&s_link);
311 if (started != k_ra8_ok) {
312 c6_join_report_fault("wifi_start", started);
313 return false;
314 }
315 const ra8_err_t got_mac = ra8_c6link_wifi_mac(&s_link, mac_out);
316 if (got_mac != k_ra8_ok) {
317 c6_join_report_fault("wifi_mac", got_mac);
318 return false;
319 }
320 c6_join_puts("c6_join: station mac=");
321 c6_join_put_mac(mac_out);
322 c6_join_puts("\r\n");
323
324 ra8_c6link_sta_cfg_t sta = {};
325 const ra8_err_t set = ra8_c6link_sta_cfg_set(&sta, credentials->ssid, credentials->psk);
326 if (set != k_ra8_ok) {
327 ra8_secure_memzero(&sta, sizeof(sta));
328 c6_join_report_fault("sta_cfg_set", set);
329 return false;
330 }
331 const ra8_err_t joined = ra8_c6link_wifi_join(&s_link, &sta);
332 ra8_secure_memzero(&sta, sizeof(sta));
333 if (joined != k_ra8_ok) {
334 c6_join_report_fault("wifi_join", joined);
335 return false;
336 }
337 if (!c6_join_wait_connected()) {
338 c6_join_puts("c6_join: FAIL association did not complete (reason=");
339 c6_join_put_u32((uint32_t)s_reason);
340 c6_join_puts(")\r\n");
341 return false;
342 }
343 c6_join_puts("c6_join: associated\r\n");
344 return true;
345}
346
362static bool c6_join_phase_ip(const ra8_c6link_mac_t* mac)
363{
364 c6_join_lease_t lease = {};
365 const ra8_err_t up = c6_join_net_up(&s_link, mac, &lease);
366 if (up != k_ra8_ok) {
367 c6_join_puts("c6_join: FAIL dhcp did not bind err=");
369 c6_join_puts("\r\n");
370 return false;
371 }
372 c6_join_puts("c6_join: dhcp bound ip=");
373 c6_join_put_ip(lease.ip);
374 c6_join_puts(" mask=");
375 c6_join_put_ip(lease.mask);
376 c6_join_puts(" gw=");
377 c6_join_put_ip(lease.gateway);
378 c6_join_puts(" server=");
380 c6_join_puts("\r\n");
381 c6_join_puts("c6_join: reachability gateway ping=");
382 c6_join_puts(lease.ping_ok ? "ok" : "no-reply");
383 c6_join_puts("\r\n");
384 return (lease.ip != 0U);
385}
386
400static void c6_join_heartbeat(bool passed)
401{
402 while (true) {
403 c6_join_puts(passed ? "c6_join: alive PASS\r\n" : "c6_join: alive FAIL\r\n");
405 }
406}
407
422static void c6_join_worker_entry(ULONG thread_input)
423{
424 (void)thread_input;
425
426 c6_join_puts("c6_join: port_init=");
428 c6_join_puts("\r\n");
429 if (s_init_err != k_ra8_ok) {
430 c6_join_puts("c6_join: FAIL port init failed -- no transaction attempted\r\n");
431 c6_join_heartbeat(false);
432 return;
433 }
434
436
437 ra8_net_credentials_t credentials = {};
440 &credentials);
441 if (provisioned != k_ra8_ok) {
442 c6_join_puts("c6_join: FAIL runtime provisioning err=");
443 c6_join_puts(ra8_err_to_str(provisioned));
444 c6_join_puts("\r\n");
445 ra8_net_provision_clear(&credentials);
446 c6_join_heartbeat(false);
447 return;
448 }
449
451 ra8_c6link_mac_t mac = {};
452 bool ok = c6_join_phase_ready(&fw);
453 ok = ok && c6_join_phase_associate(&mac, &credentials);
454 ra8_net_provision_clear(&credentials);
455 ok = ok && c6_join_phase_ip(&mac);
456
457 c6_join_puts("c6_join: events_seen=");
458 c6_join_put_u32((uint32_t)s_events);
459 c6_join_puts("\r\n");
460 if (ok) {
461 c6_join_puts("c6_join: PASS ra8_c6link joined the bench Wi-Fi and DHCP leased an "
462 "address\r\n");
463 } else {
464 c6_join_puts("c6_join: FAIL Wi-Fi join to a DHCP lease did not complete\r\n");
465 }
467}
468
482void tx_application_define(void* first_unused_memory)
483{
484 (void)first_unused_memory;
485
486 const ra8_esp_hosted_port_cfg_t cfg = {
487 .pclk_hz = s_pclka_hz,
488 .sck_hz = (uint32_t)k_c6_join_sck_hz,
489 .edge_poll_ms = (uint16_t)k_c6_join_edge_poll_ms,
490 .sci_channel = (uint8_t)k_ra8_board_pmod1_sci_channel,
491 };
493
497 0U,
499 (ULONG)sizeof(s_worker_stack),
504 c6_join_puts("c6_join: worker thread creation failed\r\n");
505 }
506}
507
518void main(void)
519{
522
524 c6_join_puts("c6_join: entering ThreadX; port init runs from tx_application_define\r\n");
525
526 tx_kernel_enter();
527
529}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static volatile uint8_t s_disconnected
Definition c6_cam_app.c:47
static uint32_t s_cpuclk_hz
Definition c6_cam_app.c:37
static volatile uint8_t s_connected
Definition c6_cam_app.c:46
static ra8_c6link_t s_link
Definition c6_cam_app.c:44
static volatile uint32_t s_events
Definition c6_cam_app.c:45
static TX_THREAD s_worker
Definition c6_cam_app.c:40
static const ra8_net_provision_uart_t s_provision_uart
Board-console binding for the shared runtime provisioner.
Definition c6_cam_app.c:50
static CHAR s_worker_name[]
Definition c6_cam_app.c:41
static UCHAR s_worker_stack[k_c6_cam_worker_stack]
Definition c6_cam_app.c:42
static uint8_t s_arena[k_c6_cam_arena_bytes]
Definition c6_cam_app.c:43
static uint32_t s_pclka_hz
Definition c6_cam_app.c:38
Shared contract for the C6 Wi-Fi join + DHCP + reachability app.
@ k_c6_join_assoc_gap_ms
Gap between association polls, milliseconds.
Definition c6_join.h:92
@ k_c6_join_assoc_tries
Association poll attempts before giving up.
Definition c6_join.h:91
void c6_join_print_banner(uint32_t cpuclk_hz, uint32_t pclka_hz)
Print the banner: identity, clocks and link parameters.
@ k_c6_join_worker_stack
Worker-thread stack, in bytes.
Definition c6_join.h:68
@ k_c6_join_uart_baud
Console rate, 8N1, over the J-Link OB VCOM.
Definition c6_join.h:61
@ k_c6_join_heartbeat_ms
Heartbeat gap after the verdict, in milliseconds and therefore in ThreadX ticks.
Definition c6_join.h:66
@ k_c6_join_worker_prio
Worker priority and preemption threshold.
Definition c6_join.h:70
@ k_c6_join_edge_poll_ms
Poll period for a side-band pin with no ICU channel.
Definition c6_join.h:63
@ k_c6_join_boot_wait_ms
Settling delay before the first transaction.
Definition c6_join.h:65
@ k_c6_join_arena_bytes
Decode arena handed to the facade.
Definition c6_join.h:71
@ k_c6_join_sck_hz
SPI bit rate; the rate silicon ran at.
Definition c6_join.h:62
ra8_err_t c6_join_net_up(ra8_c6link_t *link, const ra8_c6link_mac_t *mac, c6_join_lease_t *out)
Bring the IP layer up over the associated C6 link and prove traffic.
struct c6_join_lease c6_join_lease_t
void c6_join_put_hex(uint32_t value, uint8_t digits)
Emit a value as a fixed-width lower-case hexadecimal field.
void c6_join_put_ip(uint32_t ip)
Emit a packed IPv4 address as a dotted quad.
void c6_join_put_u32(uint32_t value)
Emit an unsigned 32-bit value in decimal.
void c6_join_put_mac(const ra8_c6link_mac_t *mac)
Emit an IEEE 802 address as six colon-separated hexadecimal octets.
void c6_join_puts(const char *text)
Write a NUL-terminated string to the board console.
@ k_c6_join_hex_byte
Hex digits printed for a byte-wide field.
Definition c6_join.h:122
void tx_application_define(void *first_unused_memory)
ThreadX system-define hook: build worker thread + byte pool.
Definition main.c:942
static bool c6_join_wait_connected(void)
Poll until station association succeeds, fails, or times out.
Definition main.c:274
static ra8_err_t s_init_err
Port-init result from tx_application_define.
Definition main.c:54
static void c6_join_heartbeat(bool passed)
Preserve the terminal verdict as a periodic console heartbeat.
Definition main.c:400
static void c6_join_on_event(void *ctx, const ra8_c6link_event_t *ev)
Record one C6 announcement and update association latches.
Definition main.c:147
static void c6_join_setup_or_halt(void)
Initialize platform services required by the join application.
Definition main.c:111
static void c6_join_worker_entry(ULONG thread_input)
Run provisioning, C6 readiness, association, DHCP, and heartbeat.
Definition main.c:422
static void c6_join_report_fault(const char *what, ra8_err_t err)
Report one failed C6 join stage without revealing credentials.
Definition main.c:178
static void c6_join_panic_halt(void)
Halt the processor after an unrecoverable start-up failure.
Definition main.c:92
static ra8_err_t c6_join_open_link(void)
Bind ESP-hosted transport and open the application C6 link.
Definition main.c:203
static bool c6_join_phase_ready(ra8_c6link_fw_version_t *out)
Open the C6 link and establish co-processor readiness.
Definition main.c:233
static bool c6_join_phase_ip(const ra8_c6link_mac_t *mac)
Bring up NetX, print the lease, and judge address acquisition.
Definition main.c:362
static bool c6_join_phase_associate(ra8_c6link_mac_t *mac_out, const ra8_net_credentials_t *credentials)
Start Wi-Fi and associate using one runtime credential record.
Definition main.c:307
static volatile uint16_t s_reason
Last 802.11 disconnect reason code.
Definition main.c:72
NetX Duo network driver shim that bridges onto the ESP32-C6 link.
void nx_ether_driver_c6_rx(void *ctx, const uint8_t *frame, uint16_t len)
Receive callback the application registers with ra8_c6link_open.
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
@ k_ra8_board_pmod1_sci_channel
Pmod1 (J26) Simple-SPI is SCI2.
ra8_err_t ra8_board_uart_console_read(uint8_t *out, size_t cap, size_t *out_len)
Polled non-blocking read from the J-Link OB VCOM console.
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_not_initialized
Module not initialized – _init() not yet called successfully.
Definition ra8_err.h:235
@ 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
const char * ra8_err_to_str(ra8_err_t err)
Human-readable string for an error code.
Definition ra8_log.c:737
Public entry point of the RA8D2 + ThreadX port of esp-hosted.
struct ra8_esp_hosted_port_cfg ra8_esp_hosted_port_cfg_t
ra8_err_t ra8_esp_hosted_port_init(const ra8_esp_hosted_port_cfg_t *cfg)
Bring the esp-hosted port up and publish the OS-abstraction vtable.
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
Runtime network provisioning contract for EK-RA8D2 applications.
struct ra8_net_credentials ra8_net_credentials_t
struct ra8_net_provision_uart ra8_net_provision_uart_t
@ k_ra8_net_provision_timeout_ms
Standard application RX timeout.
ra8_err_t ra8_net_provision_receive(const ra8_net_provision_uart_t *uart, uint32_t timeout_ms, ra8_net_credentials_t *out)
Prompt once and receive one provisioning line within a fixed timeout.
void ra8_net_provision_clear(ra8_net_credentials_t *credentials)
Explicitly erase one decoded credential record.
Secure-comparison primitives for the crypto / secure-boot paths.
void ra8_secure_memzero(void *ptr, size_t len)
Securely zero a buffer such that the write cannot be optimised away.
Definition ra8_secure.c:37
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
unsigned int UINT
ThreadX-compatible unsigned int (host stub).
#define TX_SUCCESS
#define tx_thread_create
#define tx_thread_sleep
#define TX_NO_TIME_SLICE
char CHAR
ThreadX-compatible CHAR (host stub).
#define TX_AUTO_START
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
Opaque thread stand-in for the host build.
uint32_t gateway
Default gateway from the lease; the ping target.
Definition c6_join.h:165
uint32_t mask
Subnet mask from the lease.
Definition c6_join.h:164
uint32_t dhcp_server
Address of the DHCP server that answered.
Definition c6_join.h:166
bool ping_ok
A gateway ICMP echo reply was received.
Definition c6_join.h:167
uint32_t ip
Leased station address, or zero on failure.
Definition c6_join.h:163
char psk[k_ra8_net_provision_psk_bytes_max+1U]
NUL-terminated PSK storage.
char ssid[k_ra8_net_provision_ssid_bytes_max+1U]
NUL-terminated SSID storage.