FRDM-MCXA156开发板测评(五)——USB设备测试
[复制链接]
本帖最后由 FuShenxiao 于 2025-2-15 18:01 编辑
在开发板上,除了有通过调试芯片与主控芯片相连接的MCU-Link USB,还有直接与主控芯片相连接的MCU USB。
其原理图如下,引出的USB0_DM和USB0_DP直接与MCU的USB0_DM和USB0_DP引脚相连
利用该USB口可以将MCU的部分RAM用作U盘设备
USB大容量存储设备类(The USB mass storage device class)是一种计算机和移动设备之间的传输协议,它允许一个通用串行总线(USB)设备来访问主机的计算设备,使两者之间进行文件传输。通过这个标准的计算机连接到的设备包括:移动硬盘、移动光驱、U盘、SD、TF等储存卡读卡器、数码相机、各种数字音频播放器和便携式媒体播放器、智能卡阅读器、掌上电脑和手机。
MSC的通用性和操作简单使他成为移动设备上最常见的文件系统,USB MSC并不需要任何特定的文件系统, 相反,它提供了一个简单的界面来读写接口用于访问任何硬盘驱动器。操作系统可以把MSC像本地硬盘一样格式化,并可以与他们喜欢的任何文件系统格式它,当然也可以创建多个分区。
在MCUXpresso IDE中,定义两个引脚为USB接口引脚,可以看到这两个引脚已经默认就是作为USB接口引脚了
接下来介绍几个较为关键的函数
首先定义通过指定的端点接收数据,该函数在内部调用USB_DeviceRecvRequest,返回USB故障或正常。
usb_status_t USB_DeviceMscRecv(usb_device_msc_struct_t *mscHandle)
{
usb_status_t error = kStatus_USB_Success;
usb_device_lba_app_struct_t lba;
lba.offset = mscHandle->currentOffset;
/*bulkOutBufferSize is the application buffer size, USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH is the max transfer
length by the hardware,
lba.size is the data pending for transfer ,select the minimum size to transfer ,the remaining will be transfer
next time*/
lba.size = (mscHandle->bulkOutBufferSize > USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH) ?
USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH :
mscHandle->bulkOutBufferSize;
lba.size =
(mscHandle->transferRemaining > lba.size) ? lba.size : mscHandle->transferRemaining; /* whichever is smaller */
lba.buffer = g_msc.storageDisk + lba.offset * mscHandle->lengthOfEachLba;
if (mscHandle->currentOffset < (mscHandle->totalLogicalBlockNumber))
{
error = USB_DeviceRecvRequest(g_msc.deviceHandle, mscHandle->bulkOutEndpoint, lba.buffer, lba.size);
}
else
{
mscHandle->needOutStallFlag = 0;
mscHandle->outEndpointStallFlag = 1;
mscHandle->dataOutFlag = 0;
mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA;
USB_DeviceStallEndpoint(g_msc.deviceHandle, mscHandle->bulkOutEndpoint);
}
return error;
}
通过指定端点接收发送数据。该函数在ufi处理读/写命令时使用,在内部调用USB_DeviceMscRecv或USB_device_send_recv作为方向。
usb_status_t USB_DeviceMscLbaTransfer(usb_device_msc_struct_t *mscHandle,
uint8_t direction,
usb_lba_transfer_information_struct_t *lba)
{
usb_status_t error = kStatus_USB_Success;
mscHandle->transferRemaining = lba->transferNumber * mscHandle->lengthOfEachLba;
mscHandle->currentOffset = lba->startingLogicalBlockAddress;
if (direction == USB_IN)
{
error = USB_DeviceMscSend(mscHandle);
}
else
{
error = USB_DeviceMscRecv(mscHandle);
}
return error;
}
处理usb msc ufi命令,该函数分析cbw,获取命令代码。
usb_status_t USB_DeviceMscProcessUfiCommand(usb_device_msc_struct_t *mscHandle)
{
usb_status_t error = kStatus_USB_Error;
usb_device_msc_ufi_struct_t *ufi = NULL;
ufi = &mscHandle->mscUfi;
if (USB_DEVICE_MSC_REQUEST_SENSE_COMMAND != mscHandle->mscCbw->cbwcb[0])
{
ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_NO_SENSE;
ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_NO_SENSE;
ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE;
}
ufi->thirteenCase.hostExpectedDataLength = mscHandle->mscCbw->dataTransferLength;
ufi->thirteenCase.hostExpectedDirection = (uint8_t)(mscHandle->mscCbw->flags >> USB_DEVICE_MSC_CBW_DIRECTION_SHIFT);
/*The first byte of all ufi command blocks shall contain an Operation Code, refer to ufi spec*/
switch (mscHandle->mscCbw->cbwcb[0])
{
/* ufi command operation code*/
case USB_DEVICE_MSC_INQUIRY_COMMAND: /*operation code : 0x12*/
error = USB_DeviceMscUfiInquiryCommand(mscHandle);
break;
case USB_DEVICE_MSC_READ_10_COMMAND: /*operation code : 0x28 */
case USB_DEVICE_MSC_READ_12_COMMAND: /*operation code : 0xA8 */
error = USB_DeviceMscUfiReadCommand(mscHandle);
break;
case USB_DEVICE_MSC_REQUEST_SENSE_COMMAND: /*operation code : 0x03*/
error = USB_DeviceMscUfiRequestSenseCommand(mscHandle);
break;
case USB_DEVICE_MSC_TEST_UNIT_READY_COMMAND: /*operation code : 0x00 */
if (1U == g_msc.stop)
{
ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_NOT_READY;
ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_ASC_MEDIUM_NOT_PRESENT;
}
error = USB_DeviceMscUfiTestUnitReadyCommand(mscHandle);
break;
case USB_DEVICE_MSC_WRITE_10_COMMAND: /*operation code : 0x2A */
case USB_DEVICE_MSC_WRITE_12_COMMAND: /*operation code : 0xAA */
error = USB_DeviceMscUfiWriteCommand(mscHandle);
break;
case USB_DEVICE_MSC_PREVENT_ALLOW_MEDIUM_REM_COMMAND: /*operation code :0x1E */
error = USB_DeviceMscUfiPreventAllowMediumCommand(mscHandle);
break;
case USB_DEVICE_MSC_FORMAT_UNIT_COMMAND: /*operation code : 0x04*/
error = USB_DeviceMscUfiFormatUnitCommand(mscHandle);
break;
case USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND: /*operation code : 0x25*/
case USB_DEVICE_MSC_READ_CAPACITY_16_COMMAND: /*operation code : 0x9E*/
error = USB_DeviceMscUfiReadCapacityCommand(mscHandle);
break;
case USB_DEVICE_MSC_MODE_SENSE_10_COMMAND: /* operation code :0x5A*/
case USB_DEVICE_MSC_MODE_SENSE_6_COMMAND: /* operation code : 0x1A */
error = USB_DeviceMscUfiModeSenseCommand(mscHandle);
break;
case USB_DEVICE_MSC_MODE_SELECT_10_COMMAND: /*operation code : 0x55 */
case USB_DEVICE_MSC_MODE_SELECT_6_COMMAND: /*operation code : 0x15 */
error = USB_DeviceMscUfiModeSelectCommand(mscHandle);
break;
case USB_DEVICE_MSC_READ_FORMAT_CAPACITIES_COMMAND: /*operation code : 0x23 */
error = USB_DeviceMscUfiReadFormatCapacityCommand(mscHandle);
break;
case USB_DEVICE_MSC_SEND_DIAGNOSTIC_COMMAND: /*operation code : 0x1D*/
error = USB_DeviceMscUfiSendDiagnosticCommand(mscHandle);
break;
case USB_DEVICE_MSC_VERIFY_COMMAND: /*operation code : 0x2F*/
error = USB_DeviceMscUfiVerifyCommand(mscHandle);
break;
case USB_DEVICE_MSC_START_STOP_UNIT_COMMAND: /*operation code : 0x1B*/
if (0x00U == (mscHandle->mscCbw->cbwcb[4] & 0x01U)) /* check start bit */
{
g_msc.stop = 1U; /* stop command */
}
error = USB_DeviceMscUfiStartStopUnitCommand(mscHandle);
break;
default:
error = USB_DeviceMscUfiUnsupportCommand(mscHandle);
mscHandle->dataOutFlag = 0;
mscHandle->dataInFlag = 0;
mscHandle->outEndpointStallFlag = 0;
mscHandle->inEndpointStallFlag = 0;
mscHandle->needOutStallFlag = 0;
mscHandle->needInStallFlag = 0;
break;
}
if ((USB_DEVICE_MSC_UFI_NO_SENSE != ufi->requestSense->senseKey) &&
(USB_DEVICE_MSC_COMMAND_PASSED == mscHandle->mscCsw->cswStatus) &&
(USB_DEVICE_MSC_REQUEST_SENSE_COMMAND != mscHandle->mscCbw->cbwcb[0]))
{
mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
}
return error;
}
Bulk IN端点回调函数。此回调函数用于通知上层传输的传输结果,在初始化Bulk IN管道时传递此回调指针。
usb_status_t USB_DeviceMscBulkIn(usb_device_handle deviceHandle,
usb_device_endpoint_callback_message_struct_t *event,
void *arg)
{
usb_device_msc_csw_t *csw = NULL;
usb_status_t error = kStatus_USB_Error;
usb_device_msc_struct_t *mscHandle = (usb_device_msc_struct_t *)arg;
if (event->length == USB_CANCELLED_TRANSFER_LENGTH)
{
if (mscHandle->inEndpointCswCancelFlag == 1)
{
mscHandle->inEndpointCswCancelFlag = 0;
/*cancel the transfer and wait for the calcel to be complete in bulk in callback*/
/*send csw*/
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
if (kStatus_USB_Success != USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint,
(uint8_t *)mscHandle->mscCsw, USB_DEVICE_MSC_CSW_LENGTH))
{
return kStatus_USB_Error;
}
#else
(void)USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
USB_DEVICE_MSC_CSW_LENGTH);
#endif
mscHandle->cswPrimeFlag = 1;
mscHandle->stallStatus = 0;
}
return error;
}
if (mscHandle->transferRemaining >= event->length)
{
mscHandle->transferRemaining -= event->length;
}
if (mscHandle->needInStallFlag == 1)
{
mscHandle->needInStallFlag = 0;
mscHandle->inEndpointStallFlag = 1;
mscHandle->dataInFlag = 0;
USB_DeviceStallEndpoint(g_msc.deviceHandle, mscHandle->bulkInEndpoint);
return error;
}
if ((!mscHandle->dataInFlag) && (event->length == USB_DEVICE_MSC_CSW_LENGTH))
{
csw = (usb_device_msc_csw_t *)(event->buffer);
}
if (mscHandle->dataInFlag)
{
if (mscHandle->transferRemaining)
{
mscHandle->currentOffset += (event->length / mscHandle->lengthOfEachLba);
error = USB_DeviceMscSend(mscHandle);
}
if (!mscHandle->transferRemaining)
{
mscHandle->dataInFlag = 0;
/*data transfer has been done, send the csw to host */
mscHandle->cswPrimeFlag = 1;
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
error = USB_DeviceSendRequest(g_msc.deviceHandle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
USB_DEVICE_MSC_CSW_LENGTH);
#else
(void)USB_DeviceSendRequest(g_msc.deviceHandle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
USB_DEVICE_MSC_CSW_LENGTH);
#endif
}
}
else if ((event->length == USB_DEVICE_MSC_CSW_LENGTH) && (csw->signature == USB_DEVICE_MSC_DCSWSIGNATURE))
{
mscHandle->cbwValidFlag = 1;
mscHandle->cswPrimeFlag = 0;
#if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
error = USB_DeviceRecvRequest(g_msc.deviceHandle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw,
USB_DEVICE_MSC_CBW_LENGTH);
#else
(void)USB_DeviceRecvRequest(g_msc.deviceHandle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw,
USB_DEVICE_MSC_CBW_LENGTH);
#endif
mscHandle->cbwPrimeFlag = 1;
}
else
{
}
return error;
}
Bulk OUT端点回调函数。该回调函数用于通知上层传输的传输结果,并在Bulk OUT管道初始化时传递。
usb_status_t USB_DeviceMscBulkOut(usb_device_handle deviceHandle,
usb_device_endpoint_callback_message_struct_t *event,
void *arg)
{
usb_status_t error = kStatus_USB_Success;
usb_device_msc_struct_t *mscHandle = (usb_device_msc_struct_t *)arg;
/* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
if (event->length == USB_CANCELLED_TRANSFER_LENGTH)
{
if ((mscHandle->cbwPrimeFlag == 0) && (mscHandle->inEndpointStallFlag == 0) &&
(mscHandle->outEndpointStallFlag == 0))
{
/*prime cbw*/
USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw,
USB_DEVICE_MSC_CBW_LENGTH);
mscHandle->cbwPrimeFlag = 1;
}
return error;
}
if (mscHandle->transferRemaining >= event->length)
{
mscHandle->transferRemaining -= event->length;
}
if (mscHandle->needOutStallFlag == 1)
{
mscHandle->needOutStallFlag = 0;
mscHandle->outEndpointStallFlag = 1;
mscHandle->dataOutFlag = 0;
mscHandle->cbwPrimeFlag = 0;
USB_DeviceStallEndpoint(g_msc.deviceHandle, mscHandle->bulkOutEndpoint);
return error;
}
if (mscHandle->dataOutFlag)
{
if (mscHandle->transferRemaining)
{
mscHandle->currentOffset += (event->length / mscHandle->lengthOfEachLba);
error = USB_DeviceMscRecv(mscHandle);
}
if (!mscHandle->transferRemaining)
{
mscHandle->dataOutFlag = 0;
{
USB_DeviceSendRequest(g_msc.deviceHandle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
USB_DEVICE_MSC_CSW_LENGTH);
mscHandle->cswPrimeFlag = 1;
}
}
}
else if ((mscHandle->cbwValidFlag) && (event->length == USB_DEVICE_MSC_CBW_LENGTH) &&
(mscHandle->mscCbw->signature == USB_DEVICE_MSC_DCBWSIGNATURE) &&
(!((mscHandle->mscCbw->logicalUnitNumber & 0xF0) || (mscHandle->mscCbw->cbLength & 0xE0))) &&
(mscHandle->mscCbw->logicalUnitNumber < (mscHandle->logicalUnitNumber + 1)) &&
((mscHandle->mscCbw->cbLength >= 0x01) && (mscHandle->mscCbw->cbLength <= 0x10)))
{
mscHandle->cbwPrimeFlag = 0;
mscHandle->transferRemaining = 0;
mscHandle->mscCsw->signature = USB_DEVICE_MSC_DCSWSIGNATURE;
mscHandle->mscCsw->dataResidue = 0;
mscHandle->mscCsw->tag = mscHandle->mscCbw->tag;
mscHandle->cbwValidFlag = 0;
mscHandle->mscCbw->dataTransferLength = USB_LONG_FROM_LITTLE_ENDIAN(mscHandle->mscCbw->dataTransferLength);
mscHandle->dataOutFlag = (uint8_t)(((!(mscHandle->mscCbw->flags & USB_DEVICE_MSC_CBW_DIRECTION_BIT)) &&
(mscHandle->mscCbw->dataTransferLength)) ?
1 :
0);
mscHandle->dataInFlag = (uint8_t)(
((mscHandle->mscCbw->flags & USB_DEVICE_MSC_CBW_DIRECTION_BIT) && (mscHandle->mscCbw->dataTransferLength)) ?
1 :
0);
if ((0 != mscHandle->dataInFlag) && (0 != mscHandle->inEndpointStallFlag))
{
error = kStatus_USB_Error;
return error;
}
error = USB_DeviceMscProcessUfiCommand(mscHandle);
if (error == kStatus_USB_InvalidRequest)
{
if (mscHandle->dataOutFlag == 1)
{
if (mscHandle->outEndpointStallFlag == 0)
{
mscHandle->needOutStallFlag = 1;
}
mscHandle->dataOutFlag = 0;
}
else if (mscHandle->dataInFlag == 1)
{
if (mscHandle->inEndpointStallFlag == 0)
{
mscHandle->needInStallFlag = 1;
}
mscHandle->dataInFlag = 0;
}
else
{
}
mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA;
}
if (!((mscHandle->dataOutFlag) || ((mscHandle->dataInFlag) || (mscHandle->needInStallFlag))))
{
USB_DeviceSendRequest(g_msc.deviceHandle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
USB_DEVICE_MSC_CSW_LENGTH);
mscHandle->cswPrimeFlag = 1;
}
}
else
{
USB_DeviceStallEndpoint(g_msc.deviceHandle, mscHandle->bulkOutEndpoint);
USB_DeviceStallEndpoint(g_msc.deviceHandle, mscHandle->bulkInEndpoint);
mscHandle->cbwPrimeFlag = 0;
mscHandle->cbwValidFlag = 0;
mscHandle->outEndpointStallFlag = 1;
mscHandle->inEndpointStallFlag = 1;
mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_CBW;
mscHandle->performResetRecover = 1;
}
return error;
}
初始化msc类的端点回调函数。
usb_status_t USB_DeviceMscEndpointsInit(void)
{
usb_status_t error = kStatus_USB_Error;
usb_device_endpoint_init_struct_t epInitStruct;
usb_device_endpoint_callback_struct_t epCallback;
epCallback.callbackFn = USB_DeviceMscBulkIn;
epCallback.callbackParam = (void *)&g_msc.mscStruct;
epInitStruct.zlt = 0;
epInitStruct.interval = 0;
epInitStruct.transferType = USB_ENDPOINT_BULK;
epInitStruct.endpointAddress =
USB_MSC_BULK_IN_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
g_mscHandle->bulkInEndpoint = epInitStruct.endpointAddress;
if (USB_SPEED_HIGH == g_msc.speed)
{
epInitStruct.maxPacketSize = HS_MSC_BULK_IN_PACKET_SIZE;
}
else
{
epInitStruct.maxPacketSize = FS_MSC_BULK_IN_PACKET_SIZE;
}
USB_DeviceInitEndpoint(g_msc.deviceHandle, &epInitStruct, &epCallback);
epCallback.callbackFn = USB_DeviceMscBulkOut;
epCallback.callbackParam = (void *)&g_msc.mscStruct;
epInitStruct.zlt = 0;
epInitStruct.interval = 0;
epInitStruct.transferType = USB_ENDPOINT_BULK;
epInitStruct.endpointAddress =
USB_MSC_BULK_OUT_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
g_mscHandle->bulkOutEndpoint = epInitStruct.endpointAddress;
if (USB_SPEED_HIGH == g_msc.speed)
{
epInitStruct.maxPacketSize = HS_MSC_BULK_OUT_PACKET_SIZE;
}
else
{
epInitStruct.maxPacketSize = FS_MSC_BULK_OUT_PACKET_SIZE;
}
USB_DeviceInitEndpoint(g_msc.deviceHandle, &epInitStruct, &epCallback);
g_mscHandle->dataOutFlag = 0;
g_mscHandle->dataInFlag = 0;
g_mscHandle->outEndpointStallFlag = 0;
g_mscHandle->inEndpointStallFlag = 0;
g_mscHandle->needOutStallFlag = 0;
g_mscHandle->needInStallFlag = 0;
g_mscHandle->cbwValidFlag = 1;
g_mscHandle->transferRemaining = 0;
g_mscHandle->performResetRecover = 0;
g_mscHandle->performResetDoneFlag = 0;
g_mscHandle->stallStatus = 0;
g_mscHandle->inEndpointCswCancelFlag = 0;
return error;
}
取消msc类初始化回调函数。
usb_status_t USB_DeviceMscEndpointsDeinit(void)
{
usb_status_t error = kStatus_USB_Error;
error = USB_DeviceDeinitEndpoint(g_msc.deviceHandle, g_mscHandle->bulkInEndpoint);
error = USB_DeviceDeinitEndpoint(g_msc.deviceHandle, g_mscHandle->bulkOutEndpoint);
return error;
}
设备回调函数,用于处理USB标准事件。
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{
usb_status_t error = kStatus_USB_InvalidRequest;
uint8_t *temp8 = (uint8_t *)param;
switch (event)
{
case kUSB_DeviceEventBusReset:
{
g_mscHandle->configuration = 0;
USB_DeviceControlPipeInit(g_msc.deviceHandle);
g_msc.attach = 0;
g_msc.stop = 0U;
error = kStatus_USB_Success;
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#if !((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
/* The work-around is used to fix the HS device Chirping issue.
* Please refer to the implementation for the detail information.
*/
USB_DeviceHsPhyChirpIssueWorkaround();
#endif
#endif
#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
(defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
/* Get USB speed to configure the device, including max packet size and interval of the endpoints. */
if (kStatus_USB_Success == USB_DeviceGetStatus(g_msc.deviceHandle, kUSB_DeviceStatusSpeed, &g_msc.speed))
{
USB_DeviceSetSpeed(g_msc.speed);
}
#endif
}
break;
#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
case kUSB_DeviceEventDetach:
{
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#if !((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
USB_DeviceDisconnected();
#endif
#endif
error = kStatus_USB_Success;
}
break;
#endif
case kUSB_DeviceEventSetConfiguration:
if (g_mscHandle->configuration == *temp8)
{
break;
}
if (g_mscHandle->configuration)
{
USB_DeviceMscEndpointsDeinit();
}
g_mscHandle->configuration = *temp8;
error = kStatus_USB_Success;
if (USB_MSC_CONFIGURE_INDEX == (*temp8))
{
/*USB_DeviceMscEndpointsDeinit();*/
error = USB_DeviceMscEndpointsInit();
USB_DeviceRecvRequest(g_msc.deviceHandle, g_mscHandle->bulkOutEndpoint, (uint8_t *)g_mscHandle->mscCbw,
USB_DEVICE_MSC_CBW_LENGTH);
g_mscHandle->cbwPrimeFlag = 1;
g_msc.attach = 1;
}
break;
case kUSB_DeviceEventSetInterface:
error = kStatus_USB_Success;
break;
default:
break;
}
return error;
}
检测USB端点运行状态
usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
{
usb_status_t error = kStatus_USB_Error;
if (status)
{
if ((USB_MSC_BULK_IN_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80))
{
if (g_mscHandle->inEndpointStallFlag == 0)
{
g_mscHandle->inEndpointStallFlag = 1;
g_mscHandle->cswPrimeFlag = 0;
error = USB_DeviceStallEndpoint(handle, ep);
}
}
else if ((USB_MSC_BULK_OUT_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (!(ep & 0x80)))
{
if (g_mscHandle->outEndpointStallFlag == 0)
{
g_mscHandle->outEndpointStallFlag = 1;
g_mscHandle->cbwPrimeFlag = 0;
error = USB_DeviceStallEndpoint(handle, ep);
}
}
else
{
}
}
else
{
if (g_mscHandle->performResetRecover == 1)
{
return error;
}
if ((USB_MSC_BULK_IN_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80))
{
if (g_mscHandle->inEndpointStallFlag == 1)
{
g_mscHandle->inEndpointStallFlag = 0;
g_mscHandle->cswPrimeFlag = 0;
error = USB_DeviceUnstallEndpoint(handle, ep);
}
}
else if ((USB_MSC_BULK_OUT_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (!(ep & 0x80)))
{
if (g_mscHandle->outEndpointStallFlag == 1)
{
g_mscHandle->outEndpointStallFlag = 0;
g_mscHandle->cbwPrimeFlag = 0;
error = USB_DeviceUnstallEndpoint(handle, ep);
}
}
else
{
}
if (((g_mscHandle->stallStatus == USB_DEVICE_MSC_STALL_IN_CSW) ||
(g_mscHandle->stallStatus == USB_DEVICE_MSC_STALL_IN_DATA)) &&
(g_mscHandle->performResetDoneFlag != 1))
{
if (g_mscHandle->cswPrimeFlag == 1)
{
/*cancel the transfer , after the cancel to be complete, and then prime csw in bulk out callback, */
g_mscHandle->inEndpointCswCancelFlag = 1;
USB_DeviceCancel(g_msc.deviceHandle, g_mscHandle->bulkInEndpoint);
}
else
{
USB_DeviceSendRequest(g_msc.deviceHandle, g_mscHandle->bulkInEndpoint, (uint8_t *)g_mscHandle->mscCsw,
USB_DEVICE_MSC_CSW_LENGTH);
g_mscHandle->cswPrimeFlag = 1;
}
g_mscHandle->stallStatus = 0;
}
if ((g_mscHandle->performResetDoneFlag == 1) && (g_mscHandle->inEndpointStallFlag == 0) &&
(g_mscHandle->outEndpointStallFlag == 0))
{
g_mscHandle->performResetDoneFlag = 0;
if (g_mscHandle->cbwPrimeFlag == 1)
{
g_mscHandle->cbwPrimeFlag = 0;
USB_DeviceCancel(g_msc.deviceHandle, g_mscHandle->bulkOutEndpoint);
}
else
{
USB_DeviceRecvRequest(g_msc.deviceHandle, g_mscHandle->bulkOutEndpoint, (uint8_t *)g_mscHandle->mscCbw,
USB_DEVICE_MSC_CBW_LENGTH);
g_mscHandle->cbwPrimeFlag = 1;
}
g_mscHandle->stallStatus = 0;
}
}
return error;
}
在主函数中,启动USB设备任务
int main(void)
#else
void main(void)
#endif
{
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
USB_DeviceApplicationInit();
while (1)
{
#if USB_DEVICE_CONFIG_USE_TASK
USB_DeviceTaskFn(g_msc.deviceHandle);
#endif
}
}
得到最终结果如下,可以观察到出现了U盘设备。
工程代码:
frdmmcxa156_dev_msc_ramdisk_lite_bm.rar
(5.13 MB, 下载次数: 0)
|