ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
usb_msc_sdcard_steps.c
Go to the documentation of this file.
1
44
46
47#include <stdint.h>
48#include <string.h>
49
50#include "ra8_board_ek_ra8d2.h"
51#include "ra8_err.h"
52#include "ra8_sdmmc_spi.h"
53#include "ra8_usb.h"
54
55#ifndef RA8_OFF_TARGET
56#include "tx_api.h"
57#include "ux_api.h"
58#include "ux_dcd_ra8_usb.h"
59#include "ux_device_class_storage.h"
60#include "ux_device_stack.h"
61
62/* -------------------------------------------------------------------------- */
63/* USBX pool storage + SCSI INQUIRY strings */
64/* -------------------------------------------------------------------------- */
65
72
73/* SCSI INQUIRY strings -- 8 / 16 / 4 byte fields per SBC-3. */
74static UCHAR s_msc_vendor_id[] = "RA8D2 ";
75static UCHAR s_msc_product_id[] = "SDCARD LIVE RW ";
76static UCHAR s_msc_product_rev[] = "0001";
77
78/* -------------------------------------------------------------------------- */
79/* J-Link probes (device worker + media-callback owned) */
80/* -------------------------------------------------------------------------- */
81
83static volatile uint32_t s_dbg_dev_step;
85static volatile uint32_t s_dbg_dev_err;
87static volatile uint32_t s_dbg_read_calls;
89static volatile uint32_t s_dbg_write_calls;
91static volatile uint32_t s_dbg_read_blocks;
93static volatile uint32_t s_dbg_write_blocks;
95static volatile uint32_t s_dbg_media_err;
96
97/* -------------------------------------------------------------------------- */
98/* USB descriptors (single-interface MSC; SCSI transparent; BBB) */
99/* -------------------------------------------------------------------------- */
100
101/* MSC config: bulk-only transport, SCSI command set, EP1 IN + EP2 OUT,
102 * 64-byte MPS. PID 0x0019 marks the live-SD read/write MSC identity. */
103static UCHAR s_device_framework_fs[] = {
104 /* Device descriptor (USB 2.0 sec 9.6.1) -- 18 bytes. */
105 0x12U,
106 0x01U,
107 0x00U,
108 0x02U,
109 0x00U,
110 0x00U,
111 0x00U,
112 0x40U,
113 0x09U,
114 0x12U,
115 0x19U, /* PID = 0x0019 (pid.codes test). */
116 0x00U,
117 0x00U,
118 0x01U,
119 0x01U,
120 0x02U,
121 0x03U,
122 0x01U,
123 /* Configuration descriptor (32 bytes total). */
124 0x09U,
125 0x02U,
126 0x20U,
127 0x00U,
128 0x01U,
129 0x01U,
130 0x00U,
131 0x80U,
132 0x32U,
133 /* Interface descriptor -- MSC, SCSI, BBB. */
134 0x09U,
135 0x04U,
136 0x00U,
137 0x00U,
138 0x02U,
139 0x08U,
140 0x06U,
141 0x50U,
142 0x00U,
143 /* Bulk-IN endpoint (EP1 IN, 64-byte MPS). */
144 0x07U,
145 0x05U,
146 0x81U,
147 0x02U,
148 0x40U,
149 0x00U,
150 0x00U,
151 /* Bulk-OUT endpoint (EP2 OUT, 64-byte MPS). */
152 0x07U,
153 0x05U,
154 0x02U,
155 0x02U,
156 0x40U,
157 0x00U,
158 0x00U,
159};
160
168static UCHAR s_string_framework[] = {
169 /* idx 1: "Brighton Sikarskie". */
170 0x09U,
171 0x04U,
172 0x01U,
173 0x12U,
174 'B',
175 'r',
176 'i',
177 'g',
178 'h',
179 't',
180 'o',
181 'n',
182 ' ',
183 'S',
184 'i',
185 'k',
186 'a',
187 'r',
188 's',
189 'k',
190 'i',
191 'e',
192 /* idx 2: "RA8D2 SDCARD RW". */
193 0x09U,
194 0x04U,
195 0x02U,
196 0x0FU,
197 'R',
198 'A',
199 '8',
200 'D',
201 '2',
202 ' ',
203 'S',
204 'D',
205 'C',
206 'A',
207 'R',
208 'D',
209 ' ',
210 'R',
211 'W',
212 /* idx 3: serial. */
213 0x09U,
214 0x04U,
215 0x03U,
216 0x08U,
217 '0',
218 '0',
219 '0',
220 '0',
221 '0',
222 '0',
223 '1',
224 '9',
225};
226
233
234/* -------------------------------------------------------------------------- */
235/* Storage class media callbacks (single writable live-SD LUN) */
236/* -------------------------------------------------------------------------- */
237
268static UINT sdmsc_msc_read(VOID* storage,
269 ULONG lun,
270 UCHAR* data_pointer,
271 ULONG number_blocks,
272 ULONG lba,
273 ULONG* media_status)
274{
275 (void)storage;
276 (void)lun;
278 if ((lba + number_blocks) > (ULONG)s_usb_msc_sdcard_blocks) {
279 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(k_scsi_sense_illegal_request,
282 return UX_ERROR;
283 }
284 const ra8_err_t err =
285 ra8_sdmmc_spi_read_blocks((uint32_t)lba, data_pointer, (uint32_t)number_blocks);
286 if (err != k_ra8_ok) {
287 s_dbg_media_err = (uint32_t)err;
288 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(k_scsi_sense_medium_error,
291 return UX_ERROR;
292 }
293 s_dbg_read_blocks += (uint32_t)number_blocks;
294 *media_status = 0UL;
296 return UX_SUCCESS;
297}
298
333static UINT sdmsc_msc_write(VOID* storage,
334 ULONG lun,
335 UCHAR* data_pointer,
336 ULONG number_blocks,
337 ULONG lba,
338 ULONG* media_status)
339{
340 (void)storage;
341 (void)lun;
343 if ((lba + number_blocks) > (ULONG)s_usb_msc_sdcard_blocks) {
344 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(k_scsi_sense_illegal_request,
347 return UX_ERROR;
348 }
349 const ra8_err_t err =
350 ra8_sdmmc_spi_write_blocks((uint32_t)lba, data_pointer, (uint32_t)number_blocks);
351 if (err != k_ra8_ok) {
352 s_dbg_media_err = (uint32_t)err;
353 *media_status = UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(k_scsi_sense_medium_error,
356 return UX_ERROR;
357 }
358 s_dbg_write_blocks += (uint32_t)number_blocks;
359 *media_status = 0UL;
361 return UX_SUCCESS;
362}
363
386static UINT sdmsc_msc_status(VOID* storage, ULONG lun, ULONG media_id, ULONG* media_status)
387{
388 (void)storage;
389 (void)lun;
390 (void)media_id;
391 *media_status = 0UL;
392 return UX_SUCCESS;
393}
394
395/* -------------------------------------------------------------------------- */
396/* Device side: USBX MSC with one writable live-SD LUN */
397/* -------------------------------------------------------------------------- */
398
416{
417 if (_ux_system_initialize(s_usbx_pool, k_sdmsc_usbx_pool_bytes, UX_NULL, 0) != UX_SUCCESS) {
418 return UX_ERROR;
419 }
420 return _ux_device_stack_initialize((UCHAR*)UX_NULL,
421 0,
423 sizeof(s_device_framework_fs),
425 sizeof(s_string_framework),
428 UX_NULL);
429}
430
452{
453 UX_SLAVE_CLASS_STORAGE_PARAMETER msc_params;
454 (void)memset(&msc_params, 0, sizeof(msc_params));
455 msc_params.ux_slave_class_storage_parameter_number_lun = 1UL;
456 msc_params.ux_slave_class_storage_parameter_vendor_id = s_msc_vendor_id;
457 msc_params.ux_slave_class_storage_parameter_product_id = s_msc_product_id;
458 msc_params.ux_slave_class_storage_parameter_product_rev = s_msc_product_rev;
459
460 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba =
462 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length =
464 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type =
465 UX_SLAVE_CLASS_STORAGE_MEDIA_FAT_DISK;
466 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag =
467 UX_SLAVE_CLASS_STORAGE_MEDIA_IS_REMOVABLE;
468 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read_only_flag =
469 UX_FALSE;
470 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read =
472 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write =
474 msc_params.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status =
476
477 static UCHAR s_class_name[] = "ux_slave_class_storage";
478
479 return _ux_device_stack_class_register(s_class_name,
480 _ux_device_class_storage_entry,
481 1,
482 0,
483 &msc_params);
484}
485
503[[nodiscard]] static ra8_err_t sdmsc_print_ready(void)
504{
505 ra8_err_t err = sdmsc_print("usb_msc_sdcard: USB MSC SDCARD READY (RW, ");
506 if (err != k_ra8_ok) {
507 return err;
508 }
510 if (err != k_ra8_ok) {
511 return err;
512 }
513 return sdmsc_print(" blocks)\r\n");
514}
515
517{
518 (void)arg;
519
520 if (s_usb_msc_sdcard_blocks == 0U) {
521 (void)sdmsc_print_fail("no card -- not attaching USB", k_ra8_err_invalid_state);
522 return;
523 }
525 if (ux != UX_SUCCESS) {
526 s_dbg_dev_err = (uint32_t)ux;
527 (void)sdmsc_print_fail("usbx stack", (ra8_err_t)ux);
528 return;
529 }
532 if (ux != UX_SUCCESS) {
533 s_dbg_dev_err = (uint32_t)ux;
534 (void)sdmsc_print_fail("msc class", (ra8_err_t)ux);
535 return;
536 }
539 if (err != k_ra8_ok) {
540 s_dbg_dev_err = (uint32_t)err;
541 (void)sdmsc_print_fail("dcd init", err);
542 return;
543 }
546 if (err != k_ra8_ok) {
547 s_dbg_dev_err = (uint32_t)err;
548 (void)sdmsc_print_fail("device attach", err);
549 return;
550 }
552 (void)sdmsc_print_ready();
553
554 while (1) {
557 }
558}
559
560#endif /* !RA8_OFF_TARGET */
static UCHAR s_msc_product_id[]
Definition main.c:197
static UCHAR s_string_framework[]
USBX string descriptor table (vendor / product / serial).
Definition main.c:299
@ k_scsi_ascq_none
ASCQ: none.
Definition main.c:147
@ k_scsi_sense_illegal_request
Sense key: ILLEGAL REQUEST.
Definition main.c:145
@ k_scsi_asc_lba_out_of_range
ASC: LBA out of range.
Definition main.c:146
static volatile uint32_t s_dbg_write_blocks
Total 512-B blocks the device media_write callback stored.
Definition main.c:217
static volatile uint32_t s_dbg_write_calls
Device-side media_write invocations (WRITE(10) data received).
Definition main.c:215
static UCHAR s_usbx_pool[k_wlun_usbx_pool_bytes]
USBX memory pool (USBX uses tx_byte_pool internally).
Definition main.c:193
@ 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 UCHAR s_device_framework_fs[]
Definition main.c:234
static UCHAR s_msc_product_rev[]
Definition main.c:198
static UCHAR s_language_id_framework[]
USBX language-id table – US English.
Definition main.c:368
static volatile uint32_t s_dbg_read_calls
Device-side media_read invocations.
Definition main.c:213
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 UCHAR s_msc_vendor_id[]
Definition main.c:196
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.
@ k_ra8_board_led2
LED2, GREEN, P303 (jumper E26).
@ k_ra8_board_led1
LED1, BLUE, P600 (jumper E27).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ 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
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
SD card driver in SPI-mode (PMOD-attached cards).
ra8_err_t ra8_sdmmc_spi_read_blocks(uint32_t lba, uint8_t *buf, uint32_t count)
Read count contiguous 512-byte blocks in one CMD18 transaction.
ra8_err_t ra8_sdmmc_spi_write_blocks(uint32_t lba, const uint8_t *buf, uint32_t count)
Write count contiguous 512-byte blocks in one CMD25 transaction.
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_sleep
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
static UINT sdmsc_usbx_stack_up(void)
Bring USBX system + device stack up with the MSC framework.
VOID sdmsc_device_worker(ULONG arg)
Device worker: bring the live-SD read/write MSC device up, then park.
static UINT sdmsc_class_register(void)
Register the Mass-Storage class with one writable live-SD LUN.
static UINT sdmsc_msc_read(VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
Storage media-read callback: stream blocks off the live SD card.
static volatile uint32_t s_dbg_media_err
First failing SD driver error on the media path (0 = none).
static volatile uint32_t s_dbg_read_blocks
Total 512-B blocks served to the host by media_read.
static ra8_err_t sdmsc_print_ready(void)
Print the READY banner: "usb_msc_sdcard: USB MSC SDCARD READY ...".
static UINT sdmsc_msc_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
Storage media-status callback.
static UINT sdmsc_msc_write(VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
Storage media-write callback: commit host data to the live SD card.
examples/ek_ra8d2/hw_pending/manual/usb_msc_sdcard/inc/usb_msc_sdcard_steps.h
ra8_err_t sdmsc_print(const char *text)
Print a NUL-terminated ASCII string over the SCI8 console.
@ k_sdmsc_dev_step_class
MSC class registered.
@ k_sdmsc_dev_step_dcd
DCD bridge initialized.
@ k_sdmsc_dev_step_parked
Bring-up done; worker parked.
@ k_sdmsc_dev_step_attach
Device attached (DPRPU).
@ k_sdmsc_dev_step_stack
USBX system + device stack up.
ra8_err_t sdmsc_print_dec(uint32_t value)
Print a uint32_t as ASCII decimal over the SCI8 console.
@ k_scsi_asc_unrecovered_read
ASC: unrecovered read error.
@ k_scsi_sense_medium_error
Sense key: MEDIUM ERROR.
@ k_scsi_asc_write_fault
ASC: peripheral dev write fault.
volatile uint32_t s_usb_msc_sdcard_blocks
Live SD card capacity in 512-byte blocks (0 = no card).
Definition main.c:136
ra8_err_t sdmsc_print_fail(const char *what, ra8_err_t err)
Print "FAIL <what> err=0xNNNNNNNN" on its own console line.
@ k_sdmsc_idle_ticks
Parked-loop back-off (ticks).
@ k_sdmsc_block_size
SCSI logical block size (bytes).
@ k_sdmsc_usbx_pool_bytes
USBX memory pool (bytes).
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.