|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Native USB device-side MSC (Mass Storage Class) class layer. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_usb_pmsc_storage_t |
| Caller-owned storage backend bound to the device-MSC class. More... | |
Typedefs | |
| typedef ra8_err_t(* | ra8_usb_pmsc_read_block_fn_t) (void *ctx, uint32_t lba, uint32_t block_count, uint8_t *buf) |
| Storage-backend read hook. | |
| typedef ra8_err_t(* | ra8_usb_pmsc_write_block_fn_t) (void *ctx, uint32_t lba, uint32_t block_count, const uint8_t *buf) |
| Storage-backend write hook. | |
| typedef ra8_err_t(* | ra8_usb_pmsc_get_capacity_fn_t) (void *ctx, uint32_t *block_count, uint32_t *block_size) |
| Storage-backend capacity hook – answers SCSI READ CAPACITY(10). | |
| typedef ra8_err_t(* | ra8_usb_pmsc_get_inquiry_fn_t) (void *ctx, uint8_t *vendor8, uint8_t *product16, uint8_t *revision4) |
| Storage-backend INQUIRY hook – answers SCSI INQUIRY. | |
Functions | |
| ra8_err_t | ra8_usb_pmsc_init (ra8_usb_speed_t speed) |
| Bring up the device-MSC driver on a chosen USB controller. | |
| ra8_err_t | ra8_usb_pmsc_close (void) |
| Tear down the device-MSC driver and release the controller. | |
| ra8_err_t | ra8_usb_pmsc_attach_storage (const ra8_usb_pmsc_storage_t *storage) |
| Bind a caller-owned storage backend to the device-MSC class. | |
| ra8_err_t | ra8_usb_pmsc_step (void) |
| Drive the BOT (Bulk-Only Transport) state machine forward by one step. | |
| ra8_err_t | ra8_usb_pmsc_feed_cbw (const uint8_t *cbw) |
| Inject a CBW directly into the BOT state machine. | |
| ra8_err_t | ra8_usb_pmsc_dispatch_command (uint8_t *data_buf, uint32_t data_buf_capacity, uint32_t *data_len, ra8_usb_pmsc_csw_status_t *csw_status) |
| Run the SCSI command currently parked in the BOT state. | |
| ra8_err_t | ra8_usb_pmsc_build_csw (ra8_usb_pmsc_csw_status_t csw_status, uint32_t residue, uint8_t *out_csw) |
| Build the 13-byte CSW for the in-flight command. | |
Native USB device-side MSC (Mass Storage Class) class layer.
Mirrors FSP's r_usb_pmsc peripheral-mode Mass Storage Class driver. With this layer the EK-RA8D2 can present an internal SRAM region, an SD card, or any other block device the application wires up as a USB drive to a host.
Lifecycle (mirrors ra8_usb_cdc.h and ra8_usb_hmsc.h shape):
Class-specific control requests (USB MSC BBB rev 1.0 sec 3.1):
Reference: USB Mass Storage Class Bulk-Only Transport spec rev 1.0 (USB-IF, 1999-09-31), and SCSI Primary Commands rev 4 (T10/1731-D) for the SBC opcodes used here.
Definition in file ra8_usb_pmsc.h.
| typedef ra8_err_t(* ra8_usb_pmsc_get_capacity_fn_t) (void *ctx, uint32_t *block_count, uint32_t *block_size) |
Storage-backend capacity hook – answers SCSI READ CAPACITY(10).
| [in] | ctx | Caller-supplied context. |
| [out] | block_count | Total block count (NOT block_count - 1). |
| [out] | block_size | Block size in bytes (typically 512). |
Definition at line 258 of file ra8_usb_pmsc.h.
| typedef ra8_err_t(* ra8_usb_pmsc_get_inquiry_fn_t) (void *ctx, uint8_t *vendor8, uint8_t *product16, uint8_t *revision4) |
Storage-backend INQUIRY hook – answers SCSI INQUIRY.
The driver populates the standard fields (peripheral device type, removable bit, SPC version, response data format) and copies the three caller-supplied ASCII strings into byte positions 8..15, 16..31, and 32..35 of the 36-byte INQUIRY response.
| [in] | ctx | Caller-supplied context. |
| [out] | vendor8 | 8-byte T10 vendor ID, SPACE-padded. |
| [out] | product16 | 16-byte product ID, SPACE-padded. |
| [out] | revision4 | 4-byte product revision, SPACE-padded. |
Definition at line 279 of file ra8_usb_pmsc.h.
| typedef ra8_err_t(* ra8_usb_pmsc_read_block_fn_t) (void *ctx, uint32_t lba, uint32_t block_count, uint8_t *buf) |
Storage-backend read hook.
| [in] | ctx | Caller-supplied context registered with ra8_usb_pmsc_attach_storage. |
| [in] | lba | Starting logical block address. |
| [in] | block_count | Number of blocks to read (1..65535). |
| [out] | buf | Destination buffer, sized to at least block_count * block_size bytes. |
Definition at line 225 of file ra8_usb_pmsc.h.
| typedef ra8_err_t(* ra8_usb_pmsc_write_block_fn_t) (void *ctx, uint32_t lba, uint32_t block_count, const uint8_t *buf) |
Storage-backend write hook.
| [in] | ctx | Caller-supplied context. |
| [in] | lba | Starting logical block address. |
| [in] | block_count | Number of blocks to write (1..65535). |
| [in] | buf | Source buffer, sized to at least block_count * block_size bytes. |
Definition at line 242 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_class_t : uint8_t |
Class / subclass / protocol triplet advertised in the device's interface descriptor.
Per the USB-IF "Class Codes" registry and the USB MSC overview spec rev 1.4. Subclass 0x06 = transparent SCSI; protocol 0x50 = Bulk-Only Transport (BBB).
| Enumerator | |
|---|---|
| k_ra8_pmsc_class_msc | MSC interface class. |
| k_ra8_pmsc_subclass_scsi | Transparent SCSI subclass. |
| k_ra8_pmsc_protocol_bbb | Bulk-Only Transport. |
Definition at line 111 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_csw_status_t : uint8_t |
CSW status field values the device returns after a CBW.
Per USB MSC BBB rev 1.0 sec 5.2 "Command Status Wrapper".
| Enumerator | |
|---|---|
| k_ra8_pmsc_csw_status_passed | Command succeeded. |
| k_ra8_pmsc_csw_status_failed | Command failed. |
| k_ra8_pmsc_csw_status_phase_error | BBB phase error – the host must run reset recovery. |
Definition at line 146 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_endpoint_t : uint8_t |
USB endpoint numbers advertised in the configuration descriptor.
Bulk-IN at EP1, bulk-OUT at EP2; matches the layout most stock MSC reference designs ship with.
| Enumerator | |
|---|---|
| k_ra8_pmsc_ep_bulk_in | Bulk-IN endpoint number. |
| k_ra8_pmsc_ep_bulk_out | Bulk-OUT endpoint number. |
Definition at line 88 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_inquiry_field_t : uint8_t |
Sizes of the three INQUIRY ASCII strings the storage backend returns.
Per SBC-4 sec 6.6 the T10 vendor ID is 8 bytes, the product ID is 16 bytes, and the product revision is 4 bytes. All three are SPACE-padded, NOT NUL-terminated, on the wire.
| Enumerator | |
|---|---|
| k_ra8_pmsc_inq_vendor_len | Vendor ID byte count. |
| k_ra8_pmsc_inq_product_len | Product ID byte count. |
| k_ra8_pmsc_inq_revision_len | Revision byte count. |
Definition at line 200 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_max_lun_t : uint8_t |
Number of logical units the starter exposes.
Single-LUN device. Get-Max-LUN therefore returns 0 (the highest valid LUN index).
| Enumerator | |
|---|---|
| k_ra8_pmsc_max_lun | Highest valid LUN index. |
Definition at line 136 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_packet_t : uint16_t |
Packet sizing for the local bulk endpoints.
| Enumerator | |
|---|---|
| k_ra8_pmsc_bulk_max_packet_fs | Bulk size at full speed. |
| k_ra8_pmsc_bulk_max_packet_hs | Bulk size at high speed. |
Definition at line 97 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_pipe_t : uint8_t |
PIPE numbers used by the device-MSC driver for the local bulk endpoints.
FSP / RA8D2 PIPE assignment rules constrain bulk pipes to PIPE1..PIPE5. The device-MSC class uses two pipes: bulk-IN to push SCSI data + CSW back to the host, bulk-OUT to receive CBW + data from the host. Pipes 3 / 4 mirror the host-MSC layer so a single controller can switch roles without re-keying the pipe table.
| Enumerator | |
|---|---|
| k_ra8_pmsc_pipe_bulk_in | PIPE3 -> local EP bulk IN. |
| k_ra8_pmsc_pipe_bulk_out | PIPE4 -> local EP bulk OUT. |
Definition at line 75 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_request_t : uint8_t |
MSC class-specific request codes the host issues to the device.
Per USB MSC BBB rev 1.0 sec 3.1 "Class-Specific Requests".
| Enumerator | |
|---|---|
| k_ra8_pmsc_req_mass_storage_reset | 0-byte payload. |
| k_ra8_pmsc_req_get_max_lun | 1-byte response. |
Definition at line 124 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_resp_size_t : uint16_t |
Standard SCSI response payload sizes.
The SCSI INQUIRY response is fixed at 36 bytes (5+31, see SBC-4 sec 6.6); READ_CAPACITY(10) is 8 bytes (4-byte returned-LBA
Definition at line 183 of file ra8_usb_pmsc.h.
| enum ra8_usb_pmsc_scsi_t : uint8_t |
SCSI opcodes the device-MSC class answers over BBB.
A small subset of SCSI Primary Commands rev 4 + SCSI Block Commands rev 4. Other opcodes generate a CSW with status k_ra8_pmsc_csw_status_failed and a sense code of "Invalid Command Operation Code".
Definition at line 163 of file ra8_usb_pmsc.h.
|
nodiscard |
Bind a caller-owned storage backend to the device-MSC class.
The four function pointers in storage are validated for NULL and the struct is copied into internal state. After this call the BOT state machine can answer SCSI commands the host issues.
| [in] | storage | Storage backend snapshot. Copied by value. |
| k_ra8_ok | Backend installed. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | storage was NULL or any callback was NULL. |
Definition at line 515 of file ra8_usb_pmsc.c.
References g_usb_pmsc_state, ra8_usb_pmsc_storage_t::get_capacity, ra8_usb_pmsc_storage_t::get_inquiry, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_pmsc_state_idle, RA8_CHECK_NULL_PTR, ra8_log_info, ra8_usb_pmsc_storage_t::read_block, s_tag, and ra8_usb_pmsc_storage_t::write_block.
|
nodiscard |
Build the 13-byte CSW for the in-flight command.
Test / debug entry point. Production code calls this internally during the CSW_TX phase. The CSW is laid out per USB MSC BBB rev 1.0 sec 5.2: dCSWSignature='USBS', dCSWTag echoed from the CBW, dCSWDataResidue computed from the CBW dCBWDataTransferLength minus the actual byte count produced, bCSWStatus from csw_status.
| [in] | csw_status | Status byte to embed in the CSW. |
| [in] | residue | Bytes that were NOT transferred (CBW expected minus actual). |
| [out] | out_csw | Receives the 13-byte CSW buffer. |
| k_ra8_ok | CSW constructed. |
| k_ra8_err_null_ptr | out_csw was NULL. |
| k_ra8_err_invalid_state | Driver not initialized, or no CBW currently in-flight. |
Definition at line 454 of file ra8_usb_pmsc.c.
References g_usb_pmsc_state, internal_pack_u32_le(), k_ra8_err_invalid_state, k_ra8_ok, k_ra8_pmsc_csw_len, k_ra8_pmsc_csw_off_residue, k_ra8_pmsc_csw_off_signature, k_ra8_pmsc_csw_off_status, k_ra8_pmsc_csw_off_tag, k_ra8_pmsc_csw_signature, k_ra8_pmsc_state_idle, priv_zero_bytes(), RA8_CHECK_NULL_PTR, and s_tag.
|
nodiscard |
Tear down the device-MSC driver and release the controller.
| k_ra8_ok | Released. |
| k_ra8_err_invalid_state | Driver was never initialized. |
Definition at line 568 of file ra8_usb_pmsc.c.
References g_usb_pmsc_state, k_ra8_err_invalid_state, k_ra8_pmsc_state_idle, ra8_usb_device_attach(), and ra8_usb_device_deinit().
|
nodiscard |
Run the SCSI command currently parked in the BOT state.
Test / debug entry point. After ra8_usb_pmsc_feed_cbw accepts a CBW, this routine invokes the storage backend (if any) and stages the data-phase output buffer / pulls the CSW status byte. On unsupported opcodes the CSW status is set to k_ra8_pmsc_csw_status_failed.
| [out] | data_buf | Buffer that receives the data-IN payload (or provides the data-OUT payload). Caller sized to at least data_buf_capacity bytes. |
| [in] | data_buf_capacity | Capacity of data_buf in bytes. |
| [out] | data_len | Receives the actual data byte count produced / consumed. |
| [out] | csw_status | Receives the CSW status byte the device will emit at the end of the transaction. |
| k_ra8_ok | Command dispatched (the CSW status byte may still be k_ra8_pmsc_csw_status_failed). |
| k_ra8_err_null_ptr | Any output pointer was NULL. |
| k_ra8_err_invalid_state | Driver not initialized, storage not attached, or no CBW currently in-flight. |
| k_ra8_err_invalid_size | data_buf_capacity was 0. |
Definition at line 429 of file ra8_usb_pmsc.c.
References internal_dispatch_advance_state(), internal_dispatch_preconditions(), internal_dispatch_scsi(), k_ra8_ok, k_ra8_pmsc_csw_status_failed, k_ra8_pmsc_csw_status_passed, RA8_CHECK_NULL_PTR, and s_tag.
|
nodiscard |
Inject a CBW directly into the BOT state machine.
Test / debug entry point. Production code receives CBWs from the bulk-OUT pipe; tests bypass the FIFO and feed the 31-byte buffer directly. Returns k_ra8_err_invalid_arg on signature mismatch (USB MSC BBB rev 1.0 sec 6.2.1 "Valid CBW").
| [in] | cbw | Pointer to a 31-byte CBW. |
| k_ra8_ok | CBW accepted; state machine now in CDB_DECODE. |
| k_ra8_err_null_ptr | cbw was NULL. |
| k_ra8_err_invalid_state | Driver not initialized, or storage not attached. |
| k_ra8_err_invalid_arg | Signature mismatch (CBW invalid). In this case the BOT machine transitions to a phase-error CSW_TX as required by USB MSC BBB rev 1.0 sec 6.6.1 "CBW Not Valid". |
Definition at line 284 of file ra8_usb_pmsc.c.
References g_usb_pmsc_state, internal_copy_bytes(), internal_unpack_u32_le(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_pmsc_cbw_flag_data_in, k_ra8_pmsc_cbw_off_cdb, k_ra8_pmsc_cbw_off_cdb_length, k_ra8_pmsc_cbw_off_data_length, k_ra8_pmsc_cbw_off_flags, k_ra8_pmsc_cbw_off_lun, k_ra8_pmsc_cbw_off_signature, k_ra8_pmsc_cbw_off_tag, k_ra8_pmsc_cbw_signature, k_ra8_pmsc_cdb_field_mask, k_ra8_pmsc_cdb_max_len, k_ra8_pmsc_lun_field_mask, k_ra8_pmsc_state_cdb_decode, k_ra8_pmsc_state_csw_tx, RA8_CHECK_NULL_PTR, and s_tag.
|
nodiscard |
Bring up the device-MSC driver on a chosen USB controller.
Initialises the underlying ra8_usb driver in DEVICE mode for speed, configures the bulk-IN / bulk-OUT pipes (PIPE3 / PIPE4) with the speed-appropriate maximum packet size, primes the BOT state machine to the IDLE state, and zeroes the BOT command tag counter. D+ pull-up is left off so the application can publish the configuration descriptor before the host enumerates it.
| [in] | speed | Which USB controller (FS or HS). |
| k_ra8_ok | Device-MSC ready, awaiting attach_storage. |
| k_ra8_err_invalid_arg | speed out of range. |
| k_ra8_err_hw_init_failed | Underlying ra8_usb_device_init failed. |
Definition at line 538 of file ra8_usb_pmsc.c.
References g_usb_pmsc_state, internal_configure_pipes(), k_ra8_err_hw_init_failed, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pmsc_cdb_max_len, k_ra8_pmsc_initial_tag, k_ra8_pmsc_state_idle, k_ra8_usb_speed_fs, k_ra8_usb_speed_hs, priv_zero_bytes(), ra8_log_error_val, ra8_log_info_val, ra8_usb_device_init(), and s_tag.
|
nodiscard |
Drive the BOT (Bulk-Only Transport) state machine forward by one step.
Production code calls this from the bulk-OUT completion ISR. The state machine cycles through:
Each call advances by exactly one phase; the caller pumps the state machine until it idles back to CBW reception.
| k_ra8_ok | Step advanced. |
| k_ra8_err_invalid_state | Driver not initialized, or storage not attached. |
Definition at line 470 of file ra8_usb_pmsc.c.
References g_usb_pmsc_state, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_pmsc_state_cbw_rx, k_ra8_pmsc_state_cdb_decode, k_ra8_pmsc_state_csw_tx, k_ra8_pmsc_state_data_rx, k_ra8_pmsc_state_data_tx, and k_ra8_pmsc_state_idle.