mirror of
https://github.com/ArteryTek/AT32F415_Firmware_Library.git
synced 2026-05-21 01:12:20 +00:00
upload version v2.0.0
This commit is contained in:
782
middlewares/usbd_class/msc/msc_bot_scsi.c
Normal file
782
middlewares/usbd_class/msc/msc_bot_scsi.c
Normal file
@@ -0,0 +1,782 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file msc_bot_scsi.c
|
||||
* @version v2.0.0
|
||||
* @date 2021-11-26
|
||||
* @brief usb mass storage bulk-only transport and scsi command
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
#include "msc_bot_scsi.h"
|
||||
#include "msc_diskio.h"
|
||||
|
||||
/** @addtogroup AT32F415_middlewares_usbd_class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_bot_scsi
|
||||
* @brief usb device class mass storage demo
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_bot_functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
msc_type msc_struct;
|
||||
cbw_type cbw_struct;
|
||||
csw_type csw_struct =
|
||||
{
|
||||
CSW_DCSWSIGNATURE,
|
||||
0x00,
|
||||
0x00,
|
||||
CSW_BCSWSTATUS_PASS,
|
||||
};
|
||||
|
||||
uint8_t page00_inquiry_data[] = {
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
};
|
||||
sense_type sense_data =
|
||||
{
|
||||
0x70,
|
||||
0x00,
|
||||
SENSE_KEY_ILLEGAL_REQUEST,
|
||||
0x00000000,
|
||||
0x0A,
|
||||
0x00000000,
|
||||
0x20,
|
||||
0x00,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
|
||||
uint8_t mode_sense6_data[8] =
|
||||
{
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
uint8_t mode_sense10_data[8] =
|
||||
{
|
||||
0x00,
|
||||
0x06,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
/**
|
||||
* @brief initialize bulk-only transport and scsi
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_init(void *udev)
|
||||
{
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
msc_struct.msc_state = MSC_STATE_MACHINE_IDLE;
|
||||
msc_struct.bot_status = MSC_BOT_STATE_IDLE;
|
||||
msc_struct.max_lun = MSC_SUPPORT_MAX_LUN - 1;
|
||||
|
||||
usb_flush_tx_fifo(pudev->usb_reg, USBD_MSC_BULK_IN_EPT&0x7F);
|
||||
|
||||
/* set out endpoint to receive status */
|
||||
usbd_ept_recv(pudev, USBD_MSC_BULK_OUT_EPT, (uint8_t *)&cbw_struct, CBW_CMD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reset bulk-only transport and scsi
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_reset(void *udev)
|
||||
{
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
msc_struct.msc_state = MSC_STATE_MACHINE_IDLE;
|
||||
msc_struct.bot_status = MSC_BOT_STATE_RECOVERY;
|
||||
msc_struct.max_lun = MSC_SUPPORT_MAX_LUN - 1;
|
||||
usb_flush_tx_fifo(pudev->usb_reg, USBD_MSC_BULK_IN_EPT&0x7F);
|
||||
|
||||
/* set out endpoint to receive status */
|
||||
usbd_ept_recv(pudev, USBD_MSC_BULK_OUT_EPT, (uint8_t *)&cbw_struct, CBW_CMD_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport data in handler
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param ept_num: endpoint number
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_datain_handler(void *udev, uint8_t ept_num)
|
||||
{
|
||||
switch(msc_struct.msc_state)
|
||||
{
|
||||
case MSC_STATE_MACHINE_DATA_IN:
|
||||
if(bot_scsi_cmd_process(udev) != USB_OK)
|
||||
{
|
||||
bot_scsi_send_csw(udev, CSW_BCSWSTATUS_FAILED);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_STATE_MACHINE_LAST_DATA:
|
||||
case MSC_STATE_MACHINE_SEND_DATA:
|
||||
bot_scsi_send_csw(udev, CSW_BCSWSTATUS_PASS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport data out handler
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param ept_num: endpoint number
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_dataout_handler(void *udev, uint8_t ept_num)
|
||||
{
|
||||
switch(msc_struct.msc_state)
|
||||
{
|
||||
case MSC_STATE_MACHINE_IDLE:
|
||||
bot_cbw_decode(udev);
|
||||
break;
|
||||
|
||||
case MSC_STATE_MACHINE_DATA_OUT:
|
||||
if(bot_scsi_cmd_process(udev) != USB_OK)
|
||||
{
|
||||
bot_scsi_send_csw(udev, CSW_BCSWSTATUS_FAILED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only cbw decode
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval none
|
||||
*/
|
||||
void bot_cbw_decode(void *udev)
|
||||
{
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
|
||||
csw_struct.dCSWTag = cbw_struct.dCBWTage;
|
||||
csw_struct.dCSWDataResidue = cbw_struct.dCBWDataTransferLength;
|
||||
|
||||
/* check param */
|
||||
if((cbw_struct.dCBWSignature != CBW_DCBWSIGNATURE) ||
|
||||
(usbd_get_recv_len(pudev, USBD_MSC_BULK_OUT_EPT) != CBW_CMD_LENGTH)
|
||||
|| (cbw_struct.bCBWLUN > MSC_SUPPORT_MAX_LUN) ||
|
||||
(cbw_struct.bCBWCBLength < 1) || (cbw_struct.bCBWCBLength > 16))
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
msc_struct.bot_status = MSC_BOT_STATE_ERROR;
|
||||
bot_scsi_stall(udev);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bot_scsi_cmd_process(udev) != USB_OK)
|
||||
{
|
||||
bot_scsi_stall(udev);
|
||||
}
|
||||
else if((msc_struct.msc_state != MSC_STATE_MACHINE_DATA_IN) &&
|
||||
(msc_struct.msc_state != MSC_STATE_MACHINE_DATA_OUT) &&
|
||||
(msc_struct.msc_state != MSC_STATE_MACHINE_LAST_DATA))
|
||||
{
|
||||
if(msc_struct.data_len == 0)
|
||||
{
|
||||
bot_scsi_send_csw(udev, CSW_BCSWSTATUS_PASS);
|
||||
}
|
||||
else if(msc_struct.data_len > 0)
|
||||
{
|
||||
bot_scsi_send_data(udev, msc_struct.data, msc_struct.data_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief send bot data
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param buffer: data buffer
|
||||
* @param len: data len
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_send_data(void *udev, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
uint32_t data_len = MIN(len, cbw_struct.dCBWDataTransferLength);
|
||||
|
||||
csw_struct.dCSWDataResidue -= data_len;
|
||||
csw_struct.bCSWStatus = CSW_BCSWSTATUS_PASS;
|
||||
|
||||
msc_struct.msc_state = MSC_STATE_MACHINE_SEND_DATA;
|
||||
|
||||
usbd_ept_send(pudev, USBD_MSC_BULK_IN_EPT,
|
||||
buffer, data_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief send command status
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param status: csw status
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_send_csw(void *udev, uint8_t status)
|
||||
{
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
|
||||
csw_struct.bCSWStatus = status;
|
||||
csw_struct.dCSWSignature = CSW_DCSWSIGNATURE;
|
||||
msc_struct.msc_state = MSC_STATE_MACHINE_IDLE;
|
||||
|
||||
usbd_ept_send(pudev, USBD_MSC_BULK_IN_EPT,
|
||||
(uint8_t *)&csw_struct, CSW_CMD_LENGTH);
|
||||
|
||||
usbd_ept_recv(pudev, USBD_MSC_BULK_OUT_EPT,
|
||||
(uint8_t *)&cbw_struct, CBW_CMD_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief send scsi sense code
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param sense_key: sense key
|
||||
* @param asc: asc
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_sense_code(void *udev, uint8_t sense_key, uint8_t asc)
|
||||
{
|
||||
sense_data.sense_key = sense_key;
|
||||
sense_data.asc = asc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief check address
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @param blk_offset: blk offset address
|
||||
* @param blk_count: blk number
|
||||
* @retval usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_check_address(void *udev, uint8_t lun, uint32_t blk_offset, uint32_t blk_count)
|
||||
{
|
||||
if((blk_offset + blk_count) > msc_struct.blk_nbr[lun])
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
|
||||
return USB_FAIL;
|
||||
}
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bot endpoint stall
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval none
|
||||
*/
|
||||
void bot_scsi_stall(void *udev)
|
||||
{
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
if((cbw_struct.dCBWDataTransferLength != 0) &&
|
||||
(cbw_struct.bmCBWFlags == 0) &&
|
||||
msc_struct.bot_status == MSC_BOT_STATE_IDLE)
|
||||
{
|
||||
usbd_set_stall(pudev, USBD_MSC_BULK_OUT_EPT);
|
||||
}
|
||||
usbd_set_stall(pudev, USBD_MSC_BULK_IN_EPT);
|
||||
|
||||
if(msc_struct.bot_status == MSC_BOT_STATE_ERROR)
|
||||
{
|
||||
usbd_ept_recv(pudev, USBD_MSC_BULK_OUT_EPT,
|
||||
(uint8_t *)&cbw_struct, CBW_CMD_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command test unit
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_test_unit(void *udev, uint8_t lun)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
if(cbw_struct.dCBWDataTransferLength != 0)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.data_len = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command inquiry
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_inquiry(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t *pdata;
|
||||
uint32_t trans_len = 0;
|
||||
usb_sts_type status = USB_OK;
|
||||
|
||||
if(cbw_struct.CBWCB[1] & 0x01)
|
||||
{
|
||||
pdata = page00_inquiry_data;
|
||||
trans_len = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata = get_inquiry(lun);
|
||||
if(cbw_struct.dCBWDataTransferLength < SCSI_INQUIRY_DATA_LENGTH)
|
||||
{
|
||||
trans_len = cbw_struct.dCBWDataTransferLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
trans_len = SCSI_INQUIRY_DATA_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
msc_struct.data_len = trans_len;
|
||||
while(trans_len)
|
||||
{
|
||||
trans_len --;
|
||||
msc_struct.data[trans_len] = pdata[trans_len];
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command start stop
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_start_stop(void *udev, uint8_t lun)
|
||||
{
|
||||
msc_struct.data_len = 0;
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command meidum removal
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_allow_medium_removal(void *udev, uint8_t lun)
|
||||
{
|
||||
msc_struct.data_len = 0;
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command mode sense6
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_mode_sense6(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t data_len = 8;
|
||||
msc_struct.data_len = 8;
|
||||
while(data_len)
|
||||
{
|
||||
data_len --;
|
||||
msc_struct.data[data_len] = mode_sense6_data[data_len];
|
||||
};
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command mode sense10
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_mode_sense10(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t data_len = 8;
|
||||
msc_struct.data_len = 8;
|
||||
while(data_len)
|
||||
{
|
||||
data_len --;
|
||||
msc_struct.data[data_len] = mode_sense10_data[data_len];
|
||||
};
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command capacity
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_capacity(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t *pdata = msc_struct.data;
|
||||
|
||||
msc_disk_capacity(lun, &msc_struct.blk_nbr[lun], &msc_struct.blk_size[lun]);
|
||||
|
||||
pdata[0] = (uint8_t)((msc_struct.blk_nbr[lun] - 1) >> 24);
|
||||
pdata[1] = (uint8_t)((msc_struct.blk_nbr[lun] - 1) >> 16);
|
||||
pdata[2] = (uint8_t)((msc_struct.blk_nbr[lun] - 1) >> 8);
|
||||
pdata[3] = (uint8_t)((msc_struct.blk_nbr[lun] - 1));
|
||||
|
||||
pdata[4] = (uint8_t)((msc_struct.blk_size[lun]) >> 24);
|
||||
pdata[5] = (uint8_t)((msc_struct.blk_size[lun]) >> 16);
|
||||
pdata[6] = (uint8_t)((msc_struct.blk_size[lun]) >> 8);
|
||||
pdata[7] = (uint8_t)((msc_struct.blk_size[lun]));
|
||||
|
||||
msc_struct.data_len = 8;
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command format capacity
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_format_capacity(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t *pdata = msc_struct.data;
|
||||
|
||||
pdata[0] = 0;
|
||||
pdata[1] = 0;
|
||||
pdata[2] = 0;
|
||||
pdata[3] = 0x08;
|
||||
|
||||
msc_disk_capacity(lun, &msc_struct.blk_nbr[lun], &msc_struct.blk_size[lun]);
|
||||
|
||||
pdata[4] = (uint8_t)((msc_struct.blk_nbr[lun] - 1) >> 24);
|
||||
pdata[5] = (uint8_t)((msc_struct.blk_nbr[lun] - 1) >> 16);
|
||||
pdata[6] = (uint8_t)((msc_struct.blk_nbr[lun] - 1) >> 8);
|
||||
pdata[7] = (uint8_t)((msc_struct.blk_nbr[lun] - 1));
|
||||
|
||||
pdata[8] = 0x02;
|
||||
|
||||
pdata[9] = (uint8_t)((msc_struct.blk_size[lun]) >> 16);
|
||||
pdata[10] = (uint8_t)((msc_struct.blk_size[lun]) >> 8);
|
||||
pdata[11] = (uint8_t)((msc_struct.blk_size[lun]));
|
||||
|
||||
msc_struct.data_len = 12;
|
||||
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command request sense
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_request_sense(void *udev, uint8_t lun)
|
||||
{
|
||||
uint32_t trans_len = 0x12;
|
||||
uint8_t *pdata = msc_struct.data;
|
||||
uint8_t *sdata = (uint8_t *)&sense_data;
|
||||
|
||||
while(trans_len)
|
||||
{
|
||||
trans_len --;
|
||||
pdata[trans_len] = sdata[trans_len];
|
||||
}
|
||||
|
||||
if(cbw_struct.dCBWDataTransferLength < REQ_SENSE_STANDARD_DATA_LEN)
|
||||
{
|
||||
msc_struct.data_len = cbw_struct.dCBWDataTransferLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
msc_struct.data_len = REQ_SENSE_STANDARD_DATA_LEN;
|
||||
}
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command verify
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_verify(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t *cmd = cbw_struct.CBWCB;
|
||||
if((cbw_struct.CBWCB[1] & 0x02) == 0x02)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.blk_addr = cmd[2] << 24 | cmd[3] << 16 | cmd[4] << 8 | cmd[5];
|
||||
msc_struct.blk_len = cmd[7] << 8 | cmd[8];
|
||||
|
||||
if(bot_scsi_check_address(udev, lun, msc_struct.blk_addr, msc_struct.blk_len) != USB_OK)
|
||||
{
|
||||
return USB_FAIL;
|
||||
}
|
||||
msc_struct.data_len = 0;
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command read10
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_read10(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t *cmd = cbw_struct.CBWCB;
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
uint32_t len;
|
||||
|
||||
if(msc_struct.msc_state == MSC_STATE_MACHINE_IDLE)
|
||||
{
|
||||
if((cbw_struct.bmCBWFlags & 0x80) != 0x80)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.blk_addr = cmd[2] << 24 | cmd[3] << 16 | cmd[4] << 8 | cmd[5];
|
||||
msc_struct.blk_len = cmd[7] << 8 | cmd[8];
|
||||
|
||||
if(bot_scsi_check_address(udev, lun, msc_struct.blk_addr, msc_struct.blk_len) != USB_OK)
|
||||
{
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.blk_addr *= msc_struct.blk_size[lun];
|
||||
msc_struct.blk_len *= msc_struct.blk_size[lun];
|
||||
|
||||
if(cbw_struct.dCBWDataTransferLength != msc_struct.blk_len)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
return USB_FAIL;
|
||||
}
|
||||
msc_struct.msc_state = MSC_STATE_MACHINE_DATA_IN;
|
||||
}
|
||||
msc_struct.data_len = MSC_MAX_DATA_BUF_LEN;
|
||||
|
||||
len = MIN(msc_struct.blk_len, MSC_MAX_DATA_BUF_LEN);
|
||||
if( msc_disk_read(lun, msc_struct.blk_addr, msc_struct.data, len) != USB_OK)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_HARDWARE_ERROR, MEDIUM_NOT_PRESENT);
|
||||
return USB_FAIL;
|
||||
}
|
||||
usbd_ept_send(pudev, USBD_MSC_BULK_IN_EPT, msc_struct.data, len);
|
||||
msc_struct.blk_addr += len;
|
||||
msc_struct.blk_len -= len;
|
||||
|
||||
csw_struct.dCSWDataResidue -= len;
|
||||
if(msc_struct.blk_len == 0)
|
||||
{
|
||||
msc_struct.msc_state = MSC_STATE_MACHINE_LAST_DATA;
|
||||
}
|
||||
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command write10
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param lun: logical units number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_write10(void *udev, uint8_t lun)
|
||||
{
|
||||
uint8_t *cmd = cbw_struct.CBWCB;
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
uint32_t len;
|
||||
|
||||
if(msc_struct.msc_state == MSC_STATE_MACHINE_IDLE)
|
||||
{
|
||||
if((cbw_struct.bmCBWFlags & 0x80) == 0x80)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.blk_addr = cmd[2] << 24 | cmd[3] << 16 | cmd[4] << 8 | cmd[5];
|
||||
msc_struct.blk_len = cmd[7] << 8 | cmd[8];
|
||||
|
||||
if(bot_scsi_check_address(udev, lun, msc_struct.blk_addr, msc_struct.blk_len) != USB_OK)
|
||||
{
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.blk_addr *= msc_struct.blk_size[lun];
|
||||
msc_struct.blk_len *= msc_struct.blk_size[lun];
|
||||
|
||||
if(cbw_struct.dCBWDataTransferLength != msc_struct.blk_len)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.msc_state = MSC_STATE_MACHINE_DATA_OUT;
|
||||
len = MIN(msc_struct.blk_len, MSC_MAX_DATA_BUF_LEN);
|
||||
usbd_ept_recv(pudev, USBD_MSC_BULK_OUT_EPT, (uint8_t *)msc_struct.data, len);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
len = MIN(msc_struct.blk_len, MSC_MAX_DATA_BUF_LEN);
|
||||
if(msc_disk_write(lun, msc_struct.blk_addr, msc_struct.data, len) != USB_OK)
|
||||
{
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_HARDWARE_ERROR, MEDIUM_NOT_PRESENT);
|
||||
return USB_FAIL;
|
||||
}
|
||||
|
||||
msc_struct.blk_addr += len;
|
||||
msc_struct.blk_len -= len;
|
||||
|
||||
csw_struct.dCSWDataResidue -= len;
|
||||
|
||||
if(msc_struct.blk_len == 0)
|
||||
{
|
||||
bot_scsi_send_csw(udev, CSW_BCSWSTATUS_PASS);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = MIN(msc_struct.blk_len, MSC_MAX_DATA_BUF_LEN);
|
||||
usbd_ept_recv(pudev, USBD_MSC_BULK_OUT_EPT, (uint8_t *)msc_struct.data, len);
|
||||
}
|
||||
}
|
||||
return USB_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief clear feature
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param etp_num: endpoint number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
void bot_scsi_clear_feature(void *udev, uint8_t ept_num)
|
||||
{
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
|
||||
if(msc_struct.bot_status == MSC_BOT_STATE_ERROR)
|
||||
{
|
||||
usbd_set_stall(pudev, USBD_MSC_BULK_IN_EPT);
|
||||
msc_struct.bot_status = MSC_BOT_STATE_IDLE;
|
||||
}
|
||||
else if(((ept_num & 0x80) == 0x80) && (msc_struct.bot_status != MSC_BOT_STATE_RECOVERY))
|
||||
{
|
||||
bot_scsi_send_csw(udev, CSW_BCSWSTATUS_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bulk-only transport scsi command process
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type bot_scsi_cmd_process(void *udev)
|
||||
{
|
||||
usb_sts_type status = USB_FAIL;
|
||||
switch(cbw_struct.CBWCB[0])
|
||||
{
|
||||
case MSC_CMD_INQUIRY:
|
||||
status = bot_scsi_inquiry(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_START_STOP:
|
||||
status = bot_scsi_start_stop(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_MODE_SENSE6:
|
||||
status = bot_scsi_mode_sense6(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_MODE_SENSE10:
|
||||
status = bot_scsi_mode_sense10(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_ALLOW_MEDIUM_REMOVAL:
|
||||
status = bot_scsi_allow_medium_removal(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_READ_10:
|
||||
status = bot_scsi_read10(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_READ_CAPACITY:
|
||||
status = bot_scsi_capacity(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_REQUEST_SENSE:
|
||||
status = bot_scsi_request_sense(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_TEST_UNIT:
|
||||
status = bot_scsi_test_unit(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_VERIFY:
|
||||
status = bot_scsi_verify(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_WRITE_10:
|
||||
status = bot_scsi_write10(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
case MSC_CMD_READ_FORMAT_CAPACITY:
|
||||
status = bot_scsi_format_capacity(udev, cbw_struct.bCBWLUN);
|
||||
break;
|
||||
|
||||
default:
|
||||
bot_scsi_sense_code(udev, SENSE_KEY_ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
status = USB_FAIL;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
250
middlewares/usbd_class/msc/msc_bot_scsi.h
Normal file
250
middlewares/usbd_class/msc/msc_bot_scsi.h
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file msc_bot_scsi.h
|
||||
* @version v2.0.0
|
||||
* @date 2021-11-26
|
||||
* @brief usb mass storage bulk-only transport and scsi command header file
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
/* define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MSC_BOT_SCSI_H
|
||||
#define __MSC_BOT_SCSI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "msc_class.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/** @addtogroup AT32F415_middlewares_usbd_class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USB_msc_bot_scsi
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_bot_scsi_definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MSC_SUPPORT_MAX_LUN 1
|
||||
#define MSC_MAX_DATA_BUF_LEN 4096
|
||||
|
||||
#define MSC_CMD_FORMAT_UNIT 0x04
|
||||
#define MSC_CMD_INQUIRY 0x12
|
||||
#define MSC_CMD_START_STOP 0x1B
|
||||
#define MSC_CMD_MODE_SENSE6 0x1A
|
||||
#define MSC_CMD_MODE_SENSE10 0x5A
|
||||
#define MSC_CMD_ALLOW_MEDIUM_REMOVAL 0x1E
|
||||
#define MSC_CMD_READ_10 0x28
|
||||
#define MSC_CMD_READ_12 0xA8
|
||||
#define MSC_CMD_READ_CAPACITY 0x25
|
||||
#define MSC_CMD_READ_FORMAT_CAPACITY 0x23
|
||||
#define MSC_CMD_REQUEST_SENSE 0x03
|
||||
#define MSC_CMD_TEST_UNIT 0x00
|
||||
#define MSC_CMD_VERIFY 0x2F
|
||||
#define MSC_CMD_WRITE_10 0x2A
|
||||
#define MSC_CMD_WRITE_12 0xAA
|
||||
#define MSC_CMD_WRITE_VERIFY 0x2E
|
||||
|
||||
#define MSC_REQ_GET_MAX_LUN 0xFE /*!< get max lun */
|
||||
#define MSC_REQ_BO_RESET 0xFF /*!< bulk only mass storage reset */
|
||||
|
||||
#define SET_LINE_CODING 0x20
|
||||
#define GET_LINE_CODING 0x21
|
||||
|
||||
#define CBW_CMD_LENGTH 31
|
||||
#define CBW_DCBWSIGNATURE 0x43425355
|
||||
#define CBW_BMCBWFLAGS_DIR_OUT 0x00
|
||||
#define CBW_BMCBWFLAGS_DIR_IN 0x80
|
||||
|
||||
#define CSW_CMD_LENGTH 13
|
||||
#define CSW_DCSWSIGNATURE 0x53425355
|
||||
#define CSW_BCSWSTATUS_PASS 0x00
|
||||
#define CSW_BCSWSTATUS_FAILED 0x01
|
||||
#define CSW_BCSWSTATUS_PHASE_ERR 0x02
|
||||
|
||||
#define MSC_STATE_MACHINE_CMD 0x00
|
||||
#define MSC_STATE_MACHINE_DATA_IN 0x01
|
||||
#define MSC_STATE_MACHINE_DATA_OUT 0x02
|
||||
#define MSC_STATE_MACHINE_SEND_DATA 0x03
|
||||
#define MSC_STATE_MACHINE_LAST_DATA 0x04
|
||||
#define MSC_STATE_MACHINE_STATUS 0x05
|
||||
#define MSC_STATE_MACHINE_FAILED 0x06
|
||||
#define MSC_STATE_MACHINE_IDLE 0x07
|
||||
|
||||
#define MSC_BOT_STATE_IDLE 0x00
|
||||
#define MSC_BOT_STATE_RECOVERY 0x01
|
||||
#define MSC_BOT_STATE_ERROR 0x02
|
||||
|
||||
#define REQ_SENSE_STANDARD_DATA_LEN 0x12
|
||||
#define SENSE_KEY_NO_SENSE 0x00
|
||||
#define SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
#define SENSE_KEY_NOT_READY 0x02
|
||||
#define SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
#define SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
#define SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
#define SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
#define SENSE_KEY_DATA_PROTECT 0x07
|
||||
#define SENSE_KEY_BLANK_CHECK 0x08
|
||||
#define SENSE_KEY_VENDERO_SPECIFIC 0x09
|
||||
#define SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
#define SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
#define SENSE_KEY_MISCOMPARE 0x0E
|
||||
|
||||
|
||||
#define INVALID_COMMAND 0x20
|
||||
#define INVALID_FIELED_IN_COMMAND 0x24
|
||||
#define PARAMETER_LIST_LENGTH_ERROR 0x1A
|
||||
#define INVALID_FIELD_IN_PARAMETER_LIST 0x26
|
||||
#define ADDRESS_OUT_OF_RANGE 0x21
|
||||
#define MEDIUM_NOT_PRESENT 0x3A
|
||||
#define MEDIUM_HAVE_CHANGED 0x28
|
||||
|
||||
#define SCSI_INQUIRY_DATA_LENGTH 36
|
||||
|
||||
/**
|
||||
* @brief typical command block description
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t lun;
|
||||
uint32_t address;
|
||||
uint8_t reserved1;
|
||||
uint32_t alloc_length;
|
||||
uint16_t reserved2;
|
||||
}cbd_typical_type;
|
||||
|
||||
/**
|
||||
* @brief extended command block description
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t lun;
|
||||
uint32_t address;
|
||||
uint8_t reserved1;
|
||||
uint32_t alloc_length;
|
||||
uint16_t reserved2;
|
||||
}cbd_extended_type;
|
||||
|
||||
/**
|
||||
* @brief command block wrapper
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dCBWSignature;
|
||||
uint32_t dCBWTage;
|
||||
uint32_t dCBWDataTransferLength;
|
||||
uint8_t bmCBWFlags;
|
||||
uint8_t bCBWLUN;
|
||||
uint8_t bCBWCBLength;
|
||||
uint8_t CBWCB[16];
|
||||
}cbw_type;
|
||||
|
||||
/**
|
||||
* @brief command block wrapper
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dCSWSignature;
|
||||
uint32_t dCSWTag;
|
||||
uint32_t dCSWDataResidue;
|
||||
uint32_t bCSWStatus;
|
||||
}csw_type;
|
||||
|
||||
/**
|
||||
* @brief request sense standard data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t err_code;
|
||||
uint8_t reserved1;
|
||||
uint8_t sense_key;
|
||||
uint32_t information;
|
||||
uint8_t as_length;
|
||||
uint32_t reserved2;
|
||||
uint8_t asc;
|
||||
uint8_t ascq;
|
||||
uint32_t reserved3;
|
||||
}sense_type;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t msc_state;
|
||||
uint8_t bot_status;
|
||||
uint8_t max_lun;
|
||||
|
||||
uint32_t blk_nbr[MSC_SUPPORT_MAX_LUN];
|
||||
uint32_t blk_size[MSC_SUPPORT_MAX_LUN];
|
||||
|
||||
uint32_t blk_addr;
|
||||
uint32_t blk_len;
|
||||
|
||||
uint32_t data_len;
|
||||
uint8_t data[MSC_MAX_DATA_BUF_LEN];
|
||||
}msc_type;
|
||||
|
||||
void bot_scsi_init(void *udev);
|
||||
void bot_scsi_reset(void *udev);
|
||||
void bot_scsi_datain_handler(void *pudev, uint8_t ept_num);
|
||||
void bot_scsi_dataout_handler(void *pudev, uint8_t ept_num);
|
||||
void bot_cbw_decode(void *udev);
|
||||
void bot_scsi_send_data(void *udev, uint8_t *buffer, uint32_t len);
|
||||
void bot_scsi_send_csw(void *udev, uint8_t status);
|
||||
void bot_scsi_sense_code(void *udev, uint8_t sense_key, uint8_t asc);
|
||||
usb_sts_type bot_scsi_check_address(void *udev, uint8_t lun, uint32_t blk_offset, uint32_t blk_count);
|
||||
void bot_scsi_stall(void *udev);
|
||||
usb_sts_type bot_scsi_cmd_process(void *udev);
|
||||
|
||||
usb_sts_type bot_scsi_test_unit(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_inquiry(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_start_stop(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_allow_medium_removal(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_mode_sense6(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_mode_sense10(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_read10(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_capacity(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_format_capacity(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_request_sense(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_verify(void *udev, uint8_t lun);
|
||||
usb_sts_type bot_scsi_write10(void *udev, uint8_t lun);
|
||||
void bot_scsi_clear_feature(void *udev, uint8_t ept_num);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
302
middlewares/usbd_class/msc/msc_class.c
Normal file
302
middlewares/usbd_class/msc/msc_class.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file msc_class.c
|
||||
* @version v2.0.0
|
||||
* @date 2021-11-26
|
||||
* @brief usb msc class type
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "msc_class.h"
|
||||
#include "msc_desc.h"
|
||||
#include "msc_bot_scsi.h"
|
||||
|
||||
/** @addtogroup AT32F415_middlewares_usbd_class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_class
|
||||
* @brief usb device class msc demo
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_class_private_functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
usb_sts_type class_init_handler(void *udev);
|
||||
usb_sts_type class_clear_handler(void *udev);
|
||||
usb_sts_type class_setup_handler(void *udev, usb_setup_type *setup);
|
||||
usb_sts_type class_ept0_tx_handler(void *udev);
|
||||
usb_sts_type class_ept0_rx_handler(void *udev);
|
||||
usb_sts_type class_in_handler(void *udev, uint8_t ept_num);
|
||||
usb_sts_type class_out_handler(void *udev, uint8_t ept_num);
|
||||
usb_sts_type class_sof_handler(void *udev);
|
||||
usb_sts_type class_event_handler(void *udev, usbd_event_type event);
|
||||
|
||||
/* usb rx and tx buffer */
|
||||
static uint32_t alt_setting = 0;
|
||||
|
||||
extern msc_type msc_struct;
|
||||
extern cbw_type cbw_struct;
|
||||
extern csw_type csw_struct;
|
||||
|
||||
/* usb device class handler */
|
||||
usbd_class_handler msc_class_handler =
|
||||
{
|
||||
class_init_handler,
|
||||
class_clear_handler,
|
||||
class_setup_handler,
|
||||
class_ept0_tx_handler,
|
||||
class_ept0_rx_handler,
|
||||
class_in_handler,
|
||||
class_out_handler,
|
||||
class_sof_handler,
|
||||
class_event_handler,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief initialize usb endpoint
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_init_handler(void *udev)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
|
||||
/* open in endpoint */
|
||||
usbd_ept_open(pudev, USBD_MSC_BULK_IN_EPT, EPT_BULK_TYPE, USBD_OUT_MAXPACKET_SIZE);
|
||||
|
||||
/* open out endpoint */
|
||||
usbd_ept_open(pudev, USBD_MSC_BULK_OUT_EPT, EPT_BULK_TYPE, USBD_OUT_MAXPACKET_SIZE);
|
||||
|
||||
bot_scsi_init(udev);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief clear endpoint or other state
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_clear_handler(void *udev)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
|
||||
/* close in endpoint */
|
||||
usbd_ept_close(pudev, USBD_MSC_BULK_IN_EPT);
|
||||
|
||||
/* close out endpoint */
|
||||
usbd_ept_close(pudev, USBD_MSC_BULK_OUT_EPT);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb device class setup request handler
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param setup: setup packet
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_setup_handler(void *udev, usb_setup_type *setup)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
switch(setup->bmRequestType & USB_REQ_TYPE_RESERVED)
|
||||
{
|
||||
/* class request */
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
|
||||
switch(setup->bRequest)
|
||||
{
|
||||
case MSC_REQ_GET_MAX_LUN:
|
||||
usbd_ctrl_send(pudev, &msc_struct.max_lun, 1);
|
||||
break;
|
||||
case MSC_REQ_BO_RESET:
|
||||
bot_scsi_reset(udev);
|
||||
usbd_ctrl_send_status(pudev);
|
||||
break;
|
||||
default:
|
||||
usbd_ctrl_unsupport(pudev);
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
/* standard request */
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
|
||||
switch(setup->bRequest)
|
||||
{
|
||||
case USB_STD_REQ_GET_DESCRIPTOR:
|
||||
usbd_ctrl_unsupport(pudev);
|
||||
break;
|
||||
case USB_STD_REQ_GET_INTERFACE:
|
||||
usbd_ctrl_send(pudev, (uint8_t *)&alt_setting, 1);
|
||||
break;
|
||||
case USB_STD_REQ_SET_INTERFACE:
|
||||
alt_setting = setup->wValue;
|
||||
break;
|
||||
case USB_STD_REQ_CLEAR_FEATURE:
|
||||
usbd_ept_close(pudev, (uint8_t)setup->wIndex);
|
||||
|
||||
if((setup->wIndex & 0x80) == 0x80)
|
||||
{
|
||||
usb_flush_tx_fifo(pudev->usb_reg, setup->wIndex & 0x7F);
|
||||
usbd_ept_open(pudev, (uint8_t)setup->wIndex, EPT_BULK_TYPE, USBD_IN_MAXPACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbd_ept_open(pudev, (uint8_t)setup->wIndex, EPT_BULK_TYPE, USBD_OUT_MAXPACKET_SIZE);
|
||||
}
|
||||
bot_scsi_clear_feature(udev, setup->wIndex);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usbd_ctrl_unsupport(pudev);
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb device endpoint 0 in status stage complete
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_ept0_tx_handler(void *udev)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
|
||||
/* ...user code... */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb device endpoint 0 out status stage complete
|
||||
* @param udev: usb device core handler type
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_ept0_rx_handler(void *udev)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
uint32_t recv_len = usbd_get_recv_len(pudev, 0);
|
||||
/* ...user code... */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb device transmision complete handler
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param ept_num: endpoint number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_in_handler(void *udev, uint8_t ept_num)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
usbd_core_type *pudev = (usbd_core_type *)udev;
|
||||
usb_flush_tx_fifo(pudev->usb_reg, ept_num&0x7F);
|
||||
// if(msc_struct.msc_state != MSC_STATE_MACHINE_IDLE)
|
||||
// {
|
||||
// bot_scsi_datain_handler(udev, ept_num);
|
||||
// }
|
||||
bot_scsi_datain_handler(udev, ept_num);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb device endpoint receive data
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param ept_num: endpoint number
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_out_handler(void *udev, uint8_t ept_num)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
// if(msc_struct.msc_state == MSC_STATE_MACHINE_IDLE)
|
||||
// msc_struct.msc_state = MSC_STATE_MACHINE_CMD;
|
||||
bot_scsi_dataout_handler(udev, ept_num);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb device sof handler
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_sof_handler(void *udev)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
|
||||
/* ...user code... */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb device event handler
|
||||
* @param udev: to the structure of usbd_core_type
|
||||
* @param event: usb device event
|
||||
* @retval status of usb_sts_type
|
||||
*/
|
||||
usb_sts_type class_event_handler(void *udev, usbd_event_type event)
|
||||
{
|
||||
usb_sts_type status = USB_OK;
|
||||
switch(event)
|
||||
{
|
||||
case USBD_RESET_EVENT:
|
||||
|
||||
/* ...user code... */
|
||||
|
||||
break;
|
||||
case USBD_SUSPEND_EVENT:
|
||||
|
||||
/* ...user code... */
|
||||
|
||||
break;
|
||||
case USBD_WAKEUP_EVENT:
|
||||
/* ...user code... */
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
72
middlewares/usbd_class/msc/msc_class.h
Normal file
72
middlewares/usbd_class/msc/msc_class.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file msc_class.h
|
||||
* @version v2.0.0
|
||||
* @date 2021-11-26
|
||||
* @brief usb msc class file
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
/* define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MSC_CLASS_H
|
||||
#define __MSC_CLASS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "usb_std.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/** @addtogroup AT32F415_middlewares_usbd_class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USB_msc_class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_class_definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USBD_MSC_BULK_IN_EPT 0x81
|
||||
#define USBD_MSC_BULK_OUT_EPT 0x01
|
||||
|
||||
#define USBD_IN_MAXPACKET_SIZE 0x40
|
||||
#define USBD_OUT_MAXPACKET_SIZE 0x40
|
||||
|
||||
|
||||
extern usbd_class_handler msc_class_handler;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
392
middlewares/usbd_class/msc/msc_desc.c
Normal file
392
middlewares/usbd_class/msc/msc_desc.c
Normal file
@@ -0,0 +1,392 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file msc_desc.c
|
||||
* @version v2.0.0
|
||||
* @date 2021-11-26
|
||||
* @brief usb msc device descriptor
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
#include "stdio.h"
|
||||
#include "usb_std.h"
|
||||
#include "usbd_sdr.h"
|
||||
#include "usbd_core.h"
|
||||
#include "msc_desc.h"
|
||||
|
||||
/** @addtogroup AT32F415_middlewares_usbd_class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_desc
|
||||
* @brief usb device msc descriptor
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_desc_private_functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
usbd_desc_t *get_device_descriptor(void);
|
||||
usbd_desc_t *get_device_qualifier(void);
|
||||
usbd_desc_t *get_device_configuration(void);
|
||||
usbd_desc_t *get_device_other_speed(void);
|
||||
usbd_desc_t *get_device_lang_id(void);
|
||||
usbd_desc_t *get_device_manufacturer_string(void);
|
||||
usbd_desc_t *get_device_product_string(void);
|
||||
usbd_desc_t *get_device_serial_string(void);
|
||||
usbd_desc_t *get_device_interface_string(void);
|
||||
usbd_desc_t *get_device_config_string(void);
|
||||
|
||||
uint16_t usbd_unicode_convert(uint8_t *string, uint8_t *unicode_buf);
|
||||
static void usbd_int_to_unicode (uint32_t value , uint8_t *pbuf , uint8_t len);
|
||||
static void get_serial_num(void);
|
||||
static uint8_t g_usbd_desc_buffer[256];
|
||||
|
||||
/**
|
||||
* @brief device descriptor handler structure
|
||||
*/
|
||||
usbd_desc_handler msc_desc_handler =
|
||||
{
|
||||
get_device_descriptor,
|
||||
get_device_qualifier,
|
||||
get_device_configuration,
|
||||
get_device_other_speed,
|
||||
get_device_lang_id,
|
||||
get_device_manufacturer_string,
|
||||
get_device_product_string,
|
||||
get_device_serial_string,
|
||||
get_device_interface_string,
|
||||
get_device_config_string,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief usb device standard descriptor
|
||||
*/
|
||||
uint8_t g_usbd_descriptor[USB_DEVICE_DESC_LEN] =
|
||||
{
|
||||
USB_DEVICE_DESC_LEN, /* bLength */
|
||||
USB_DESCIPTOR_TYPE_DEVICE, /* bDescriptorType */
|
||||
0x00, /* bcdUSB */
|
||||
0x02,
|
||||
0x00, /* bDeviceClass */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
|
||||
LBYTE(USBD_VENDOR_ID), /* idVendor */
|
||||
HBYTE(USBD_VENDOR_ID), /* idVendor */
|
||||
LBYTE(USBD_PRODUCT_ID), /* idProduct */
|
||||
HBYTE(USBD_PRODUCT_ID), /* idProduct */
|
||||
0x00, /* bcdDevice rel. 2.00 */
|
||||
0x02,
|
||||
USB_MFC_STRING, /* Index of manufacturer string */
|
||||
USB_PRODUCT_STRING, /* Index of product string */
|
||||
USB_SERIAL_STRING, /* Index of serial number string */
|
||||
1 /* bNumConfigurations */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief usb configuration standard descriptor
|
||||
*/
|
||||
uint8_t g_usbd_configuration[USBD_CONFIG_DESC_SIZE] =
|
||||
{
|
||||
USB_DEVICE_CFG_DESC_LEN, /* bLength: configuration descriptor size */
|
||||
USB_DESCIPTOR_TYPE_CONFIGURATION, /* bDescriptorType: configuration */
|
||||
LBYTE(USBD_CONFIG_DESC_SIZE), /* wTotalLength: bytes returned */
|
||||
HBYTE(USBD_CONFIG_DESC_SIZE), /* wTotalLength: bytes returned */
|
||||
0x01, /* bNumInterfaces: 2 interface */
|
||||
0x01, /* bConfigurationValue: configuration value */
|
||||
0x04, /* iConfiguration: index of string descriptor describing
|
||||
the configuration */
|
||||
0xC0, /* bmAttributes: self powered */
|
||||
0x32, /* MaxPower 100 mA: this current is used for detecting vbus */
|
||||
|
||||
USB_DEVICE_IF_DESC_LEN, /* bLength: interface descriptor size */
|
||||
USB_DESCIPTOR_TYPE_INTERFACE, /* bDescriptorType: interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: number of interface */
|
||||
0x00, /* bAlternateSetting: alternate set */
|
||||
0x02, /* bNumEndpoints: number of endpoints */
|
||||
USB_CLASS_CODE_MSC, /* bInterfaceClass: msc class code */
|
||||
0x06, /* bInterfaceSubClass: subclass code scsi */
|
||||
0x50, /* bInterfaceProtocol: protocol code BBB */
|
||||
0x05, /* iInterface: index of string descriptor */
|
||||
|
||||
USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
|
||||
USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
|
||||
USBD_MSC_BULK_IN_EPT, /* bEndpointAddress: the address of endpoint on usb device described by this descriptor */
|
||||
USB_EPT_DESC_BULK, /* bmAttributes: endpoint attributes */
|
||||
LBYTE(USBD_IN_MAXPACKET_SIZE),
|
||||
HBYTE(USBD_IN_MAXPACKET_SIZE), /* wMaxPacketSize: maximum packe size this endpoint */
|
||||
0x00, /* bInterval: interval for polling endpoint for data transfers */
|
||||
|
||||
USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
|
||||
USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
|
||||
USBD_MSC_BULK_OUT_EPT, /* bEndpointAddress: the address of endpoint on usb device described by this descriptor */
|
||||
USB_EPT_DESC_BULK, /* bmAttributes: endpoint attributes */
|
||||
LBYTE(USBD_OUT_MAXPACKET_SIZE),
|
||||
HBYTE(USBD_OUT_MAXPACKET_SIZE), /* wMaxPacketSize: maximum packe size this endpoint */
|
||||
0x00, /* bInterval: interval for polling endpoint for data transfers */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief usb string lang id
|
||||
*/
|
||||
uint8_t g_string_lang_id[USBD_SIZ_STRING_LANGID] =
|
||||
{
|
||||
USBD_SIZ_STRING_LANGID,
|
||||
USB_DESCIPTOR_TYPE_STRING,
|
||||
0x09,
|
||||
0x04,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief usb string serial
|
||||
*/
|
||||
uint8_t g_string_serial[USBD_SIZ_STRING_SERIAL] =
|
||||
{
|
||||
USBD_SIZ_STRING_SERIAL,
|
||||
USB_DESCIPTOR_TYPE_STRING,
|
||||
};
|
||||
|
||||
|
||||
/* device descriptor */
|
||||
usbd_desc_t device_descriptor =
|
||||
{
|
||||
USB_DEVICE_DESC_LEN,
|
||||
g_usbd_descriptor
|
||||
};
|
||||
|
||||
/* config descriptor */
|
||||
usbd_desc_t config_descriptor =
|
||||
{
|
||||
USBD_CONFIG_DESC_SIZE,
|
||||
g_usbd_configuration
|
||||
};
|
||||
|
||||
/* langid descriptor */
|
||||
usbd_desc_t langid_descriptor =
|
||||
{
|
||||
USBD_SIZ_STRING_LANGID,
|
||||
g_string_lang_id
|
||||
};
|
||||
|
||||
/* serial descriptor */
|
||||
usbd_desc_t serial_descriptor =
|
||||
{
|
||||
USBD_SIZ_STRING_SERIAL,
|
||||
g_string_serial
|
||||
};
|
||||
|
||||
usbd_desc_t vp_desc;
|
||||
|
||||
/**
|
||||
* @brief standard usb unicode convert
|
||||
* @param string: source string
|
||||
* @param unicode_buf: unicode buffer
|
||||
* @retval length
|
||||
*/
|
||||
uint16_t usbd_unicode_convert(uint8_t *string, uint8_t *unicode_buf)
|
||||
{
|
||||
uint16_t str_len = 0, id_pos = 2;
|
||||
uint8_t *tmp_str = string;
|
||||
|
||||
while(*tmp_str != '\0')
|
||||
{
|
||||
str_len ++;
|
||||
unicode_buf[id_pos ++] = *tmp_str ++;
|
||||
unicode_buf[id_pos ++] = 0x00;
|
||||
}
|
||||
|
||||
str_len = str_len * 2 + 2;
|
||||
unicode_buf[0] = (uint8_t)str_len;
|
||||
unicode_buf[1] = USB_DESCIPTOR_TYPE_STRING;
|
||||
|
||||
return str_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb int convert to unicode
|
||||
* @param value: int value
|
||||
* @param pbus: unicode buffer
|
||||
* @param len: length
|
||||
* @retval none
|
||||
*/
|
||||
static void usbd_int_to_unicode (uint32_t value , uint8_t *pbuf , uint8_t len)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
|
||||
for( idx = 0 ; idx < len ; idx ++)
|
||||
{
|
||||
if( ((value >> 28)) < 0xA )
|
||||
{
|
||||
pbuf[ 2 * idx] = (value >> 28) + '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
|
||||
}
|
||||
|
||||
value = value << 4;
|
||||
|
||||
pbuf[2 * idx + 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb get serial number
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
static void get_serial_num(void)
|
||||
{
|
||||
uint32_t serial0, serial1, serial2;
|
||||
|
||||
serial0 = *(uint32_t*)MCU_ID1;
|
||||
serial1 = *(uint32_t*)MCU_ID2;
|
||||
serial2 = *(uint32_t*)MCU_ID3;
|
||||
|
||||
serial0 += serial2;
|
||||
|
||||
if (serial0 != 0)
|
||||
{
|
||||
usbd_int_to_unicode (serial0, &g_string_serial[2] ,8);
|
||||
usbd_int_to_unicode (serial1, &g_string_serial[18] ,4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get device descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_descriptor(void)
|
||||
{
|
||||
return &device_descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get device qualifier
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t * get_device_qualifier(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get config descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_configuration(void)
|
||||
{
|
||||
return &config_descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get other speed descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_other_speed(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get lang id descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_lang_id(void)
|
||||
{
|
||||
return &langid_descriptor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief get manufacturer descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_manufacturer_string(void)
|
||||
{
|
||||
vp_desc.length = usbd_unicode_convert((uint8_t *)USBD_DESC_MANUFACTURER_STRING, g_usbd_desc_buffer);
|
||||
vp_desc.descriptor = g_usbd_desc_buffer;
|
||||
return &vp_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get product descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_product_string(void)
|
||||
{
|
||||
vp_desc.length = usbd_unicode_convert((uint8_t *)USBD_DESC_PRODUCT_STRING, g_usbd_desc_buffer);
|
||||
vp_desc.descriptor = g_usbd_desc_buffer;
|
||||
return &vp_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get serial descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_serial_string(void)
|
||||
{
|
||||
get_serial_num();
|
||||
return &serial_descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get interface descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_interface_string(void)
|
||||
{
|
||||
vp_desc.length = usbd_unicode_convert((uint8_t *)USBD_DESC_INTERFACE_STRING, g_usbd_desc_buffer);
|
||||
vp_desc.descriptor = g_usbd_desc_buffer;
|
||||
return &vp_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get device config descriptor
|
||||
* @param none
|
||||
* @retval usbd_desc
|
||||
*/
|
||||
usbd_desc_t *get_device_config_string(void)
|
||||
{
|
||||
vp_desc.length = usbd_unicode_convert((uint8_t *)USBD_DESC_CONFIGURATION_STRING, g_usbd_desc_buffer);
|
||||
vp_desc.descriptor = g_usbd_desc_buffer;
|
||||
return &vp_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
98
middlewares/usbd_class/msc/msc_desc.h
Normal file
98
middlewares/usbd_class/msc/msc_desc.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file msc_desc.h
|
||||
* @version v2.0.0
|
||||
* @date 2021-11-26
|
||||
* @brief usb msc descriptor header file
|
||||
**************************************************************************
|
||||
* Copyright notice & Disclaimer
|
||||
*
|
||||
* The software Board Support Package (BSP) that is made available to
|
||||
* download from Artery official website is the copyrighted work of Artery.
|
||||
* Artery authorizes customers to use, copy, and distribute the BSP
|
||||
* software and its related documentation for the purpose of design and
|
||||
* development in conjunction with Artery microcontrollers. Use of the
|
||||
* software is governed by this copyright notice and the following disclaimer.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
||||
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
||||
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
||||
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
||||
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/* define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MSC_DESC_H
|
||||
#define __MSC_DESC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "msc_class.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/** @addtogroup AT32F415_middlewares_usbd_class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USB_msc_desc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_msc_desc_definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define BCD_NUM 0x0110
|
||||
|
||||
#define USBD_VENDOR_ID 0x2E3C
|
||||
#define USBD_PRODUCT_ID 0x5720
|
||||
|
||||
#define USBD_CONFIG_DESC_SIZE 32
|
||||
#define USBD_SIZ_STRING_LANGID 4
|
||||
#define USBD_SIZ_STRING_SERIAL 0x1A
|
||||
|
||||
#define USBD_DESC_MANUFACTURER_STRING "Artery"
|
||||
#define USBD_DESC_PRODUCT_STRING "AT32 Mass Storage"
|
||||
#define USBD_DESC_CONFIGURATION_STRING "Mass Storage Config"
|
||||
#define USBD_DESC_INTERFACE_STRING "Mass Storage Interface"
|
||||
|
||||
#define HID_BINTERVAL_TIME 0xFF
|
||||
|
||||
#define USBD_CDC_CS_INTERFACE 0x24
|
||||
#define USBD_CDC_CS_ENDPOINT 0x25
|
||||
|
||||
#define USBD_CDC_SUBTYPE_HEADER 0x00
|
||||
#define USBD_CDC_SUBTYPE_CMF 0x01
|
||||
#define USBD_CDC_SUBTYPE_ACM 0x02
|
||||
#define USBD_CDC_SUBTYPE_UFD 0x06
|
||||
|
||||
|
||||
#define MCU_ID1 (0x1FFFF7E8)
|
||||
#define MCU_ID2 (0x1FFFF7EC)
|
||||
#define MCU_ID3 (0x1FFFF7F0)
|
||||
|
||||
extern uint8_t g_usbd_descriptor[USB_DEVICE_DESC_LEN];
|
||||
extern uint8_t g_usbd_configuration[USBD_CONFIG_DESC_SIZE];
|
||||
extern usbd_desc_handler msc_desc_handler;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user