ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_usb_pmsc.h File Reference

Native USB device-side MSC (Mass Storage Class) class layer. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_usb.h"
Include dependency graph for ra8_usb_pmsc.h:
This graph shows which files directly or indirectly include this file:

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.

Enumerations

enum  ra8_usb_pmsc_pipe_t : uint8_t {
  k_ra8_pmsc_pipe_bulk_in = 3U ,
  k_ra8_pmsc_pipe_bulk_out = 4U
}
 PIPE numbers used by the device-MSC driver for the local bulk endpoints. More...
enum  ra8_usb_pmsc_endpoint_t : uint8_t {
  k_ra8_pmsc_ep_bulk_in = 1U ,
  k_ra8_pmsc_ep_bulk_out = 2U
}
 USB endpoint numbers advertised in the configuration descriptor. More...
enum  ra8_usb_pmsc_packet_t : uint16_t {
  k_ra8_pmsc_bulk_max_packet_fs = 64U ,
  k_ra8_pmsc_bulk_max_packet_hs = 512U
}
 Packet sizing for the local bulk endpoints. More...
enum  ra8_usb_pmsc_class_t : uint8_t {
  k_ra8_pmsc_class_msc = 0x08U ,
  k_ra8_pmsc_subclass_scsi = 0x06U ,
  k_ra8_pmsc_protocol_bbb = 0x50U
}
 Class / subclass / protocol triplet advertised in the device's interface descriptor. More...
enum  ra8_usb_pmsc_request_t : uint8_t {
  k_ra8_pmsc_req_mass_storage_reset = 0xFFU ,
  k_ra8_pmsc_req_get_max_lun = 0xFEU
}
 MSC class-specific request codes the host issues to the device. More...
enum  ra8_usb_pmsc_max_lun_t : uint8_t { k_ra8_pmsc_max_lun = 0U }
 Number of logical units the starter exposes. More...
enum  ra8_usb_pmsc_csw_status_t : uint8_t {
  k_ra8_pmsc_csw_status_passed = 0x00U ,
  k_ra8_pmsc_csw_status_failed = 0x01U ,
  k_ra8_pmsc_csw_status_phase_error = 0x02U
}
 CSW status field values the device returns after a CBW. More...
enum  ra8_usb_pmsc_scsi_t : uint8_t {
  k_ra8_pmsc_scsi_test_unit_ready = 0x00U ,
  k_ra8_pmsc_scsi_request_sense = 0x03U ,
  k_ra8_pmsc_scsi_inquiry = 0x12U ,
  k_ra8_pmsc_scsi_mode_sense_6 = 0x1AU ,
  k_ra8_pmsc_scsi_read_capacity_10 = 0x25U ,
  k_ra8_pmsc_scsi_read_10 = 0x28U ,
  k_ra8_pmsc_scsi_write_10 = 0x2AU
}
 SCSI opcodes the device-MSC class answers over BBB. More...
enum  ra8_usb_pmsc_resp_size_t : uint16_t {
  k_ra8_pmsc_inquiry_resp_len = 36U ,
  k_ra8_pmsc_read_capacity_resp_len = 8U ,
  k_ra8_pmsc_request_sense_resp_len = 18U ,
  k_ra8_pmsc_mode_sense_resp_len = 4U ,
  k_ra8_pmsc_block_size_default = 512U
}
 Standard SCSI response payload sizes. More...
enum  ra8_usb_pmsc_inquiry_field_t : uint8_t {
  k_ra8_pmsc_inq_vendor_len = 8U ,
  k_ra8_pmsc_inq_product_len = 16U ,
  k_ra8_pmsc_inq_revision_len = 4U
}
 Sizes of the three INQUIRY ASCII strings the storage backend returns. More...

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.

Detailed Description

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):

  1. ra8_usb_pmsc_init(speed) flips the controller to device mode, configures the bulk-IN / bulk-OUT pipes for MSC, primes the BOT (Bulk-Only-Transport) state machine to the IDLE state, and leaves D+ pull-up off so the application can finalise its descriptor table before advertising on the bus.
  2. ra8_usb_pmsc_attach_storage(storage) registers a caller-owned storage backend. The four function-pointer hooks let the class layer answer the SCSI commands (INQUIRY, READ_CAPACITY(10), READ(10), WRITE(10), TEST_UNIT_READY, REQUEST_SENSE, MODE_SENSE(6)) that the host issues after enumeration. The storage layer can be SRAM, SD/MMC, OctoSPI flash, or anything that exposes block read / block write.
  3. ra8_usb_pmsc_step() is invoked by the application from the bulk-OUT completion ISR. Each call pumps the BOT state machine: IDLE -> CBW_RX -> CDB_DECODE -> DATA_IN/OUT -> CSW_TX -> IDLE.
  4. ra8_usb_pmsc_close() drops the bulk pipes and tears down the device-mode controller.

