auto-sync
This commit is contained in:
parent
47445d908c
commit
0ed1bc3af1
|
@ -0,0 +1,40 @@
|
|||
https://github.com/tegesoft/Chibios-USB-Devices/
|
||||
http://www.chibios.com/forum/viewtopic.php?f=3&t=619
|
||||
|
||||
Mass Storage Device
|
||||
===================
|
||||
|
||||
This driver implements a USB mass storage device. It requires a Chibios block device (e.g mmc_spi or SDC)
|
||||
|
||||
Example usage:
|
||||
--------------
|
||||
```c
|
||||
|
||||
USBMassStorageDriver UMSD1;
|
||||
|
||||
mmcObjectInit(&MMCD1);
|
||||
mmcStart(&MMCD1, &mmccfg);
|
||||
mmcConnect(&MMCD1);
|
||||
|
||||
msdInit(&USBD1, &MMCD1, &UMSD1);
|
||||
```
|
||||
|
||||
Events:
|
||||
--------------
|
||||
```c
|
||||
chEvtRegisterMask(&UMSD1.evt_connected, &listener_connected, 1);
|
||||
chEvtRegisterMask(&UMSD1.evt_ejected, &listener_ejected, 2);
|
||||
|
||||
while(TRUE) {
|
||||
if(chEvtWaitOneTimeout(1, TIME_IMMEDIATE)) {
|
||||
/* drive is now connected */
|
||||
|
||||
/* wait until the drive is ejected */
|
||||
chEvtWaitOne(2);
|
||||
|
||||
/* drive is now ejected. do something */
|
||||
}
|
||||
|
||||
chThdSleepMilliseconds(1000);
|
||||
}
|
||||
```
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _USB_MSD_H_
|
||||
#define _USB_MSD_H_
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/* Default to disabled for USB Mass Storage */
|
||||
#if !defined(HAL_USE_MASS_STORAGE_USB)
|
||||
# define HAL_USE_MASS_STORAGE_USB FALSE
|
||||
#endif
|
||||
|
||||
#if HAL_USE_MASS_STORAGE_USB || defined(__DOXYGEN__)
|
||||
|
||||
|
||||
#if 0
|
||||
#define MSD_RW_LED_ON() palSetPad(GPIOI, GPIOI_TRI_LED_BLUE)
|
||||
#define MSD_RW_LED_OFF() palClearPad(GPIOI, GPIOI_TRI_LED_BLUE)
|
||||
#define MSD_R_LED_ON() palSetPad(GPIOI, GPIOI_TRI_LED_BLUE)
|
||||
#define MSD_R_LED_OFF() palClearPad(GPIOI, GPIOI_TRI_LED_BLUE)
|
||||
#define MSD_W_LED_ON() palSetPad(GPIOH, GPIOI_TRI_LED_BLUE)
|
||||
#define MSD_W_LED_OFF() palClearPad(GPIOH, GPIOI_TRI_LED_BLUE)
|
||||
#else
|
||||
#define MSD_RW_LED_ON()
|
||||
#define MSD_RW_LED_OFF()
|
||||
#define MSD_R_LED_ON()
|
||||
#define MSD_R_LED_OFF()
|
||||
#define MSD_W_LED_ON()
|
||||
#define MSD_W_LED_OFF()
|
||||
#endif
|
||||
|
||||
|
||||
#if STM32_USB_USE_OTG2 && STM32_USE_USB_OTG2_HS
|
||||
# define USB_MS_EP_SIZE 512
|
||||
#else
|
||||
# define USB_MS_EP_SIZE 64
|
||||
#endif
|
||||
|
||||
#define MSD_THREAD_STACK_SIZE 1024
|
||||
|
||||
#define MSD_REQ_RESET 0xFF
|
||||
#define MSD_GET_MAX_LUN 0xFE
|
||||
#define MSD_CBW_SIGNATURE 0x43425355
|
||||
#define MSD_CSW_SIGNATURE 0x53425355
|
||||
#define MSD_COMMAND_DIR_DATA_OUT (0 << 7)
|
||||
#define MSD_COMMAND_DIR_DATA_IN (1 << 7)
|
||||
|
||||
#define MSD_SETUP_WORD(setup, index) (uint16_t)(((uint16_t)setup[index+1] << 8) | (setup[index] & 0x00FF))
|
||||
|
||||
#define MSD_SETUP_VALUE(setup) MSD_SETUP_WORD(setup, 2)
|
||||
#define MSD_SETUP_INDEX(setup) MSD_SETUP_WORD(setup, 4)
|
||||
#define MSD_SETUP_LENGTH(setup) MSD_SETUP_WORD(setup, 6)
|
||||
|
||||
typedef enum {
|
||||
SCSI_CMD_TEST_UNIT_READY = 0x00,
|
||||
SCSI_CMD_REQUEST_SENSE_6 = 0x03,
|
||||
SCSI_CMD_INQUIRY = 0x12,
|
||||
SCSI_CMD_MODE_SENSE_6 = 0x1A,
|
||||
SCSI_CMD_START_STOP_UNIT = 0x1B,
|
||||
SCSI_CMD_SEND_DIAGNOSTIC = 0x1D,
|
||||
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
|
||||
SCSI_CMD_READ_FORMAT_CAPACITY = 0x23,
|
||||
SCSI_CMD_READ_CAPACITY_10 = 0x25,
|
||||
SCSI_CMD_READ_10 = 0x28,
|
||||
SCSI_CMD_WRITE_10 = 0x2A,
|
||||
SCSI_CMD_VERIFY_10 = 0x2F,
|
||||
SCSI_CMD_SYNCHRONIZE_CACHE_10 = 0x35,
|
||||
} msd_scsi_command_t;
|
||||
|
||||
|
||||
|
||||
#define MSD_COMMAND_PASSED 0x00
|
||||
#define MSD_COMMAND_FAILED 0x01
|
||||
#define MSD_COMMAND_PHASE_ERROR 0x02
|
||||
|
||||
#define SCSI_SENSE_KEY_GOOD 0x00
|
||||
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
||||
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
||||
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
||||
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
||||
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
||||
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
||||
|
||||
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
|
||||
#define SCSI_ASENSE_PEREPHERIAL_DEVICE_WRITE_FAULT 0x03
|
||||
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
|
||||
#define SCSI_ASENSE_UNRECOVERED_READ_ERROR 0x11
|
||||
#define SCSI_ASENSE_INVALID_COMMAND 0x20
|
||||
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
|
||||
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
|
||||
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
|
||||
#define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28
|
||||
#define SCSI_ASENSE_FORMAT_ERROR 0x31
|
||||
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
|
||||
|
||||
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
|
||||
#define SCSI_ASENSEQ_PEREPHERIAL_DEVICE_WRITE_FAULT 0x00
|
||||
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
|
||||
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
|
||||
|
||||
|
||||
PACK_STRUCT_BEGIN typedef struct {
|
||||
uint32_t signature;
|
||||
uint32_t tag;
|
||||
uint32_t data_len;
|
||||
uint8_t flags;
|
||||
uint8_t lun;
|
||||
uint8_t scsi_cmd_len;
|
||||
uint8_t scsi_cmd_data[16];
|
||||
} PACK_STRUCT_STRUCT msd_cbw_t PACK_STRUCT_END;
|
||||
|
||||
PACK_STRUCT_BEGIN typedef struct {
|
||||
uint32_t signature;
|
||||
uint32_t tag;
|
||||
uint32_t data_residue;
|
||||
uint8_t status;
|
||||
} PACK_STRUCT_STRUCT msd_csw_t PACK_STRUCT_END;
|
||||
|
||||
typedef struct {
|
||||
uint8_t byte[18];
|
||||
} PACK_STRUCT_STRUCT scsi_sense_response_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t mode_data_length; //Number of bytes that follow
|
||||
uint8_t medium_type; //0x00 for SBC devices
|
||||
uint8_t device_specifc_paramters; //bit 7 is the write protect bit
|
||||
uint8_t block_descriptor_length; //Length in bytes of all block descriptors in the mode parameter list.
|
||||
} PACK_STRUCT_STRUCT scsi_mode_sense6_response_t;
|
||||
|
||||
PACK_STRUCT_BEGIN typedef struct
|
||||
{
|
||||
uint8_t peripheral;
|
||||
uint8_t removable;
|
||||
uint8_t version;
|
||||
uint8_t response_data_format;
|
||||
uint8_t additional_length;
|
||||
uint8_t sccstp;
|
||||
uint8_t bqueetc;
|
||||
uint8_t cmdque;
|
||||
uint8_t vendorID[8];
|
||||
uint8_t productID[16];
|
||||
uint8_t productRev[4];
|
||||
} PACK_STRUCT_STRUCT scsi_inquiry_response_t PACK_STRUCT_END;
|
||||
|
||||
PACK_STRUCT_BEGIN typedef struct {
|
||||
uint8_t payload_byte_length[4];
|
||||
uint32_t last_block_addr;
|
||||
uint32_t block_size;
|
||||
} PACK_STRUCT_STRUCT scsi_read_format_capacity_response_t PACK_STRUCT_END;
|
||||
|
||||
PACK_STRUCT_BEGIN typedef struct {
|
||||
uint32_t last_block_addr;
|
||||
uint32_t block_size;
|
||||
} PACK_STRUCT_STRUCT scsi_read_capacity10_response_t PACK_STRUCT_END;
|
||||
|
||||
PACK_STRUCT_BEGIN typedef struct {
|
||||
uint8_t op_code;
|
||||
uint8_t lun_immed;
|
||||
uint8_t res1;
|
||||
uint8_t res2;
|
||||
uint8_t loej_start;
|
||||
uint8_t control;
|
||||
} PACK_STRUCT_STRUCT scsi_start_stop_unit_request_t;
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
MSD_WAIT_MODE_NONE = 0,
|
||||
MSD_WAIT_MODE_BULK_IN,
|
||||
MSD_WAIT_MODE_BULK_OUT
|
||||
} msd_wait_mode_t;
|
||||
|
||||
typedef enum {
|
||||
MSD_STATE_IDLE = 0,
|
||||
MSD_STATE_READ_CMD_BLOCK,
|
||||
MSD_STATE_EJECTED
|
||||
} msd_state_t;
|
||||
|
||||
typedef enum {
|
||||
USB_MSD_DRIVER_UNINITIALIZED = 0,
|
||||
USB_MSD_DRIVER_ERROR,
|
||||
USB_MSD_DRIVER_OK,
|
||||
USB_MSD_DRIVER_STOPPED,
|
||||
USB_MSD_DRIVER_ERROR_BLK_DEV_NOT_READY,
|
||||
} usb_msd_driver_state_t;
|
||||
|
||||
typedef struct USBMassStorageDriver USBMassStorageDriver;
|
||||
|
||||
struct USBMassStorageDriver {
|
||||
/* Driver Setup Data */
|
||||
USBDriver *usbp;
|
||||
BaseBlockDevice *bbdp;
|
||||
EventSource evt_connected;
|
||||
EventSource evt_ejected;
|
||||
BlockDeviceInfo block_dev_info;
|
||||
bool block_dev_info_valid_flag;
|
||||
usb_msd_driver_state_t driver_state;
|
||||
usbep_t ms_ep_number;
|
||||
uint16_t msd_interface_number;
|
||||
bool_t (*enable_msd_callback)(void);
|
||||
bool_t (*suspend_threads_callback)(void);
|
||||
|
||||
/* Externally modifiable settings */
|
||||
bool_t enable_media_removial;
|
||||
bool_t disable_usb_bus_disconnect_on_eject;
|
||||
BaseSequentialStream *chp; /*For debug logging*/
|
||||
|
||||
/*Internal data for operation of the driver */
|
||||
BinarySemaphore bsem;
|
||||
BinarySemaphore usb_transfer_thread_bsem;
|
||||
BinarySemaphore mass_sorage_thd_bsem;
|
||||
volatile uint32_t trigger_transfer_index;
|
||||
|
||||
volatile bool_t bulk_in_interupt_flag;
|
||||
volatile bool_t bulk_out_interupt_flag;
|
||||
|
||||
struct {
|
||||
scsi_read_format_capacity_response_t format_capacity_response;
|
||||
scsi_read_capacity10_response_t read_capacity10_response;
|
||||
scsi_mode_sense6_response_t mode_sense6_response;
|
||||
uint8_t max_lun_len_buf[1];
|
||||
scsi_inquiry_response_t scsi_inquiry_response;
|
||||
} data;
|
||||
|
||||
msd_state_t state;
|
||||
msd_cbw_t cbw;
|
||||
msd_csw_t csw;
|
||||
scsi_sense_response_t sense;
|
||||
|
||||
volatile bool_t reconfigured_or_reset_event;
|
||||
|
||||
bool_t command_succeeded_flag;
|
||||
bool_t stall_in_endpoint;
|
||||
bool_t stall_out_endpoint;
|
||||
|
||||
|
||||
/*Debugging Information*/
|
||||
volatile uint32_t read_error_count;
|
||||
volatile uint32_t write_error_count;
|
||||
volatile uint32_t read_success_count;
|
||||
volatile uint32_t write_success_count;
|
||||
char *msd_thread_state;
|
||||
char *transfer_thread_state;
|
||||
char *scsi_command_state;
|
||||
volatile uint8_t last_bad_scsi_command;
|
||||
|
||||
/* Externally readable values */
|
||||
volatile bool_t debug_enable_msd;
|
||||
volatile msd_wait_mode_t debug_wait_for_isr;
|
||||
|
||||
WORKING_AREA(waMassStorage, MSD_THREAD_STACK_SIZE);
|
||||
WORKING_AREA(waMassStorageUSBTransfer, MSD_THREAD_STACK_SIZE);
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
usb_msd_driver_state_t msdInit(USBDriver *usbp, BaseBlockDevice *bbdp, USBMassStorageDriver *msdp, const usbep_t ms_ep_number, const uint16_t msd_interface_number);
|
||||
usb_msd_driver_state_t msdStart(USBMassStorageDriver *msdp);
|
||||
usb_msd_driver_state_t msdStop(USBMassStorageDriver *msdp);
|
||||
void msdBulkInCallbackComplete(USBDriver *usbp, usbep_t ep);
|
||||
void msdBulkOutCallbackComplete(USBDriver *usbp, usbep_t ep);
|
||||
bool_t msdRequestsHook(USBDriver *usbp);
|
||||
bool_t msdRequestsHook2(USBDriver *usbp, USBMassStorageDriver *msdp);
|
||||
const char* usb_msd_driver_state_t_to_str(const usb_msd_driver_state_t driver_state);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HAL_USE_MASS_STORAGE_USB */
|
||||
|
||||
#endif /* _USB_MSD_H_ */
|
Loading…
Reference in New Issue