|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Native USB host-side MSC (Mass Storage Class) class layer. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_usb_hmsc_device_t |
| Snapshot of the attached MSC device, passed to the attach callback. More... | |
| struct | ra8_usb_hmsc_inquiry_response_t |
| Decoded SCSI INQUIRY response. More... | |
Typedefs | |
| typedef void(* | ra8_usb_hmsc_attach_fn_t) (void *ctx, const ra8_usb_hmsc_device_t *device) |
| Attach-callback signature. | |
Enumerations | |
| enum | ra8_usb_hmsc_pipe_t : uint8_t { k_ra8_hmsc_pipe_bulk_in = 3U , k_ra8_hmsc_pipe_bulk_out = 4U } |
| PIPE numbers used by the host-MSC driver for the attached peripheral's bulk endpoints. More... | |
| enum | ra8_usb_hmsc_packet_t : uint16_t { k_ra8_hmsc_bulk_max_packet_fs = 64U , k_ra8_hmsc_bulk_max_packet_hs = 512U } |
| Packet sizing for the attached device's bulk endpoints. More... | |
| enum | ra8_usb_hmsc_class_t : uint8_t { k_ra8_hmsc_class_msc = 0x08U , k_ra8_hmsc_subclass_scsi = 0x06U , k_ra8_hmsc_protocol_bbb = 0x50U } |
| Class / subclass / protocol triplet that identifies an MSC function within an attached USB device's descriptor walk. More... | |
| enum | ra8_usb_hmsc_request_t : uint8_t { k_ra8_hmsc_req_mass_storage_reset = 0xFFU , k_ra8_hmsc_req_get_max_lun = 0xFEU } |
| MSC class-specific request codes the host issues to the attached device. More... | |
| enum | ra8_usb_hmsc_max_lun_t : uint8_t { k_ra8_hmsc_max_lun = 4U } |
| Compile-time ceiling on the number of logical units the starter tracks per attached device. More... | |
| enum | ra8_usb_hmsc_csw_status_t : uint8_t { k_ra8_hmsc_csw_status_passed = 0x00U , k_ra8_hmsc_csw_status_failed = 0x01U , k_ra8_hmsc_csw_status_phase_error = 0x02U } |
| CSW status field values returned by the device after a CBW. More... | |
| enum | ra8_usb_hmsc_scsi_t : uint8_t { k_ra8_hmsc_scsi_test_unit_ready = 0x00U , k_ra8_hmsc_scsi_request_sense = 0x03U , k_ra8_hmsc_scsi_inquiry = 0x12U , k_ra8_hmsc_scsi_read_capacity_10 = 0x25U , k_ra8_hmsc_scsi_read_10 = 0x28U , k_ra8_hmsc_scsi_write_10 = 0x2AU } |
| SCSI opcodes the host-MSC class issues over BBB. More... | |
| enum | ra8_usb_hmsc_resp_size_t : uint16_t { k_ra8_hmsc_inquiry_resp_len = 36U , k_ra8_hmsc_read_capacity_resp_len = 8U , k_ra8_hmsc_block_size_default = 512U } |
| Standard SCSI response payload sizes. More... | |
Functions | |
| ra8_err_t | ra8_usb_hmsc_init (ra8_usb_speed_t speed) |
| Bring up the host-MSC driver on a chosen USB controller. | |
| ra8_err_t | ra8_usb_hmsc_close (void) |
| Tear down the host-MSC driver and release the controller. | |
| ra8_err_t | ra8_usb_hmsc_enumerate (ra8_usb_hmsc_device_t *out_device) |
| Enumerate the attached MSC device end to end (polled). | |
| ra8_err_t | ra8_usb_hmsc_attach_callback (ra8_usb_hmsc_attach_fn_t on_attach, void *ctx) |
| Register (or detach) the attach callback. | |
| ra8_err_t | ra8_usb_hmsc_inquiry (uint8_t target_lun, ra8_usb_hmsc_inquiry_response_t *response) |
| Issue a SCSI INQUIRY (opcode 0x12) over BBB. | |
| ra8_err_t | ra8_usb_hmsc_read_capacity (uint8_t target_lun, uint32_t *block_count, uint32_t *block_size) |
| Issue a SCSI READ CAPACITY(10) (opcode 0x25) over BBB. | |
| ra8_err_t | ra8_usb_hmsc_read10 (uint8_t target_lun, uint32_t lba, uint16_t block_count, uint8_t *out_buf) |
| Issue a SCSI READ(10) (opcode 0x28) over BBB. | |
| ra8_err_t | ra8_usb_hmsc_write10 (uint8_t target_lun, uint32_t lba, uint16_t block_count, const uint8_t *in_buf) |
| Issue a SCSI WRITE(10) (opcode 0x2A) over BBB. | |
| ra8_err_t | ra8_usb_hmsc_build_cbw (uint8_t target_lun, uint32_t data_transfer_length, bool data_in, const uint8_t *cdb, uint8_t cdb_len, uint8_t *out_cbw) |
| Construct the 31-byte CBW header for the given SCSI command. | |
| ra8_err_t | ra8_usb_hmsc_decode_csw (const uint8_t *csw, uint32_t expected_tag, ra8_usb_hmsc_csw_status_t *out_status) |
| Decode a 13-byte CSW. | |
Native USB host-side MSC (Mass Storage Class) class layer.
Glues the host-mode bring-up paths in ra8_usb to a USB Mass Storage Class (BBB / Bulk-Only-Transport) peripheral - typically a thumb drive or external SSD - attached on the EK-RA8D2's USB-host port. Mirrors FSP's r_usb_hmsc host-MSC class flow but compiled as part of this tree with no FSP / CherryUSB / TinyUSB binaries pulled in.
Lifecycle (mirrors ra8_usb_hcdc.h shape):
The starter only tracks a single attached MSC device with up to k_ra8_hmsc_max_lun logical units; hubs and CD-ROM (ATAPI) command blocks are deferred follow-ups.
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_hmsc.h.
| typedef void(* ra8_usb_hmsc_attach_fn_t) (void *ctx, const ra8_usb_hmsc_device_t *device) |
Attach-callback signature.
| [in] | ctx | Caller-supplied context registered with ra8_usb_hmsc_attach_callback. |
| [in] | device | Snapshot of the attached MSC device. The pointer remains valid only for the duration of the call; copy out anything you need. |
Definition at line 229 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_class_t : uint8_t |
Class / subclass / protocol triplet that identifies an MSC function within an attached USB device's descriptor walk.
Numbered from 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_hmsc_class_msc | MSC interface class. |
| k_ra8_hmsc_subclass_scsi | Transparent SCSI subclass. |
| k_ra8_hmsc_protocol_bbb | Bulk-Only Transport. |
Definition at line 96 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_csw_status_t : uint8_t |
CSW status field values returned by the device after a CBW.
Per USB MSC BBB rev 1.0 sec 5.2 "Command Status Wrapper". Anything outside this set is treated as a protocol error.
| Enumerator | |
|---|---|
| k_ra8_hmsc_csw_status_passed | Command succeeded. |
| k_ra8_hmsc_csw_status_failed | Command failed. |
| k_ra8_hmsc_csw_status_phase_error | BBB phase error – need reset recovery. |
Definition at line 137 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_max_lun_t : uint8_t |
Compile-time ceiling on the number of logical units the starter tracks per attached device.
The MSC BBB spec allows up to 16 LUNs (4-bit field) but 99% of consumer thumb drives expose LUN 0 only. We size the internal tables for a small ceiling here.
| Enumerator | |
|---|---|
| k_ra8_hmsc_max_lun | Max LUNs the starter tracks. |
Definition at line 126 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_packet_t : uint16_t |
Packet sizing for the attached device's bulk endpoints.
| Enumerator | |
|---|---|
| k_ra8_hmsc_bulk_max_packet_fs | Bulk size at full speed. |
| k_ra8_hmsc_bulk_max_packet_hs | Bulk size at high speed. |
Definition at line 82 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_pipe_t : uint8_t |
PIPE numbers used by the host-MSC driver for the attached peripheral's bulk endpoints.
FSP / RA8D2 PIPE assignment rules constrain bulk pipes to PIPE1..PIPE5. The host-MSC class only uses two pipes: bulk-IN to pull data + CSW, bulk-OUT to push CBW + data. See USB MSC BBB rev 1.0 sec 3 "Functional Characteristics".
| Enumerator | |
|---|---|
| k_ra8_hmsc_pipe_bulk_in | PIPE3 -> attached EP bulk IN. |
| k_ra8_hmsc_pipe_bulk_out | PIPE4 -> attached EP bulk OUT. |
Definition at line 73 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_request_t : uint8_t |
MSC class-specific request codes the host issues to the attached device.
Per USB MSC BBB rev 1.0 sec 3.1 "Class-Specific Requests". Get_Max_LUN returns the highest LUN index, Reset_Recovery issues a Bulk-Only Mass Storage Reset (the spec's protocol-level recovery handshake).
| Enumerator | |
|---|---|
| k_ra8_hmsc_req_mass_storage_reset | 0-byte payload. |
| k_ra8_hmsc_req_get_max_lun | 1-byte response. |
Definition at line 112 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_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) and the READ_CAPACITY(10) response is 8 bytes (4- byte returned-LBA + 4-byte block-length, SBC-4 sec 5.10).
| Enumerator | |
|---|---|
| k_ra8_hmsc_inquiry_resp_len | INQUIRY response len. |
| k_ra8_hmsc_read_capacity_resp_len | READ_CAPACITY(10). |
| k_ra8_hmsc_block_size_default | SCSI default block. |
Definition at line 169 of file ra8_usb_hmsc.h.
| enum ra8_usb_hmsc_scsi_t : uint8_t |
SCSI opcodes the host-MSC class issues over BBB.
A small subset of SCSI Primary Commands rev 4 + SCSI Block Commands rev 4. Matches FSP's usb_atapi_t enumeration but only the values our public API actually uses are spelled out.
Definition at line 152 of file ra8_usb_hmsc.h.
|
nodiscard |
Register (or detach) the attach callback.
The supplied callback fires exactly once per attach event, after the descriptor walk identifies an MSC interface (class=0x08 / subclass=0x06 SCSI / protocol=0x50 BBB) and the Get-Max-LUN class request lands. Pass NULL to detach.
| [in] | on_attach | Callback. NULL detaches. |
| [in] | ctx | Context pointer threaded back into on_attach. |
| k_ra8_ok | Callback installed. |
| k_ra8_err_invalid_state | Driver was never initialized. |
Definition at line 489 of file ra8_usb_hmsc.c.
References g_usb_hmsc_state, k_ra8_err_invalid_state, and k_ra8_ok.
|
nodiscard |
Construct the 31-byte CBW header for the given SCSI command.
Test / debug entry point. Production code uses this internally; the unit-test build calls it directly to prove the CBW layout (signature 'USBC', tag, dCBWDataTransferLength, bmCBWFlags direction bit, LUN, CDB length, CDB bytes) matches USB MSC BBB rev 1.0 sec 5.1.
| [in] | target_lun | Logical unit (0..15). |
| [in] | data_transfer_length | dCBWDataTransferLength field. |
| [in] | data_in | true for IN (device-to-host), false for OUT. |
| [in] | cdb | 6 / 10 / 12-byte SCSI Command Descriptor Block. |
| [in] | cdb_len | Length of the CDB in bytes (1..16). |
| [out] | out_cbw | Receives the 31-byte CBW header. |
| k_ra8_ok | CBW constructed. |
| k_ra8_err_null_ptr | cdb or out_cbw was NULL. |
| k_ra8_err_invalid_arg | cdb_len out of range or target_lun out of range. |
Definition at line 369 of file ra8_usb_hmsc.c.
References internal_copy_bytes(), internal_next_tag(), internal_pack_u32_le(), internal_zero_bytes(), k_ra8_err_invalid_arg, k_ra8_hmsc_cbw_flag_data_in, k_ra8_hmsc_cbw_flag_data_out, k_ra8_hmsc_cbw_len, k_ra8_hmsc_cbw_off_cdb, k_ra8_hmsc_cbw_off_cdb_length, k_ra8_hmsc_cbw_off_data_length, k_ra8_hmsc_cbw_off_flags, k_ra8_hmsc_cbw_off_lun, k_ra8_hmsc_cbw_off_signature, k_ra8_hmsc_cbw_off_tag, k_ra8_hmsc_cbw_signature, k_ra8_hmsc_cdb_field_mask, k_ra8_hmsc_cdb_max_len, k_ra8_hmsc_lun_field_mask, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_issue_cbw().
|
nodiscard |
Tear down the host-MSC driver and release the controller.
| k_ra8_ok | Released. |
| k_ra8_err_invalid_state | Driver was never initialized. |
Definition at line 469 of file ra8_usb_hmsc.c.
References g_usb_hmsc_state, k_ra8_err_invalid_state, ra8_usb_host_deinit(), and ra8_usb_host_set_uact().
Referenced by fileops_run_ladder(), microsd_host_enumerate(), microsd_host_pass(), mlun_host_enumerate(), mlun_host_pass(), ospirw_host_enumerate(), ospirw_host_pass(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_pass(), selftest_host_pass(), wlun_host_enumerate(), and wlun_host_pass().
|
nodiscard |
Decode a 13-byte CSW.
Test / debug entry point. Validates the signature ('USBS'), the tag echo, and returns the decoded status byte.
| [in] | csw | Pointer to the 13-byte CSW buffer. |
| [in] | expected_tag | dCBWTag from the CBW that initiated the transfer. |
| [out] | out_status | Decoded CSW status byte. |
| k_ra8_ok | Signature + tag match; *out_status valid. |
| k_ra8_err_null_ptr | Either pointer was NULL. |
| k_ra8_err_invalid_arg | Signature mismatch or tag mismatch. |
Definition at line 414 of file ra8_usb_hmsc.c.
References internal_unpack_u32_le(), k_ra8_err_invalid_arg, k_ra8_hmsc_csw_off_signature, k_ra8_hmsc_csw_off_status, k_ra8_hmsc_csw_off_tag, k_ra8_hmsc_csw_signature, k_ra8_hmsc_csw_status_failed, k_ra8_hmsc_csw_status_passed, k_ra8_hmsc_csw_status_phase_error, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_read_csw().
|
nodiscard |
Enumerate the attached MSC device end to end (polled).
Runs the hardware-proven ladder on the controller selected by ra8_usb_hmsc_init: waits for the D+ attach, hunts the (reset, address) combination the device answers at, assigns address 1 when it sat at the default, reads + parses the configuration descriptor for the MSC BOT interface and its bulk endpoints, issues SET_CONFIGURATION and a best-effort GET_MAX_LUN, and configures the bulk pipes. On success the registered attach callback fires with the device snapshot and the SCSI entry points (ra8_usb_hmsc_inquiry / _read_capacity / _read10 / _write10) are ready.
| [out] | out_device | Optional copy of the device snapshot (may be NULL). |
| k_ra8_ok | Device enumerated and pipes configured. |
| k_ra8_err_invalid_state | ra8_usb_hmsc_init has not run. |
| k_ra8_err_hw_timeout | Nothing attached / nothing answered. |
| k_ra8_err_hw_error | A stage failed (STALL / short response). |
Enumerate the attached MSC device end to end (polled).
See the public header for the documented contract; runs the hardware-proven polled ladder: attach wait, (reset, address) hunt, address assignment, configuration parse + activate, GET_MAX_LUN, bulk pipe setup, then fires the attach callback.
| [out] | out_device | See header (may be NULL). |
| k_ra8_ok | Device enumerated; SCSI calls may follow. |
Definition at line 566 of file ra8_usb_hmsc_enum.c.
References g_usb_hmsc_state, internal_enum_ladder(), internal_enum_publish(), k_ra8_err_invalid_state, and k_ra8_ok.
Referenced by fileops_run_ladder(), microsd_host_enumerate(), mlun_host_enumerate(), ospirw_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), and wlun_host_enumerate().
|
nodiscard |
Bring up the host-MSC driver on a chosen USB controller.
Initialises the underlying ra8_usb driver in HOST mode for speed, primes the BOT tag counter, leaves the bus in the "wait for attach" state (UACT cleared), and arms the internal enumeration step machine.
| [in] | speed | Which USB controller (FS or HS). |
| k_ra8_ok | Host-MSC ready, awaiting attach. |
| k_ra8_err_invalid_arg | speed out of range. |
| k_ra8_err_hw_init_failed | Underlying ra8_usb_host_init failed. |
Definition at line 446 of file ra8_usb_hmsc.c.
References g_usb_hmsc_state, k_ra8_err_hw_init_failed, k_ra8_err_invalid_arg, k_ra8_hmsc_initial_tag, k_ra8_ok, k_ra8_usb_speed_fs, k_ra8_usb_speed_hs, ra8_log_error_val, ra8_log_info_val, ra8_usb_host_init(), and s_tag.
Referenced by fileops_run_ladder(), microsd_host_pass(), mlun_host_pass(), ospirw_host_pass(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), selftest_host_enumerate(), and wlun_host_pass().
|
nodiscard |
Issue a SCSI INQUIRY (opcode 0x12) over BBB.
Builds a 6-byte SCSI CDB, wraps it in a 31-byte CBW (signature 'USBC' / 0x43425355), pushes CBW on bulk-OUT, drains the 36-byte response on bulk-IN, then drains the 13-byte CSW (signature 'USBS' / 0x53425355). On success *response is filled in.
| [in] | target_lun | Logical unit (0..max_lun). |
| [out] | response | Decoded INQUIRY response. |
| k_ra8_ok | INQUIRY succeeded. |
| k_ra8_err_null_ptr | response was NULL. |
| k_ra8_err_invalid_state | Driver not initialized, or no device attached. |
| k_ra8_err_invalid_arg | target_lun out of range. |
| k_ra8_err_hw_error | BBB transfer failed (CSW status != 0). |
Definition at line 780 of file ra8_usb_hmsc.c.
References internal_build_inquiry_cdb(), internal_check_ready(), internal_decode_inquiry(), internal_run_data_in(), k_ra8_hmsc_cdb6_len, k_ra8_hmsc_cdb_max_len, k_ra8_hmsc_inquiry_resp_len, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
|
nodiscard |
Issue a SCSI READ(10) (opcode 0x28) over BBB.
Reads block_count contiguous blocks starting at lba into out_buf. Caller is responsible for sizing out_buf to at least block_count * block_size bytes (use the value returned by ra8_usb_hmsc_read_capacity).
| [in] | target_lun | Logical unit (0..max_lun). |
| [in] | lba | Starting logical block address. |
| [in] | block_count | Number of blocks to read (1..65535). |
| [out] | out_buf | Destination buffer, sized appropriately. |
| k_ra8_ok | Read complete. |
| k_ra8_err_null_ptr | out_buf was NULL. |
| k_ra8_err_invalid_state | Driver not initialized, or no device attached. |
| k_ra8_err_invalid_arg | Argument out of range (zero block count, bogus LUN). |
| k_ra8_err_hw_error | BBB transfer failed. |
Definition at line 827 of file ra8_usb_hmsc.c.
References internal_build_rw10_cdb(), internal_check_ready(), internal_run_data_in(), k_ra8_err_invalid_arg, k_ra8_hmsc_block_size_default, k_ra8_hmsc_cdb10_len, k_ra8_hmsc_cdb_max_len, k_ra8_hmsc_scsi_read_10, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by internal_usbmsc_read(), microsd_verify_one(), mlun_verify_one(), ospirw_verify_one(), selftest_browse_root(), selftest_verify_mram_raw(), selftest_verify_mram_raw(), selftest_verify_mram_raw(), selftest_verify_mram_raw(), selftest_verify_ospi_raw(), and wlun_verify_one().
|
nodiscard |
Issue a SCSI READ CAPACITY(10) (opcode 0x25) over BBB.
Reads the device's logical block count and block size. The 8-byte response holds the LAST valid LBA (block count - 1) and the block size, both big-endian on the wire; this function decodes both and adds 1 to the LBA so *block_count is the inclusive total.
| [in] | target_lun | Logical unit (0..max_lun). |
| [out] | block_count | Total number of blocks on the LUN. |
| [out] | block_size | Block size in bytes (typically 512). |
| k_ra8_ok | Capacity read. |
| k_ra8_err_null_ptr | Either pointer was NULL. |
| k_ra8_err_invalid_state | Driver not initialized, or no device attached. |
| k_ra8_err_invalid_arg | target_lun out of range. |
| k_ra8_err_hw_error | BBB transfer failed. |
Definition at line 799 of file ra8_usb_hmsc.c.
References internal_build_read_capacity_cdb(), internal_check_ready(), internal_run_data_in(), internal_unpack_u32_be(), k_ra8_hmsc_block_size_default, k_ra8_hmsc_cap_off_blk_size, k_ra8_hmsc_cap_off_last_lba, k_ra8_hmsc_cdb10_len, k_ra8_hmsc_cdb_max_len, k_ra8_hmsc_read_capacity_resp_len, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by internal_usbmsc_get_caps(), microsd_verify_one(), mlun_verify_one(), ospirw_verify_one(), and wlun_verify_one().
|
nodiscard |
Issue a SCSI WRITE(10) (opcode 0x2A) over BBB.
Writes block_count contiguous blocks starting at lba from in_buf. Caller is responsible for sizing in_buf to at least block_count * block_size bytes.
| [in] | target_lun | Logical unit (0..max_lun). |
| [in] | lba | Starting logical block address. |
| [in] | block_count | Number of blocks to write (1..65535). |
| [in] | in_buf | Source buffer, sized appropriately. |
| k_ra8_ok | Write complete. |
| k_ra8_err_null_ptr | in_buf was NULL. |
| k_ra8_err_invalid_state | Driver not initialized, or no device attached. |
| k_ra8_err_invalid_arg | Argument out of range. |
| k_ra8_err_hw_error | BBB transfer failed. |
Definition at line 851 of file ra8_usb_hmsc.c.
References internal_build_rw10_cdb(), internal_check_ready(), internal_run_data_out(), k_ra8_err_invalid_arg, k_ra8_hmsc_block_size_default, k_ra8_hmsc_cdb10_len, k_ra8_hmsc_cdb_max_len, k_ra8_hmsc_scsi_write_10, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by internal_usbmsc_write(), ospirw_write_disk(), selftest_write_protect_probe(), selftest_write_protect_probe(), selftest_write_protect_probe(), selftest_write_protect_probe(), selftest_write_protect_probe(), and wlun_write_disk().