📄 massstorage.c
字号:
if (g_u32Length > MAX_PACKET_SIZE)
{
if (*((__IO uint32_t *)(&USBD->EP[3].BUFSEG)) == BUF_BULK0)
{
_DRVUSB_SET_EP_BUF(3, USB_SRAM_BASE + BUF_BULK1);
_DRVUSB_TRIG_EP(3, MAX_PACKET_SIZE);
my_memcpy((char *)g_u32Address, g_au8UsbBulk0, MAX_PACKET_SIZE);
}
else
{
_DRVUSB_SET_EP_BUF(3, USB_SRAM_BASE + BUF_BULK0);
_DRVUSB_TRIG_EP(3, MAX_PACKET_SIZE);
my_memcpy((char *)g_u32Address, g_au8UsbBulk1, MAX_PACKET_SIZE);
}
g_u32Address += MAX_PACKET_SIZE;
g_u32Length -= MAX_PACKET_SIZE;
/* Buffer full. Writer it to storage first. */
if (g_u32Address >= (STORAGE_DATA_BUF + STORAGE_BUFFER_SIZE))
{
if (g_sCBW.bCBWLUN==F_DATA_FLASH_LUN)
DataFlashWrite(g_u32DataFlashStartAddr, STORAGE_BUFFER_SIZE, (uint32_t)STORAGE_DATA_BUF);
g_u32Address = STORAGE_DATA_BUF;
g_u32DataFlashStartAddr += STORAGE_BUFFER_SIZE;
}
}
else
{
if (*((__IO uint32_t *)(&USBD->EP[3].BUFSEG)) == BUF_BULK0)
{
my_memcpy((char *)g_u32Address, g_au8UsbBulk0, g_u32Length);
}
else
{
my_memcpy((char *)g_u32Address, g_au8UsbBulk1, g_u32Length);
}
g_u32Address += g_u32Length;
g_u32Length = 0;
if (g_sCBW.u8OPCode == UFI_WRITE_10)
{
lba = get_be32(&g_sCBW.au8Data[0]);
len = g_sCBW.dCBWDataTransferLength;
if (g_sCBW.bCBWLUN==F_DATA_FLASH_LUN)
{
len = lba * UDC_SECTOR_SIZE + g_sCBW.dCBWDataTransferLength - g_u32DataFlashStartAddr;
if (len)
{
DataFlashWrite(g_u32DataFlashStartAddr, len, (uint32_t)STORAGE_DATA_BUF);
}
}
}
g_u8BulkState = BULK_IN;
UsbBulkInAck ();
}
}
//======================================================
int32_t UsbBulkOutAck(void)
{
uint8_t u8Len;
int32_t i;
if (g_u8BulkState == BULK_CBW)
{
u8Len = *((__IO uint32_t *)(&USBD->EP[3].MXPLD));
/* Check Signature & length of CBW */
if ((*(uint32_t *) g_au8UsbBulk0 != CBW_SIGNATURE) || (u8Len != 31))
{
return FALSE;
}
/* Get the CBW */
for (i = 0; i < u8Len; i++)
*((uint8_t *) (&g_sCBW.dCBWSignature) + i) = g_au8UsbBulk0[i];
/* Prepare to echo the tag from CBW to CSW */
g_sCSW.dCSWTag = g_sCBW.dCBWTag;
/* Parse Op-Code of CBW */
switch (g_sCBW.u8OPCode)
{
case UFI_PREVENT_ALLOW_MEDIUM_REMOVAL:
{
if (g_sCBW.au8Data[2] & 0x01)
{
g_au8SenseKey[0] = 0x05; //INVALID COMMAND
g_au8SenseKey[1] = 0x24;
g_au8SenseKey[2] = 0;
preventflag = 1;
}
else
preventflag = 0;
g_u8BulkState = BULK_IN;
UsbBulkInAck ();
return TRUE;
}
case UFI_VERIFY_10:
case UFI_START_STOP:
case UFI_TEST_UNIT_READY:
{
g_u8BulkState = BULK_IN;
UsbBulkInAck ();
return TRUE;
}
case UFI_REQUEST_SENSE:
{
ReqSenCommand();
g_u8BulkState = BULK_IN;
_DRVUSB_TRIG_EP(2, 18);
return TRUE;
}
case UFI_READ_FORMAT_CAPACITY:
{
if (g_u32Length == 0)
{
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = MassCMD_BUF;
}
RdFmtCapCommand();
g_u8BulkState = BULK_IN;
if (g_u32Length > 0)
{
if (g_u32Length > MAX_PACKET_SIZE)
g_u8Size = MAX_PACKET_SIZE;
else
g_u8Size = g_u32Length;
my_memcpy(g_au8UsbBulk1, (char *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
UsbRead ();
}
else
UsbBulkInAck ();
return TRUE;
}
case UFI_READ_CAPACITY:
{
if (g_u32Length == 0)
{
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = MassCMD_BUF;
}
RdCurCapCommand();
g_u8BulkState = BULK_IN;
if (g_u32Length > 0)
{
if (g_u32Length > MAX_PACKET_SIZE)
g_u8Size = MAX_PACKET_SIZE;
else
g_u8Size = g_u32Length;
my_memcpy(g_au8UsbBulk1, (char *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
UsbRead ();
}
else
UsbBulkInAck ();
return TRUE;
}
case UFI_MODE_SELECT_10:
{
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = MassCMD_BUF;
if (g_u32Length > 0)
{
_DRVUSB_TRIG_EP(3, MAX_PACKET_SIZE);
g_u8BulkState = BULK_OUT;
}
return TRUE;
}
case UFI_MODE_SENSE_10:
{
if (g_u32Length == 0)
{
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = MassCMD_BUF;
}
ModeSenseCommand();
g_u8BulkState = BULK_IN;
if (g_u32Length > 0)
{
if (g_u32Length > MAX_PACKET_SIZE)
g_u8Size = MAX_PACKET_SIZE;
else
g_u8Size = g_u32Length;
my_memcpy(g_au8UsbBulk1, (char *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
_DRVUSB_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
UsbRead ();
}
else
UsbBulkInAck ();
return TRUE;
}
case UFI_INQUIRY:
{
my_memcpy(g_au8UsbBulk1, (void *)InquiryID, 36);
g_u8BulkState = BULK_IN;
_DRVUSB_TRIG_EP(2, 36);
return TRUE;
}
case UFI_READ_10:
{
/* Check if it is a new transfer */
if(g_u32Length == 0)
{
/* Prepare the data for Bulk IN transfer */
/* Get LBA address */
g_u32Address = get_be32(&g_sCBW.au8Data[0]);
g_u32LbaAddress = g_u32Address * UDC_SECTOR_SIZE;
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32BytesInStorageBuf = g_u32Length;
if(g_sCBW.bCBWLUN==F_DATA_FLASH_LUN)
{
i = g_u32Length;
if(i > STORAGE_BUFFER_SIZE)
i = STORAGE_BUFFER_SIZE;
DataFlashRead(g_u32Address * UDC_SECTOR_SIZE, i, (unsigned int)STORAGE_DATA_BUF);
g_u32BytesInStorageBuf = i;
g_u32LbaAddress += i;
}
}
g_u32Address = STORAGE_DATA_BUF;
/* Indicate the next packet should be Bulk IN Data packet */
g_u8BulkState = BULK_IN;
if(g_u32BytesInStorageBuf > 0)
{
/* Set the packet size */
if (g_u32BytesInStorageBuf > MAX_PACKET_SIZE)
g_u8Size = MAX_PACKET_SIZE;
else
g_u8Size = g_u32BytesInStorageBuf;
/* Prepare the first data packet (DATA1) */
my_memcpy(g_au8UsbBulk1, (char *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
/* kick - start */
#if 1 // For USB read issue
_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_SET_EP_BUF(2, USB_SRAM_BASE + BUF_BULK0);
UsbRead();
#endif
}
else
{
UsbBulkInAck();
}
return TRUE;
}
case UFI_WRITE_10:
{
if (g_u32Length == 0)
{
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = STORAGE_DATA_BUF;
g_u32DataFlashStartAddr = get_be32(&g_sCBW.au8Data[0]) * UDC_SECTOR_SIZE;
}
if ((g_u32Length > 0))
{
_DRVUSB_TRIG_EP(3, MAX_PACKET_SIZE);
g_u8BulkState = BULK_OUT;
}
return TRUE;
}
case VENDER_CMD: /* Vender Command */
{
extern __weak int32_t ProcessVenderCmd(uint8_t u8Cmd);
if((uint32_t)&ProcessVenderCmd != NULL)
return ProcessVenderCmd(g_sCBW.u8LUN);
}
default:
{
/* Unsupported command */
g_au8SenseKey[0] = 0x05;
g_au8SenseKey[1] = 0x20;
g_au8SenseKey[2] = 0x00;
/* If CBW request for data phase, just return zero packet to end data phase */
if (g_sCBW.dCBWDataTransferLength > 0)
{
/* Data Phase, zero/short packet */
if ((g_sCBW.bmCBWFlags & 0x80) != 0)
{
/* Data-In */
g_u8BulkState = BULK_IN;
_DRVUSB_TRIG_EP(2, 0);
}
}
else
{ /* Status Phase */
g_u8BulkState = BULK_IN;
UsbBulkInAck ();
}
return TRUE;
}
}
}
else if (g_u8BulkState == BULK_OUT)
{
switch (g_sCBW.u8OPCode)
{
case UFI_WRITE_10:
case UFI_MODE_SELECT_10:
{
UsbWrite();
return TRUE;
}
case VENDER_CMD:
{
extern __weak void ComWrite(void);
if((uint32_t)ComWrite != NULL)
ComWrite();
return TRUE;
}
}
}
return TRUE;
}
//======================================================
// USB USB Event
//======================================================
void UsbUsb(uint32_t u32INTSTS)
{
uint32_t u32STS = _DRVUSB_GET_EPSTS();
if (u32INTSTS & INTSTS_SETUP)
{
/* Clear setup event */
_DRVUSB_SET_EVENT_FLAG(INTSTS_SETUP);
if (!UsbSetup())
{
/* Setup error, stall the device */
_DRVUSB_SET_CFGP(0, (CFGP_SSTALL | CFGP_CLRRDY));
_DRVUSB_SET_CFGP(1, (CFGP_SSTALL | CFGP_CLRRDY));
}
}
else if(u32INTSTS & INTSTS_EPTF0)
{
/* Ctrl In */
_DRVUSB_SET_EVENT_FLAG(INTSTS_EPTF0);
UsbInAck();
}
else if(u32INTSTS & INTSTS_EPTF1)
{
/* Ctrl Out */
_DRVUSB_SET_EVENT_FLAG(INTSTS_EPTF1);
UsbOutAck();
}
else if(u32INTSTS & INTSTS_EPTF2)
{
/* Bulk In */
_DRVUSB_SET_EVENT_FLAG(INTSTS_EPTF2);
g_u32OutToggle = u32STS;
UsbBulkInAck();
}
else if(u32INTSTS & INTSTS_EPTF3)
{
/* Bulk Out */
_DRVUSB_SET_EVENT_FLAG(INTSTS_EPTF3);
if (g_u32OutToggle == (u32STS & STS3))
{
_DRVUSB_TRIG_EP(3, MAX_PACKET_SIZE);
}
else
{
if (UsbBulkOutAck())
g_u32OutToggle = u32STS & STS3;
else
{
/* stall */
g_bCBWInvalid = TRUE;
_DRVUSB_SET_CFGP(2, (CFGP_SSTALL | CFGP_CLRRDY));
_DRVUSB_SET_CFGP(3, (CFGP_SSTALL | CFGP_CLRRDY));
}
}
}
else
{ /* Unknow event */
_DRVUSB_SET_EVENT_FLAG(INTSTS_USB);
}
}
//======================================================
// USB ISR
//======================================================
void UsbIsr(void)
{
uint32_t u32INTSTS = _DRVUSB_GET_EVENT_FLAG();
if (u32INTSTS & INTSTS_FLDET)
{
/* Handle the USB attached/detached event */
UsbFdt();
}
else if(u32INTSTS & INTSTS_BUS)
{
/* Handle the USB bus event: Reset, Suspend, and Resume */
UsbBus();
}
else if(u32INTSTS & INTSTS_USB)
{
/* Handle the USB Protocol/Clase event */
UsbUsb(u32INTSTS);
}
}
//======================================================
// USB Initialization
//======================================================
void udcInit(void)
{
int32_t temp;
/* Enable PHY to send bus reset event */
_DRVUSB_ENABLE_USB();
_DRVUSB_ENABLE_SE0();
RoughDelay(1000);
_DRVUSB_DISABLE_SE0();
RoughDelay(1000);
/* Disable PHY */
_DRVUSB_DISABLE_USB();
/* Enable USB device clock */
SYSCLK->APBCLK.USBD_EN = 1;
/* Reset IP */
SYS->IPRSTC2.USBD_RST = 1;
SYS->IPRSTC2.USBD_RST = 0;
/* Select USB divider source */
SYSCLK->CLKDIV.USB_N = 0;
_DRVUSB_ENABLE_USB();
_DRVUSB_ENABLE_SE0();
temp = 0x100;
while(temp--);
_DRVUSB_DISABLE_SE0();
g_u8UsbState = USB_STATE_DETACHED;
_DRVUSB_TRIG_EP(1, 0x08);
UsbFdt();
}
void udcMassBulk(void)
{
/* Handler the USB ISR by polling */
while(1)
{
UsbIsr();
}
}
uint8_t Flash_Identify(uint8_t tLUN)
{
if (tLUN==F_DATA_FLASH_LUN)
{
g_dataFlashTotalSectors = DATA_FLASH_STORAGE_SIZE / UDC_SECTOR_SIZE;
if(g_dataFlashTotalSectors < 0)
{
/* cannot read format */
g_au8SenseKey[0] = 0x03;
g_au8SenseKey[1] = 0x30;
g_au8SenseKey[2] = 0x01;
return FALSE;
}
}
return TRUE;
}
uint8_t udcFlashInit(void)
{
F_DATA_FLASH_LUN = MassLUN;
MassLUN++;
if (!Flash_Identify(F_DATA_FLASH_LUN))
return 0;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -