forked from jappel/VersaMCU
Add UF2 bootloader for USB firmware flashing
Vendored and trimmed from microsoft/uf2-samdx1, adapted to the actual ATSAMD21G17D (128 KiB flash / 16 KiB RAM), fixing the flash/RAM-size mismatch that the previously commented-out SAM-BA bootloader target had (it assumed a 256 KiB SAMD21G18A). Builds as a standalone PlatformIO environment (bootloader/platformio.ini), no python2/make dependency. Compiles clean, fits in the 8 KiB bootloader region (7292/8192 bytes). Not yet flashed/verified on real hardware.
This commit is contained in:
parent
ce5db617a1
commit
de52b57041
143 changed files with 69119 additions and 0 deletions
165
bootloader/lib/usb_msc/sbc_protocol.h
Normal file
165
bootloader/lib/usb_msc/sbc_protocol.h
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SCSI Block Commands
|
||||
*
|
||||
* This file contains definitions of some of the commands found in the
|
||||
* SCSI SBC-2 standard.
|
||||
*
|
||||
* Note that the SBC specification depends on several commands defined
|
||||
* by the SCSI Primary Commands (SPC) standard. Each version of the SBC
|
||||
* standard is meant to be used in conjunction with a specific version
|
||||
* of the SPC standard, as follows:
|
||||
* - SBC depends on SPC
|
||||
* - SBC-2 depends on SPC-3
|
||||
* - SBC-3 depends on SPC-4
|
||||
*
|
||||
* Copyright (c) 2016 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
#ifndef _SBC_PROTOCOL_H_
|
||||
#define _SBC_PROTOCOL_H_
|
||||
|
||||
#include "lib/usb_msc/usb_includes.h"
|
||||
|
||||
/**
|
||||
* \ingroup usb_msc_protocol
|
||||
* \defgroup usb_sbc_protocol SCSI Block Commands protocol definitions
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \name SCSI commands defined by SBC-2 */
|
||||
#define SBC_FORMAT_UNIT 0x04
|
||||
#define SBC_READ6 0x08
|
||||
#define SBC_WRITE6 0x0A
|
||||
#define SBC_START_STOP_UNIT 0x1B
|
||||
#define SBC_READ_CAPACITY10 0x25
|
||||
#define SBC_READ10 0x28
|
||||
#define SBC_WRITE10 0x2A
|
||||
#define SBC_VERIFY10 0x2F
|
||||
|
||||
/** \name SBC-2 Mode page definitions */
|
||||
enum scsi_sbc_mode {
|
||||
SCSI_MS_MODE_RW_ERR_RECOV = 0x01, /**< Read-Write Error Recovery mode page */
|
||||
SCSI_MS_MODE_FORMAT_DEVICE = 0x03, /**< Format Device mode page */
|
||||
SCSI_MS_MODE_FLEXIBLE_DISK = 0x05, /**< Flexible Disk mode page */
|
||||
SCSI_MS_MODE_CACHING = 0x08
|
||||
};
|
||||
|
||||
/** \name SBC-2 Device-Specific Parameter */
|
||||
#define SCSI_MS_SBC_WP 0x80 /**< Write Protected */
|
||||
#define SCSI_MS_SBC_DPOFUA 0x10 /**< DPO and FUA supported */
|
||||
|
||||
/**
|
||||
* \brief SBC-2 Short LBA mode parameter block descriptor
|
||||
* \note Fields are MSB first (BE)
|
||||
*/
|
||||
struct sbc_slba_block_desc {
|
||||
be32_t nr_blocks; /**< Number of Blocks (BE32) */
|
||||
be32_t block_len; /**< Block Length (BE32) */
|
||||
#define SBC_SLBA_BLOCK_LEN_MASK 0x00FFFFFFU /**< Mask reserved bits */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SBC-2 Caching mode page
|
||||
* \note Fields are MSB first (BE)
|
||||
*/
|
||||
struct sbc_caching_mode_page {
|
||||
uint8_t page_code;
|
||||
uint8_t page_length;
|
||||
uint8_t flags2;
|
||||
#define SBC_MP_CACHE_IC (1 << 7) /**< Initiator Control */
|
||||
#define SBC_MP_CACHE_ABPF (1 << 6) /**< Abort Pre-Fetch */
|
||||
#define SBC_MP_CACHE_CAP (1 << 5) /**< Catching Analysis Permitted */
|
||||
#define SBC_MP_CACHE_DISC (1 << 4) /**< Discontinuity */
|
||||
#define SBC_MP_CACHE_SIZE (1 << 3) /**< Size enable */
|
||||
#define SBC_MP_CACHE_WCE (1 << 2) /**< Write back Cache Enable */
|
||||
#define SBC_MP_CACHE_MF (1 << 1) /**< Multiplication Factor */
|
||||
#define SBC_MP_CACHE_RCD (1 << 0) /**< Read Cache Disable */
|
||||
uint8_t retention;
|
||||
be16_t dis_pf_transfer_len;
|
||||
be16_t min_prefetch;
|
||||
be16_t max_prefetch;
|
||||
be16_t max_prefetch_ceil;
|
||||
uint8_t flags12;
|
||||
#define SBC_MP_CACHE_FSW (1 << 7) /**< Force Sequential Write */
|
||||
#define SBC_MP_CACHE_LBCSS (1 << 6) /**< Logical Blk Cache Seg Sz */
|
||||
#define SBC_MP_CACHE_DRA (1 << 5) /**< Disable Read-Ahead */
|
||||
#define SBC_MP_CACHE_NV_DIS (1 << 0) /**< Non-Volatile Cache Disable */
|
||||
uint8_t nr_cache_segments;
|
||||
be16_t cache_segment_size;
|
||||
uint8_t reserved[4];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SBC-2 Read-Write Error Recovery mode page
|
||||
* \note Fields are MSB first (BE)
|
||||
*/
|
||||
struct sbc_rdwr_error_recovery_mode_page {
|
||||
uint8_t page_code;
|
||||
uint8_t page_length;
|
||||
#define SPC_MP_RW_ERR_RECOV_PAGE_LENGTH 0x0A
|
||||
uint8_t flags1;
|
||||
#define SBC_MP_RW_ERR_RECOV_AWRE (1 << 7)
|
||||
#define SBC_MP_RW_ERR_RECOV_ARRE (1 << 6)
|
||||
#define SBC_MP_RW_ERR_RECOV_TB (1 << 5)
|
||||
#define SBC_MP_RW_ERR_RECOV_RC (1 << 4)
|
||||
#define SBC_MP_RW_ERR_RECOV_ERR (1 << 3)
|
||||
#define SBC_MP_RW_ERR_RECOV_PER (1 << 2)
|
||||
#define SBC_MP_RW_ERR_RECOV_DTE (1 << 1)
|
||||
#define SBC_MP_RW_ERR_RECOV_DCR (1 << 0)
|
||||
uint8_t read_retry_count;
|
||||
uint8_t correction_span;
|
||||
uint8_t head_offset_count;
|
||||
uint8_t data_strobe_offset_count;
|
||||
uint8_t flags2;
|
||||
uint8_t write_retry_count;
|
||||
uint8_t flags3;
|
||||
be16_t recovery_time_limit;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SBC-2 READ CAPACITY (10) parameter data (8 bytes)
|
||||
* \note Fields are MSB first (BE)
|
||||
*/
|
||||
struct sbc_read_capacity10_data {
|
||||
be32_t max_lba; /**< LBA of last logical block (BE32) */
|
||||
be32_t block_len; /**< Number of bytes in the last logical block (BE32) */
|
||||
};
|
||||
|
||||
#endif /*_SBC_PROTOCOL_H_*/
|
||||
342
bootloader/lib/usb_msc/spc_protocol.h
Normal file
342
bootloader/lib/usb_msc/spc_protocol.h
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SCSI Primary Commands
|
||||
*
|
||||
* This file contains definitions of some of the commands found in the
|
||||
* SPC-2 standard.
|
||||
*
|
||||
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
#ifndef _SPC_PROTOCOL_H_
|
||||
#define _SPC_PROTOCOL_H_
|
||||
|
||||
#include "lib/usb_msc/usb_includes.h"
|
||||
|
||||
/**
|
||||
* \ingroup usb_msc_protocol
|
||||
* \defgroup usb_spc_protocol SCSI Primary Commands protocol definitions
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**< \name SCSI commands defined by SPC-2 */
|
||||
#define SPC_TEST_UNIT_READY 0x00
|
||||
#define SPC_REQUEST_SENSE 0x03
|
||||
#define SPC_INQUIRY 0x12
|
||||
#define SPC_MODE_SELECT6 0x15
|
||||
#define SPC_MODE_SENSE6 0x1A
|
||||
#define SPC_SEND_DIAGNOSTIC 0x1D
|
||||
#define SPC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
|
||||
#define SPC_MODE_SENSE10 0x5A
|
||||
#define SPC_REPORT_LUNS 0xA0
|
||||
|
||||
/**< \brief May be set in byte 0 of the INQUIRY CDB */
|
||||
/**< Enable Vital Product Data */
|
||||
#define SCSI_INQ_REQ_EVPD 0x01
|
||||
/**< Command Support Data specified by the PAGE OR OPERATION CODE field */
|
||||
#define SCSI_INQ_REQ_CMDT 0x02
|
||||
|
||||
_Pragma("pack(1)")
|
||||
|
||||
/**
|
||||
* \brief SCSI Standard Inquiry data structure
|
||||
*/
|
||||
struct scsi_inquiry_data {
|
||||
uint8_t pq_pdt; /**< Peripheral Qual / Peripheral Dev Type */
|
||||
#define SCSI_INQ_PQ_CONNECTED 0x00 /**< Peripheral connected */
|
||||
#define SCSI_INQ_PQ_NOT_CONN 0x20 /**< Peripheral not connected */
|
||||
#define SCSI_INQ_PQ_NOT_SUPP 0x60 /**< Peripheral not supported */
|
||||
#define SCSI_INQ_DT_DIR_ACCESS 0x00 /**< Direct Access (SBC) */
|
||||
#define SCSI_INQ_DT_SEQ_ACCESS 0x01 /**< Sequential Access */
|
||||
#define SCSI_INQ_DT_PRINTER 0x02 /**< Printer */
|
||||
#define SCSI_INQ_DT_PROCESSOR 0x03 /**< Processor device */
|
||||
#define SCSI_INQ_DT_WRITE_ONCE 0x04 /**< Write-once device */
|
||||
#define SCSI_INQ_DT_CD_DVD 0x05 /**< CD/DVD device */
|
||||
#define SCSI_INQ_DT_OPTICAL 0x07 /**< Optical Memory */
|
||||
#define SCSI_INQ_DT_MC 0x08 /**< Medium Changer */
|
||||
#define SCSI_INQ_DT_ARRAY 0x0c /**< Storage Array Controller */
|
||||
#define SCSI_INQ_DT_ENCLOSURE 0x0d /**< Enclosure Services */
|
||||
#define SCSI_INQ_DT_RBC 0x0e /**< Simplified Direct Access */
|
||||
#define SCSI_INQ_DT_OCRW 0x0f /**< Optical card reader/writer */
|
||||
#define SCSI_INQ_DT_BCC 0x10 /**< Bridge Controller Commands */
|
||||
#define SCSI_INQ_DT_OSD 0x11 /**< Object-based Storage */
|
||||
#define SCSI_INQ_DT_NONE 0x1f /**< No Peripheral */
|
||||
uint8_t flags1; /**< Flags (byte 1) */
|
||||
#define SCSI_INQ_RMB 0x80 /**< Removable Medium */
|
||||
uint8_t version; /**< Version */
|
||||
#define SCSI_INQ_VER_NONE 0x00 /**< No standards conformance */
|
||||
#define SCSI_INQ_VER_SPC 0x03 /**< SCSI Primary Commands (link to SBC) */
|
||||
#define SCSI_INQ_VER_SPC2 0x04 /**< SCSI Primary Commands - 2 (link to SBC-2) */
|
||||
#define SCSI_INQ_VER_SPC3 0x05 /**< SCSI Primary Commands - 3 (link to SBC-2) */
|
||||
#define SCSI_INQ_VER_SPC4 0x06 /**< SCSI Primary Commands - 4 (link to SBC-3) */
|
||||
uint8_t flags3; /**< Flags (byte 3) */
|
||||
#define SCSI_INQ_NORMACA 0x20 /**< Normal ACA Supported */
|
||||
#define SCSI_INQ_HISUP 0x10 /**< Hierarchal LUN addressing */
|
||||
#define SCSI_INQ_RSP_SPC2 0x02 /**< SPC-2 / SPC-3 response format */
|
||||
uint8_t addl_len; /**< Additional Length (n-4) */
|
||||
#define SCSI_INQ_ADDL_LEN(tot) ((tot)-5) /**< Total length is \a tot */
|
||||
uint8_t flags5; /**< Flags (byte 5) */
|
||||
#define SCSI_INQ_SCCS 0x80
|
||||
uint8_t flags6; /**< Flags (byte 6) */
|
||||
#define SCSI_INQ_BQUE 0x80
|
||||
#define SCSI_INQ_ENCSERV 0x40
|
||||
#define SCSI_INQ_MULTIP 0x10
|
||||
#define SCSI_INQ_MCHGR 0x08
|
||||
#define SCSI_INQ_ADDR16 0x01
|
||||
uint8_t flags7; /**< Flags (byte 7) */
|
||||
#define SCSI_INQ_WBUS16 0x20
|
||||
#define SCSI_INQ_SYNC 0x10
|
||||
#define SCSI_INQ_LINKED 0x08
|
||||
#define SCSI_INQ_CMDQUE 0x02
|
||||
uint8_t vendor_id[8]; /**< T10 Vendor Identification */
|
||||
uint8_t product_id[16]; /**< Product Identification */
|
||||
uint8_t product_rev[4]; /**< Product Revision Level */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SCSI Standard Request sense data structure
|
||||
*/
|
||||
#define SCSI_SENSE_VALID 0x80 /**< Indicates the INFORMATION field contains valid information */
|
||||
#define SCSI_SENSE_RESPONSE_CODE_MASK 0x7F
|
||||
#define SCSI_SENSE_CURRENT 0x70 /**< Response code 70h (current errors) */
|
||||
#define SCSI_SENSE_DEFERRED 0x71
|
||||
|
||||
#define SCSI_SENSE_FILEMARK 0x80 /**< Indicates that the current command has read a filemark or setmark. */
|
||||
#define SCSI_SENSE_EOM 0x40 /**< Indicates that an end-of-medium condition exists. */
|
||||
#define SCSI_SENSE_ILI \
|
||||
0x20 /**< Indicates that the requested logical block length did not match the logical block length of the data on \
|
||||
the medium. */
|
||||
#define SCSI_SENSE_RESERVED 0x10 /**< Reserved */
|
||||
#define SCSI_SENSE_KEY(x) (x & 0x0F) /**< Sense Key */
|
||||
|
||||
#define SCSI_SENSE_ADDL_LEN(total_len) ((total_len)-8)
|
||||
|
||||
#define SCSI_SENSE_SKSV 0x80 /**< Indicates the SENSE-KEY SPECIFIC field contains valid information */
|
||||
|
||||
struct scsi_request_sense_data {
|
||||
/** 1st byte: REQUEST SENSE response flags*/
|
||||
uint8_t valid_reponse_code;
|
||||
/** 2nd byte */
|
||||
uint8_t obsolete;
|
||||
/** 3rd byte */
|
||||
uint8_t sense_flag_key;
|
||||
/** 4th to 7th bytes - INFORMATION field */
|
||||
uint8_t information[4];
|
||||
/** 8th byte - ADDITIONAL SENSE LENGTH field */
|
||||
uint8_t AddSenseLen;
|
||||
/** 9th to 12th byte - COMMAND-SPECIFIC INFORMATION field */
|
||||
uint8_t CmdSpecINFO[4];
|
||||
/** 13th to 14th byte - ADDITIONAL SENSE CODE and QUALIFIER field */
|
||||
union {
|
||||
struct {
|
||||
uint8_t code; /**< ADDITIONAL SENSE CODE (ASC) */
|
||||
uint8_t qualifier; /**< ADDITIONAL SENSE CODE QUALIFIER (ASCQ) */
|
||||
} add_sense;
|
||||
be16_t AddSense; /**< ASC | ASCQ */
|
||||
};
|
||||
/** 15th byte - FIELD REPLACEABLE UNIT CODE field */
|
||||
uint8_t FldReplUnitCode;
|
||||
/** 16th byte */
|
||||
uint8_t SenseKeySpec[3];
|
||||
};
|
||||
|
||||
_Pragma("pack()")
|
||||
|
||||
/**< Vital Product Data page codes */
|
||||
enum scsi_vpd_page_code {
|
||||
SCSI_VPD_SUPPORTED_PAGES = 0x00,
|
||||
SCSI_VPD_UNIT_SERIAL_NUMBER = 0x80,
|
||||
SCSI_VPD_DEVICE_IDENTIFICATION = 0x83
|
||||
};
|
||||
#define SCSI_VPD_HEADER_SIZE 4
|
||||
|
||||
/**< Constants associated with the Device Identification VPD page */
|
||||
#define SCSI_VPD_ID_HEADER_SIZE 4
|
||||
|
||||
#define SCSI_VPD_CODE_SET_BINARY 1
|
||||
#define SCSI_VPD_CODE_SET_ASCII 2
|
||||
#define SCSI_VPD_CODE_SET_UTF8 3
|
||||
|
||||
#define SCSI_VPD_ID_TYPE_T10 1
|
||||
|
||||
/**< Sense keys */
|
||||
enum scsi_sense_key {
|
||||
SCSI_SK_NO_SENSE = 0x0,
|
||||
SCSI_SK_RECOVERED_ERROR = 0x1,
|
||||
SCSI_SK_NOT_READY = 0x2,
|
||||
SCSI_SK_MEDIUM_ERROR = 0x3,
|
||||
SCSI_SK_HARDWARE_ERROR = 0x4,
|
||||
SCSI_SK_ILLEGAL_REQUEST = 0x5,
|
||||
SCSI_SK_UNIT_ATTENTION = 0x6,
|
||||
SCSI_SK_DATA_PROTECT = 0x7,
|
||||
SCSI_SK_BLANK_CHECK = 0x8,
|
||||
SCSI_SK_VENDOR_SPECIFIC = 0x9,
|
||||
SCSI_SK_COPY_ABORTED = 0xa,
|
||||
SCSI_SK_ABORTED_COMMAND = 0xb,
|
||||
SCSI_SK_VOLUME_OVERFLOW = 0xd,
|
||||
SCSI_SK_MISCOMPARE = 0xe
|
||||
};
|
||||
|
||||
/**< Additional Sense Code | Additional Sense Code Qualifier pairs (BE16) */
|
||||
enum scsi_asc_ascq {
|
||||
SCSI_ASC_NO_ADDITIONAL_SENSE_INFO = 0x0000,
|
||||
SCSI_ASC_LU_NOT_READY_REBUILD_IN_PROGRESS = 0x0405,
|
||||
SCSI_ASC_WRITE_ERROR = 0x0c00,
|
||||
SCSI_ASC_UNRECOVERED_READ_ERROR = 0x1100,
|
||||
SCSI_ASC_INVALID_COMMAND_OPERATION_CODE = 0x2000,
|
||||
SCSI_ASC_INVALID_FIELD_IN_CDB = 0x2400,
|
||||
SCSI_ASC_WRITE_PROTECTED = 0x2700,
|
||||
SCSI_ASC_NOT_READY_TO_READY_CHANGE = 0x2800,
|
||||
SCSI_ASC_MEDIUM_NOT_PRESENT = 0x3A00,
|
||||
SCSI_ASC_INTERNAL_TARGET_FAILURE = 0x4400
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SPC-2 Mode parameter
|
||||
* This subclauses describes the block descriptors and the pages
|
||||
* used with MODE SELECT and MODE SENSE commands
|
||||
* that are applicable to all SCSI devices.
|
||||
*/
|
||||
enum scsi_spc_mode {
|
||||
SCSI_MS_MODE_VENDOR_SPEC = 0x00,
|
||||
SCSI_MS_MODE_INFEXP = 0x1C, /**< Informational exceptions control page */
|
||||
SCSI_MS_MODE_ALL = 0x3f
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SPC-2 Informational exceptions control page
|
||||
* See chapter 8.3.8
|
||||
* \note Fields are MSB first (BE)
|
||||
*/
|
||||
struct spc_control_page_info_execpt {
|
||||
uint8_t page_code;
|
||||
uint8_t page_length;
|
||||
#define SPC_MP_INFEXP_PAGE_LENGTH 0x0A
|
||||
uint8_t flags1;
|
||||
#define SPC_MP_INFEXP_PERF (1 << 7) /**< Initiator Control */
|
||||
#define SPC_MP_INFEXP_EBF (1 << 5) /**< Caching Analysis Permitted */
|
||||
#define SPC_MP_INFEXP_EWASC (1 << 4) /**< Discontinuity */
|
||||
#define SPC_MP_INFEXP_DEXCPT (1 << 3) /**< Size enable */
|
||||
#define SPC_MP_INFEXP_TEST (1 << 2) /**< Write-back Cache Enable */
|
||||
#define SPC_MP_INFEXP_LOGERR (1 << 0) /**< Log errors bit */
|
||||
uint8_t mrie;
|
||||
#define SPC_MP_INFEXP_MRIE_NO_REPORT 0x00
|
||||
#define SPC_MP_INFEXP_MRIE_ASYNC_EVENT 0x01
|
||||
#define SPC_MP_INFEXP_MRIE_GEN_UNIT 0x02
|
||||
#define SPC_MP_INFEXP_MRIE_COND_RECOV_ERROR 0x03
|
||||
#define SPC_MP_INFEXP_MRIE_UNCOND_RECOV_ERROR 0x04
|
||||
#define SPC_MP_INFEXP_MRIE_NO_SENSE 0x05
|
||||
#define SPC_MP_INFEXP_MRIE_ONLY_REPORT 0x06
|
||||
be32_t interval_timer;
|
||||
be32_t report_count;
|
||||
};
|
||||
|
||||
enum scsi_spc_mode_sense_pc {
|
||||
SCSI_MS_SENSE_PC_CURRENT = 0,
|
||||
SCSI_MS_SENSE_PC_CHANGEABLE = 1,
|
||||
SCSI_MS_SENSE_PC_DEFAULT = 2,
|
||||
SCSI_MS_SENSE_PC_SAVED = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check whether dbd field is set in sense code
|
||||
* \param[in] cdb pointer to the sense code block
|
||||
* \return Operation status.
|
||||
*/
|
||||
static inline bool scsi_mode_sense_dbd_is_set(const uint8_t *cdb)
|
||||
{
|
||||
return (cdb[1] >> 3) & 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get page code from mode sense code
|
||||
* \param[in] cdb pointer to the sense code block
|
||||
* \return Operation status.
|
||||
*/
|
||||
static inline uint8_t scsi_mode_sense_get_page_code(const uint8_t *cdb)
|
||||
{
|
||||
return cdb[2] & 0x3f;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get pc from mode sense code
|
||||
* \param[in] cdb pointer to the sense code block
|
||||
* \return Operation status.
|
||||
*/
|
||||
static inline uint8_t scsi_mode_sense_get_pc(const uint8_t *cdb)
|
||||
{
|
||||
return cdb[2] >> 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief SCSI Mode Parameter Header used by MODE SELECT(6) and MODE SENSE(6)
|
||||
* \note Fields are MSB first (BE)
|
||||
*/
|
||||
struct scsi_mode_param_header6 {
|
||||
uint8_t mode_data_length; /**< Number of bytes after this */
|
||||
uint8_t medium_type; /**< Medium Type */
|
||||
uint8_t device_specific_parameter; /**< Defined by command set */
|
||||
uint8_t block_descriptor_length; /**< Length of block descriptors */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SCSI Mode Parameter Header used by MODE SELECT(10) and MODE SENSE(10)
|
||||
* \note Fields are MSB first (BE)
|
||||
*/
|
||||
struct scsi_mode_param_header10 {
|
||||
le16_t mode_data_length; /**< Number of bytes after this */
|
||||
uint8_t medium_type; /**< Medium Type */
|
||||
uint8_t device_specific_parameter; /**< Defined by command set */
|
||||
uint8_t flags4; /**< LONGLBA in bit 0 */
|
||||
uint8_t reserved;
|
||||
le16_t block_descriptor_length; /**< Length of block descriptors */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SCSI Page_0 Mode Page header (SPF not set)
|
||||
*/
|
||||
struct scsi_mode_page_0_header {
|
||||
uint8_t page_code;
|
||||
#define SCSI_PAGE_CODE_PS (1 << 7) /**< Parameters Savable */
|
||||
#define SCSI_PAGE_CODE_SPF (1 << 6) /**< SubPage Format */
|
||||
uint8_t page_length; /**< Number of bytes after this */
|
||||
#define SCSI_MS_PAGE_LEN(total) ((total)-2)
|
||||
};
|
||||
|
||||
#endif /**< SPC_PROTOCOL_H_ */
|
||||
137
bootloader/lib/usb_msc/usb_includes.h
Normal file
137
bootloader/lib/usb_msc/usb_includes.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief USB Include Header Files.
|
||||
*
|
||||
* This file contains the USB definitions and data structures provided by the
|
||||
* USB 2.0 specification.
|
||||
*
|
||||
* Copyright (C) 2015 - 2017 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel AVR product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _USB_INCLUDES_H_
|
||||
#define _USB_INCLUDES_H_
|
||||
|
||||
#ifdef USB_USER_INCLUDES
|
||||
|
||||
//#include "usb_user_includes.h"
|
||||
|
||||
#else
|
||||
/* Include START headers */
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
//#include <utils.h>
|
||||
//#include <utils_list.h>
|
||||
//#include <utils_assert.h>
|
||||
//#include <hal_atomic.h>
|
||||
|
||||
typedef uint16_t le16_t;
|
||||
typedef uint32_t le32_t;
|
||||
typedef uint16_t be16_t;
|
||||
typedef uint32_t be32_t;
|
||||
|
||||
#if (defined __GNUC__) || (defined __CC_ARM)
|
||||
#define is_constant(exp) __builtin_constant_p(exp)
|
||||
#else
|
||||
#define is_constant(exp) (0)
|
||||
#endif
|
||||
|
||||
/*! \brief Toggles the endianism of \a u16 (by swapping its bytes).
|
||||
*
|
||||
* \param u16 U16 of which to toggle the endianism.
|
||||
*
|
||||
* \return Value resulting from \a u16 with toggled endianism.
|
||||
*
|
||||
* \note More optimized if only used with values known at compile time.
|
||||
*/
|
||||
#define swap_u16(u16) ((uint16_t)(((uint16_t)(u16) >> 8) | ((uint16_t)(u16) << 8)))
|
||||
|
||||
/*! \brief Toggles the endianism of \a u32 (by swapping its bytes).
|
||||
*
|
||||
* \param u32 U32 of which to toggle the endianism.
|
||||
*
|
||||
* \return Value resulting from \a u32 with toggled endianism.
|
||||
*
|
||||
* \note More optimized if only used with values known at compile time.
|
||||
*/
|
||||
#if (defined __GNUC__)
|
||||
#define swap_u32(u32) \
|
||||
(is_constant(u32) \
|
||||
? ((uint32_t)(((uint32_t)swap_u16((uint32_t)(u32) >> 16)) | ((uint32_t)swap_u16((uint32_t)(u32)) << 16))) \
|
||||
: ((uint32_t)__builtin_bswap32((uint32_t)(u32))))
|
||||
#else
|
||||
#define swap_u32(u32) \
|
||||
((uint32_t)(((uint32_t)swap_u16((uint32_t)(u32) >> 16)) | ((uint32_t)swap_u16((uint32_t)(u32)) << 16)))
|
||||
#endif
|
||||
|
||||
/** Get a value from/to LE16 data */
|
||||
#define LE16(x) (x)
|
||||
/** Get a value from/to LE32 data */
|
||||
#define LE32(x) (x)
|
||||
/** Get a value from/to BE16 data */
|
||||
#define BE16(x) swap_u16(x)
|
||||
/** Get a value from/to BE32 data */
|
||||
#define BE32(x) swap_u32(x)
|
||||
|
||||
/** Get byte 0 for BE 16-bit value */
|
||||
#define BE16B0(a) ((uint8_t)((a) >> 8))
|
||||
/** Get byte 1 for BE 16-bit value */
|
||||
#define BE16B1(a) ((uint8_t)((a) >> 0))
|
||||
|
||||
/** Get byte 0 for BE 32-bit value */
|
||||
#define BE32B0(a) ((uint8_t)((a) >> 24))
|
||||
/** Get byte 1 for BE 32-bit value */
|
||||
#define BE32B1(a) ((uint8_t)((a) >> 16))
|
||||
/** Get byte 2 for BE 32-bit value */
|
||||
#define BE32B2(a) ((uint8_t)((a) >> 8))
|
||||
/** Get byte 3 for BE 32-bit value */
|
||||
#define BE32B3(a) ((uint8_t)((a) >> 0))
|
||||
|
||||
/** Get byte 0 for LE 16-bit value */
|
||||
#define LE16B0(a) ((uint8_t)((a) >> 0))
|
||||
/** Get byte 1 for LE 16-bit value */
|
||||
#define LE16B1(a) ((uint8_t)((a) >> 8))
|
||||
|
||||
/** Get byte 0 for LE 32-bit value */
|
||||
#define LE32B0(a) ((uint8_t)((a) >> 0))
|
||||
/** Get byte 1 for LE 32-bit value */
|
||||
#define LE32B1(a) ((uint8_t)((a) >> 8))
|
||||
/** Get byte 2 for LE 32-bit value */
|
||||
#define LE32B2(a) ((uint8_t)((a) >> 16))
|
||||
/** Get byte 3 for LE 32-bit value */
|
||||
#define LE32B3(a) ((uint8_t)((a) >> 24))
|
||||
|
||||
#endif /* USB_USER_INCLUDES */
|
||||
|
||||
#endif /* _USB_INCLUDES_H_ */
|
||||
765
bootloader/lib/usb_msc/usb_protocol.h
Normal file
765
bootloader/lib/usb_msc/usb_protocol.h
Normal file
|
|
@ -0,0 +1,765 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief USB protocol definitions.
|
||||
*
|
||||
* This file contains the USB definitions and data structures provided by the
|
||||
* USB 2.0 specification.
|
||||
*
|
||||
* Copyright (C) 2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel AVR product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _USB_PROTOCOL_H_
|
||||
#define _USB_PROTOCOL_H_
|
||||
|
||||
#include "usb_includes.h"
|
||||
|
||||
/**
|
||||
* \ingroup usb_group
|
||||
* \defgroup usb_protocol_group USB Protocol Definitions
|
||||
*
|
||||
* This module defines constants and data structures provided by the USB
|
||||
* 2.0 specification.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __CC_ARM
|
||||
#pragma anon_unions
|
||||
#endif
|
||||
|
||||
/*! Value for field bcdUSB */
|
||||
#define USB_V2_0 (0x0200) /*!< USB Specification version 2.00 */
|
||||
#define USB_V2_1 (0x0201) /*!< USB Specification version 2.01 (support BOS) */
|
||||
|
||||
/*! \name Generic definitions (Class, subclass and protocol)
|
||||
*/
|
||||
/*! @{ */
|
||||
#define USB_CLASS_NO (0x00)
|
||||
#define USB_SUBCLASS_NO (0x00)
|
||||
#define USB_PROTOCOL_NO (0x00)
|
||||
/*! @} */
|
||||
|
||||
/*! \name IAD (Interface Association Descriptor) constants */
|
||||
/*! @{ */
|
||||
#define USB_CLASS_IAD (0xEF)
|
||||
#define USB_SUBCLASS_IAD (0x02)
|
||||
#define USB_PROTOCOL_IAD (0x01)
|
||||
/*! @} */
|
||||
|
||||
/**
|
||||
* \brief USB request data transfer direction (bmRequestType)
|
||||
*/
|
||||
#define USB_REQT_DIR_OUT (0 << 7) /*!< Host to device */
|
||||
#define USB_REQT_DIR_H2D (0 << 7) /*!< Host to device */
|
||||
#define USB_REQT_DIR_IN (1 << 7) /*!< Device to host */
|
||||
#define USB_REQT_DIR_D2H (1 << 7) /*!< Device to host */
|
||||
#define USB_REQT_DIR_MASK (1 << 7) /*!< Mask */
|
||||
|
||||
/**
|
||||
* \brief USB request types (bmRequestType)
|
||||
*/
|
||||
#define USB_REQT_TYPE_STANDARD (0 << 5) /*!< Standard request */
|
||||
#define USB_REQT_TYPE_CLASS (1 << 5) /*!< Class-specific request */
|
||||
#define USB_REQT_TYPE_VENDOR (2 << 5) /*!< Vendor-specific request */
|
||||
#define USB_REQT_TYPE_MASK (3 << 5) /*!< Mask */
|
||||
|
||||
/**
|
||||
* \brief USB recipient codes (bmRequestType)
|
||||
*/
|
||||
#define USB_REQT_RECIP_DEVICE (0 << 0) /*!< Recipient device */
|
||||
#define USB_REQT_RECIP_INTERFACE (1 << 0) /*!< Recipient interface */
|
||||
#define USB_REQT_RECIP_ENDPOINT (2 << 0) /*!< Recipient endpoint */
|
||||
#define USB_REQT_RECIP_OTHER (3 << 0) /*!< Recipient other */
|
||||
#define USB_REQT_RECIP_MASK (0x1F) /*!< Mask */
|
||||
|
||||
/**
|
||||
* \brief Standard USB control transfer stages.
|
||||
*/
|
||||
enum usb_ctrl_stage { USB_SETUP_STAGE = 0, USB_DATA_STAGE = 1, USB_STATUS_STAGE = 2 };
|
||||
|
||||
/**
|
||||
* \brief Standard USB requests (bRequest)
|
||||
*/
|
||||
enum usb_req_code {
|
||||
USB_REQ_GET_STATUS = 0,
|
||||
USB_REQ_CLEAR_FTR = 1,
|
||||
USB_REQ_SET_FTR = 3,
|
||||
USB_REQ_SET_ADDRESS = 5,
|
||||
USB_REQ_GET_DESC = 6,
|
||||
USB_REQ_SET_DESC = 7,
|
||||
USB_REQ_GET_CONFIG = 8,
|
||||
USB_REQ_SET_CONFIG = 9,
|
||||
USB_REQ_GET_INTERFACE = 10,
|
||||
USB_REQ_SET_INTERFACE = 11,
|
||||
USB_REQ_SYNCH_FRAME = 12,
|
||||
USB_REQ_SET_SEL = 48,
|
||||
USB_REQ_ISOCH_DELAY = 49
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard USB device status flags
|
||||
*
|
||||
*/
|
||||
enum usb_dev_status {
|
||||
USB_DEV_STAT_BUS_POWERED = 0,
|
||||
USB_DEV_STAT_SELF_POWERED = 1,
|
||||
USB_DEV_STAT_REMOTEWAKEUP = 2,
|
||||
USB_DEV_STAT_U1_ENABLE = 4,
|
||||
USB_DEV_STAT_U2_ENABLE = 8,
|
||||
USB_DEV_STAT_LTM_ENABLE = 16
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard USB Interface status flags
|
||||
*
|
||||
*/
|
||||
enum usb_interface_status {
|
||||
USB_IFACE_STAT_RESERVED = 0,
|
||||
USB_IFACE_STAT_REMOTEWAKE_CAP = 1,
|
||||
USB_IFACE_STAT_REMOTEWAKE = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard USB endpoint status flags
|
||||
*
|
||||
*/
|
||||
enum usb_endpoint_status { USB_EP_STAT_HALT = 1 };
|
||||
|
||||
/**
|
||||
* \brief Standard USB device feature flags
|
||||
*
|
||||
* \note valid for SetFeature request.
|
||||
*/
|
||||
enum usb_device_feature {
|
||||
USB_DEV_FTR_REMOTE_WAKEUP = 1, /*!< Remote wakeup enabled */
|
||||
USB_DEV_FTR_TEST_MODE = 2, /*!< USB test mode */
|
||||
USB_DEV_FTR_OTG_B_HNP_ENABLE = 3,
|
||||
USB_DEV_FTR_OTG_A_HNP_SP = 4,
|
||||
USB_DEV_FTR_OTG_A_ALT_HNP_SP = 5,
|
||||
USB_DEV_FTR_U1_ENABLE = 48,
|
||||
USB_DEV_FTR_U2_ENABLE = 49,
|
||||
USB_DEV_FTR_LTM_ENABLE = 50
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Test Mode possible on HS USB device
|
||||
*
|
||||
* \note valid for USB_DEV_FTR_TEST_MODE request.
|
||||
*/
|
||||
enum usb_device_hs_test_mode {
|
||||
USB_DEV_TEST_MODE_J = 1,
|
||||
USB_DEV_TEST_MODE_K = 2,
|
||||
USB_DEV_TEST_MODE_SE0_NAK = 3,
|
||||
USB_DEV_TEST_MODE_PACKET = 4,
|
||||
USB_DEV_TEST_MODE_FORCE_ENABLE = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard Feature Selectors for Interface
|
||||
*/
|
||||
enum usb_iface_feature { USB_IFACE_FTR_FUNC_SUSP = 0 };
|
||||
|
||||
/**
|
||||
* \brief Standard USB endpoint feature/status flags
|
||||
*/
|
||||
enum usb_endpoint_feature { USB_EP_FTR_HALT = 0 };
|
||||
|
||||
/**
|
||||
* \brief Standard USB Test Mode Selectors
|
||||
*/
|
||||
enum usb_test_mode_selector {
|
||||
USB_TEST_J = 0x01,
|
||||
USB_TEST_K = 0x02,
|
||||
USB_TEST_SE0_NAK = 0x03,
|
||||
USB_TEST_PACKET = 0x04,
|
||||
USB_TEST_FORCE_ENABLE = 0x05
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard USB descriptor types
|
||||
*/
|
||||
enum usb_descriptor_type {
|
||||
USB_DT_DEVICE = 1,
|
||||
USB_DT_CONFIG = 2,
|
||||
USB_DT_STRING = 3,
|
||||
USB_DT_INTERFACE = 4,
|
||||
USB_DT_ENDPOINT = 5,
|
||||
USB_DT_DEVICE_QUALIFIER = 6,
|
||||
USB_DT_OTHER_SPEED_CONFIG = 7,
|
||||
USB_DT_INTERFACE_POWER = 8,
|
||||
USB_DT_OTG = 9,
|
||||
USB_DT_DEBUG = 10,
|
||||
USB_DT_IAD = 11,
|
||||
USB_DT_BOS = 15,
|
||||
USB_DT_DEV_CAP = 16,
|
||||
USB_DT_SS_EP_COMPANION = 48
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Capability types
|
||||
*/
|
||||
enum usb_capability_type {
|
||||
USB_CAPT_WIRELESS = 1,
|
||||
USB_CAPT_2_0_EXT = 2,
|
||||
USB_CAPT_SUPER_SPEED = 3,
|
||||
USB_CAPT_CONTAINER_ID = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief USB 2.0 Extension attributes
|
||||
*/
|
||||
enum usb_2_0_ext_attr { USB_2_0_EXT_LPM_SP = 1 };
|
||||
|
||||
/**
|
||||
* \brief USB SuperSpeed Capability attributes
|
||||
*/
|
||||
enum usb_ss_cap_attr { USB_SS_LTM_SP };
|
||||
|
||||
/**
|
||||
* \brief USB Speed Supports
|
||||
*/
|
||||
enum usb_speed_sp {
|
||||
USB_SPEED_LOW_SP = 1,
|
||||
USB_SPEED_LS_SP = 1,
|
||||
USB_SPEED_FULL_SP = 2,
|
||||
USB_SPEED_FS_SP = 2,
|
||||
USB_SPEED_HIGH_SP = 4,
|
||||
USB_SPEED_HS_SP = 4,
|
||||
USB_SPEED_SUPER_SP = 8,
|
||||
USB_SPEED_SS_SP = 8
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard USB endpoint transfer types
|
||||
*/
|
||||
enum usb_ep_type {
|
||||
USB_EP_TYPE_CONTROL = 0x00,
|
||||
USB_EP_TYPE_ISOCHRONOUS = 0x01,
|
||||
USB_EP_TYPE_BULK = 0x02,
|
||||
USB_EP_TYPE_INTERRUPT = 0x03,
|
||||
USB_EP_TYPE_MASK = 0x03u
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief USB endpoint interrupt types
|
||||
*/
|
||||
enum usb_ep_int_type { USB_EP_INT_T_PERIODIC = 0x00u, USB_EP_INT_T_NOTIFICATION = 0x01u, USB_EP_INT_T_MASK = 0x03u };
|
||||
|
||||
/**
|
||||
* \brief Standard USB endpoint synchronization types
|
||||
*/
|
||||
enum usb_ep_sync_type {
|
||||
USB_EP_SYNC_T_NO = 0x00u,
|
||||
USB_EP_SYNC_T_ASYNC = 0x02u,
|
||||
USB_EP_SYNC_T_ADAPTIVE = 0x02u,
|
||||
USB_EP_SYNC_T_SYNC = 0x03u,
|
||||
USB_EP_SYNC_T_MASK = 0x03u
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard USB endpoint usage types
|
||||
*/
|
||||
enum usb_ep_usage_type {
|
||||
USB_EP_USAGE_T_DATA = 0x00u,
|
||||
USB_EP_USAGE_T_FEEDBACK = 0x01u,
|
||||
USB_EP_USAGE_T_FEEDBACK_DATA = 0x02u,
|
||||
USB_EP_USAGE_T_MASK = 0x03u
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Standard USB language IDs for string descriptors
|
||||
*/
|
||||
enum usb_langid {
|
||||
USB_LANGID_EN_US = 0x0409 /*!< English (United States) */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Mask selecting the index part of an endpoint address
|
||||
*/
|
||||
#define USB_EP_ADDR_MASK 0x0f
|
||||
/**
|
||||
* \brief Endpoint transfer direction is IN
|
||||
*/
|
||||
#define USB_EP_DIR_IN 0x80
|
||||
/**
|
||||
* \brief Endpoint transfer direction is OUT
|
||||
*/
|
||||
#define USB_EP_DIR_OUT 0x00
|
||||
|
||||
/**
|
||||
* \brief Maximum length in bytes of a USB descriptor
|
||||
*
|
||||
* The maximum length of a USB descriptor is limited by the 8-bit
|
||||
* bLength field.
|
||||
*/
|
||||
#define USB_DESC_LEN_MAX 255
|
||||
|
||||
/*
|
||||
* 2-byte alignment requested for all USB structures.
|
||||
*/
|
||||
_Pragma("pack(1)")
|
||||
|
||||
/**
|
||||
* \brief A USB Device SETUP request
|
||||
*
|
||||
* The data payload of SETUP packets always follows this structure.
|
||||
*/
|
||||
typedef struct usb_req {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
union {
|
||||
le16_t wValue;
|
||||
struct {
|
||||
uint8_t l;
|
||||
uint8_t h;
|
||||
} wValueBytes;
|
||||
};
|
||||
union {
|
||||
le16_t wIndex;
|
||||
struct {
|
||||
uint8_t l;
|
||||
uint8_t h;
|
||||
} wIndexBytes;
|
||||
};
|
||||
union {
|
||||
le16_t wLength;
|
||||
struct {
|
||||
uint8_t l;
|
||||
uint8_t h;
|
||||
} wLengthBytes;
|
||||
};
|
||||
} usb_req_t;
|
||||
|
||||
/**
|
||||
* \brief Standard USB device descriptor structure
|
||||
*/
|
||||
typedef struct usb_dev_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
le16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
le16_t idVendor;
|
||||
le16_t idProduct;
|
||||
le16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} usb_dev_desc_t;
|
||||
|
||||
/**
|
||||
* \brief Binary device Object Store (BOS) descriptor structure
|
||||
*/
|
||||
typedef struct usb_bos_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
le16_t wTotalLength;
|
||||
uint8_t bNumDeviceCaps;
|
||||
} usb_bos_desc_t;
|
||||
|
||||
/**
|
||||
* \brief Device Capability Descriptor structure
|
||||
*/
|
||||
typedef struct usb_cap_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint8_t Vars[1];
|
||||
} usb_cap_desc_t;
|
||||
|
||||
/**
|
||||
* \brief USB 2.0 Extension Descriptor structure
|
||||
*/
|
||||
typedef struct usb_2_0_ext {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint32_t bmAttributes;
|
||||
} usb_2_0_ext_t;
|
||||
|
||||
/**
|
||||
* \brief LPM Device Capabilities descriptor structure
|
||||
*/
|
||||
typedef struct usb_2_0_ext usb_lpm_cap_desc_t;
|
||||
|
||||
/**
|
||||
* \brief SuperSpeed USB Device Capability structure
|
||||
*/
|
||||
typedef struct usb_ss_cap_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint8_t bmAttributes;
|
||||
le16_t wSpeedsSupported;
|
||||
uint8_t bFunctionalitySupport;
|
||||
uint8_t bU1DevExitLat;
|
||||
uint8_t bU2DevExitLat;
|
||||
} usb_ss_cap_desc_t;
|
||||
|
||||
/**
|
||||
* \brief USB Container ID Descriptor structure
|
||||
*/
|
||||
typedef struct usb_container_id_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint8_t bReserved;
|
||||
uint8_t ContainerID[16];
|
||||
} usb_container_id_desc_t;
|
||||
|
||||
/**
|
||||
* \brief Standard USB device qualifier descriptor structure
|
||||
*
|
||||
* This descriptor contains information about the device when running at
|
||||
* the "other" speed (i.e. if the device is currently operating at high
|
||||
* speed, this descriptor can be used to determine what would change if
|
||||
* the device was operating at full speed.)
|
||||
*/
|
||||
typedef struct usb_dev_qual_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
le16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t bNumConfigurations;
|
||||
uint8_t bReserved;
|
||||
} usb_dev_qual_desc_t;
|
||||
|
||||
/**
|
||||
* \brief Standard USB configuration descriptor structure
|
||||
*/
|
||||
typedef struct usb_config_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
le16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} usb_config_desc_t;
|
||||
|
||||
#define USB_CONFIG_ATTR_MUST_SET (1 << 7) /*!< Must always be set */
|
||||
#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) /*!< Bus-powered */
|
||||
#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) /*!< Self-powered */
|
||||
#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) /*!< remote wakeup supported */
|
||||
|
||||
#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) /*!< Max power in mA */
|
||||
|
||||
/**
|
||||
* \brief Standard USB association descriptor structure
|
||||
*/
|
||||
typedef struct usb_iad_desc {
|
||||
uint8_t bLength; /*!< Size of this descriptor in bytes */
|
||||
uint8_t bDescriptorType; /*!< Interface descriptor type */
|
||||
uint8_t bFirstInterface; /*!< Number of interface */
|
||||
uint8_t bInterfaceCount; /*!< value to select alternate setting */
|
||||
uint8_t bFunctionClass; /*!< Class code assigned by the USB */
|
||||
uint8_t bFunctionSubClass; /*!< Sub-class code assigned by the USB */
|
||||
uint8_t bFunctionProtocol; /*!< Protocol code assigned by the USB */
|
||||
uint8_t iFunction; /*!< Index of string descriptor */
|
||||
} usb_iad_desc_t;
|
||||
|
||||
/**
|
||||
* \brief Standard USB interface descriptor structure
|
||||
*/
|
||||
typedef struct usb_iface_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} usb_iface_desc_t;
|
||||
|
||||
/**
|
||||
* \brief Standard USB endpoint descriptor structure
|
||||
*/
|
||||
typedef struct usb_ep_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
le16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
} usb_ep_desc_t;
|
||||
|
||||
/**
|
||||
* \brief SuperSpeed Endpoint Companion descriptor structure
|
||||
*/
|
||||
typedef struct usb_ss_ep_comp_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bMaxBurst;
|
||||
uint8_t bmAttributes;
|
||||
le16_t wBytesPerInterval;
|
||||
} usb_ss_ep_comp_desc_t;
|
||||
|
||||
/**
|
||||
* \brief LPM Token bmAttributes structure
|
||||
*/
|
||||
typedef struct usb_lpm_attributes {
|
||||
uint8_t bLinkState : 4;
|
||||
uint8_t HIRD : 4;
|
||||
uint8_t bRemoteWake : 1;
|
||||
uint8_t Reserved : 2;
|
||||
} usb_lpm_attributes_t;
|
||||
|
||||
/**
|
||||
* \brief A standard USB string descriptor structure
|
||||
*/
|
||||
typedef struct usb_str_desc {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
} usb_str_desc_t;
|
||||
|
||||
typedef struct usb_str_langid_desc {
|
||||
usb_str_desc_t desc;
|
||||
le16_t string[1];
|
||||
} usb_str_langid_desc_t;
|
||||
|
||||
_Pragma("pack()")
|
||||
|
||||
/** \name Macros to build USB standard descriptors */
|
||||
/*@{*/
|
||||
|
||||
/** Build bytes for USB device descriptor. */
|
||||
#define USB_DEV_DESC_BYTES(bcdUSB, \
|
||||
bDeviceClass, \
|
||||
bDeviceSubClass, \
|
||||
bDeviceProtocol, \
|
||||
bMaxPacketSize0, \
|
||||
idVendor, \
|
||||
idProduct, \
|
||||
bcdDevice, \
|
||||
iManufacturer, \
|
||||
iProduct, \
|
||||
iSerialNumber, \
|
||||
bNumConfigurations) \
|
||||
18, /* bLength */ \
|
||||
0x01, /* bDescriptorType: DEVICE */ \
|
||||
LE_BYTE0(bcdUSB), LE_BYTE1(bcdUSB), bDeviceClass, bDeviceSubClass, bDeviceProtocol, bMaxPacketSize0, \
|
||||
LE_BYTE0(idVendor), LE_BYTE1(idVendor), LE_BYTE0(idProduct), LE_BYTE1(idProduct), LE_BYTE0(bcdDevice), \
|
||||
LE_BYTE1(bcdDevice), iManufacturer, iProduct, iSerialNumber, bNumConfigurations
|
||||
|
||||
#define USB_DEV_DESC_LEN 18
|
||||
|
||||
/** Build bytes for USB configuration descriptor. */
|
||||
#define USB_CONFIG_DESC_BYTES( \
|
||||
wTotalLength, bNumInterfaces, bConfigurationValue, iConfiguration, bmAttributes, bMaxPower) \
|
||||
9, /* bLength */ \
|
||||
0x02, /* bDescriptorType: CONFIGURATION */ \
|
||||
LE_BYTE0(wTotalLength), LE_BYTE1(wTotalLength), bNumInterfaces, bConfigurationValue, iConfiguration, \
|
||||
bmAttributes, bMaxPower
|
||||
|
||||
#define USB_CONFIG_DESC_LEN 9
|
||||
|
||||
/** Build bytes for USB IAD descriptor. */
|
||||
#define USB_IAD_DESC_BYTES( \
|
||||
bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol, iFunction) \
|
||||
8, /* bLength */ \
|
||||
USB_DT_IAD, /* bDescriptorType */ \
|
||||
bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol, iFunction
|
||||
|
||||
#define USB_IAD_DESC_LEN 8
|
||||
|
||||
/** Build bytes for USB interface descriptor. */
|
||||
#define USB_IFACE_DESC_BYTES(bInterfaceNumber, \
|
||||
bAlternateSetting, \
|
||||
bNumEndpoints, \
|
||||
bInterfaceClass, \
|
||||
bInterfaceSubClass, \
|
||||
bInterfaceProtocol, \
|
||||
iInterface) \
|
||||
9, /* bLength */ \
|
||||
0x04, /* bDescriptorType: INTERFACE */ \
|
||||
bInterfaceNumber, bAlternateSetting, bNumEndpoints, bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol, \
|
||||
iInterface
|
||||
|
||||
#define USB_IFACE_DESC_LEN 9
|
||||
|
||||
/** Build bytes for USB endpoint descriptor. */
|
||||
#define USB_ENDP_DESC_BYTES(bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \
|
||||
7, /* bLength */ \
|
||||
0x05, /* bDescriptorType: ENDPOINT */ \
|
||||
bEndpointAddress, bmAttributes, LE_BYTE0(wMaxPacketSize), LE_BYTE1(wMaxPacketSize), bInterval
|
||||
|
||||
#define USB_ENDP_DESC_LEN 7
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** \brief Get a word (calculate by little endian 16-bit data)
|
||||
* \param[in] ptr Byte pointer to the address to get data
|
||||
* \return a 16-bit word
|
||||
*/
|
||||
static inline uint16_t usb_get_u16(const uint8_t *ptr)
|
||||
{
|
||||
return (ptr[0] + (ptr[1] << 8));
|
||||
}
|
||||
|
||||
/** \brief Get a double word (calculate by little endian 32-bit data)
|
||||
* \param[in] ptr Byte pointer to the address to get data
|
||||
* \return a 32-bit word
|
||||
*/
|
||||
static inline uint32_t usb_get_u32(const uint8_t *ptr)
|
||||
{
|
||||
return (ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24));
|
||||
}
|
||||
|
||||
/** \brief Get descriptor length
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \return descriptor length
|
||||
*/
|
||||
static inline uint8_t usb_desc_len(const uint8_t *desc)
|
||||
{
|
||||
return desc[0];
|
||||
}
|
||||
|
||||
/** \brief Get descriptor type
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \return descriptor type
|
||||
*/
|
||||
static inline uint8_t usb_desc_type(const uint8_t *desc)
|
||||
{
|
||||
return desc[1];
|
||||
}
|
||||
|
||||
/** \brief Get next USB descriptor
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \return Byte pointer to the next descriptor
|
||||
*/
|
||||
static inline uint8_t *usb_desc_next(uint8_t *desc)
|
||||
{
|
||||
return (desc + usb_desc_len(desc));
|
||||
}
|
||||
|
||||
/** \brief Get idVendor of USB Device Descriptor
|
||||
* \param[in] dev_desc Byte pointer to the descriptor start address
|
||||
* \return 16-bit idVendor value
|
||||
*/
|
||||
static inline uint16_t usb_dev_desc_vid(const uint8_t *dev_desc)
|
||||
{
|
||||
return usb_get_u16(dev_desc + 8);
|
||||
}
|
||||
|
||||
/** \brief Get idProduct of USB Device Descriptor
|
||||
* \param[in] dev_desc Byte pointer to the descriptor start address
|
||||
* \return 16-bit idProduct value
|
||||
*/
|
||||
static inline uint16_t usb_dev_desc_pid(const uint8_t *dev_desc)
|
||||
{
|
||||
return usb_get_u16(dev_desc + 10);
|
||||
}
|
||||
|
||||
/** \brief Get wTotalLength of USB Configuration Descriptor
|
||||
* \param[in] cfg_desc Byte pointer to the descriptor start address
|
||||
* \return 16-bit total length of configuration list
|
||||
*/
|
||||
static inline uint16_t usb_cfg_desc_total_len(const uint8_t *cfg_desc)
|
||||
{
|
||||
return usb_get_u16(cfg_desc + 2);
|
||||
}
|
||||
|
||||
/** \brief Get Next USB Descriptor After the Configuration Descriptors list
|
||||
* \param[in] cfg_desc Byte pointer to the descriptor start address
|
||||
* \return Byte pointer to descriptor after configuration end
|
||||
*/
|
||||
static inline uint8_t *usb_cfg_desc_next(uint8_t *cfg_desc)
|
||||
{
|
||||
return (cfg_desc + usb_cfg_desc_total_len(cfg_desc));
|
||||
}
|
||||
|
||||
/** \brief Find specific USB Descriptor by its type
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \param[in] eof Byte pointer to the descriptor end address
|
||||
* \param[in] type The descriptor type expected
|
||||
* \return Pointer to the descriptor
|
||||
* \retval NULL if not found
|
||||
*/
|
||||
uint8_t *usb_find_desc(uint8_t *desc, uint8_t *eof, uint8_t type);
|
||||
|
||||
/** Get interface descriptor next to the specified one (by interface number)
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \param[in] eof Byte pointer to the descriptor end address
|
||||
* \param[in] iface_n The interface number to check
|
||||
* \return Pointer to the descriptor
|
||||
* \retval >= eof if not found
|
||||
*/
|
||||
uint8_t *usb_find_iface_after(uint8_t *desc, uint8_t *eof, uint8_t iface_n);
|
||||
|
||||
/** Find endpoint descriptor, breaks if interface descriptor detected
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \param[in] eof Byte pointer to the descriptor end address
|
||||
* \return Pointer to the descriptor
|
||||
* \retval NULL if not found
|
||||
*/
|
||||
uint8_t *usb_find_ep_desc(uint8_t *desc, uint8_t *eof);
|
||||
|
||||
/** Find configuration descriptor by its configuration number
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \param[in] eof Byte pointer to the descriptor end address
|
||||
* \param[in] cfg_value The configure value expected
|
||||
* \return Pointer to the descriptor
|
||||
* \retval NULL if not found
|
||||
*/
|
||||
uint8_t *usb_find_cfg_desc(uint8_t *desc, uint8_t *eof, uint8_t cfg_value);
|
||||
|
||||
/** Find string descriptor by its index
|
||||
* \param[in] desc Byte pointer to the descriptor start address
|
||||
* \param[in] eof Byte pointer to the descriptor end address
|
||||
* \param[in] str_index The string index expected
|
||||
* \return Pointer to the descriptor
|
||||
* \retval NULL if not found
|
||||
*/
|
||||
uint8_t *usb_find_str_desc(uint8_t *desc, uint8_t *eof, uint8_t str_index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _USB_PROTOCOL_H_ */
|
||||
177
bootloader/lib/usb_msc/usb_protocol_msc.h
Normal file
177
bootloader/lib/usb_msc/usb_protocol_msc.h
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief USB Mass Storage Class (MSC) protocol definitions.
|
||||
*
|
||||
* Copyright (c) 2016 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _USB_PROTOCOL_MSC_H_
|
||||
#define _USB_PROTOCOL_MSC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \ingroup usb_protocol_group
|
||||
* \defgroup usb_msc_protocol USB Mass Storage Class (MSC) protocol definitions
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \name Possible Class value
|
||||
*/
|
||||
//@{
|
||||
#define MSC_CLASS 0x08
|
||||
//@}
|
||||
|
||||
/**
|
||||
* \name Possible SubClass value
|
||||
* \note In practice, most devices should use
|
||||
* #MSC_SUBCLASS_TRANSPARENT and specify the actual command set in
|
||||
* the standard INQUIRY data block, even if the MSC spec indicates
|
||||
* otherwise. In particular, RBC is not supported by certain major
|
||||
* operating systems like Windows XP.
|
||||
*/
|
||||
//@{
|
||||
#define MSC_SUBCLASS_RBC 0x01 /**< Reduced Block Commands */
|
||||
#define MSC_SUBCLASS_ATAPI 0x02 /**< CD/DVD devices */
|
||||
#define MSC_SUBCLASS_QIC_157 0x03 /**< Tape devices */
|
||||
#define MSC_SUBCLASS_UFI 0x04 /**< Floppy disk drives */
|
||||
#define MSC_SUBCLASS_SFF_8070I 0x05 /**< Floppy disk drives */
|
||||
#define MSC_SUBCLASS_TRANSPARENT 0x06 /**< Determined by INQUIRY */
|
||||
//@}
|
||||
|
||||
/**
|
||||
* \name Possible protocol value
|
||||
* \note Only the BULK protocol should be used in new designs.
|
||||
*/
|
||||
//@{
|
||||
#define MSC_PROTOCOL_CBI 0x00 /**< Command/Bulk/Interrupt */
|
||||
#define MSC_PROTOCOL_CBI_ALT 0x01 /**< W/o command completion */
|
||||
#define MSC_PROTOCOL_BULK 0x50 /**< Bulk-only */
|
||||
//@}
|
||||
|
||||
/**
|
||||
* \brief MSC USB requests (bRequest)
|
||||
*/
|
||||
|
||||
#define USB_REQ_MSC_BULK_RESET 0xFF /**< Mass Storage Reset */
|
||||
#define USB_REQ_MSC_GET_MAX_LUN 0xFE /**< Get Max LUN */
|
||||
|
||||
_Pragma("pack(1)")
|
||||
|
||||
/**
|
||||
* \name A Command Block Wrapper (CBW)
|
||||
* \note Fields are LSB first (LE)
|
||||
*/
|
||||
//@{
|
||||
struct usb_msc_cbw {
|
||||
le32_t dCBWSignature; /**< Must contain 'USBC' (0x43425355, LE32) */
|
||||
le32_t dCBWTag; /**< Unique command ID (LE32) */
|
||||
le32_t dCBWDataTransferLength; /**< Number of bytes to transfer (LE32) */
|
||||
uint8_t bmCBWFlags; /**< Direction in bit 7 */
|
||||
uint8_t bCBWLUN; /**< Logical Unit Number */
|
||||
uint8_t bCBWCBLength; /**< Number of valid CDB bytes */
|
||||
uint8_t CDB[16]; /**< SCSI Command Descriptor Block */
|
||||
};
|
||||
|
||||
#define USB_CBW_SIGNATURE 0x43425355 /**< dCBWSignature value */
|
||||
#define USB_CBW_DIRECTION_IN (1 << 7) /**< Data from device to host */
|
||||
#define USB_CBW_DIRECTION_OUT (0 << 7) /**< Data from host to device */
|
||||
#define USB_CBW_LUN_MASK 0x0F /**< Valid bits in bCBWLUN */
|
||||
#define USB_CBW_LEN_MASK 0x1F /**< Valid bits in bCBWCBLength */
|
||||
//@}
|
||||
|
||||
/**
|
||||
* \name A Command Status Wrapper (CSW)
|
||||
* \note Fields are LSB first (LE)
|
||||
*/
|
||||
//@{
|
||||
struct usb_msc_csw {
|
||||
le32_t dCSWSignature; /**< Must contain 'USBS' */
|
||||
le32_t dCSWTag; /**< Same as dCBWTag */
|
||||
le32_t dCSWDataResidue; /**< Number of bytes not transfered */
|
||||
uint8_t bCSWStatus; /**< Status code */
|
||||
};
|
||||
|
||||
#define USB_CSW_SIGNATURE 0x53425355 /**< dCSWSignature value */
|
||||
#define USB_CSW_STATUS_PASS 0x00 /**< Command Passed */
|
||||
#define USB_CSW_STATUS_FAIL 0x01 /**< Command Failed */
|
||||
#define USB_CSW_STATUS_PE 0x02 /**< Phase Error */
|
||||
//@}
|
||||
|
||||
_Pragma("pack()")
|
||||
|
||||
//@}
|
||||
|
||||
/**
|
||||
* \brief Fill a Bulk-Only Mass Storage Reset request
|
||||
* \param[out] req Pointer to the request to fill
|
||||
* \param[in] iface Interface Number
|
||||
*/
|
||||
static inline void usb_fill_BOMSReset_req(struct usb_req *req, uint8_t iface)
|
||||
{
|
||||
req->bmRequestType = 0x21;
|
||||
req->bRequest = USB_REQ_MSC_BULK_RESET;
|
||||
req->wValue = 0;
|
||||
req->wIndex = iface;
|
||||
req->wLength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Fill a GetMaxLUN request
|
||||
* \param[out] req Pointer to the request to fill
|
||||
* \param[in] iface Interface Number
|
||||
*/
|
||||
static inline void usb_fill_GetMaxLUN_req(struct usb_req *req, uint8_t iface)
|
||||
{
|
||||
req->bmRequestType = 0xA1;
|
||||
req->bRequest = USB_REQ_MSC_GET_MAX_LUN;
|
||||
req->wValue = 0;
|
||||
req->wIndex = iface;
|
||||
req->wLength = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _USB_PROTOCOL_MSC_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue