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
52
53#include <stdint.h>
54#include <string.h>
55
56#include "ra8_board_ek_ra8d2.h"
57#include "ra8_boot_entry.h"
58#include "ra8_cgc.h"
59#include "ra8_err.h"
60#include "ra8_gpio_constants.h"
61#include "ra8_isr.h"
62#include "ra8_port_constants.h"
63#include "ra8_port_utils.h"
64#include "ra8_time.h"
65#include "ra8_usb.h"
67
68#ifndef RA8_OFF_TARGET
69#include "tx_api.h"
70#include "ux_api.h"
71#include "ux_dcd_ra8_usb.h"
72#include "ux_device_class_cdc_acm.h"
73#include "ux_device_stack.h"
74
75/* Strong SysTick override: route the tick into BOTH the ra8_time millisecond
76 * counter (for ra8_delay_ms and the polled host stack's timeouts) AND
77 * ThreadX's timer; the 1 ms pulse also recovers the DCD's storm-guard mask. */
78
79extern void _tx_timer_interrupt(void);
80
90static volatile bool s_tx_kernel_up = false;
91
92void SysTick_Handler(void);
101#endif
102
103/* -------------------------------------------------------------------------- */
104/* Pinout (FSP-aligned, EK-RA8D2 v1 User's Manual) */
105/* -------------------------------------------------------------------------- */
106
109
112
115
118
121
124
125/* -------------------------------------------------------------------------- */
126/* Tunables */
127/* -------------------------------------------------------------------------- */
128
129/* The shared sizing/geometry enums (::cdc_config_t, ::cdc_geom_t) live in the
130 * companion `usb_selftest_cdc_steps.h`; the host-only formatter, mask, and
131 * phase enums live in `usb_selftest_cdc_steps.c`. Only the device-side step
132 * enum is private to this unit. */
133
145
146#ifndef RA8_OFF_TARGET
147
148/* -------------------------------------------------------------------------- */
149/* ThreadX workers + USBX pool storage */
150/* -------------------------------------------------------------------------- */
151
159
166
174
181
188
195static UX_SLAVE_CLASS_CDC_ACM* s_cdc_acm = UX_NULL;
196
205static TX_SEMAPHORE s_cdc_active_sem;
206
207/* -------------------------------------------------------------------------- */
208/* J-Link probes (device side) */
209/* -------------------------------------------------------------------------- */
210
211/* The host-side ladder probes (``s_dbg_phase``, ``s_dbg_rounds_ok``,
212 * ``s_dbg_pid``, ``s_dbg_mismatch``, ``s_dbg_pass_count``) live in the
213 * companion `usb_selftest_cdc_steps.c` alongside their only writers. */
214
216static volatile uint32_t s_dbg_dev_echo_calls;
218static volatile uint32_t s_dbg_dev_last_len;
220static volatile uint32_t s_dbg_dev_step;
222static volatile uint32_t s_dbg_dev_err;
223
224/* -------------------------------------------------------------------------- */
225/* USB descriptors (CDC-ACM: comm + data interface via an IAD) */
226/* -------------------------------------------------------------------------- */
227
228/* CDC-ACM config: one communications interface + one data interface joined
229 * by an Interface Association Descriptor, EP3 IN (interrupt notify), EP2 OUT
230 * / EP1 IN (bulk data, 64-byte MPS). Layout per CDC 1.20 sec 5 + USB 2.0 sec
231 * 9.6 -- byte-identical to the proven usb_cdc_echo device, retagged PID
232 * 0x0017 for the CDC self-test identity. The host only drives the bulk data
233 * pipes (EP2 OUT / EP1 IN); the interrupt-IN notify endpoint is unused. */
234static UCHAR s_device_framework_fs[] = {
235 /* Device descriptor (USB 2.0 sec 9.6.1) -- 18 bytes. bcdUSB 0x0200 and
236 class MISC/common/IAD so IAD-based composites enumerate cleanly. */
237 0x12U,
238 0x01U,
239 0x00U,
240 0x02U,
241 0xEFU, /* class = MISC */
242 0x02U, /* subclass = common */
243 0x01U, /* protocol = IAD */
244 0x40U,
245 0x09U,
246 0x12U,
247 0x17U, /* PID = 0x0017 (pid.codes test). */
248 0x00U,
249 0x00U,
250 0x01U,
251 0x01U,
252 0x02U,
253 0x03U,
254 0x01U,
255 /* Configuration descriptor (75 bytes total = 0x4B). */
256 0x09U,
257 0x02U,
258 0x4BU,
259 0x00U,
260 0x02U,
261 0x01U,
262 0x00U,
263 0x80U,
264 0x32U,
265 /* Interface association (CDC). */
266 0x08U,
267 0x0BU,
268 0x00U,
269 0x02U,
270 0x02U,
271 0x02U,
272 0x01U,
273 0x00U,
274 /* Communications interface (CDC ACM). */
275 0x09U,
276 0x04U,
277 0x00U,
278 0x00U,
279 0x01U,
280 0x02U,
281 0x02U,
282 0x01U,
283 0x00U,
284 /* CDC header functional descriptor. bcdCDC = 0x0120. */
285 0x05U,
286 0x24U,
287 0x00U,
288 0x20U,
289 0x01U,
290 /* Call-management functional descriptor. */
291 0x05U,
292 0x24U,
293 0x01U,
294 0x01U,
295 0x01U,
296 /* ACM functional descriptor. */
297 0x04U,
298 0x24U,
299 0x02U,
300 0x02U,
301 /* Union functional descriptor. */
302 0x05U,
303 0x24U,
304 0x06U,
305 0x00U,
306 0x01U,
307 /* Interrupt-IN endpoint (EP3 IN, 8-byte MPS, 255 ms poll). */
308 0x07U,
309 0x05U,
310 0x83U,
311 0x03U,
312 0x08U,
313 0x00U,
314 0xFFU,
315 /* Data-class interface. */
316 0x09U,
317 0x04U,
318 0x01U,
319 0x00U,
320 0x02U,
321 0x0AU,
322 0x00U,
323 0x00U,
324 0x00U,
325 /* Bulk-OUT endpoint (EP2 OUT, 64-byte MPS). */
326 0x07U,
327 0x05U,
328 0x02U,
329 0x02U,
330 0x40U,
331 0x00U,
332 0x00U,
333 /* Bulk-IN endpoint (EP1 IN, 64-byte MPS). */
334 0x07U,
335 0x05U,
336 0x81U,
337 0x02U,
338 0x40U,
339 0x00U,
340 0x00U,
341};
342
350static UCHAR s_string_framework[] = {
351 /* idx 1: "Brighton Sikarskie". */
352 0x09U,
353 0x04U,
354 0x01U,
355 0x12U,
356 'B',
357 'r',
358 'i',
359 'g',
360 'h',
361 't',
362 'o',
363 'n',
364 ' ',
365 'S',
366 'i',
367 'k',
368 'a',
369 'r',
370 's',
371 'k',
372 'i',
373 'e',
374 /* idx 2: "RA8D2 CDC ECHO". */
375 0x09U,
376 0x04U,
377 0x02U,
378 0x0EU,
379 'R',
380 'A',
381 '8',
382 'D',
383 '2',
384 ' ',
385 'C',
386 'D',
387 'C',
388 ' ',
389 'E',
390 'C',
391 'H',
392 'O',
393 /* idx 3: serial. */
394 0x09U,
395 0x04U,
396 0x03U,
397 0x08U,
398 '0',
399 '0',
400 '0',
401 '0',
402 '0',
403 '0',
404 '1',
405 '3',
406};
407
408/* USBX LANGID descriptor 0x0409 (English-US), little-endian byte pair. */
409typedef enum : uint8_t {
413
420
421/* -------------------------------------------------------------------------- */
422/* CDC-ACM activate / deactivate callbacks */
423/* -------------------------------------------------------------------------- */
424
445static VOID cdc_activate(VOID* cdc_instance)
446{
447 s_cdc_acm = (UX_SLAVE_CLASS_CDC_ACM*)cdc_instance;
448 if (_ux_system_slave != UX_NULL) {
449 _ux_system_slave->ux_system_slave_device.ux_slave_device_state =
450 (unsigned long)UX_DEVICE_CONFIGURED;
451 }
452 (void)tx_semaphore_put(&s_cdc_active_sem);
453}
454
468static VOID cdc_deactivate(VOID* cdc_instance)
469{
470 (void)cdc_instance;
471 s_cdc_acm = UX_NULL;
472}
473
474/* -------------------------------------------------------------------------- */
475/* Device side: USBX CDC-ACM echo */
476/* -------------------------------------------------------------------------- */
477
495{
496 if (_ux_system_initialize(s_usbx_pool, k_cdc_usbx_pool_bytes, UX_NULL, 0) != UX_SUCCESS) {
497 return UX_ERROR;
498 }
499 return _ux_device_stack_initialize((UCHAR*)UX_NULL,
500 0,
502 sizeof(s_device_framework_fs),
504 sizeof(s_string_framework),
507 UX_NULL);
508}
509
530{
531 UX_SLAVE_CLASS_CDC_ACM_PARAMETER cdc_params = {
532 .ux_slave_class_cdc_acm_instance_activate = cdc_activate,
533 .ux_slave_class_cdc_acm_instance_deactivate = cdc_deactivate,
534 .ux_slave_class_cdc_acm_parameter_change = UX_NULL,
535 };
536 static UCHAR s_class_name[] = "ux_slave_class_cdc_acm";
537
538 return _ux_device_stack_class_register(s_class_name,
539 _ux_device_class_cdc_acm_entry,
540 1,
541 0,
542 &cdc_params);
543}
544
565static void cdc_echo_iter(UCHAR* buf, ULONG cap)
566{
567 if (_ux_system_slave != UX_NULL) {
568 _ux_system_slave->ux_system_slave_device.ux_slave_device_state =
569 (unsigned long)UX_DEVICE_CONFIGURED;
570 }
571 ULONG n = 0UL;
572 if (_ux_device_class_cdc_acm_read(s_cdc_acm, buf, cap, &n) != UX_SUCCESS) {
573 tx_thread_sleep(1U);
574 return;
575 }
576 if (n == 0UL) {
577 return;
578 }
579 if (_ux_device_class_cdc_acm_write(s_cdc_acm, buf, n, &n) != UX_SUCCESS) {
580 return;
581 }
583 s_dbg_dev_last_len = (uint32_t)n;
585}
586
604static VOID cdc_device_worker(ULONG arg)
605{
606 (void)arg;
607
608 UINT ux = cdc_usbx_stack_up();
609 if (ux != UX_SUCCESS) {
610 s_dbg_dev_err = (uint32_t)ux;
611 return;
612 }
614 ux = cdc_class_register();
615 if (ux != UX_SUCCESS) {
616 s_dbg_dev_err = (uint32_t)ux;
617 return;
618 }
621 if (e != k_ra8_ok) {
622 s_dbg_dev_err = (uint32_t)e;
623 return;
624 }
627 if (e != k_ra8_ok) {
628 s_dbg_dev_err = (uint32_t)e;
629 return;
630 }
632
633 static UCHAR s_echo_buf[k_cdc_echo_buf];
634 while (1) {
635 if (s_cdc_acm == UX_NULL) {
636 (void)tx_semaphore_get(&s_cdc_active_sem, TX_WAIT_FOREVER);
637 continue;
638 }
640 cdc_echo_iter(s_echo_buf, (ULONG)k_cdc_echo_buf);
641 }
642}
643
661VOID tx_application_define(VOID* first_unused_memory)
662{
663 static CHAR s_semaphore_name[] = "cdc_active";
664 static CHAR s_device_thread_name[] = "cdc_device";
665 static CHAR s_host_thread_name[] = "cdc_host";
666
667 (void)first_unused_memory;
668 s_tx_kernel_up = true;
669 (void)tx_semaphore_create(&s_cdc_active_sem, s_semaphore_name, 0U);
673 0UL,
683 0UL,
690}
691#endif /* !RA8_OFF_TARGET */
692
693/* -------------------------------------------------------------------------- */
694/* Startup */
695/* -------------------------------------------------------------------------- */
696
710static void cdc_panic_halt(void)
711{
712 while (1) {
713 __asm__ volatile("wfi");
714 }
715}
716
757
772static void cdc_setup_or_halt(void)
773{
774 uint32_t cpuclk0_hz = 0U;
775 if (ra8_cgc_init() != k_ra8_ok) {
777 }
780 }
783 }
786 }
787 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
789 }
792 }
795 }
798 }
800}
801
816void main(void)
817{
819
821
822#ifndef RA8_OFF_TARGET
823 tx_kernel_enter();
824#endif
825
827}
void main(void)
Secure fallback main entry point.
Definition main.c:37
void tx_application_define(void *first_unused_memory)
ThreadX system-define hook: build worker thread + byte pool.
Definition main.c:942
void _tx_timer_interrupt(void)
void SysTick_Handler(void)
SysTick exception handler – tail-calls the ThreadX timer.
Definition main.c:146
static volatile bool s_tx_kernel_up
Set in tx_application_define; gates ThreadX tick delivery.
Definition main.c:86
static UCHAR s_host_stack[k_wlun_host_stack]
Stack backing storage for s_host_thread.
Definition main.c:186
static TX_THREAD s_device_thread
ThreadX TCB for the USBX device-side worker thread.
Definition main.c:164
static UCHAR s_string_framework[]
USBX string descriptor table (vendor / product / serial).
Definition main.c:299
static UCHAR s_usbx_pool[k_wlun_usbx_pool_bytes]
USBX memory pool (USBX uses tx_byte_pool internally).
Definition main.c:193
usb_langid_byte_t
Definition main.c:358
@ k_usb_langid_en_us_lo
LANGID 0x0409 low byte.
Definition main.c:359
@ k_usb_langid_en_us_hi
LANGID 0x0409 high byte.
Definition main.c:360
static CHAR s_host_thread_name[]
Definition main.c:202
static TX_THREAD s_host_thread
ThreadX TCB for the host-side worker thread.
Definition main.c:179
static UCHAR s_device_framework_fs[]
Definition main.c:234
static UCHAR s_language_id_framework[]
USBX language-id table – US English.
Definition main.c:368
static UCHAR s_device_stack[k_wlun_thread_stack]
Stack backing storage for s_device_thread.
Definition main.c:171
static volatile uint32_t s_dbg_dev_step
Device worker progress: 1 stack, 2 class, 3 dcd, 4 attach, 5 parked.
Definition main.c:219
static volatile uint32_t s_dbg_dev_err
Device worker first failing return code (0 = none).
Definition main.c:221
static CHAR s_device_thread_name[]
Definition main.c:201
static VOID cdc_deactivate(VOID *cdc_instance)
CDC-ACM deactivate callback.
Definition main.c:468
static void cdc_route_usb_or_halt(void)
Route both ports' pins: FS as device, HS as host.
Definition main.c:733
static const ra8_port_pin_t k_cdc_pin_fs_dm
USBFS D- (P8_15).
Definition main.c:117
static const ra8_port_pin_t k_cdc_pin_fs_vbusen
USBFS VBUSEN (P5_00) – GPIO LOW for the device role.
Definition main.c:111
static void cdc_setup_or_halt(void)
Bring CGC + both USB clocks + SysTick + SCI8 + LEDs + pins up.
Definition main.c:772
static const ra8_port_pin_t k_cdc_pin_fs_vbus
USBFS VBUS sense pin (P4_07, PSEL = 0x13).
Definition main.c:108
static VOID cdc_activate(VOID *cdc_instance)
CDC-ACM activate callback.
Definition main.c:445
static VOID cdc_device_worker(ULONG arg)
Device-side worker: bring the CDC-ACM device up, then echo forever.
Definition main.c:604
static volatile uint32_t s_dbg_dev_last_len
Bytes the device echoed on the most recent round.
Definition main.c:218
static volatile uint32_t s_dbg_dev_echo_calls
Device-side echo iterations (one read+write each).
Definition main.c:216
static const ra8_port_pin_t k_cdc_pin_hs_vbus
USBHS_VBUS sense pin (P4_08, PSEL = 0x14).
Definition main.c:120
cdc_dev_step_t
J-Link probe values marking device-worker bring-up progress.
Definition main.c:138
@ k_cdc_dev_step_class
CDC-ACM class registered.
Definition main.c:140
@ k_cdc_dev_step_echo
Echo loop running.
Definition main.c:143
@ k_cdc_dev_step_dcd
DCD bridge initialized.
Definition main.c:141
@ k_cdc_dev_step_attach
Device attached (DPRPU).
Definition main.c:142
@ k_cdc_dev_step_stack
USBX system + device stack up.
Definition main.c:139
static UINT cdc_usbx_stack_up(void)
Bring USBX system + device stack up with the CDC-ACM framework.
Definition main.c:494
static UINT cdc_class_register(void)
Register the CDC-ACM class against configuration 1, interface 0.
Definition main.c:529
static const ra8_port_pin_t k_cdc_pin_hs_pwr
J7 host-power switch (PD07): HIGH = U18 supplies VBUS (UM 6.2).
Definition main.c:123
static void cdc_echo_iter(UCHAR *buf, ULONG cap)
One device echo iteration: read a bulk-OUT chunk, write it back.
Definition main.c:565
static const ra8_port_pin_t k_cdc_pin_fs_dp
USBFS D+ (P8_14).
Definition main.c:114
static UX_SLAVE_CLASS_CDC_ACM * s_cdc_acm
Active CDC-ACM class instance, captured by the activate callback.
Definition main.c:195
static TX_SEMAPHORE s_cdc_active_sem
Posted by the activate callback so the echo worker blocks on it instead of polling s_cdc_acm with tx_...
Definition main.c:205
static void cdc_panic_halt(void)
Halt forever in WFI – panic stop on init failure.
Definition main.c:710
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_led_toggle(ra8_board_led_id_t led)
Toggle led's output state.
ra8_err_t ra8_board_led_init(ra8_board_led_id_t led)
Configure led as a digital output, initial level low (off).
@ k_ra8_board_led2
LED2, GREEN, P303 (jumper E26).
@ k_ra8_board_led1
LED1, BLUE, P600 (jumper E27).
ra8_err_t ra8_board_io_expander_set_usbhs_host_mode(void)
Drive the U15 I/O expander to select USB-HS HOST mode.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
@ k_ra8_board_usbhs_pin_pwr
PD07 J7 host-power switch (HIGH = U18 drives 5 V VBUS).
@ k_ra8_board_usbhs_pin_vbus
P4_08 USBHS_VBUS sense.
@ k_ra8_board_usbfs_pin_dm
P8_15 D-.
@ k_ra8_board_usbfs_pin_vbusen
P5_00 VBUSEN GPIO.
@ k_ra8_board_usbfs_pin_vbus
P4_07 VBUS sense.
@ k_ra8_board_usbfs_pin_dp
P8_14 D+.
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
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
ra8_err_t ra8_cgc_usbfs_clock_enable(void)
Bring up the USB-FS module clock (USBCKCR / USBCKDIVCR).
ra8_err_t ra8_cgc_usbhs_pll_enable(void)
Bring up the USBHS PHY reference clock + module clock.
Error Code Definitions for ra8-firmware.
@ 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
PSEL codes for peripheral pin routing on the RA8D2.
@ k_ra8_psel_usb_fs
10011b: USB Full-Speed.
@ k_ra8_psel_usb_hs
10100b: USB High-Speed (e.g.
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
Typed Port / Pin Constants for the RA8D2 IOPORT Module.
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
@ k_ra8_level_high
Drive or read 1.
@ k_ra8_level_low
Drive or read 0.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_gpio_output_init(ra8_port_pin_t pin, ra8_level_t init_level)
Configure a pin as a digital output and drive it to an initial level.
Definition gpio.c:88
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
void ux_dcd_ra8_usb_irq_reenable(void)
Storm-guard recovery: zero the run counter and re-enable the USB IRQ.
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_time_on_tick(void)
SysTick IRQ handler – called from the vector table.
Definition ra8_time.c:170
Native USB controller driver public API (device + host modes).
ra8_err_t ra8_usb_device_attach(ra8_usb_speed_t speed, bool attached)
Raise / drop the D+ pull-up to advertise the device to the host.
@ k_ra8_usb_speed_fs
Full-Speed controller (USBFS @ 0x40250000).
unsigned int UINT
ThreadX-compatible unsigned int (host stub).
#define tx_thread_create
#define tx_thread_sleep
#define TX_NO_TIME_SLICE
char CHAR
ThreadX-compatible CHAR (host stub).
#define TX_AUTO_START
#define TX_WAIT_FOREVER
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
Opaque thread stand-in for the host build.
Host-side self-test ladder + console helpers shared with main.c.
@ k_cdc_echo_buf
One-MPS scratch buffer (bytes).
VOID cdc_host_worker(ULONG arg)
Host-side worker: retry the full pass until it succeeds.
@ k_cdc_thread_stack
Device worker stack (bytes).
@ k_cdc_usbx_pool_bytes
USBX memory pool (bytes).
@ k_cdc_host_priority
Host worker priority (below USBX).
@ k_cdc_dev_priority
Device bring-up worker priority.
@ k_cdc_host_stack
Host worker stack (bytes).
@ k_cdc_baud
J-Link OB CDC log baud.
USBX device-controller-driver (DCD) bridge to ra8_usb.
ra8_err_t ux_dcd_ra8_usb_initialize(ra8_usb_speed_t speed)
Register the ra8_usb bridge as the active USBX DCD.