📄 massstorage.c
字号:
// Get Device Descriptor
case DESC_DEVICE:
{
udcOnLine = 1;
if (len > LEN_DEVICE)
len = LEN_DEVICE;
my_memcpy(g_au8UsbCtrl, (void *)MassDeviceDescriptor, len);
break;
}
// Get Configuration Descriptor
case DESC_CONFIG:
{
if (len > MassConfigurationBlock[2])
len = MassConfigurationBlock[2];
my_memcpy(g_au8UsbCtrl, (void *)MassConfigurationBlock, len);
break;
}
// Get String Descriptor
case DESC_STRING:
{
// Get Language
if(tmp[4] == 0)
{
if(len > MassStringDescriptor0[0])
len = MassStringDescriptor0[0];
my_memcpy(g_au8UsbCtrl, (void *)MassStringDescriptor0, len);
break;
}
// Get String Descriptor
if(len > MassStringDescriptor1[0])
len = MassStringDescriptor1[0];
my_memcpy(g_au8UsbCtrl, (void *)MassStringDescriptor1, len);
break;
}
default:
return FALSE;
}
_DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
_DRVUSB_TRIG_EP(0, len);
g_u8Flag = FLAG_OUT_ACK;
return TRUE;
}
case SET_ADDRESS:
{
/* Accept set address command only before USB configured */
if((g_u8UsbState & USB_STATE_FLAG_CONFIGURED) == 0)
{
/* Get the device address */
g_u8Address = tmp[2];
_DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 0);
g_u8Flag = FLAG_SET_ADDRESS;
return TRUE;
}
return FALSE;
}
case SET_CONFIGURATION:
{
g_u8Config = tmp[2];
_DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 0);
g_u8Flag = FLAG_SET_CONFIG;
return TRUE;
}
case CLEAR_FEATURE:
case SET_FEATURE:
{
if (g_bCBWInvalid)
{
/* Invalid CBW */
}
else if((tmp[0] == 2) && (tmp[2] == FEATURE_ENDPOINT_HALT))
{
uint32_t u32CfgAddr;
uint8_t u8Cfg;
u32CfgAddr = ((tmp[4] & 0xF) << 4) + USBD_CFGP0;
u8Cfg = *((__IO uint32_t *) (u32CfgAddr)) & 0xFF;
if(tmp[1] == CLEAR_FEATURE)
u8Cfg &= ~EPT_stall;
else
u8Cfg |= EPT_stall;
*((__IO uint32_t *) (u32CfgAddr)) = u8Cfg;
}
else
return FALSE;
_DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 0);
return TRUE;
}
case GET_CONFIGURATION:
{
g_au8UsbCtrl[0] = g_u8Config;
_DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 1);
g_u8Flag = FLAG_OUT_ACK;
return TRUE;
}
case GET_STATUS:
{
uint8_t u8Data;
u8Data = tmp[0];
// Device
if (u8Data == 0x80)
g_au8UsbCtrl[0] = 1; // Self-Powered
// Interface
else if (u8Data == 0x81)
g_au8UsbCtrl[0] = 0;
// Endpoint
else if (u8Data == 0x82)
{
uint32_t u32CfgAddr;
u8Data = tmp[4];
u32CfgAddr = ((u8Data & 0xF) << 4) + USBD_CFGP0;
g_au8UsbCtrl[0] = (inp32(u32CfgAddr) >> 1) & 1;
}
else
return FALSE;
g_au8UsbCtrl[1] = 0;
_DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 1);
g_u8Flag = FLAG_OUT_ACK;
return TRUE;
}
case GET_INTERFACE:
{
g_au8UsbCtrl[0] = 0;
_DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 1);
g_u8Flag = FLAG_OUT_ACK;
return TRUE;
}
case SET_INTERFACE:
{
g_u8Flag = FLAG_SET_INTERFACE;
_DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 0);
return TRUE;
}
default:
return FALSE;
}
}
//======================================================
int32_t UsbClassReq(void)
{
uint8_t tmp[8];
my_memcpy(tmp, g_au8UsbSetup, 8);
if ((tmp[2] != 0) || (tmp[3] != 0) || (tmp[4] != 0) || (tmp[5] != 0))
return FALSE;
switch(tmp[1])
{
// Bulk-Only Mass Storage Reset
case BULK_ONLY_MASS_STORAGE_RESET:
{
if ((tmp[6] != 0) || (tmp[7] != 0))
return FALSE;
g_bCBWInvalid = FALSE;
_DRVUSB_SET_CFG(0, DATA1 (CFG0_SETTING));
_DRVUSB_TRIG_EP(0, 0);
_DRVUSB_SET_CFG(2, DATA0 (CFG2_SETTING));
g_u8BulkState = BULK_CBW;
_DRVUSB_TRIG_EP(3, 31);
return TRUE;
}
// Get Max LUN
case GET_MAX_LUN:
{
if ((tmp[6] != 1) || (tmp[7] != 0))
return FALSE;
g_au8UsbCtrl[0] = MassLUN - 1;
if (MassLUN != 1)
while(1);
_DRVUSB_SET_CFG(0, DATA1(CFG0_SETTING));
_DRVUSB_SET_CFG(3, DATA0(CFG3_SETTING));
_DRVUSB_TRIG_EP(0, 1);
g_u8Flag = FLAG_OUT_ACK;
return TRUE;
}
}
return FALSE;
}
//======================================================
int32_t UsbSetup(void)
{
/* Clear the data IN/OUT ready flag of control end-points */
_DRVUSB_SET_CFG_EP0(CFGP_CLRRDY);
_DRVUSB_SET_CFG_EP1(CFGP_CLRRDY);
/* USB device request in setup packet: offset 0, D[6..5]: 0=Stardard, 1=Class, 2=Vendor, 3=Reserved */
switch (g_au8UsbSetup[0] & 0x60)
{
case REQ_STANDARD:
return UsbStdReq();
case REQ_CLASS:
return UsbClassReq();
default:
return FALSE;
}
}
//======================================================
void UsbInAck(void)
{
switch (g_u8Flag)
{
// Out ACK
case FLAG_OUT_ACK:
_DRVUSB_TRIG_EP(1, 0);
break;
// Set Address
case FLAG_SET_ADDRESS:
{
if (g_u8Address == 0)
g_u8UsbState = USB_STATE_DEFAULT;
else
g_u8UsbState = USB_STATE_ADDRESS;
_DRVUSB_SET_FADDR(g_u8Address);
break;
}
// Set Interface
case FLAG_SET_INTERFACE:
// Set Configuration
case FLAG_SET_CONFIG:
{
if (g_u8Config == 0)
g_u8UsbState = USB_STATE_ADDRESS;
else
{
g_u8UsbState = USB_STATE_CONFIGURED;
// ---------------------------------
_DRVUSB_SET_CFG(2, DATA0 (CFG2_SETTING));
_DRVUSB_TRIG_EP(3, 31);
// ---------------------------------
}
break;
}
// Get Max. LUN
case FLAG_GET_MAX_LUN:
_DRVUSB_TRIG_EP(1, 0);
return;
default:
return;
}
g_u8Flag = 0;
}
//======================================================
void UsbOutAck(void)
{
switch (g_u8Flag)
{
// Get Max. LUN
case FLAG_GET_MAX_LUN:
{
// ---------------------------------
_DRVUSB_SET_CFG(2, DATA0 (CFG2_SETTING));
_DRVUSB_TRIG_EP(3, 31);
// ---------------------------------
break;
}
default:
return;
}
g_u8Flag = 0;
}
//======================================================
void UsbRead(void)
{
uint32_t u32Len;
/* DATA0/DATA1 Toggle */
if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
else
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK1);
/* Trigger to send out the data packet */
_DRVUSB_TRIG_EP(2, g_u8Size);
g_u32Length -= g_u8Size;
g_u32BytesInStorageBuf -= g_u8Size;
if (g_u32Length)
{
if (g_u32BytesInStorageBuf)
{
/* Prepare next data packet */
g_u8Size = MAX_PACKET_SIZE;
if (g_u8Size > g_u32Length)
g_u8Size = g_u32Length;
if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
{
my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
}
else
{
my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
}
g_u32Address += g_u8Size;
}
else
{
u32Len = g_u32Length;
if (u32Len > STORAGE_BUFFER_SIZE)
u32Len = STORAGE_BUFFER_SIZE;
DataFlashRead(g_u32LbaAddress, u32Len, (uint32_t)STORAGE_DATA_BUF);
g_u32BytesInStorageBuf = u32Len;
g_u32LbaAddress += u32Len;
g_u32Address = STORAGE_DATA_BUF;
/* Prepare next data packet */
g_u8Size = MAX_PACKET_SIZE;
if (g_u8Size > g_u32Length)
g_u8Size = g_u32Length;
if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
{
my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
}
else
{
my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
}
g_u32Address += g_u8Size;
}
}
}
void UsbReadTrig(void)
{
uint32_t u32Len;
if (g_u32Length)
{
if (g_u32BytesInStorageBuf)
{
/* Prepare next data packet */
g_u8Size = MAX_PACKET_SIZE;
if (g_u8Size > g_u32Length)
g_u8Size = g_u32Length;
if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
{
my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
}
else
{
my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
}
g_u32Address += g_u8Size;
}
else
{
u32Len = g_u32Length;
if (u32Len > STORAGE_BUFFER_SIZE)
u32Len = STORAGE_BUFFER_SIZE;
DataFlashRead(g_u32LbaAddress, u32Len, (uint32_t)STORAGE_DATA_BUF);
g_u32BytesInStorageBuf = u32Len;
g_u32LbaAddress += u32Len;
g_u32Address = STORAGE_DATA_BUF;
/* Prepare next data packet */
g_u8Size = MAX_PACKET_SIZE;
if (g_u8Size > g_u32Length)
g_u8Size = g_u32Length;
if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
{
my_memcpy(g_au8UsbBulk0, (int8_t *)g_u32Address, g_u8Size);
}
else
{
my_memcpy(g_au8UsbBulk1, (int8_t *)g_u32Address, g_u8Size);
}
g_u32Address += g_u8Size;
}
/* DATA0/DATA1 Toggle */
if (*((__IO uint32_t *)(&USBD->EP[2].BUFSEG)) == BUF_BULK1)
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
else
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK1);
/* Trigger to send out the data packet */
_DRVUSB_TRIG_EP(2, g_u8Size);
g_u32Length -= g_u8Size;
g_u32BytesInStorageBuf -= g_u8Size;
}
else
_DRVUSB_TRIG_EP(2, 0);
}
//======================================================
void UsbBulkInAck(void)
{
int32_t volatile idx;
if (g_u8BulkState == BULK_CSW)
{
/* Prepare to receive the CBW */
g_u8BulkState = BULK_CBW;
_DRVUSB_SET_EP_BUF(3, USB_SRAM_BASE + BUF_BULK0);
_DRVUSB_TRIG_EP(3, 31);
}
else if (g_u8BulkState == BULK_IN)
{
switch (g_sCBW.u8OPCode)
{
case UFI_READ_FORMAT_CAPACITY:
case UFI_READ_CAPACITY:
case UFI_MODE_SENSE_10:
//case UFI_READ_10:
{
if (g_u32Length > 0)
{
UsbRead();
return;
}
}
case UFI_READ_10:
{
if (g_u32Length > 0)
{
//UsbRead();
UsbReadTrig();
return;
}
}
case UFI_REQUEST_SENSE:
case UFI_INQUIRY:
{
g_sCSW.dCSWDataResidue = 0;
g_sCSW.bCSWStatus = 0;
break;
}
case UFI_PREVENT_ALLOW_MEDIUM_REMOVAL:
case UFI_VERIFY_10:
case UFI_START_STOP:
case UFI_WRITE_10:
case VENDER_CMD:
{
int32_t tmp;
tmp = g_sCBW.dCBWDataTransferLength - STORAGE_BUFFER_SIZE;
if (tmp < 0)
tmp = 0;
g_sCSW.dCSWDataResidue = tmp;
g_sCSW.bCSWStatus = 0;
break;
}
case UFI_TEST_UNIT_READY:
{
g_sCSW.dCSWDataResidue = 0;
g_sCSW.bCSWStatus = 0;
break;
}
default:
{
/* Unsupported commmand. Return command fail status */
g_sCSW.dCSWDataResidue = g_sCBW.dCBWDataTransferLength;
g_sCSW.bCSWStatus = 0x01;
break;
}
}
/* Return the CSW */
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK1);
my_memcpy(g_au8UsbBulk1, &g_sCSW.dCSWSignature, 16);
g_u8BulkState = BULK_CSW;
_DRVUSB_TRIG_EP(2, 13);
}
}
//======================================================
void UsbWrite(void)
{
uint32_t lba, len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -