61static const char*
s_tag =
"USBHMSC";
75typedef enum : uint8_t {
92typedef enum : uint8_t {
103typedef enum : uint8_t {
115typedef enum : uint32_t {
125typedef enum : uint8_t {
136typedef enum : uint32_t {
145typedef enum : uint8_t {
163typedef enum : uint8_t {
172typedef enum : uint32_t {
184typedef enum : uint8_t {
195typedef enum : uint8_t {
209typedef enum : uint8_t {
350 for (uint16_t i = 0U; i < len; ++i) {
359 for (uint16_t i = 0U; i < len; ++i) {
370 uint32_t data_transfer_length,
415 uint32_t expected_tag,
426 if (tag != expected_tag) {
566 const uint16_t cap = *inout_len;
697 const uint8_t* in_buf,
717 uint16_t offset = 0U;
718 while (offset < push_len) {
719 uint16_t chunk = (uint16_t)(push_len - offset);
728 offset = (uint16_t)(offset + chunk);
821 *block_count = last_lba + 1U;
830 if (block_count == 0U) {
843 uint16_t got_len = (xfer_len > UINT16_MAX) ? UINT16_MAX : (uint16_t)xfer_len;
854 if (block_count == 0U) {
864 const uint16_t push_len = (xfer_len > UINT16_MAX) ? UINT16_MAX : (uint16_t)xfer_len;
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_hw_error
Generic hardware fault detected (error flag set, fault interrupt).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Cross-translation-unit private helpers shared inside ra8_hal.
ra8_usb_hmsc_state_t g_usb_hmsc_state
Singleton host-MSC shadow state, shared across the ra8_usb_hmsc split.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
#define ra8_log_error_val(tag, message, value)
RA8 log error val.
SysTick-based tick counter, delay and timestamp helpers.
Native USB controller driver public API (device + host modes).
ra8_usb_speed_t
Selects which controller instance the call targets.
@ k_ra8_usb_speed_hs
High-Speed controller (USBHS @ 0x40351000).
@ k_ra8_usb_speed_fs
Full-Speed controller (USBFS @ 0x40250000).
ra8_usb_hmsc_initial_tag_t
Starting value of the BOT dCBWTag counter.
@ k_ra8_hmsc_initial_tag
First tag handed out post-init.
static uint32_t internal_unpack_u32_le(const uint8_t *src)
ra8_usb_hmsc_byte_shift_t
Per-byte left-shift constants for little-endian / big-endian serialisation.
@ k_ra8_hmsc_shift_byte2
RA8 hmsc shift byte2.
@ k_ra8_hmsc_shift_byte3
RA8 hmsc shift byte3.
@ k_ra8_hmsc_shift_byte0
RA8 hmsc shift byte0.
@ k_ra8_hmsc_shift_byte1
RA8 hmsc shift byte1.
static ra8_err_t internal_read_csw(uint32_t expected_tag)
Read and validate the 13-byte CSW that closes a BOT exchange.
static void internal_build_inquiry_cdb(uint8_t *cdb)
static ra8_err_t internal_run_data_in(uint8_t target_lun, const uint8_t *cdb, uint8_t cdb_len, uint8_t *out_buf, uint16_t *inout_len)
static void internal_decode_inquiry(const uint8_t *raw, ra8_usb_hmsc_inquiry_response_t *response)
Decode a 36-byte SCSI standard INQUIRY response into the public struct.
static ra8_err_t internal_check_ready(uint8_t target_lun)
static ra8_err_t internal_recv_bytes(uint8_t *dst, uint16_t *inout_len)
Pull bytes from the bulk-IN pipe (data + CSW phase).
ra8_usb_hmsc_lun_mask_t
Field width masks for the bCBWLUN + bCBWCBLength bytes.
@ k_ra8_hmsc_lun_field_mask
Low 4 bits of bCBWLUN.
@ k_ra8_hmsc_cdb_field_mask
Low 5 bits of bCBWCBLen.
ra8_usb_hmsc_inquiry_offset_t
Byte offsets inside the SBC-4 standard INQUIRY response.
@ k_ra8_hmsc_inq_off_product_rev
Product revision.
@ k_ra8_hmsc_inq_off_product_id
Product ID start.
@ k_ra8_hmsc_inq_off_vendor_id
T10 Vendor ID start.
@ k_ra8_hmsc_inq_off_version
Byte 2 (SPC version).
@ k_ra8_hmsc_inq_off_dev_type
Byte 0 (qual+devtype).
@ k_ra8_hmsc_inq_off_removable
Byte 1 (removable).
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.
static void internal_pack_u32_le(uint32_t value, uint8_t *dst)
ra8_usb_hmsc_cbw_offset_t
Byte offsets inside the 31-byte CBW header.
@ k_ra8_hmsc_cbw_off_lun
bCBWLUN (low nib).
@ k_ra8_hmsc_cbw_off_data_length
dCBWDataTransferLen.
@ k_ra8_hmsc_cbw_off_tag
dCBWTag [4].
@ k_ra8_hmsc_cbw_off_cdb_length
bCBWCBLength (low 5).
@ k_ra8_hmsc_cbw_off_flags
bmCBWFlags.
@ k_ra8_hmsc_cbw_off_signature
dCBWSignature [4].
@ k_ra8_hmsc_cbw_off_cdb
CBWCB [16].
static void internal_copy_bytes(uint8_t *dst, const uint8_t *src, uint16_t len)
ra8_usb_hmsc_inquiry_field_t
Bit-field shifts / masks inside the SCSI INQUIRY response byte 0 / byte 1 (SBC-4 sec 6....
@ k_ra8_hmsc_inq_dev_type_mask
Byte 0 [4:0] dev type.
@ k_ra8_hmsc_inq_removable_shift
Byte 1 [7] removable bit.
@ k_ra8_hmsc_inq_removable_mask
1-bit removable flag.
@ k_ra8_hmsc_inq_qual_shift
Byte 0 [7:5] qualifier.
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.
static uint32_t internal_next_tag(void)
Hand out the next BOT tag (monotonic uint32 counter).
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_attach_callback(ra8_usb_hmsc_attach_fn_t on_attach, void *ctx)
Register (or detach) the attach callback.
ra8_usb_hmsc_byte_mask_t
Byte mask for serialisation.
@ k_ra8_hmsc_byte_mask
Single-byte extraction mask.
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.
static void internal_build_rw10_cdb(uint8_t opcode, uint32_t lba, uint16_t block_count, uint8_t *cdb)
Build a 10-byte CDB for SCSI READ(10) / WRITE(10).
ra8_err_t ra8_usb_hmsc_close(void)
Tear down the host-MSC driver and release the controller.
ra8_usb_hmsc_signature_t
BOT wrapper signatures (USB MSC BBB rev 1.0 sec 5).
@ k_ra8_hmsc_cbw_signature
'USBC' little-endian.
@ k_ra8_hmsc_csw_signature
'USBS' little-endian.
ra8_usb_hmsc_cdb_offset_t
SCSI CDB byte offsets used when assembling READ(10) / WRITE(10) / READ_CAPACITY(10) / INQUIRY blocks.
@ k_ra8_hmsc_cdb_off_cnt_lsb
READ(10): count low.
@ k_ra8_hmsc_cdb_off_opcode
Operation Code.
@ k_ra8_hmsc_cdb_off_lba_lsb
READ(10): LBA byte 0.
@ k_ra8_hmsc_cdb_off_cnt_msb
READ(10): count high.
@ k_ra8_hmsc_cdb_off_lba_b2
READ(10): LBA byte 1.
@ k_ra8_hmsc_cdb_off_inq_alloc
INQUIRY allocation len.
@ k_ra8_hmsc_cdb_off_lba_b1
READ(10): LBA byte 2.
@ k_ra8_hmsc_cdb_off_lba_msb
READ(10): LBA byte 3.
ra8_usb_hmsc_csw_offset_t
Byte offsets inside the 13-byte CSW.
@ k_ra8_hmsc_csw_off_tag
dCSWTag [4].
@ k_ra8_hmsc_csw_off_status
bCSWStatus.
@ k_ra8_hmsc_csw_off_signature
dCSWSignature [4].
@ k_ra8_hmsc_csw_off_residue
dCSWDataResidue.
static void internal_build_read_capacity_cdb(uint8_t *cdb)
static uint32_t internal_unpack_u32_be(const uint8_t *src)
Assemble a 32-bit word from four big-endian bytes.
static ra8_err_t internal_run_data_out(uint8_t target_lun, const uint8_t *cdb, uint8_t cdb_len, const uint8_t *in_buf, uint16_t push_len)
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.
static uint16_t internal_bulk_max_packet(ra8_usb_speed_t speed)
Pick the bulk-endpoint max-packet ceiling for the negotiated speed.
static ra8_err_t internal_send_cbw(const uint8_t *cbw)
Push a CBW out on the bulk-OUT pipe.
ra8_err_t ra8_usb_hmsc_init(ra8_usb_speed_t speed)
Bring up the host-MSC driver on a chosen USB controller.
ra8_usb_hmsc_capacity_offset_t
Byte offsets inside the SCSI READ_CAPACITY(10) 8-byte response (SBC-4 sec 5.10).
@ k_ra8_hmsc_cap_off_last_lba
Last valid LBA (big-endian).
@ k_ra8_hmsc_cap_off_blk_size
Block length (big-endian).
ra8_usb_hmsc_cbw_flag_t
bmCBWFlags direction bit values.
@ k_ra8_hmsc_cbw_flag_data_in
Device -> host.
@ k_ra8_hmsc_cbw_flag_data_out
Host -> device.
static void internal_zero_bytes(uint8_t *dst, uint16_t len)
Zero len bytes at dst byte-by-byte.
static ra8_err_t internal_issue_cbw(uint8_t target_lun, uint32_t xfer_len, bool data_in, const uint8_t *cdb, uint8_t cdb_len, uint32_t *out_tag)
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.
Native USB host-side MSC (Mass Storage Class) class layer.
void(* ra8_usb_hmsc_attach_fn_t)(void *ctx, const ra8_usb_hmsc_device_t *device)
Attach-callback signature.
@ k_ra8_hmsc_pipe_bulk_in
PIPE3 -> attached EP bulk IN.
@ k_ra8_hmsc_pipe_bulk_out
PIPE4 -> attached EP bulk OUT.
@ k_ra8_hmsc_max_lun
Max LUNs the starter tracks.
ra8_usb_hmsc_csw_status_t
CSW status field values returned by the device after a CBW.
@ k_ra8_hmsc_csw_status_failed
Command failed.
@ k_ra8_hmsc_csw_status_phase_error
BBB phase error – need reset recovery.
@ k_ra8_hmsc_csw_status_passed
Command succeeded.
@ k_ra8_hmsc_bulk_max_packet_fs
Bulk size at full speed.
@ k_ra8_hmsc_bulk_max_packet_hs
Bulk size at high speed.
@ k_ra8_hmsc_read_capacity_resp_len
READ_CAPACITY(10).
@ k_ra8_hmsc_block_size_default
SCSI default block.
@ k_ra8_hmsc_inquiry_resp_len
INQUIRY response len.
@ k_ra8_hmsc_scsi_inquiry
INQUIRY.
@ k_ra8_hmsc_scsi_read_10
READ(10).
@ k_ra8_hmsc_scsi_write_10
WRITE(10).
@ k_ra8_hmsc_scsi_read_capacity_10
READ CAPACITY(10).
Cross-TU surface shared between the host-MSC class layer(ra8_usb_hmsc.c) and the polled enumeration l...
@ k_ra8_hmsc_csw_len
CSW length (BBB sec 5.2).
@ k_ra8_hmsc_cdb6_len
6-byte SCSI CDB.
@ k_ra8_hmsc_cdb_max_len
CDB ceiling.
@ k_ra8_hmsc_cdb10_len
10-byte SCSI CDB.
@ k_ra8_hmsc_cbw_len
CBW length (BBB sec 5.1).
ra8_err_t ra8_usb_host_bulk_out(ra8_usb_speed_t speed, uint8_t pipe_num, const uint8_t *data, uint16_t len)
Transmit one bulk packet to the device and wait for the ACK.
ra8_err_t ra8_usb_host_bulk_in(ra8_usb_speed_t speed, uint8_t pipe_num, uint8_t *buf, uint16_t max_len, uint16_t *out_received)
Receive a bulk transfer from the device into buf.
ra8_err_t ra8_usb_host_init(ra8_usb_speed_t speed)
Bring up a USB controller in HOST mode.
ra8_err_t ra8_usb_host_deinit(ra8_usb_speed_t speed)
Tear down a host-mode controller and drop its MSTP reference.
ra8_err_t ra8_usb_host_set_uact(ra8_usb_speed_t speed, bool enable)
Enable / disable SOF (Start-of-Frame) generation on the bus.
Snapshot of the attached MSC device, passed to the attach callback.
Decoded SCSI INQUIRY response.
uint8_t vendor_id[8]
T10 Vendor ID, ASCII.
uint8_t peripheral_device_type
Bits [4:0] of byte 0.
uint8_t version
SPC version code.
uint8_t peripheral_qualifier
Bits [7:5] of byte 0.
uint8_t removable
1 = removable medium.
uint8_t product_id[16]
Product ID, ASCII.
uint8_t product_revision[4]
Product revision, ASCII.
Singleton shadow state for the host-MSC driver.