/** * @brief CDC_InterfaceDeInit * The function DeInit the Host Channels used for the CDC class. * @param pdev: Selected device * @param hdev: Selected device property * @retval None */ void CDC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { if ( CDC_Machine.CDC_CommItf.hc_num_in) { USB_OTG_HC_Halt(pdev, CDC_Machine.CDC_CommItf.hc_num_in); USBH_Free_Channel (pdev,CDC_Machine.CDC_CommItf.hc_num_in); CDC_Machine.CDC_CommItf.hc_num_in = 0; /* Reset the Channel as Free */ } if ( CDC_Machine.CDC_DataItf.hc_num_out) { USB_OTG_HC_Halt(pdev, CDC_Machine.CDC_DataItf.hc_num_out); USBH_Free_Channel (pdev,CDC_Machine.CDC_DataItf.hc_num_out); CDC_Machine.CDC_DataItf.hc_num_out = 0; /* Reset the Channel as Free */ } if ( CDC_Machine.CDC_DataItf.hc_num_in) { USB_OTG_HC_Halt(pdev, CDC_Machine.CDC_DataItf.hc_num_in); USBH_Free_Channel (pdev,CDC_Machine.CDC_DataItf.hc_num_in); CDC_Machine.CDC_DataItf.hc_num_in = 0; /* Reset the Channel as Free */ } // return USBH_OK; }
/** * @brief USBH_MSC_InterfaceDeInit * De-Initialize interface by freeing host channels allocated to interface * @param pdev: Selected device * @param hdev: Selected device property * @retval None */ void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { if ( MSC_Machine.hc_num_out) { USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out); USBH_Free_Channel (pdev, MSC_Machine.hc_num_out); MSC_Machine.hc_num_out = 0; /* Reset the Channel as Free */ } if ( MSC_Machine.hc_num_in) { USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in); USBH_Free_Channel (pdev, MSC_Machine.hc_num_in); MSC_Machine.hc_num_in = 0; /* Reset the Channel as Free */ } }
/** * @brief USBH_MSC_InterfaceDeInit * De-Initialize interface by freeing host channels allocated to interface * @param pdev: Selected device * @param hdev: Selected device property * @retval None */ void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, USBH_DeviceProp_TypeDef *hdev) { if ( MSC_Machine.hc_num_out) { USB_OTG_HC_Halt((&USB_OTG_FS_dev), MSC_Machine.hc_num_out); USBH_Free_Channel (pdev, MSC_Machine.hc_num_out); MSC_Machine.hc_num_out = 0; /* Reset the Channel as Free */ } if ( MSC_Machine.hc_num_in) { USB_OTG_HC_Halt((&USB_OTG_FS_dev), MSC_Machine.hc_num_in); USBH_Free_Channel (pdev, MSC_Machine.hc_num_in); MSC_Machine.hc_num_in = 0; /* Reset the Channel as Free */ } }
USBH_Status USBH_Dev_DefaultCB_Task(USB_OTG_CORE_HANDLE *pcore , USBH_DEV *pdev) { // this is called periodically until the device state machine changes char isDevRoot = pdev->Parent == 0; if (isDevRoot == 0) { // since this device now has an address // we can let the hub handle new devices on another port USBH_DEV* parentHub = (USBH_DEV*)pdev->Parent; Hub_Data_t* hubData = (Hub_Data_t*)parentHub->Usr_Data; hubData->port_busy = 0; // this is a useless device, free the channel so another dev can use them USBH_Free_Channel(pcore, &(pdev->Control.hc_num_in)); USBH_Free_Channel(pcore, &(pdev->Control.hc_num_out)); } return USBH_OK; }
/** * @brief USBH_DeInit * Re-Initialize Host * @param None * @retval status: USBH_Status */ USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) { /* Software Init */ phost->gState = HOST_IDLE; phost->gStateBkp = HOST_IDLE; phost->EnumState = ENUM_IDLE; phost->RequestState = CMD_SEND; phost->Control.state = CTRL_SETUP; phost->Control.ep0size = USB_OTG_MAX_EP0_SIZE; phost->device_prop.address = USBH_DEVICE_ADDRESS_DEFAULT; phost->device_prop.speed = HPRT0_PRTSPD_FULL_SPEED; USBH_Free_Channel (pdev, phost->Control.hc_num_in); USBH_Free_Channel (pdev, phost->Control.hc_num_out); return USBH_OK; }
/** * @brief USBH_HID_InterfaceDeInit * The function DeInit the Host Channels used for the HID class. * @param pdev: Selected device * @param hdev: Selected device property * @retval None */ void USBH_HID_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { //USBH_HOST *pphost = phost; if(HID_Machine.hc_num_in != 0x00) { USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_in); USBH_Free_Channel (pdev, HID_Machine.hc_num_in); HID_Machine.hc_num_in = 0; /* Reset the Channel as Free */ } if(HID_Machine.hc_num_out != 0x00) { USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_out); USBH_Free_Channel (pdev, HID_Machine.hc_num_out); HID_Machine.hc_num_out = 0; /* Reset the Channel as Free */ } start_toggle = 0; }
// The function DeInit the Host Channels used for the HID class. void USBH_HID_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { HID_Machine_TypeDef *HID_Machine = &HID_Machines[pdev->cfg.coreID]; //USBH_HOST *pphost = phost; if(HID_Machine->hc_num_in != 0x00) { USB_OTG_HC_Halt(pdev, HID_Machine->hc_num_in); USBH_Free_Channel (pdev, HID_Machine->hc_num_in); HID_Machine->hc_num_in = 0; /* Reset the Channel as Free */ } if(HID_Machine->hc_num_out != 0x00) { USB_OTG_HC_Halt(pdev, HID_Machine->hc_num_out); USBH_Free_Channel (pdev, HID_Machine->hc_num_out); HID_Machine->hc_num_out = 0; /* Reset the Channel as Free */ } start_toggles[pdev->cfg.coreID] = 0; }
/** * This function will free a pipe, it will release all resouces of the pipe. * * @param pipe the pipe handler to be free. * * @return the error code, RT_EOK on successfully. */ static rt_err_t susb_free_pipe(upipe_t pipe) { rt_uint8_t channel; RT_ASSERT(pipe != RT_NULL); RT_DEBUG_LOG(RT_DEBUG_USB, ("susb_free_pipe:%d\n", pipe->ep.bEndpointAddress)); channel = (rt_uint32_t)pipe->user_data & 0xFF; USBH_Free_Channel(&USB_OTG_Core, channel); rt_free(pipe); return RT_EOK; }
void USBPT_Work() { if (USBPT_Has_Dev == 0) { if (HCD_IsDeviceConnected(&USB_OTG_Core_host) != 0) { USBPT_printf("USBPT Device Connecting \r\n"); if (USBH_Open_Channel( &USB_OTG_Core_host, &(USBPT_Dev->Control.hc_num_in), 0x80, USBPT_Dev->device_prop.address, // still 0 at this point USBPT_Dev->device_prop.speed, EP_TYPE_CTRL, USBPT_Dev->Control.ep0size) == HC_OK && USBH_Open_Channel( &USB_OTG_Core_host, &(USBPT_Dev->Control.hc_num_out), 0x00, USBPT_Dev->device_prop.address, // still 0 at this point USBPT_Dev->device_prop.speed, EP_TYPE_CTRL, USBPT_Dev->Control.ep0size) == HC_OK ) { DCD_DevConnect(&USB_OTG_Core_dev); USBPT_Has_Dev = 1; } else { dbg_printf(DBGMODE_ERR, "USBPT Unable to allocate control EP HC \r\n"); } } else { return; } } else { if (HCD_IsDeviceConnected(&USB_OTG_Core_host) == 0) { USBPT_printf("USBPT Device Disconnecting \r\n"); USBD_DeInit(&USB_OTG_Core_dev); DCD_DevDisconnect(&USB_OTG_Core_dev); USBPT_Has_Dev = 0; for (uint8_t i = 0; i < USBPTH_MAX_LISTENERS; i++) { USBH_Free_Channel(&USB_OTG_Core_host, &(USBPTH_Listeners[i].hc)); } USBH_Free_Channel(&USB_OTG_Core_host, &(USBPT_Dev->Control.hc_num_out)); USBH_Free_Channel(&USB_OTG_Core_host, &(USBPT_Dev->Control.hc_num_in)); } } for (uint8_t i = 0; i < USBPTH_MAX_LISTENERS; i++) { USBPTH_HC_EP_t* pl = &USBPTH_Listeners[i]; int8_t hc = USBPTH_Listeners[i].hc; if (hc >= 0) // if listener is actually allocated { USBH_EpDesc_TypeDef* epDesc = pl->epDesc; uint8_t epnum = epDesc->bEndpointAddress; uint8_t epType = 0; USBPT_GeneralInDataLen = epDesc->wMaxPacketSize; // try to send read tokens only on even frames if (USB_OTG_IsEvenFrame(&USB_OTG_Core_host) == 0) continue; dbg_trace(); // attempt to start the read, check the read type first if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) { epType = EP_TYPE_INTR; USBH_InterruptReceiveData(&USB_OTG_Core_host, USBPT_GeneralInData, USBPT_GeneralInDataLen, hc); } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) { epType = EP_TYPE_BULK; USBH_BulkReceiveData(&USB_OTG_Core_host, USBPT_GeneralInData, USBPT_GeneralInDataLen, hc); } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) { epType = EP_TYPE_ISOC; USBH_IsocReceiveData(&USB_OTG_Core_host, USBPT_GeneralInData, USBPT_GeneralInDataLen, hc); } // now we wait for a reply, or maybe there isn't one USBH_Status status; char sent = 0; delay_1ms_cnt = 100; do { URB_STATE us = HCD_GetURB_State(&USB_OTG_Core_host, hc); if (us == URB_DONE) { // data was indeed received // print it to the serial port for monitoring USBPT_printf("USBPT:IN:EP0x%02X:", epnum); for (uint16_t c = 0; c < USBPT_GeneralInDataLen; c++) { USBPT_printf(" 0x%02X", USBPT_GeneralInData[c]); } USBPT_printf("\r\n"); // relay the data to the host DCD_EP_Tx(&USB_OTG_Core_dev, epnum, USBPT_GeneralInData, USBPT_GeneralInDataLen); sent = 1; break; } else if (us == URB_ERROR) { dbg_printf(DBGMODE_ERR, "DataIn Error on EP 0x%02X \r\n", epnum); break; } else if (us == URB_STALL) { dbg_printf(DBGMODE_ERR, "DataIn Stalled EP 0x%02X \r\n", epnum); break; } else if (us == URB_NOTREADY) { // NAK, no data break; } } while (delay_1ms_cnt > 0); if (delay_1ms_cnt == 0) { dbg_printf(DBGMODE_ERR, "DataIn Read Timed Out EP 0x%02X \r\n", epnum); } } } }
uint8_t USBPTD_DataOut (void *pcore , uint8_t epnum) { USB_OTG_CORE_HANDLE* pcore_ = (USB_OTG_CORE_HANDLE*)pcore; DCD_DEV* pdev = &(pcore_->dev); uint8_t* data; uint16_t wLength; if (epnum == 0x00) { // CTRL REQ wLength = USBPT_CtrlDataLen; data = USBPT_CtrlData; } else { wLength = pdev->out_ep[epnum].xfer_count; data = pdev->out_ep[epnum].xfer_buff; } // print to monitor USBPT_printf("USBPT:OUT:EP0x%02X:", epnum); for (uint16_t i = 0; i < wLength; i++) { USBPT_printf(" 0x%02X", data[i]); } USBPT_printf("\r\n"); if (epnum == 0x00) { // CTRL REQ USBH_Status status; delay_1ms_cnt = 100; // wait for transfer complete do { status = USBH_CtlReq(&USB_OTG_Core_host, USBPT_Dev, USBPT_CtrlData , USBPT_CtrlDataLen ); if (status == USBH_OK || status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) { break; } else { status = USBH_HandleControl(&USB_OTG_Core_host, USBPT_Dev); if (status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) { break; } } } while (delay_1ms_cnt > 0); if (delay_1ms_cnt == 0) { dbg_printf(DBGMODE_ERR, "USBPTD_DataOut timed out while sending to device, status: 0x%04X \r\n", status); USBD_CtlError(pcore , 0); return USBD_FAIL; } else if (status != USBH_OK) { dbg_printf(DBGMODE_ERR, "USBPTD_DataOut failed to send to device, status: 0x%04X \r\n", status); USBD_CtlError(pcore , 0); return USBD_FAIL; } else { // everything is OK USBD_CtlSendStatus(pcore); return USBD_OK; } } else { wLength = pdev->out_ep[epnum].xfer_count; data = pdev->out_ep[epnum].xfer_buff; // allocate memory needed if (USBPT_GeneralOutData != 0) free(USBPT_GeneralOutData); USBPT_GeneralOutDataLen = wLength; USBPT_GeneralOutData = malloc(wLength); memcpy(USBPT_GeneralOutData, data, USBPT_GeneralOutDataLen); USBH_EpDesc_TypeDef* epDesc = 0; for (uint8_t i = 0; i < USBPTH_OutEPCnt; i++) { // look for appropriate EP if (USBPTH_OutEP[i]->bEndpointAddress == epnum) { epDesc = USBPTH_OutEP[i]; break; } } if (epDesc != 0) // EP found { uint8_t epType = 0; int8_t hc = -1; if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) { epType = EP_TYPE_INTR; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) { epType = EP_TYPE_BULK; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) { epType = EP_TYPE_ISOC; } // dynamically allocate host channel for use if (USBH_Open_Channel( &USB_OTG_Core_host, &hc, epnum, USBPT_Dev->device_prop.address, USBPT_Dev->device_prop.speed, epType, epDesc->wMaxPacketSize) == HC_OK) { // try to only send on even frame volatile uint32_t syncTries = 0x7FFFFFFF; while (USB_OTG_IsEvenFrame(&USB_OTG_Core_host) == 0 && syncTries--) __NOP(); // send using appropriate method switch (epType) { case EP_TYPE_INTR: USBH_InterruptSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc); break; case EP_TYPE_BULK: USBH_BulkSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc); break; case EP_TYPE_ISOC: USBH_IsocSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc); break; default: break; } // wait until done sending USBH_Status status; delay_1ms_cnt = 100; do { URB_STATE us = HCD_GetURB_State(&USB_OTG_Core_host, hc); if (us == URB_DONE) { break; } else if (us == URB_ERROR) { dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Send Error on EP 0x%02X \r\n", epnum); DCD_EP_Stall(pcore, epnum); break; } else if (us == URB_STALL) { dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Stalled EP 0x%02X \r\n", epnum); DCD_EP_Stall(pcore, epnum); break; } } while (delay_1ms_cnt > 0); if (delay_1ms_cnt == 0) { dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Send Timed Out EP 0x%02X \r\n", epnum); } // free the channel to be used by something else later USBH_Free_Channel(&USB_OTG_Core_host, &hc); } else { dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Failed to Alloc HC for EP 0x%02X \r\n", epnum); } } else { dbg_printf(DBGMODE_ERR, "USBPTD_DataOut No Such EP 0x%02X \r\n", epnum); } return USBD_OK; } return USBD_OK; }
/* * This is broken. We need to enumerate differently. * It causes major problems with several devices if detected in an unexpected order. * * * Oleg - I wouldn't do anything before the newly connected device is considered sane. * i.e.(delays are not indicated for brevity): * 1. reset * 2. GetDevDescr(); * 3a. If ACK, continue with allocating address, addressing, etc. * 3b. Else reset again, count resets, stop at some number (5?). * 4. When max.number of resets is reached, toggle power/fail * If desired, this could be modified by performing two resets with GetDevDescr() in the middle - however, from my experience, if a device answers to GDD() * it doesn't need to be reset again * New steps proposal: * 1: get address pool instance. exit on fail * 2: pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf). exit on fail. * 3: bus reset, 100ms delay * 4: set address * 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail * 6: while (configurations) { * for(each configuration) { * for (each driver) { * 6a: Ask device if it likes configuration. Returns 0 on OK. * If successful, the driver configured device. * The driver now owns the endpoints, and takes over managing them. * The following will need codes: * Everything went well, instance consumed, exit with success. * Instance already in use, ignore it, try next driver. * Not a supported device, ignore it, try next driver. * Not a supported configuration for this device, ignore it, try next driver. * Could not configure device, fatal, exit with fail. * } * } * } * 7: for(each driver) { * 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID * 8: if we get here, no driver likes the device plugged in, so exit failure. * */ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) { //uint8_t bAddress = 0; //printf("Configuring: parent = %i, port = %i\r\n", parent, port); uint8_t devConfigIndex; uint8_t rcode = 0; uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; EpInfo epInfo; USB_OTG_CORE_HANDLE *pdev = coreConfig; epInfo.epAddr = 0; epInfo.maxPktSize = 8; epInfo.epAttribs = 0; epInfo.bmNakPower = USB_NAK_MAX_POWER; // assume: // HC0 for control - out // HC1 for control - in //uint8_t hcnum = USBH_GetFreeChannel(pdev); //if(hcnum > 1) { // USBH_Free_Channel(pdev, epInfo.hcNumOut); // USBH_Free_Channel(pdev, epInfo.hcNumIn); //} USBH_Free_Channel(pdev, 0); USBH_Free_Channel(pdev, 1); epInfo.hcNumOut = USBH_Alloc_Channel(pdev, 0x00); // ep_addr = 0 epInfo.hcNumIn = USBH_Alloc_Channel(pdev, 0x80); USBH_Open_Channel(pdev, epInfo.hcNumOut, 0x0, (lowspeed)?bmLOWSPEED:bmFULLSPEED, EP_TYPE_CTRL, 0x8); USBH_Open_Channel(pdev, epInfo.hcNumIn, 0x0, (lowspeed)?bmLOWSPEED:bmFULLSPEED, EP_TYPE_CTRL, 0x8); printf("\nControl Pipe: out = %d (0), in = %d (1)", epInfo.hcNumOut, epInfo.hcNumIn); delay_ms(1000); AddressPool &addrPool = GetAddressPool(); // Get pointer to pseudo device with address 0 assigned p = addrPool.GetUsbDevicePtr(0); if (!p) { printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n"); return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; } // Save old pointer to EP_RECORD of address 0 // oldep_ptr = p->epinfo; // Temporary assign new pointer to epInfo to p->epinfo in order to // avoid toggle inconsistence p->epinfo = &epInfo; p->lowspeed = lowspeed; // Get device descriptor rcode = getDevDescr(0, 0, 8, (uint8_t*)buf); // 8 should be enough, sizeof (USB_DEVICE_DESCRIPTOR) printf("\nControl - Got 1st 8 bytes desc"); // Extract Max Packet Size from the device descriptor epInfo.maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; //USB::USBH_Modify_Channel (pdev, epInfo.hcNumOut, 0, 0, 0, 0, epInfo.maxPktSize); //USB::USBH_Modify_Channel (pdev, epInfo.hcNumIn, 0, 0, 0, 0, epInfo.maxPktSize); // Restore p->epinfo // keep CtrlXfer's hcNumOut/In in p->epinfo. p->epinfo = oldep_ptr; if (rcode) { printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n"); return rcode; } // to-do? // Allocate new address according to device class //bAddress = addrPool.AllocAddress(parent, false, port); //if (!bAddress) // return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; rcode = getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); printf("\nControl - Got 2nd 18 bytes desc."); uint16_t vid = (uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; uint16_t pid = (uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; uint8_t klass = ((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass; // Attempt to configure if VID/PID or device class matches with a driver for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { if (!devConfig[devConfigIndex]) continue; // no driver if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed if (devConfig[devConfigIndex]->VIDPIDOK(vid, pid)) { rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); break; } else if (devConfig[devConfigIndex]->DEVCLASSOK(klass)) { rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); if (!rcode) break; } } if (devConfigIndex < USB_NUMDEVICES) { return rcode; } // blindly attempt to configure for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { if (!devConfig[devConfigIndex]) continue; if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); //printf("ERROR ENUMERATING %2.2x\r\n", rcode); if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) { // in case of an error dev_index should be reset to 0 // in order to start from the very beginning the // next time the program gets here //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) // devConfigIndex = 0; return rcode; } } // if we get here that means that the device class is not supported by any of registered classes rcode = DefaultAddressing(parent, port, lowspeed); return rcode; }
/* USB main task. Performs enumeration/cleanup */ void USB::Task(USB_OTG_CORE_HANDLE *pdev) //USB state machine { uint8_t rcode; uint8_t tmpdata; static unsigned long delay = 0; bool lowspeed = false; STM32F2::Task(); tmpdata = getVbusState(); /* modify USB task state if Vbus changed */ switch (tmpdata) { case SE1: //illegal state usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; lowspeed = false; break; case SE0: //disconnected if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED) usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; lowspeed = false; break; case LSHOST: // if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { lowspeed = true; // } case FSHOST: //attached if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { delay = millis() + USB_SETTLE_DELAY; usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; STM_EVAL_LEDToggle(LED1); } break; }// switch( tmpdata for (uint8_t i = 0; i < USB_NUMDEVICES; i++) if (devConfig[i]) rcode = devConfig[i]->Poll(); switch (usb_task_state) { case USB_DETACHED_SUBSTATE_INITIALIZE: init(); for (uint8_t i = 0; i < USB_NUMDEVICES; i++) if (devConfig[i]) rcode = devConfig[i]->Release(); usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; break; case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here break; case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here break; case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device if (delay < millis()) usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; break; case USB_ATTACHED_SUBSTATE_RESET_DEVICE: STM_EVAL_LEDToggle(LED1); //regWr(rHCTL, bmBUSRST); //issue bus reset // what if i want to reset the specified device? (need to survey usb hub feature later) pdev->host.SofHits = 0; HCD_ResetPort(); //usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; // the HCD_ResetPort() function will take care of a complete bus reset. so skip next phase. usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; break; /* case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: if ((regRd(rHCTL) & bmBUSRST) == 0) { tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation regWr(rMODE, tmpdata); usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; //delay = millis() + 20; //20ms wait after reset per USB spec } break;*/ case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order if(pdev->host.port_need_reset) { usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; pdev->host.port_need_reset = 0; printf("\nLS Dev, reset again"); break; } STM_EVAL_LEDToggle(LED1); //if (regRd(rHIRQ) & bmFRAMEIRQ) { if(pdev->host.SofHits) { //when first SOF received _and_ 20ms has passed we can continue usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET; delay = millis() + 20; } break; case USB_ATTACHED_SUBSTATE_WAIT_RESET: if (delay < millis()) { usb_task_state = USB_STATE_CONFIGURING; } break; case USB_STATE_CONFIGURING: STM_EVAL_LEDToggle(LED1); //Serial.print("\r\nConf.LS: "); //Serial.println(lowspeed, HEX); printf("\nTODO:Support all 8 USB pipe?"); rcode = Configuring(0, 0, lowspeed); if (rcode) { if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) { usb_error = rcode; usb_task_state = USB_STATE_ERROR; } } else usb_task_state = USB_STATE_RUNNING; break; case USB_STATE_RUNNING: break; case USB_STATE_ERROR: //MAX3421E::Init(); AddressPool &addrPool = GetAddressPool(); // Get pointer to pseudo device with address 0 assigned UsbDevice *p = addrPool.GetUsbDevicePtr(0); USBH_Free_Channel(pdev, p->epinfo->hcNumOut); USBH_Free_Channel(pdev, p->epinfo->hcNumIn); break; } // switch( usb_task_state ) }
/** * @brief This function send data to the device. * @param fileName : name of the file * @retval the filestate will be returned * FS_SUCCESS : returned to the parent function when the file length become to zero */ void CDC_StopReception( USB_OTG_CORE_HANDLE *pdev) { RX_Enabled = 0; USB_OTG_HC_Halt(pdev, CDC_Machine.CDC_DataItf.hc_num_in); USBH_Free_Channel (pdev,CDC_Machine.CDC_DataItf.hc_num_in); }