//========================================================================= //------------------------------------------------------------------------- __myevic__ void hidInit() { /* Init setup packet buffer */ /* Buffer range for setup packet -> [0 ~ 0x7] */ USBD->STBUFSEG = SETUP_BUF_BASE; /*****************************************************/ /* EP0 ==> control IN endpoint, address 0 */ USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); /* Buffer range for EP0 */ USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE); /* EP1 ==> control OUT endpoint, address 0 */ USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); /* Buffer range for EP1 */ USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE); /*****************************************************/ /* EP2 ==> Interrupt IN endpoint, address 1 */ USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM); /* Buffer range for EP2 */ USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE); /* EP3 ==> Interrupt OUT endpoint, address 2 */ USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | INT_OUT_EP_NUM); /* Buffer range for EP3 */ USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE); /* trigger to receive OUT data */ USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); }
void MSC_ReadTrig(void) { uint32_t u32Len; if (g_u32Length) { if (g_u32BytesInStorageBuf) { /* Prepare next data packet */ g_u8Size = EP2_MAX_PKT_SIZE; if (g_u8Size > g_u32Length) g_u8Size = g_u32Length; if (USBD_GET_EP_BUF_ADDR(EP2) == g_u32BulkBuf1) USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), (uint8_t *)g_u32Address, g_u8Size); else USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size); g_u32Address += g_u8Size; } else { u32Len = g_u32Length; if (u32Len > STORAGE_BUFFER_SIZE) u32Len = STORAGE_BUFFER_SIZE; MSC_ReadMedia(g_u32LbaAddress, u32Len, (uint8_t *)STORAGE_DATA_BUF); g_u32BytesInStorageBuf = u32Len; g_u32LbaAddress += u32Len; g_u32Address = STORAGE_DATA_BUF; /* Prepare next data packet */ g_u8Size = EP2_MAX_PKT_SIZE; if (g_u8Size > g_u32Length) g_u8Size = g_u32Length; if (USBD_GET_EP_BUF_ADDR(EP2) == g_u32BulkBuf1) USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), (uint8_t *)g_u32Address, g_u8Size); else USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size); g_u32Address += g_u8Size; } /* DATA0/DATA1 Toggle */ if (USBD_GET_EP_BUF_ADDR(EP2) == g_u32BulkBuf1) USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0); else USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf1); /* Trigger to send out the data packet */ USBD_SET_PAYLOAD_LEN(EP2, g_u8Size); g_u32Length -= g_u8Size; g_u32BytesInStorageBuf -= g_u8Size; } else USBD_SET_PAYLOAD_LEN(EP2, 0); }
void MSC_Write(void) { uint32_t lba, len; if (g_u32Length > EP3_MAX_PKT_SIZE) { if (USBD_GET_EP_BUF_ADDR(EP3) == g_u32BulkBuf0) { USBD_SET_EP_BUF_ADDR(EP3, g_u32BulkBuf1); USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), EP3_MAX_PKT_SIZE); } else { USBD_SET_EP_BUF_ADDR(EP3, g_u32BulkBuf0); USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), EP3_MAX_PKT_SIZE); } g_u32Address += EP3_MAX_PKT_SIZE; g_u32Length -= EP3_MAX_PKT_SIZE; /* Buffer full. Writer it to storage first. */ if (g_u32Address >= (STORAGE_DATA_BUF + STORAGE_BUFFER_SIZE)) { DataFlashWrite(g_u32DataFlashStartAddr, STORAGE_BUFFER_SIZE, (uint32_t)STORAGE_DATA_BUF); g_u32Address = STORAGE_DATA_BUF; g_u32DataFlashStartAddr += STORAGE_BUFFER_SIZE; } } else { if (USBD_GET_EP_BUF_ADDR(EP3) == g_u32BulkBuf0) USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0), g_u32Length); else USBD_MemCopy((uint8_t *)g_u32Address, (uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), g_u32Length); g_u32Address += g_u32Length; g_u32Length = 0; if ((g_sCBW.u8OPCode == UFI_WRITE_10) || (g_sCBW.u8OPCode == UFI_WRITE_12)) { lba = get_be32(&g_sCBW.au8Data[0]); len = g_sCBW.dCBWDataTransferLength; 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; MSC_AckCmd(); } }
/** * @brief USBD Endpoint Config. * @param None. * @retval None. */ void CCID_Init(void) { /* Init setup packet buffer */ /* Buffer for setup packet -> [0 ~ 0x7] */ USBD->BUFSEG = SETUP_BUF_BASE; /*****************************************************/ /* EP0 ==> control IN endpoint, address 0 */ USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); /* Buffer range for EP0 */ USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE); /* EP1 ==> control OUT endpoint, address 0 */ USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); /* Buffer range for EP1 */ USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE); /*****************************************************/ /* EP2 ==> Bulk IN endpoint, address 2 */ USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | BULK_IN_EP_NUM); /* Buffer offset for EP2 */ USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE); /* EP3 ==> Bulk Out endpoint, address 2 */ USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | BULK_OUT_EP_NUM); /* Buffer offset for EP3 */ USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE); /* trigger receive OUT data */ USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); /* EP4 ==> Interrupt IN endpoint, address 3 */ USBD_CONFIG_EP(EP4, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM); /* Buffer offset for EP4 -> */ USBD_SET_EP_BUF_ADDR(EP4, EP4_BUF_BASE); /* check card state */ gu8IsDeviceReady = 1; pu8IntInBuf = &UsbIntMessageBuffer[0]; pUsbMessageBuffer = &UsbMessageBuffer[0]; RDR_to_PC_NotifySlotChange(); USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP4)), pu8IntInBuf, 2); USBD_SET_PAYLOAD_LEN(EP4, 2); }
void USB_VirtualCOM_Init() { // Initialize state USB_VirtualCOM_txQueue.head = USB_VirtualCOM_txQueue.tail = NULL; USB_VirtualCOM_bulkInWaiting = 1; USB_VirtualCOM_rxBuffer.readIndex = USB_VirtualCOM_rxBuffer.writeIndex = 0; USB_VirtualCOM_rxBuffer.dataSize = 0; USB_VirtualCOM_rxCallbackPtr = NULL; USB_VirtualCOM_isAsync = 0; // Open USB USBD_Open(&USB_VirtualCOM_UsbdInfo, USB_VirtualCOM_HandleClassRequest, NULL); // Initialize setup packet buffer USBD->STBUFSEG = USB_VCOM_SETUP_BUF_BASE; // Control IN endpoint USBD_CONFIG_EP(USB_VCOM_CTRL_IN_EP, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | USB_VCOM_CTRL_IN_EP_NUM); USBD_SET_EP_BUF_ADDR(USB_VCOM_CTRL_IN_EP, USB_VCOM_CTRL_IN_BUF_BASE); // Control OUT endpoint USBD_CONFIG_EP(USB_VCOM_CTRL_OUT_EP, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | USB_VCOM_CTRL_OUT_EP_NUM); USBD_SET_EP_BUF_ADDR(USB_VCOM_CTRL_OUT_EP, USB_VCOM_CTRL_OUT_BUF_BASE); // Bulk IN endpoint USBD_CONFIG_EP(USB_VCOM_BULK_IN_EP, USBD_CFG_EPMODE_IN | USB_VCOM_BULK_IN_EP_NUM); USBD_SET_EP_BUF_ADDR(USB_VCOM_BULK_IN_EP, USB_VCOM_BULK_IN_BUF_BASE); // Bulk OUT endpoint USBD_CONFIG_EP(USB_VCOM_BULK_OUT_EP, USBD_CFG_EPMODE_OUT | USB_VCOM_BULK_OUT_EP_NUM); USBD_SET_EP_BUF_ADDR(USB_VCOM_BULK_OUT_EP, USB_VCOM_BULK_OUT_BUF_BASE); USBD_SET_PAYLOAD_LEN(USB_VCOM_BULK_OUT_EP, USB_VCOM_BULK_OUT_MAX_PKT_SIZE); // Interrupt IN endpoint USBD_CONFIG_EP(USB_VCOM_INT_IN_EP, USBD_CFG_EPMODE_IN | USB_VCOM_INT_IN_EP_NUM); USBD_SET_EP_BUF_ADDR(USB_VCOM_INT_IN_EP, USB_VCOM_INT_IN_BUF_BASE); // Start USB USBD_Start(); // Enable USB interrupt NVIC_EnableIRQ(USBD_IRQn); }
void MSC_Init(void) { /* Init setup packet buffer */ /* Buffer range for setup packet -> [0 ~ 0x7] */ USBD->BUFSEG = SETUP_BUF_BASE; /*****************************************************/ /* EP0 ==> control IN endpoint, address 0 */ USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); /* Buffer range for EP0 */ USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE); /* EP1 ==> control OUT endpoint, address 0 */ USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); /* Buffer range for EP1 */ USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE); /*****************************************************/ /* EP2 ==> Bulk IN endpoint, address 2 */ USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | BULK_IN_EP_NUM); /* Buffer range for EP2 */ USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE); /* EP3 ==> Bulk Out endpoint, address 3 */ USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | BULK_OUT_EP_NUM); /* Buffer range for EP3 */ USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE); /* trigger to receive OUT data */ USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); /*****************************************************/ g_u32BulkBuf0 = EP3_BUF_BASE; g_u32BulkBuf1 = EP2_BUF_BASE; g_sCSW.dCSWSignature = CSW_SIGNATURE; g_TotalSectors = DATA_FLASH_STORAGE_SIZE / UDC_SECTOR_SIZE; }
/** * @brief USBD Endpoint Config. * @param None. * @retval None. */ void HID_Init(void) { /* Init setup packet buffer */ /* Buffer range for setup packet -> [0 ~ 0x7] */ USBD->STBUFSEG = SETUP_BUF_BASE; /*****************************************************/ /* EP0 ==> control IN endpoint, address 0 */ USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); /* Buffer range for EP0 */ USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE); /* EP1 ==> control OUT endpoint, address 0 */ USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); /* Buffer range for EP1 */ USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE); /*****************************************************/ /* EP2 ==> Interrupt IN endpoint, address 1 */ USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM); /* Buffer range for EP2 */ USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE); }
/** * @brief USBD Endpoint Config. * @param None. * @retval None. */ void PTR_Init(void) { /* Init setup packet buffer */ /* Buffer for setup packet -> [0 ~ 0x7] */ USBD->BUFSEG = SETUP_BUF_BASE; /*****************************************************/ /* EP0 ==> control IN endpoint, address 0 */ USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); /* Buffer range for EP0 */ USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE); /* EP1 ==> control OUT endpoint, address 0 */ USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); /* Buffer range for EP1 */ USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE); /*****************************************************/ /* EP2 ==> Bulk IN endpoint, address 1 */ USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | BULK_IN_EP_NUM); /* Buffer offset for EP2 */ USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE); /* EP3 ==> Bulk Out endpoint, address 2 */ USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | BULK_OUT_EP_NUM); /* Buffer offset for EP3 */ USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE); /* trigger receive OUT data */ USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); /* EP4 ==> Interrupt IN endpoint, address 3 */ USBD_CONFIG_EP(EP4, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM); /* Buffer offset for EP4 -> */ USBD_SET_EP_BUF_ADDR(EP4, EP4_BUF_BASE); /*****************************************************/ /* EP5 ==> Interrupt IN endpoint, address 4 */ USBD_CONFIG_EP(EP5, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM_1); /* Buffer range for EP5 */ USBD_SET_EP_BUF_ADDR(EP5, EP5_BUF_BASE); /* EP6 ==> Interrupt OUT endpoint, address 5 */ USBD_CONFIG_EP(EP6, USBD_CFG_EPMODE_OUT | INT_OUT_EP_NUM); /* Buffer range for EP6 */ USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE); /* trigger to receive OUT data */ USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE); }
//========================================================================= //------------------------------------------------------------------------- __myevic__ void SetupEndpoints() { /* Init setup packet buffer */ /* Buffer range for setup packet -> [0 ~ 0x7] */ USBD->STBUFSEG = SETUP_BUF_BASE; /*****************************************************/ /* EP0 ==> control IN endpoint, address 0 */ USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); /* Buffer range for EP0 */ USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE); /* EP1 ==> control OUT endpoint, address 0 */ USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); /* Buffer range for EP1 */ USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE); /*****************************************************/ /* EP2 ==> Interrupt IN endpoint, address 1 */ USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | HID_INT_IN_EP_NUM); /* Buffer range for EP2 */ USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE); /* EP3 ==> Interrupt OUT endpoint, address 2 */ USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | HID_INT_OUT_EP_NUM); /* Buffer range for EP3 */ USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE); /* trigger to receive OUT data */ USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); /*****************************************************/ if ( dfStatus.vcom ) { /* EP4 ==> Interrupt IN endpoint, address 3 */ USBD_CONFIG_EP(EP4, USBD_CFG_EPMODE_IN | VCOM_INT_IN_EP_NUM); /* Buffer offset for EP4 -> */ USBD_SET_EP_BUF_ADDR(EP4, EP4_BUF_BASE); /* EP5 ==> Bulk IN endpoint, address 1 */ USBD_CONFIG_EP(EP5, USBD_CFG_EPMODE_IN | VCOM_BULK_IN_EP_NUM); /* Buffer offset for EP5 */ USBD_SET_EP_BUF_ADDR(EP5, EP5_BUF_BASE); /* EP6 ==> Bulk Out endpoint, address 2 */ USBD_CONFIG_EP(EP6, USBD_CFG_EPMODE_OUT | VCOM_BULK_OUT_EP_NUM); /* Buffer offset for EP6 */ USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE); /* trigger receive OUT data */ USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE); } else if ( dfStatus.storage ) { /* EP5 ==> Bulk IN endpoint, address 1 */ USBD_CONFIG_EP(EP5, USBD_CFG_EPMODE_IN | MSC_BULK_IN_EP_NUM); /* Buffer offset for EP5 */ USBD_SET_EP_BUF_ADDR(EP5, EP5_BUF_BASE); /* EP6 ==> Bulk Out endpoint, address 2 */ USBD_CONFIG_EP(EP6, USBD_CFG_EPMODE_OUT | MSC_BULK_OUT_EP_NUM); /* Buffer offset for EP6 */ USBD_SET_EP_BUF_ADDR(EP6, EP6_BUF_BASE); /* trigger receive OUT data */ USBD_SET_PAYLOAD_LEN(EP6, EP6_MAX_PKT_SIZE); } }
void MSC_ProcessCmd(void) { uint8_t u8Len; int32_t i; uint32_t Hcount, Dcount; if (g_u8EP3Ready) { g_u8EP3Ready = 0; if (g_u8BulkState == BULK_CBW) { u8Len = USBD_GET_PAYLOAD_LEN(EP3); /* Check Signature & length of CBW */ /* Bulk Out buffer */ if ((*(uint32_t *) ((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0) != CBW_SIGNATURE) || (u8Len != 31)) { /* Invalid CBW */ g_u8Prevent = 1; USBD_SET_EP_STALL(EP2); USBD_SET_EP_STALL(EP3); USBD_LockEpStall((1 << EP2) | (1 << EP3)); return; } /* Get the CBW */ for (i = 0; i < u8Len; i++) *((uint8_t *) (&g_sCBW.dCBWSignature) + i) = *(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0 + i); /* Prepare to echo the tag from CBW to CSW */ g_sCSW.dCSWTag = g_sCBW.dCBWTag; Hcount = g_sCBW.dCBWDataTransferLength; /* 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; g_u8Prevent = 1; } else g_u8Prevent = 0; g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } case UFI_TEST_UNIT_READY: { if (Hcount != 0) { if (g_sCBW.bmCBWFlags == 0) /* Ho > Dn (Case 9) */ { g_u8Prevent = 1; USBD_SET_EP_STALL(EP3); g_sCSW.bCSWStatus = 0x1; g_sCSW.dCSWDataResidue = Hcount; } } else /* Hn == Dn (Case 1) */ { if (g_u8Remove) { g_sCSW.dCSWDataResidue = 0; g_sCSW.bCSWStatus = 1; g_au8SenseKey[0] = 0x02; /* Not ready */ g_au8SenseKey[1] = 0x3A; g_au8SenseKey[2] = 0; g_u8Prevent = 1; } else { g_sCSW.dCSWDataResidue = 0; g_sCSW.bCSWStatus = 0; } } g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } case UFI_START_STOP: { if ((g_sCBW.au8Data[2] & 0x03) == 0x2) { g_u8Remove = 1; } } case UFI_VERIFY_10: { g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } case UFI_REQUEST_SENSE: { if ((Hcount > 0) && (Hcount <= 18)) { MSC_RequestSense(); USBD_SET_PAYLOAD_LEN(EP2, Hcount); g_u8BulkState = BULK_IN; g_sCSW.bCSWStatus = 0; g_sCSW.dCSWDataResidue = 0; return; } else { USBD_SET_EP_STALL(EP2); g_u8Prevent = 1; g_sCSW.bCSWStatus = 0x01; g_sCSW.dCSWDataResidue = 0; g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } } case UFI_READ_FORMAT_CAPACITY: { if (g_u32Length == 0) { g_u32Length = g_sCBW.dCBWDataTransferLength; g_u32Address = MassCMD_BUF; } MSC_ReadFormatCapacity(); g_u8BulkState = BULK_IN; if (g_u32Length > 0) { if (g_u32Length > EP2_MAX_PKT_SIZE) g_u8Size = EP2_MAX_PKT_SIZE; else g_u8Size = g_u32Length; /* Bulk IN buffer */ USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size); g_u32Address += g_u8Size; USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0); MSC_Read(); } return; } case UFI_READ_CAPACITY: { if (g_u32Length == 0) { g_u32Length = g_sCBW.dCBWDataTransferLength; g_u32Address = MassCMD_BUF; } MSC_ReadCapacity(); g_u8BulkState = BULK_IN; if (g_u32Length > 0) { if (g_u32Length > EP2_MAX_PKT_SIZE) g_u8Size = EP2_MAX_PKT_SIZE; else g_u8Size = g_u32Length; /* Bulk IN buffer */ USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size); g_u32Address += g_u8Size; USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0); MSC_Read(); } return; } case UFI_MODE_SELECT_6: case UFI_MODE_SELECT_10: { g_u32Length = g_sCBW.dCBWDataTransferLength; g_u32Address = MassCMD_BUF; if (g_u32Length > 0) { USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); g_u8BulkState = BULK_OUT; } return; } case UFI_MODE_SENSE_6: { *(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+0) = 0x3; *(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+1) = 0x0; *(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+2) = 0x0; *(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+3) = 0x0; USBD_SET_PAYLOAD_LEN(EP2, 4); g_u8BulkState = BULK_IN; g_sCSW.bCSWStatus = 0; g_sCSW.dCSWDataResidue = Hcount - 4;; return; } case UFI_MODE_SENSE_10: { if (g_u32Length == 0) { g_u32Length = g_sCBW.dCBWDataTransferLength; g_u32Address = MassCMD_BUF; } MSC_ModeSense10(); g_u8BulkState = BULK_IN; if (g_u32Length > 0) { if (g_u32Length > EP2_MAX_PKT_SIZE) g_u8Size = EP2_MAX_PKT_SIZE; else g_u8Size = g_u32Length; /* Bulk IN buffer */ USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size); g_u32Address += g_u8Size; USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0); MSC_Read(); } return; } case UFI_INQUIRY: { if ((Hcount > 0) && (Hcount <= 36)) { /* Bulk IN buffer */ USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_au8InquiryID, Hcount); USBD_SET_PAYLOAD_LEN(EP2, Hcount); g_u8BulkState = BULK_IN; g_sCSW.bCSWStatus = 0; g_sCSW.dCSWDataResidue = 0; return; } else { USBD_SET_EP_STALL(EP2); g_u8Prevent = 1; g_sCSW.bCSWStatus = 0x01; g_sCSW.dCSWDataResidue = 0; g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } } case UFI_READ_12: case UFI_READ_10: { /* Check if it is a new transfer */ if(g_u32Length == 0) { Dcount = (get_be32(&g_sCBW.au8Data[4])>>8) * 512; if (g_sCBW.bmCBWFlags == 0x80) /* IN */ { if (Hcount == Dcount) /* Hi == Di (Case 6)*/ { } else if (Hcount < Dcount) /* Hn < Di (Case 2) || Hi < Di (Case 7) */ { if (Hcount) /* Hi < Di (Case 7) */ { g_u8Prevent = 1; g_sCSW.bCSWStatus = 0x01; g_sCSW.dCSWDataResidue = 0; } else /* Hn < Di (Case 2) */ { g_u8Prevent = 1; g_sCSW.bCSWStatus = 0x01; g_sCSW.dCSWDataResidue = 0; g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } } else if (Hcount > Dcount) /* Hi > Dn (Case 4) || Hi > Di (Case 5) */ { g_u8Prevent = 1; g_sCSW.bCSWStatus = 0x01; g_sCSW.dCSWDataResidue = 0; } } else /* Ho <> Di (Case 10) */ { g_u8Prevent = 1; USBD_SET_EP_STALL(EP3); g_sCSW.bCSWStatus = 0x01; g_sCSW.dCSWDataResidue = Hcount; g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } } /* 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; i = g_u32Length; if (i > STORAGE_BUFFER_SIZE) i = STORAGE_BUFFER_SIZE; MSC_ReadMedia(g_u32Address * UDC_SECTOR_SIZE, i, (uint8_t *)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 > EP2_MAX_PKT_SIZE) g_u8Size = EP2_MAX_PKT_SIZE; else g_u8Size = g_u32BytesInStorageBuf; /* Prepare the first data packet (DATA1) */ /* Bulk IN buffer */ USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1), (uint8_t *)g_u32Address, g_u8Size); g_u32Address += g_u8Size; /* kick - start */ USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf1); /* Trigger to send out the data packet */ USBD_SET_PAYLOAD_LEN(EP2, g_u8Size); g_u32Length -= g_u8Size; g_u32BytesInStorageBuf -= g_u8Size; } return; } case UFI_WRITE_12: case UFI_WRITE_10: { if (g_u32Length == 0) { Dcount = (get_be32(&g_sCBW.au8Data[4])>>8) * 512; if (g_sCBW.bmCBWFlags == 0x00) /* OUT */ { if (Hcount == Dcount) /* Ho == Do (Case 12)*/ { g_sCSW.dCSWDataResidue = 0; g_sCSW.bCSWStatus = 0; } else if (Hcount < Dcount) /* Hn < Do (Case 3) || Ho < Do (Case 13) */ { g_u8Prevent = 1; g_sCSW.dCSWDataResidue = 0; g_sCSW.bCSWStatus = 0x1; if (Hcount == 0) /* Hn < Do (Case 3) */ { g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } } else if (Hcount > Dcount) /* Ho > Do (Case 11) */ { g_u8Prevent = 1; g_sCSW.dCSWDataResidue = 0; g_sCSW.bCSWStatus = 0x1; } g_u32Length = g_sCBW.dCBWDataTransferLength; g_u32Address = STORAGE_DATA_BUF; g_u32DataFlashStartAddr = get_be32(&g_sCBW.au8Data[0]) * UDC_SECTOR_SIZE; } else /* Hi <> Do (Case 8) */ { g_u8Prevent = 1; g_sCSW.dCSWDataResidue = Hcount; g_sCSW.bCSWStatus = 0x1; USBD_SET_EP_STALL(EP2); g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } } if ((g_u32Length > 0)) { USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); g_u8BulkState = BULK_OUT; } return; } case UFI_READ_16: { USBD_SET_EP_STALL(EP2); g_u8Prevent = 1; g_sCSW.bCSWStatus = 0x01; g_sCSW.dCSWDataResidue = 0; g_u8BulkState = BULK_IN; MSC_AckCmd(); return; } 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; USBD_SET_PAYLOAD_LEN(EP2, 0); } } else { /* Status Phase */ g_u8BulkState = BULK_IN; MSC_AckCmd(); } return; } }
void MSC_ClassRequest(void) { uint8_t buf[8]; USBD_GetSetupPacket(buf); if (buf[0] & 0x80) /* request data transfer direction */ { // Device to host switch (buf[1]) { case GET_MAX_LUN: { /* Check interface number with cfg descriptor and check wValue = 0, wLength = 1 */ if ((((buf[3]<<8)+buf[2]) == 0) && (((buf[5]<<8)+buf[4]) == 0) && (((buf[7]<<8)+buf[6]) == 1)) { M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0; /* Data stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 1); /* Status stage */ USBD_PrepareCtrlOut(0,0); } else /* Invalid Get MaxLun command */ { USBD_SetStall(0); } break; } default: { /* Setup error, stall the device */ USBD_SetStall(0); break; } } } else { // Host to device switch (buf[1]) { case BULK_ONLY_MASS_STORAGE_RESET: { /* Check interface number with cfg descriptor and check wValue = 0, wLength = 0 */ if ((((buf[3]<<8)+buf[2]) == 0) && (((buf[5]<<8)+buf[4]) == 0) && (((buf[7]<<8)+buf[6]) == 0)) { USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); USBD_LockEpStall(0); /* Clear ready */ USBD->EP[EP2].CFG |= USBD_CFG_CLRRDY_Msk; USBD->EP[EP3].CFG |= USBD_CFG_CLRRDY_Msk; /* Prepare to receive the CBW */ g_u8EP3Ready = 0; g_u8BulkState = BULK_CBW; USBD_SET_DATA1(EP3); USBD_SET_EP_BUF_ADDR(EP3, g_u32BulkBuf0); USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); } else /* Invalid Reset command */ { USBD_SetStall(0); } break; } default: { // Stall /* Setup error, stall the device */ USBD_SetStall(0); break; } } } }