/** * Write data to the RX ring buffer. * If the data size exceeds current buffer capacity, excess * data will be discarded. * This is an internal function. * * @param src Source buffer. * @param size Data size. * * @return Number of bytes actually written. */ static uint16_t USB_VirtualCOM_RxBuffer_Write(uint8_t *src, uint16_t size) { uint16_t copySize1, copySize2; // Discard overflowing data size = Minimum(USB_VCOM_RX_BUF_SIZE - USB_VirtualCOM_rxBuffer.dataSize, size); // Copy data to write index up to buffer end copySize1 = Minimum(USB_VCOM_RX_BUF_SIZE - USB_VirtualCOM_rxBuffer.writeIndex, size); if(copySize1 == 0) { return 0; } USBD_MemCopy((uint8_t *) (USB_VirtualCOM_rxBuffer.buffer + USB_VirtualCOM_rxBuffer.writeIndex), src, copySize1); // Copy data (if any) to buffer start if(copySize1 != size) { copySize2 = size - copySize1; USBD_MemCopy((uint8_t *) USB_VirtualCOM_rxBuffer.buffer, src + copySize1, copySize2); } // Update index and used size USB_VirtualCOM_rxBuffer.writeIndex = (USB_VirtualCOM_rxBuffer.writeIndex + size) % USB_VCOM_RX_BUF_SIZE; USB_VirtualCOM_rxBuffer.dataSize += size; return size; }
void EP2_Handler(void) { /* BULK IN transfer */ if (gu8IsBulkInReady) { if(gi32UsbdMessageLength >= EP2_MAX_PKT_SIZE) { gu8IsBulkInReady = 1; USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, EP2_MAX_PKT_SIZE); USBD_SET_PAYLOAD_LEN(EP2, EP2_MAX_PKT_SIZE); pUsbMessageBuffer += EP2_MAX_PKT_SIZE; gi32UsbdMessageLength -= EP2_MAX_PKT_SIZE; } else { USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, gi32UsbdMessageLength); USBD_SET_PAYLOAD_LEN(EP2, gi32UsbdMessageLength); gi32UsbdMessageLength = 0; gu8IsBulkInReady = 0; } } if (!gu8IsBulkOutReady) USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); }
/** * Reads data from the RX ring buffer. * If the data size exceeds currently available bytes, it will * be reduced. * This is an internal function. * * @param dst Destination buffer. * @param size Data size. * * @return Number of bytes actually read. */ static uint16_t USB_VirtualCOM_RxBuffer_Read(uint8_t *dst, uint16_t size) { uint16_t copySize1, copySize2; // Do not read more than is available size = Minimum(USB_VirtualCOM_rxBuffer.dataSize, size); // Copy data from read index up to buffer end copySize1 = Minimum(USB_VCOM_RX_BUF_SIZE - USB_VirtualCOM_rxBuffer.readIndex, size); if(copySize1 == 0) { return 0; } USBD_MemCopy(dst, (uint8_t *) (USB_VirtualCOM_rxBuffer.buffer + USB_VirtualCOM_rxBuffer.readIndex), copySize1); // Copy data (if any) from buffer start if(copySize1 != size) { copySize2 = size - copySize1; USBD_MemCopy(dst + copySize1, (uint8_t *) USB_VirtualCOM_rxBuffer.buffer, copySize2); } // Update index and used size USB_VirtualCOM_rxBuffer.readIndex = (USB_VirtualCOM_rxBuffer.readIndex + size) % USB_VCOM_RX_BUF_SIZE; USB_VirtualCOM_rxBuffer.dataSize -= size; return size; }
void CCID_BulkInMessage(void) { gi32UsbdMessageLength = USB_MESSAGE_HEADER_SIZE + make32(&UsbMessageBuffer[OFFSET_DWLENGTH]); pUsbMessageBuffer = UsbMessageBuffer; if (gu8IsBulkInReady) { if(gi32UsbdMessageLength >= EP2_MAX_PKT_SIZE) { gu8IsBulkInReady = 1; USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, EP2_MAX_PKT_SIZE); USBD_SET_PAYLOAD_LEN(EP2, EP2_MAX_PKT_SIZE); pUsbMessageBuffer += EP2_MAX_PKT_SIZE; gi32UsbdMessageLength -= EP2_MAX_PKT_SIZE; } else { USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), pUsbMessageBuffer, gi32UsbdMessageLength); USBD_SET_PAYLOAD_LEN(EP2, gi32UsbdMessageLength); gi32UsbdMessageLength = 0; gu8IsBulkInReady = 0; } } }
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 Repeat Control IN pipe * * @param None * * @return None * * @details This function processes the remained data of Control IN transfer. * */ void USBD_CtrlIn(void) { static uint8_t u8ZeroFlag = 0; if(g_usbd_CtrlInSize) { // Process remained data if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize) { // Data size > MXPLD USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize); USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize; g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize; } else { // Data size <= MXPLD USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize); USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize); if(g_usbd_CtrlInSize == g_usbd_CtrlMaxPktSize) u8ZeroFlag = 1; g_usbd_CtrlInPointer = 0; g_usbd_CtrlInSize = 0; } } else { // In ACK for Set address if((g_usbd_SetupPacket[0] == 0) && (g_usbd_SetupPacket[1] == 5)) { if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0)) { USBD_SET_ADDR(g_usbd_UsbAddr); } } // For size if n x MXPLD if(u8ZeroFlag) { USBD_SET_PAYLOAD_LEN(EP0, 0); u8ZeroFlag = 0; } // No more data for IN token USBD_PrepareCtrlOut(0, 0); DBG_PRINTF("Ctrl In Done.\n"); } }
/** * @brief Repeat Control IN pipe * * @param None * * @return None * * @details This function processes the remained data of Control IN transfer. * */ void USBD_CtrlIn(void) { static uint8_t u8ZeroFlag = 0; DBG_PRINTF("Ctrl In Ack. residue %d\n", g_usbd_CtrlInSize); if(g_usbd_CtrlInSize) { // Process remained data if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize) { // Data size > MXPLD USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize); USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize; g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize; } else { // Data size <= MXPLD USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize); USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize); if(g_usbd_CtrlInSize == g_usbd_CtrlMaxPktSize) u8ZeroFlag = 1; g_usbd_CtrlInPointer = 0; g_usbd_CtrlInSize = 0; } } else // No more data for IN token { // In ACK for Set address if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS)) { if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0)) { USBD_SET_ADDR(g_usbd_UsbAddr); } } /* For the case of data size is integral times maximum packet size */ if(u8ZeroFlag) { USBD_SET_PAYLOAD_LEN(EP0, 0); u8ZeroFlag = 0; } DBG_PRINTF("Ctrl In done.\n"); } }
//----- (000025B8) -------------------------------------------------------- __myevic__ uint32_t hidGetInfoCmd( CMD_T *pCmd ) { uint32_t u32StartAddr; uint32_t u32ParamLen; u32StartAddr = pCmd->u32Arg1; u32ParamLen = pCmd->u32Arg2; myprintf( "Get Info command - Start Addr: %d Param Len: %d\n", pCmd->u32Arg1, pCmd->u32Arg2 ); if ( u32ParamLen ) { dfChecksum = Checksum( (uint8_t *)DataFlash.params, FMC_FLASH_PAGE_SIZE - 4 ); if ( u32StartAddr + u32ParamLen > FMC_FLASH_PAGE_SIZE ) { u32ParamLen = FMC_FLASH_PAGE_SIZE - u32StartAddr; } MemCpy( hidData, ((uint8_t *)&DataFlash) + u32StartAddr, u32ParamLen ); hidDataIndex = u32ParamLen; pCmd->u32Signature = u32ParamLen; USBD_MemCopy( (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), hidData, EP2_MAX_PKT_SIZE ); USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE ); hidDataIndex -= EP2_MAX_PKT_SIZE; } return 0; }
/** * Copies a packet to the bulk IN buffer and sets the payload length. * USB_VirtualCOM_bulkInWaiting will be set to false. * This is an internal function. * * @param buffer Source buffer (can be NULL for zero-length packets). * @param size Packet size. Must be <= USB_VCOM_BULK_IN_MAX_PKT_SIZE. */ static void USB_VirtualCOM_SendBulkInPayload(const uint8_t *buffer, uint32_t size) { USB_VirtualCOM_bulkInWaiting = 0; if(buffer != NULL && size != 0) { USBD_MemCopy((uint8_t *) (USBD_BUF_BASE + USB_VCOM_BULK_IN_BUF_BASE), (uint8_t *) buffer, size); } USBD_SET_PAYLOAD_LEN(USB_VCOM_BULK_IN_EP, size); }
int32_t HID_CmdReadPages(CMD_T *pCmd) { uint32_t u32StartPage; uint32_t u32Pages; u32StartPage = pCmd->u32Arg1; u32Pages = pCmd->u32Arg2; printf("Read command - Start page: %d Pages Numbers: %d\n", u32StartPage, u32Pages); if(u32Pages) { /* Update data to page buffer to upload */ /* TODO: We need to update the page data if got a page read command. (0xFF is used in this sample code) */ memcpy(g_u8PageBuff, g_u8TestPages, sizeof(g_u8PageBuff)); g_u32BytesInPageBuf = PAGE_SIZE; /* The signature word is used as page counter */ pCmd->u32Signature = 1; /* Trigger HID IN */ USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5)), (void *)g_u8PageBuff, EP5_MAX_PKT_SIZE); USBD_SET_PAYLOAD_LEN(EP5, EP5_MAX_PKT_SIZE); g_u32BytesInPageBuf -= EP5_MAX_PKT_SIZE; } return 0; }
void MSC_AckCmd(uint32_t u32Residue) { g_sCSW.dCSWDataResidue = u32Residue; g_sCSW.bCSWStatus = g_u8Prevent; USBD_MemCopy((uint8_t *)g_u32MassBase, (uint8_t *)&g_sCSW.dCSWSignature, 16); MSC_BulkIn(g_u32MassBase, 13); g_u8BulkState = BULK_NORMAL; }
void HID_GetOutReport(uint8_t *pu8EpBuf, uint32_t u32Size) { uint8_t u8Cmd; uint32_t u32StartPage; uint32_t u32Pages; uint32_t u32PageCnt; /* Get command information */ u8Cmd = gCmd.u8Cmd; u32StartPage = gCmd.u32Arg1; u32Pages = gCmd.u32Arg2; u32PageCnt = gCmd.u32Signature; /* The signature word is used to count pages */ /* Check if it is in the data phase of write command */ if((u8Cmd == HID_CMD_WRITE) && (u32PageCnt < u32Pages)) { /* Process the data phase of write command */ /* Get data from HID OUT */ USBD_MemCopy(&g_u8PageBuff[g_u32BytesInPageBuf], pu8EpBuf, EP3_MAX_PKT_SIZE); g_u32BytesInPageBuf += EP3_MAX_PKT_SIZE; /* The HOST must make sure the data is PAGE_SIZE alignment */ if(g_u32BytesInPageBuf >= PAGE_SIZE) { printf("Writing page %d\n", u32StartPage + u32PageCnt); /* TODO: We should program received data to storage here */ memcpy(g_u8TestPages + u32PageCnt * PAGE_SIZE, g_u8PageBuff, sizeof(g_u8PageBuff)); u32PageCnt++; /* Write command complete! */ if(u32PageCnt >= u32Pages) { u8Cmd = HID_CMD_NONE; printf("Write command complete.\n"); } g_u32BytesInPageBuf = 0; } /* Update command status */ gCmd.u8Cmd = u8Cmd; gCmd.u32Signature = u32PageCnt; } else { /* Check and process the command packet */ if(ProcessCommand(pu8EpBuf, u32Size)) { printf("Unknown HID command!\n"); } } }
/** * USB CDC class request handler. * This is an internal function. */ static void USB_VirtualCOM_HandleClassRequest() { USB_SetupPacket_t setupPacket; USBD_GetSetupPacket((uint8_t *) &setupPacket); if(setupPacket.bmRequestType & 0x80) { // Transfer direction: device to host switch(setupPacket.bRequest) { case USB_VCOM_REQ_GET_LINE_CODE: if(setupPacket.wIndex == USB_VCOM_INDEX) { // Copy line coding data to USB buffer USBD_MemCopy((uint8_t *) (USBD_BUF_BASE + USB_VCOM_CTRL_IN_BUF_BASE), (uint8_t *) &USB_VirtualCOM_lineCoding, USB_VirtualCOM_LineCoding_t_SIZE); } // Data stage USBD_SET_DATA1(USB_VCOM_CTRL_IN_EP); USBD_SET_PAYLOAD_LEN(USB_VCOM_CTRL_IN_EP, USB_VirtualCOM_LineCoding_t_SIZE); // Status stage USBD_PrepareCtrlOut(NULL, 0); break; default: // Setup error, stall the device USBD_SetStall(USB_VCOM_CTRL_IN_EP); USBD_SetStall(USB_VCOM_CTRL_OUT_EP); break; } } else { // Transfer direction: host to device switch(setupPacket.bRequest) { case USB_VCOM_REQ_SET_CONTROL_LINE_STATE: // Control signals are ignored // Status stage USBD_SET_DATA1(USB_VCOM_CTRL_IN_EP); USBD_SET_PAYLOAD_LEN(USB_VCOM_CTRL_IN_EP, 0); break; case USB_VCOM_REQ_SET_LINE_CODE: if(setupPacket.wIndex == USB_VCOM_INDEX) { // Prepare for line coding copy USBD_PrepareCtrlOut((uint8_t *) &USB_VirtualCOM_lineCoding, USB_VirtualCOM_LineCoding_t_SIZE); } // Status stage USBD_SET_DATA1(USB_VCOM_CTRL_IN_EP); USBD_SET_PAYLOAD_LEN(USB_VCOM_CTRL_IN_EP, 0); break; default: // Setup error, stall the device USBD_SetStall(USB_VCOM_CTRL_IN_EP); USBD_SetStall(USB_VCOM_CTRL_OUT_EP); break; } } }
void CCID_ClassRequest(void) { uint8_t buf[8]; USBD_GetSetupPacket(buf); if (buf[0] & 0x80) /* request data transfer direction */ { // Device to host switch (buf[1]) { case CCID_GET_CLOCK_FREQUENCIES: case CCID_GET_DATA_RATES: { uint8_t pData[1] = {0}; USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)), pData, sizeof(pData)); /* Data stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, sizeof(pData)); /* Status stage */ USBD_PrepareCtrlOut(0,0); break; } default: { /* Setup error, stall the device */ USBD_SetStall(0); break; } } } else { // Host to device switch (buf[1]) { case CCID_ABORT: { /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } default: { // Stall /* Setup error, stall the device */ USBD_SetStall(0); break; } } } }
void EP4_Handler(void) { /* INT IN transfer */ if (gu8IsDeviceReady) { 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); gu8IsDeviceReady = 0; } if (!gu8IsBulkOutReady) USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); }
/** * @brief Prepare the first Control IN pipe * * @param[in] pu8Buf The pointer of data sent to USB host. * @param[in] u32Size The IN transfer size. * * @return None * * @details Prepare data for Control IN transfer. * */ void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size) { DBG_PRINTF("Prepare Ctrl In %d\n", u32Size); if(u32Size > g_usbd_CtrlMaxPktSize) { // Data size > MXPLD g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize; g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize; USBD_SET_DATA1(EP0); USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize); USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); } else { // Data size <= MXPLD g_usbd_CtrlInPointer = 0; g_usbd_CtrlInSize = 0; USBD_SET_DATA1(EP0); USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size); USBD_SET_PAYLOAD_LEN(EP0, u32Size); } }
//------------------------------------------------------------------------- __myevic__ void hidStartInReport( uint32_t u32ParamLen ) { hidDataIndex = u32ParamLen; hidCmd.u32Signature = u32ParamLen; USBD_MemCopy( (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), hidInDataPtr, EP2_MAX_PKT_SIZE ); USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE ); hidDataIndex -= EP2_MAX_PKT_SIZE; }
void HID_SetInReport(void) { uint32_t u32StartPage; uint32_t u32TotalPages; uint32_t u32PageCnt; uint8_t *ptr; uint8_t u8Cmd; u8Cmd = gCmd.u8Cmd; u32StartPage = gCmd.u32Arg1; u32TotalPages= gCmd.u32Arg2; u32PageCnt = gCmd.u32Signature; /* Check if it is in data phase of read command */ if(u8Cmd == HID_CMD_READ) { /* Process the data phase of read command */ if((u32PageCnt >= u32TotalPages) && (g_u32BytesInPageBuf == 0)) { /* The data transfer is complete. */ u8Cmd = HID_CMD_NONE; printf("Read command complete!\n"); } else { if(g_u32BytesInPageBuf == 0) { /* The previous page has sent out. Read new page to page buffer */ /* TODO: We should update new page data here. (0xFF is used in this sample code) */ printf("Reading page %d\n", u32StartPage + u32PageCnt); memcpy(g_u8PageBuff, g_u8TestPages + u32PageCnt * PAGE_SIZE, sizeof(g_u8PageBuff)); g_u32BytesInPageBuf = PAGE_SIZE; /* Update the page counter */ u32PageCnt++; } /* Prepare the data for next HID IN transfer */ ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5)); USBD_MemCopy(ptr, (void *)&g_u8PageBuff[PAGE_SIZE - g_u32BytesInPageBuf], EP5_MAX_PKT_SIZE); USBD_SET_PAYLOAD_LEN(EP5, EP5_MAX_PKT_SIZE); g_u32BytesInPageBuf -= EP5_MAX_PKT_SIZE; } } gCmd.u8Cmd = u8Cmd; gCmd.u32Signature = u32PageCnt; }
//----- (000025B8) -------------------------------------------------------- __myevic__ uint32_t hidFMCReadCmd( CMD_T *pCmd ) { uint32_t u32StartAddr; uint32_t u32ParamLen; u32StartAddr = pCmd->u32Arg1; u32ParamLen = pCmd->u32Arg2; myprintf( "FMC Read command - Start Addr: %d Param Len: %d\n", pCmd->u32Arg1, pCmd->u32Arg2 ); if ( ! u32ParamLen % EP2_MAX_PKT_SIZE ) { return -1; } if ( u32ParamLen ) { if ( u32ParamLen > FMC_FLASH_PAGE_SIZE ) { u32ParamLen = FMC_FLASH_PAGE_SIZE; } SYS_UnlockReg(); FMC_ENABLE_ISP(); for ( uint32_t i = 0 ; i < u32ParamLen ; i += 4 ) { uint32_t data; data = FMC_Read( u32StartAddr + i ); MemCpy( &hidData[i], &data, 4 ); } FMC_DISABLE_ISP(); SYS_LockReg(); hidDataIndex = u32ParamLen; pCmd->u32Signature = u32ParamLen; USBD_MemCopy( (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), hidData, EP2_MAX_PKT_SIZE ); USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE ); hidDataIndex -= EP2_MAX_PKT_SIZE; } return 0; }
int32_t ProcessCommand(uint8_t *pu8Buffer, uint32_t u32BufferLen) { uint32_t u32sum; USBD_MemCopy((uint8_t *)&gCmd, pu8Buffer, u32BufferLen); /* Check size */ if((gCmd.u8Size > sizeof(gCmd)) || (gCmd.u8Size > u32BufferLen)) return -1; /* Check signature */ if(gCmd.u32Signature != HID_CMD_SIGNATURE) return -1; /* Calculate checksum & check it*/ u32sum = CalCheckSum((uint8_t *)&gCmd, gCmd.u8Size); if(u32sum != gCmd.u32Checksum) return -1; switch(gCmd.u8Cmd) { case HID_CMD_ERASE: { HID_CmdEraseSectors(&gCmd); break; } case HID_CMD_READ: { HID_CmdReadPages(&gCmd); break; } case HID_CMD_WRITE: { HID_CmdWritePages(&gCmd); break; } case HID_CMD_TEST: { HID_CmdTest(&gCmd); break; } default: return -1; } return 0; }
/** * @brief Repeat Control OUT pipe * * @param None * * @return None * * @details This function processes the successive Control OUT transfer. * */ void USBD_CtrlOut(void) { uint32_t u32Size; DBG_PRINTF("Ctrl Out Ack %d\n", g_usbd_CtrlOutSize); if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) { u32Size = USBD_GET_PAYLOAD_LEN(EP1); USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size); g_usbd_CtrlOutPointer += u32Size; g_usbd_CtrlOutSize += u32Size; if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); } }
void EP3_Handler(void) { /* BULK OUT */ static int offset = 0; uint32_t len; len = USBD_GET_PAYLOAD_LEN(EP3); USBD_MemCopy(&UsbMessageBuffer[offset], (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP3)), len); if((len >= 0x0A && len != 0xFF) || offset != 0) { if(offset == 0) { /* Calculate number of byte to receive to finish the message */ gi32UsbdMessageLength = USB_MESSAGE_HEADER_SIZE + make32(&UsbMessageBuffer[OFFSET_DWLENGTH]); } gi32UsbdMessageLength -= (int) len; /* Prepare next reception if whole message not received */ if(gi32UsbdMessageLength > 0) { pUsbMessageBuffer = UsbMessageBuffer + len; offset += len; } if(gi32UsbdMessageLength == 0) { gu8IsBulkOutReady = 1; offset = 0; } if(gi32UsbdMessageLength < 0) { UsbMessageBuffer[OFFSET_DWLENGTH] = 0xFF; UsbMessageBuffer[OFFSET_DWLENGTH+1] = 0xFF; UsbMessageBuffer[OFFSET_DWLENGTH+2] = 0xFF; UsbMessageBuffer[OFFSET_DWLENGTH+3] = 0xFF; gu8IsBulkOutReady = 1; } } CCID_DispatchMessage(); /* trigger next out packet */ if (gi32UsbdMessageLength > 0) USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); }
/** * @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_Write(const uint8_t *buf,int len) { barrier(); gi8BulkInReady = 0; barrier(); USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), (uint8_t *)buf, len); barrier(); USBD_SET_PAYLOAD_LEN(EP2, len); barrier(); while(gi8BulkInReady == 0) barrier();; gi8BulkInReady = 0; barrier(); /* if(len <8) delay(4); else delay(len/4); */ }
void MSC_RequestSense(void) { uint8_t tmp[20]; memset(tmp, 0, 18); if (g_u8Prevent) { g_u8Prevent = 0; tmp[0]= 0x70; } else tmp[0] = 0xf0; tmp[2] = g_au8SenseKey[0]; tmp[7] = 0x0a; tmp[12] = g_au8SenseKey[1]; tmp[13] = g_au8SenseKey[2]; USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), tmp, 20); g_au8SenseKey[0] = 0; g_au8SenseKey[1] = 0; g_au8SenseKey[2] = 0; }
/** * @brief Process SETUP packet * * @param None * * @return None * * @details Parse SETUP packet and perform the corresponding action. * */ void USBD_ProcessSetupPacket(void) { /* Get SETUP packet from USB buffer */ USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8); /* Check the request type */ switch(g_usbd_SetupPacket[0] & 0x60) { case REQ_STANDARD: // Standard { USBD_StandardRequest(); break; } case REQ_CLASS: // Class { if(g_usbd_pfnClassRequest != NULL) { g_usbd_pfnClassRequest(); } break; } case REQ_VENDOR: // Vendor { if(g_usbd_pfnVendorRequest != NULL) { g_usbd_pfnVendorRequest(); } break; } default: // reserved { /* Setup error, stall the device */ USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); break; } } }
//----- (00002788) -------------------------------------------------------- __myevic__ void hidGetOutReport( uint8_t *pu8Buffer, uint32_t u32BufferLen ) { uint8_t u8Cmd; uint8_t *hidDataPtr; uint32_t u32StartAddr; uint32_t u32DataSize; uint32_t u32ByteCount; uint32_t u32Page; uint32_t sz; uint32_t veo; u8Cmd = hidCmd.u8Cmd; u32StartAddr = hidCmd.u32Arg1; u32DataSize = hidCmd.u32Arg2; u32ByteCount = hidCmd.u32Signature; hidDataPtr = &hidData[hidDataIndex]; switch ( hidCmd.u8Cmd ) { case HID_CMD_SETPARAMS: { USBD_MemCopy( hidDataPtr, pu8Buffer, EP3_MAX_PKT_SIZE ); hidDataIndex += EP3_MAX_PKT_SIZE; if ( hidDataIndex >= u32DataSize ) { u8Cmd = HID_CMD_NONE; if ( u32StartAddr + u32DataSize > FMC_FLASH_PAGE_SIZE ) { sz = FMC_FLASH_PAGE_SIZE - u32StartAddr; } else { sz = u32DataSize; } MemCpy( (uint8_t*)(&hidDFData) + u32StartAddr, hidData, sz ); myprintf( "Set Sys Param complete.\n" ); dfStruct_t * df = (dfStruct_t*)hidDFData; if ( Checksum( (uint8_t*)df->params, FMC_FLASH_PAGE_SIZE - 4 ) == df->Checksum ) { myprintf( "\tCompany ID ............................ [0x%08x]\n", df->i.fmcCID ); myprintf( "\tDevice ID ............................. [0x%08x]\n", df->i.fmcDID ); myprintf( "\tProduct ID ............................ [0x%08x]\n", df->i.fmcPID ); myprintf( "\tu8UpdateAPRom ......................... [0x%08x]\n", df->p.BootFlag ); MemCpy( DataFlash.params, df->params, DATAFLASH_PARAMS_SIZE ); DFCheckValuesValidity(); UpdateDataFlash(); if ( df->i.Year >= 2000 && df->i.Year <= 2099 ) { S_RTC_TIME_DATA_T rtd; rtd.u32Year = df->i.Year; rtd.u32Month = df->i.Month; rtd.u32Day = df->i.Day; rtd.u32DayOfWeek = 0; rtd.u32Hour = df->i.Hour; rtd.u32Minute = df->i.Minute; rtd.u32Second = df->i.Second; rtd.u32TimeScale = RTC_CLOCK_24; SetRTC( &rtd ); } gFlags.refresh_display = 1; } else { myprintf( "Sys Param Receive fail.\n" ); } hidDataIndex = 0; } break; } case HID_CMD_SETLOGO: { USBD_MemCopy( hidDataPtr, pu8Buffer, EP3_MAX_PKT_SIZE ); hidDataIndex += EP3_MAX_PKT_SIZE; if ( hidDataIndex < FMC_FLASH_PAGE_SIZE && hidDataIndex + u32ByteCount < u32DataSize ) { break; } u32Page = u32StartAddr + u32ByteCount; myprintf( "Writing page %d\n", u32Page ); SYS_UnlockReg(); FMC_ENABLE_ISP(); FMC_ENABLE_AP_UPDATE(); if ( FMCEraseWritePage( u32Page, (uint32_t*)hidData ) ) { myprintf( "Data Flash Erase error!\n" ); } veo = FMCVerifyPage( u32Page, (uint32_t*)hidData ); if ( veo ) { myprintf( "Data Flash Verify error! 0x%x\n", 4 * veo - 4 ); } MemClear( hidData, FMC_FLASH_PAGE_SIZE ); u32ByteCount += hidDataIndex; myprintf( "g_u32BytesInPageBuf %d, u32LenCnt 0x%x\n", hidDataIndex, u32ByteCount ); FMC_DISABLE_AP_UPDATE(); FMC_DISABLE_ISP(); SYS_LockReg(); if ( u32ByteCount < u32DataSize ) { hidDataIndex = 0; } else { u8Cmd = HID_CMD_NONE; myprintf( "set boot logo command complete.\n" ); } break; } case HID_CMD_LDUPDATE: { USBD_MemCopy( hidDataPtr, pu8Buffer, EP3_MAX_PKT_SIZE ); hidDataIndex += EP3_MAX_PKT_SIZE; if ( hidDataIndex < FMC_FLASH_PAGE_SIZE && hidDataIndex + u32ByteCount < u32DataSize ) { break; } u32Page = u32StartAddr + u32ByteCount; myprintf( "Writing page 0x%08X\n", u32Page ); SYS_UnlockReg(); FMC_ENABLE_ISP(); FMC_EnableLDUpdate(); if ( FMCEraseWritePage( u32Page, (uint32_t*)hidData ) ) { myprintf( "Data Flash Erase error!\n" ); } veo = FMCVerifyPage( u32Page, (uint32_t*)hidData ); if ( veo ) { myprintf( "Data Flash Verify error! 0x%x\n", 4 * veo - 4 ); } MemClear( hidData, FMC_FLASH_PAGE_SIZE ); u32ByteCount += hidDataIndex; hidDataIndex = 0; myprintf( "g_u32BytesInPageBuf %d, u32LenCnt 0x%x\n", hidDataIndex, u32ByteCount ); FMC_DisableLDUpdate(); FMC_DISABLE_ISP(); SYS_LockReg(); if ( u32ByteCount >= u32DataSize ) { u8Cmd = HID_CMD_NONE; myprintf( "Update LDROM command complete.\n" ); } break; } default: { if ( hidProcessCommand( pu8Buffer, u32BufferLen ) ) { myprintf( "Unknown HID command!\n" ); } return; } } hidCmd.u8Cmd = u8Cmd; hidCmd.u32Signature = u32ByteCount; }
//------------------------------------------------------------------------- int32_t hidProcessCommand( uint8_t *pu8Buffer, uint32_t u32BufferLen ) { uint32_t u32sum; USBD_MemCopy( (uint8_t*)&hidCmd, pu8Buffer, u32BufferLen ); /* Check size */ if( ( hidCmd.u8Size > sizeof(hidCmd) ) || ( hidCmd.u8Size > u32BufferLen ) ) return -1; /* Check signature */ if( hidCmd.u32Signature != HID_CMD_SIGNATURE ) return -1; /* Calculate checksum & check it*/ u32sum = Checksum((uint8_t *)&hidCmd, hidCmd.u8Size); if( u32sum != hidCmd.u32Checksum ) return -1; switch( hidCmd.u8Cmd ) { case HID_CMD_GETINFO: { hidGetInfoCmd( &hidCmd ); break; } case HID_CMD_LDUPDATE: { hidLDUpdateCmd( &hidCmd ); break; } case HID_CMD_SETPARAMS: { hidSetParamCmd( &hidCmd ); break; } case HID_CMD_RESETPARAMS: { hidResetParamCmd( &hidCmd ); break; } case HID_CMD_SETLOGO: { hidBootLogoCmd( &hidCmd ); break; } case HID_CMD_RESET : { hidResetSysCmd( &hidCmd ); break; } case HID_CMD_FMCREAD : { hidFMCReadCmd( &hidCmd ); break; } case HID_CMD_SCREENSHOT: { hidScreenshot( &hidCmd ); break; } default: { return -1; } } return 0; }
//----- (00002C60) -------------------------------------------------------- __myevic__ void hidSetInReport() { uint8_t cmd = hidCmd.u8Cmd; switch ( cmd ) { case HID_CMD_GETINFO: case HID_CMD_SCREENSHOT: { if ( hidDataIndex ) { USBD_MemCopy( (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), &hidInDataPtr[hidCmd.u32Signature - hidDataIndex], EP2_MAX_PKT_SIZE ); USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE ); hidDataIndex -= EP2_MAX_PKT_SIZE; } else { cmd = HID_CMD_NONE; } break; } case HID_CMD_FMCREAD: { if ( !hidDataIndex ) { uint32_t u32Addr = hidCmd.u32Arg1 + hidCmd.u32Signature; int32_t u32Size = hidCmd.u32Arg2 - hidCmd.u32Signature; if ( u32Size > 0 ) { if ( u32Size > FMC_FLASH_PAGE_SIZE ) u32Size = FMC_FLASH_PAGE_SIZE; SYS_UnlockReg(); FMC_ENABLE_ISP(); for ( int i = 0 ; i < u32Size ; i += 4 ) { uint32_t data = FMC_Read( u32Addr + i ); MemCpy( &hidData[ FMC_FLASH_PAGE_SIZE - u32Size + i ], &data, 4 ); } FMC_DISABLE_ISP(); SYS_LockReg(); hidDataIndex = u32Size; hidCmd.u32Signature += u32Size; } } if ( hidDataIndex ) { USBD_MemCopy( (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2)), &hidData[ FMC_FLASH_PAGE_SIZE - hidDataIndex ], EP2_MAX_PKT_SIZE ); USBD_SET_PAYLOAD_LEN( EP2, EP2_MAX_PKT_SIZE ); hidDataIndex -= EP2_MAX_PKT_SIZE; } else { cmd = HID_CMD_NONE; } break; } default: cmd = HID_CMD_NONE; break; } hidCmd.u8Cmd = cmd; }