Class-specific control requests (USB MSC BBB rev 1.0 sec 3.1):

  • Get Max LUN (bmRequestType=0xA1 / bRequest=0xFE / wLength=1): the starter is single-LUN, so it returns 0.
  • Mass Storage Reset (bmRequestType=0x21 / bRequest=0xFF / wLength=0): resets the BOT state machine to IDLE.

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 Documentation

◆ ra8_usb_pmsc_get_capacity_fn_t

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).

Parameters
[in]ctxCaller-supplied context.
[out]block_countTotal block count (NOT block_count - 1).
[out]block_sizeBlock size in bytes (typically 512).
Returns
ra8_err_t error code.

Definition at line 258 of file ra8_usb_pmsc.h.

◆ ra8_usb_pmsc_get_inquiry_fn_t

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.

Parameters
[in]ctxCaller-supplied context.
[out]vendor88-byte T10 vendor ID, SPACE-padded.
[out]product1616-byte product ID, SPACE-padded.
[out]revision44-byte product revision, SPACE-padded.
Returns
ra8_err_t error code.

Definition at line 279 of file ra8_usb_pmsc.h.

◆ ra8_usb_pmsc_read_block_fn_t

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.

Parameters
[in]ctxCaller-supplied context registered with ra8_usb_pmsc_attach_storage.
[in]lbaStarting logical block address.
[in]block_countNumber of blocks to read (1..65535).
[out]bufDestination buffer, sized to at least block_count * block_size bytes.
Returns
ra8_err_t error code. Non-zero failures land in the CSW as k_ra8_pmsc_csw_status_failed.

Definition at line 225 of file ra8_usb_pmsc.h.

◆ ra8_usb_pmsc_write_block_fn_t

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.

Parameters
[in]ctxCaller-supplied context.
[in]lbaStarting logical block address.
[in]block_countNumber of blocks to write (1..65535).
[in]bufSource buffer, sized to at least block_count * block_size bytes.
Returns
ra8_err_t error code.

Definition at line 242 of file ra8_usb_pmsc.h.

Enumeration Type Documentation

◆ ra8_usb_pmsc_class_t

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.

◆ ra8_usb_pmsc_csw_status_t

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.

◆ ra8_usb_pmsc_endpoint_t

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.

◆ ra8_usb_pmsc_inquiry_field_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.

◆ ra8_usb_pmsc_max_lun_t

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.

◆ ra8_usb_pmsc_packet_t

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.

◆ ra8_usb_pmsc_pipe_t

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.

◆ ra8_usb_pmsc_request_t

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.

◆ ra8_usb_pmsc_resp_size_t

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

  • 4-byte block-length, SBC-4 sec 5.10); REQUEST SENSE is 18 bytes (SPC-4 sec 6.30); MODE SENSE(6) is 4 bytes for the minimal "header-only" reply.
Enumerator
k_ra8_pmsc_inquiry_resp_len 

INQUIRY response len.

k_ra8_pmsc_read_capacity_resp_len 

READ_CAPACITY(10).

k_ra8_pmsc_request_sense_resp_len 

REQUEST SENSE response.

k_ra8_pmsc_mode_sense_resp_len 

MODE SENSE(6) response.

k_ra8_pmsc_block_size_default 

SCSI default block.

Definition at line 183 of file ra8_usb_pmsc.h.

◆ ra8_usb_pmsc_scsi_t

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".

Enumerator
k_ra8_pmsc_scsi_test_unit_ready 

TEST UNIT READY.

k_ra8_pmsc_scsi_request_sense 

REQUEST SENSE.

k_ra8_pmsc_scsi_inquiry 

INQUIRY.

k_ra8_pmsc_scsi_mode_sense_6 

MODE SENSE(6).

k_ra8_pmsc_scsi_read_capacity_10 

READ CAPACITY(10).

k_ra8_pmsc_scsi_read_10 

READ(10).

k_ra8_pmsc_scsi_write_10 

WRITE(10).

Definition at line 163 of file ra8_usb_pmsc.h.

Function Documentation

◆ ra8_usb_pmsc_attach_storage()

ra8_err_t ra8_usb_pmsc_attach_storage ( const ra8_usb_pmsc_storage_t * storage)
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.

Parameters
[in]storageStorage backend snapshot. Copied by value.
Returns
ra8_err_t error code.
Return values
k_ra8_okBackend installed.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrstorage was NULL or any callback was NULL.
Precondition
ra8_usb_pmsc_init has run.
All four callbacks non-NULL.
Postcondition
Subsequent SCSI commands route through the supplied callbacks.
Note
Not thread-safe.
Since
0.1.0

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.

◆ ra8_usb_pmsc_build_csw()

ra8_err_t ra8_usb_pmsc_build_csw ( ra8_usb_pmsc_csw_status_t csw_status,
uint32_t residue,
uint8_t * out_csw )
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.

Parameters
[in]csw_statusStatus byte to embed in the CSW.
[in]residueBytes that were NOT transferred (CBW expected minus actual).
[out]out_cswReceives the 13-byte CSW buffer.
Returns
ra8_err_t error code.
Return values
k_ra8_okCSW constructed.
k_ra8_err_null_ptrout_csw was NULL.
k_ra8_err_invalid_stateDriver not initialized, or no CBW currently in-flight.
Precondition
out_csw non-NULL.
A prior ra8_usb_pmsc_feed_cbw set the dCBWTag we echo.
Postcondition
out_csw[0..3] == 0x55, 0x53, 0x42, 0x53 (CSW signature 'USBS', little-endian on wire).
out_csw[12] == csw_status.
Note
Not thread-safe.
Since
0.1.0

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.

◆ ra8_usb_pmsc_close()

ra8_err_t ra8_usb_pmsc_close ( void )
nodiscard

Tear down the device-MSC driver and release the controller.

Returns
ra8_err_t error code.
Return values
k_ra8_okReleased.
k_ra8_err_invalid_stateDriver was never initialized.
Precondition
Single-threaded shutdown context.
Postcondition
ra8_usb_device_deinit ran; D+ pull-up dropped; subsequent device-MSC API calls return k_ra8_err_invalid_state.
Note
Not thread-safe.
Since
0.1.0

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().

◆ ra8_usb_pmsc_dispatch_command()

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 )
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.

Parameters
[out]data_bufBuffer that receives the data-IN payload (or provides the data-OUT payload). Caller sized to at least data_buf_capacity bytes.
[in]data_buf_capacityCapacity of data_buf in bytes.
[out]data_lenReceives the actual data byte count produced / consumed.
[out]csw_statusReceives the CSW status byte the device will emit at the end of the transaction.
Returns
ra8_err_t error code.
Return values
k_ra8_okCommand dispatched (the CSW status byte may still be k_ra8_pmsc_csw_status_failed).
k_ra8_err_null_ptrAny output pointer was NULL.
k_ra8_err_invalid_stateDriver not initialized, storage not attached, or no CBW currently in-flight.
k_ra8_err_invalid_sizedata_buf_capacity was 0.
Precondition
ra8_usb_pmsc_feed_cbw returned k_ra8_ok immediately prior.
Postcondition
On success *data_len is the byte count to push / pull and *csw_status is the CSW status byte.
Note
Not thread-safe.
Since
0.1.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.

◆ ra8_usb_pmsc_feed_cbw()

ra8_err_t ra8_usb_pmsc_feed_cbw ( const uint8_t * cbw)
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").

Parameters
[in]cbwPointer to a 31-byte CBW.
Returns
ra8_err_t error code.
Return values
k_ra8_okCBW accepted; state machine now in CDB_DECODE.
k_ra8_err_null_ptrcbw was NULL.
k_ra8_err_invalid_stateDriver not initialized, or storage not attached.
k_ra8_err_invalid_argSignature 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".
Precondition
cbw non-NULL.
Postcondition
On k_ra8_ok the cached SCSI opcode and data-length are valid for ra8_usb_pmsc_dispatch_command.
Note
Not thread-safe.
Since
0.1.0

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.

◆ ra8_usb_pmsc_init()

ra8_err_t ra8_usb_pmsc_init ( ra8_usb_speed_t speed)
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.

Parameters
[in]speedWhich USB controller (FS or HS).
Returns
ra8_err_t error code.
Return values
k_ra8_okDevice-MSC ready, awaiting attach_storage.
k_ra8_err_invalid_argspeed out of range.
k_ra8_err_hw_init_failedUnderlying ra8_usb_device_init failed.
Precondition
Single-threaded init context.
ra8_mstp_init and ra8_pwr_init already ran.
Postcondition
ra8_usb_device_init succeeded for speed.
Internal BOT state machine in IDLE; storage backend NULL.
Note
Not thread-safe.
See also
ra8_usb_pmsc_attach_storage
ra8_usb_pmsc_close
Since
0.1.0

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.

◆ ra8_usb_pmsc_step()

ra8_err_t ra8_usb_pmsc_step ( void )
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:

  • IDLE: wait for the bulk-OUT pipe to deliver a 31-byte CBW.
  • CBW_RX: parse the CBW, validate the 'USBC' signature, decode the CDB.
  • CDB_DECODE: dispatch to one of the SCSI command handlers (INQUIRY / READ_CAPACITY / READ(10) / WRITE(10) / TEST_UNIT_READY / REQUEST_SENSE / MODE_SENSE(6)).
  • DATA_TX: push read data on bulk-IN.
  • DATA_RX: drain write data from bulk-OUT.
  • CSW_TX: push the 13-byte CSW on bulk-IN.
  • IDLE.

Each call advances by exactly one phase; the caller pumps the state machine until it idles back to CBW reception.

Returns
ra8_err_t error code.
Return values
k_ra8_okStep advanced.
k_ra8_err_invalid_stateDriver not initialized, or storage not attached.
Precondition
ra8_usb_pmsc_init has run.
ra8_usb_pmsc_attach_storage has run.
Postcondition
Internal BOT state machine advances by one phase.
Note
Not thread-safe.
Since
0.1.0

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.