ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ns_usb.c
Go to the documentation of this file.
1
42
43#include <stdint.h>
44#include <string.h>
45
46#include "ns_usb_internal.h"
47#include "ra8_usb.h"
48#include "tx_api.h"
49#include "ux_api.h"
50#include "ux_dcd_ra8_usb.h"
51#include "ux_device_class_cdc_acm.h"
52#include "ux_device_stack.h"
53#include "ux_system.h"
54
55/* =============================================================================
56 * Bench milestone counters (NS .bss; J-Link reads these)
57 * =============================================================================
58 *
59 * ``g_tz_nsc_cgc_usb_match`` is defined in ns_main.c (the HIL gate symbol). The
60 * USB worker advances it once per polled-dispatch iteration, so a continuing
61 * advance proves the NS-resident USBX worker is alive and dispatching.
62 */
63
65extern volatile uint32_t g_tz_nsc_cgc_usb_match;
66
84
93volatile uint32_t g_tz_usb_state;
94
102volatile uint32_t g_tz_usb_configured;
103
110volatile uint32_t g_tz_usb_dispatch_count;
111
120volatile uint32_t g_tz_usb_intsts_or;
121
122/* =============================================================================
123 * Non-Secure ra8_delay_ms (ThreadX-backed; replaces ra8_time.c in the NS link)
124 * =============================================================================
125 */
126
143void ra8_delay_ms(uint32_t ms)
144{
145 (void)tx_thread_sleep(ms == 0U ? 1UL : (ULONG)ms);
146}
147
163uint32_t ra8_time_ms(void)
164{
165 return (uint32_t)tx_time_get();
166}
167
168/* =============================================================================
169 * Worker thread + USBX pool storage (NS .bss)
170 * =============================================================================
171 */
172
181
189
196
203
209static CHAR s_ns_usb_thread_name[] = "ns_usb_worker";
210
217static UX_SLAVE_CLASS_CDC_ACM* s_ns_cdc_acm = UX_NULL;
218
219/* =============================================================================
220 * USB descriptors (DEVICE + CONFIG + IAD + CDC interfaces + endpoints)
221 * =============================================================================
222 *
223 * Verbatim from the validated threadx_usbx_cdc_demo: VID/PID 1209:000a (pid.codes
224 * test range), one CDC-ACM communications interface + one CDC data interface,
225 * EP3 IN (interrupt) for notifications, EP2 OUT / EP1 IN (bulk, 64-byte MPS).
226 * Layout per CDC 1.20 sec 5 + USB 2.0 sec 9.6; bcdUSB 0x0200 (macOS rejects IAD
227 * composite devices that advertise USB 1.1).
228 */
229static UCHAR s_ns_device_framework_fs[] = {
230 /* Device descriptor (18 bytes). idVendor 0x1209, idProduct 0x000A. */
231 0x12U,
232 0x01U,
233 0x00U,
234 0x02U,
235 0xEFU,
236 0x02U,
237 0x01U,
238 0x40U,
239 0x09U,
240 0x12U,
241 0x0AU,
242 0x00U,
243 0x00U,
244 0x01U,
245 0x01U,
246 0x02U,
247 0x03U,
248 0x01U,
249 /* Configuration descriptor (wTotalLength 0x4B = 75). */
250 0x09U,
251 0x02U,
252 0x4BU,
253 0x00U,
254 0x02U,
255 0x01U,
256 0x00U,
257 0x80U,
258 0x32U,
259 /* Interface association (CDC). */
260 0x08U,
261 0x0BU,
262 0x00U,
263 0x02U,
264 0x02U,
265 0x02U,
266 0x01U,
267 0x00U,
268 /* Communications interface (CDC ACM). */
269 0x09U,
270 0x04U,
271 0x00U,
272 0x00U,
273 0x01U,
274 0x02U,
275 0x02U,
276 0x01U,
277 0x00U,
278 /* CDC header functional descriptor (bcdCDC 0x0120). */
279 0x05U,
280 0x24U,
281 0x00U,
282 0x20U,
283 0x01U,
284 /* Call-management functional descriptor. */
285 0x05U,
286 0x24U,
287 0x01U,
288 0x01U,
289 0x01U,
290 /* ACM functional descriptor. */
291 0x04U,
292 0x24U,
293 0x02U,
294 0x02U,
295 /* Union functional descriptor. */
296 0x05U,
297 0x24U,
298 0x06U,
299 0x00U,
300 0x01U,
301 /* Interrupt-IN endpoint (EP3 IN, 8-byte MPS, 255 ms poll). */
302 0x07U,
303 0x05U,
304 0x83U,
305 0x03U,
306 0x08U,
307 0x00U,
308 0xFFU,
309 /* Data-class interface. */
310 0x09U,
311 0x04U,
312 0x01U,
313 0x00U,
314 0x02U,
315 0x0AU,
316 0x00U,
317 0x00U,
318 0x00U,
319 /* Bulk-OUT endpoint (EP2 OUT, 64-byte MPS). */
320 0x07U,
321 0x05U,
322 0x02U,
323 0x02U,
324 0x40U,
325 0x00U,
326 0x00U,
327 /* Bulk-IN endpoint (EP1 IN, 64-byte MPS). */
328 0x07U,
329 0x05U,
330 0x81U,
331 0x02U,
332 0x40U,
333 0x00U,
334 0x00U,
335};
336
342static UCHAR s_ns_string_framework[] = {
343 /* idx 1: "Brighton Sikarskie". */
344 0x09U,
345 0x04U,
346 0x01U,
347 0x12U,
348 'B',
349 'r',
350 'i',
351 'g',
352 'h',
353 't',
354 'o',
355 'n',
356 ' ',
357 'S',
358 'i',
359 'k',
360 'a',
361 'r',
362 's',
363 'k',
364 'i',
365 'e',
366 /* idx 2: "EK-RA8D2 CDC Echo!". */
367 0x09U,
368 0x04U,
369 0x02U,
370 0x12U,
371 'E',
372 'K',
373 '-',
374 'R',
375 'A',
376 '8',
377 'D',
378 '2',
379 ' ',
380 'C',
381 'D',
382 'C',
383 ' ',
384 'E',
385 'c',
386 'h',
387 'o',
388 '!',
389 /* idx 3: serial "00000001". */
390 0x09U,
391 0x04U,
392 0x03U,
393 0x08U,
394 '0',
395 '0',
396 '0',
397 '0',
398 '0',
399 '0',
400 '0',
401 '1',
402};
403
405typedef enum : uint8_t {
409
411
412/* =============================================================================
413 * CDC-ACM activate / deactivate callbacks
414 * =============================================================================
415 */
416
429static VOID ns_cdc_activate(VOID* cdc_instance)
430{
431 s_ns_cdc_acm = (UX_SLAVE_CLASS_CDC_ACM*)cdc_instance;
432 if (_ux_system_slave != UX_NULL) {
433 _ux_system_slave->ux_system_slave_device.ux_slave_device_state =
434 (unsigned long)UX_DEVICE_CONFIGURED;
435 }
436 /* Mirror CDC bulk OUT (pipe 2) back on IN (pipe 1) inside the bridge
437 * bottom-half, which the polled ra8_usb_dispatch reaches. */
440}
441
453static VOID ns_cdc_deactivate(VOID* cdc_instance)
454{
455 (void)cdc_instance;
456 s_ns_cdc_acm = UX_NULL;
457}
458
459/* =============================================================================
460 * USBX bring-up helpers
461 * =============================================================================
462 */
463
476{
477 if (_ux_system_initialize(s_ns_usbx_pool, (ULONG)k_ns_usb_pool_bytes, UX_NULL, 0) != UX_SUCCESS) {
478 return UX_ERROR;
479 }
480 return _ux_device_stack_initialize((UCHAR*)UX_NULL,
481 0,
485 sizeof(s_ns_string_framework),
488 UX_NULL);
489}
490
503{
504 UX_SLAVE_CLASS_CDC_ACM_PARAMETER cdc_params = {
505 .ux_slave_class_cdc_acm_instance_activate = ns_cdc_activate,
506 .ux_slave_class_cdc_acm_instance_deactivate = ns_cdc_deactivate,
507 .ux_slave_class_cdc_acm_parameter_change = UX_NULL,
508 };
509 /* (UCHAR*)(uintptr_t): USBX takes a non-const class name; the uintptr_t hop
510 * launders the string-literal const without tripping -Wcast-qual. */
511 return _ux_device_stack_class_register((UCHAR*)(uintptr_t)"ux_slave_class_cdc_acm",
512 _ux_device_class_cdc_acm_entry,
513 1,
514 0,
515 &cdc_params);
516}
517
518/* =============================================================================
519 * USBX worker thread
520 * =============================================================================
521 */
522
536static VOID ns_usb_worker(ULONG arg)
537{
538 (void)arg;
539
540 if (ns_usbx_stack_up() != UX_SUCCESS) {
541 return;
542 }
544
545 if (ns_cdc_class_register() != UX_SUCCESS) {
546 return;
547 }
549
551 return;
552 }
554
556 return;
557 }
559
560 /* Polled controller service: drives bus reset, chapter-9 SETUP, and the
561 * bulk auto-echo (all inside ra8_usb_dispatch -> internal_event_cb ->
562 * ux_dcd_ra8_usb_irq). Time-sliced against ::ns_host_worker at the same
563 * priority, so this yields each tick and the host's transfers land inside the
564 * dispatch service window. */
566 while (1) {
571 }
572}
573
volatile uint32_t g_tz_nsc_cgc_usb_match
Success counter: advances forever once all three veneers returned OK.
Definition ns_main.c:102
static UCHAR s_ns_usb_stack[k_ns_usb_thread_stack]
Stack backing storage for s_ns_usb_thread.
Definition ns_usb.c:195
tz_usb_state_t
USBX bring-up progress breadcrumbs written to g_tz_usb_state.
Definition ns_usb.c:77
@ k_tz_usb_state_dcd_ready
DCD bridge installed.
Definition ns_usb.c:80
@ k_tz_usb_state_attached
Device attached (D+ pull-up on).
Definition ns_usb.c:81
@ k_tz_usb_state_stack_up
USBX stack initialised.
Definition ns_usb.c:78
@ k_tz_usb_state_dispatched
Entered the polled-dispatch loop.
Definition ns_usb.c:82
@ k_tz_usb_state_cdc_ready
CDC-ACM class registered.
Definition ns_usb.c:79
static UCHAR s_ns_language_id_framework[]
Definition ns_usb.c:410
static UINT ns_usbx_stack_up(void)
Bring the USBX system + device stack up on the FS framework.
Definition ns_usb.c:475
static UCHAR s_ns_device_framework_fs[]
Definition ns_usb.c:229
static CHAR s_ns_usb_thread_name[]
Worker thread name (writable NS data; ThreadX name_ptr is CHAR*).
Definition ns_usb.c:209
static UCHAR s_ns_string_framework[]
USBX string descriptor table (vendor / product / serial).
Definition ns_usb.c:342
static VOID ns_cdc_activate(VOID *cdc_instance)
CDC-ACM activate callback – capture the class + enable bulk auto-echo.
Definition ns_usb.c:429
static UINT ns_cdc_class_register(void)
Register the CDC-ACM class against the device-stack configuration.
Definition ns_usb.c:502
void ra8_delay_ms(uint32_t ms)
Non-Secure ra8_delay_ms – sleep ms ThreadX ticks.
Definition ns_usb.c:143
volatile uint32_t g_tz_usb_configured
Advances each time the CDC-ACM activate callback fires (enumeration reached SET_CONFIGURATION – the h...
Definition ns_usb.c:102
static VOID ns_cdc_deactivate(VOID *cdc_instance)
CDC-ACM deactivate callback – drop the live class pointer.
Definition ns_usb.c:453
volatile uint32_t g_tz_usb_intsts_or
Bitwise OR of every INTSTS0 snapshot the worker has seen.
Definition ns_usb.c:120
volatile uint32_t g_tz_usb_dispatch_count
Polled-dispatch iteration counter (USB worker liveness).
Definition ns_usb.c:110
static TX_THREAD s_ns_usb_thread
ThreadX TCB for the NS USBX worker.
Definition ns_usb.c:188
ns_usb_langid_t
USBX LANGID 0x0409 (English-US), little-endian byte pair.
Definition ns_usb.c:405
@ k_ns_usb_langid_lo
LANGID 0x0409 low byte.
Definition ns_usb.c:406
@ k_ns_usb_langid_hi
LANGID 0x0409 high byte.
Definition ns_usb.c:407
uint32_t ra8_time_ms(void)
Non-Secure ra8_time_ms – monotonic millisecond clock from ThreadX.
Definition ns_usb.c:163
ns_usb_cfg_t
USBX worker thread + pool tunables.
Definition ns_usb.c:174
@ k_ns_usb_echo_in_pipe
CDC bulk-IN -> pipe 1 (auto-echo).
Definition ns_usb.c:179
@ k_ns_usb_echo_out_pipe
CDC bulk-OUT -> pipe 2 (auto-echo).
Definition ns_usb.c:178
@ k_ns_usb_pool_bytes
USBX memory pool (bytes).
Definition ns_usb.c:176
@ k_ns_usb_thread_stack
Worker thread stack (bytes).
Definition ns_usb.c:175
@ k_ns_usb_thread_prio
Worker priority + preempt threshold.
Definition ns_usb.c:177
static VOID ns_usb_worker(ULONG arg)
NS USBX worker – bring CDC up then poll the controller forever.
Definition ns_usb.c:536
static UX_SLAVE_CLASS_CDC_ACM * s_ns_cdc_acm
Active CDC-ACM class instance captured by the activate callback.
Definition ns_usb.c:217
void tx_application_define(void *first_unused_memory)
ThreadX application-define callback – spawn the device + host workers.
Definition ns_usb.c:587
volatile uint32_t g_tz_usb_state
USBX bring-up progress breadcrumb (localises a stall under J-Link).
Definition ns_usb.c:93
static UCHAR s_ns_usbx_pool[k_ns_usb_pool_bytes]
USBX memory pool (USBX manages it as a tx_byte_pool).
Definition ns_usb.c:202
Private split-seam shared between ns_usb.c and ns_usb_host.c (#96).
TX_THREAD s_ns_host_thread
ThreadX TCB for the HS host worker (defined in ns_usb_host.c).
Definition ns_usb_host.c:88
CHAR s_ns_host_thread_name[]
HS host worker thread name (defined in ns_usb_host.c; ThreadX CHAR*).
VOID ns_host_worker(ULONG arg)
HS host worker – enumerate the looped FS device, then echo forever.
@ k_ns_host_stack_bytes
HS host worker stack (bytes).
@ k_ns_time_slice
ThreadX time-slice (ticks) per worker.
UCHAR s_ns_host_stack[k_ns_host_stack_bytes]
Stack backing storage for s_ns_host_thread (defined in ns_usb_host.c).
Definition ns_usb_host.c:95
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
Native USB controller driver public API (device + host modes).
uint16_t ra8_usb_intsts0_snapshot(ra8_usb_speed_t speed)
Read INTSTS0 without acking any bits.
void ra8_usb_dispatch(ra8_usb_speed_t speed)
Snapshot INTSTS0 and fire the installed event handler.
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_time_get
#define tx_thread_sleep
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.
USBX device-controller-driver (DCD) bridge to ra8_usb.
void ux_dcd_ra8_usb_auto_echo_enable(uint8_t out_pipe, uint8_t in_pipe)
Enable ISR-side auto-echo from a bulk OUT pipe to a bulk IN pipe.
ra8_err_t ux_dcd_ra8_usb_initialize(ra8_usb_speed_t speed)
Register the ra8_usb bridge as the active USBX DCD.