//***************************************************************************** // // USBLibDMAChannelEnable() for USB controllers that use uDMA. // //***************************************************************************** static void uDMAUSBChannelEnable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel) { uint32_t ui32IntEnabled; // // Save if the interrupt was enabled or not. // ui32IntEnabled = IntIsEnabled(psUSBDMAInst->ui32IntNum); // // Disable the USB interrupt if it was enabled. // if(ui32IntEnabled) { OS_INT_DISABLE(psUSBDMAInst->ui32IntNum); } // // Mark this channel as pending and not complete. // psUSBDMAInst->ui32Pending |= (1 << (ui32Channel - 1)); psUSBDMAInst->ui32Complete &= ~(1 << (ui32Channel - 1)); // // Enable DMA for the endpoint. // if(UDMAConfigIsRx(psUSBDMAInst->pui32Config[ui32Channel - 1])) { MAP_USBEndpointDMAEnable(psUSBDMAInst->ui32Base, psUSBDMAInst->pui8Endpoint[ui32Channel - 1], USB_EP_DEV_OUT | USB_EP_HOST_IN); } else { MAP_USBEndpointDMAEnable(psUSBDMAInst->ui32Base, psUSBDMAInst->pui8Endpoint[ui32Channel - 1], USB_EP_DEV_IN | USB_EP_HOST_OUT); } // // Enable the DMA in the uDMA controller. // MAP_uDMAChannelEnable(ui32Channel - 1); // // Enable the USB interrupt if it was enabled before. // if(ui32IntEnabled) { OS_INT_ENABLE(psUSBDMAInst->ui32IntNum); } }
//***************************************************************************** // // USBLibDMAChannelEnable() for USB controllers with an integrated DMA // controller. // //***************************************************************************** static void iDMAUSBChannelEnable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel) { uint32_t ui32IntEnabled; // // Save if the interrupt was enabled or not. // ui32IntEnabled = IntIsEnabled(psUSBDMAInst->ui32IntNum); // // Disable the USB interrupt if it was enabled. // if(ui32IntEnabled) { OS_INT_DISABLE(psUSBDMAInst->ui32IntNum); } // // Mark this channel as pending and not complete. // psUSBDMAInst->ui32Pending |= (1 << (ui32Channel - 1)); psUSBDMAInst->ui32Complete &= ~(1 << (ui32Channel - 1)); // // Enable the interrupt for this DMA channel. // USBDMAChannelIntEnable(psUSBDMAInst->ui32Base, ui32Channel - 1); // // Enable the DMA channel. // USBDMAChannelEnable(psUSBDMAInst->ui32Base, ui32Channel - 1); // // Enable the USB interrupt if it was enabled before. // if(ui32IntEnabled) { OS_INT_ENABLE(psUSBDMAInst->ui32IntNum); } }
//***************************************************************************** // //! Initializes the USB controller for OTG mode operation. //! //! \param ui32Index specifies the USB controller that is to be initialized for //! OTG mode operation. //! \param ui32PollingRate is the rate in milliseconds to poll the controller //! for changes in mode. //! \param pvPool is a pointer to the data to use as a memory pool for this //! controller. //! \param ui32PoolSize is the size in bytes of the buffer passed in as //! \e pvPool. //! //! This function initializes the USB controller hardware into a state //! suitable for OTG mode operation. Applications must use this function to //! ensure that the controller is in a neutral state and able to receive //! appropriate interrupts before host or device mode is chosen by OTG //! negotiation. The \e ui32PollingRate parameter is used to set the rate at //! which the USB library will poll the controller to determine the mode. This //! has the most effect on how quickly the USB library will detect changes when //! going to host mode. The parameters \e pvPool and \e ui32PoolSize are //! passed on to the USB host library functions to provide memory for the USB //! library when it is acting as a host. Any device and host initialization //! should have been called before calling this function to prevent the USB //! library from attempting to run in device or host mode before the USB //! library is fully configured. //! //! \return None. // //***************************************************************************** void USBOTGModeInit(uint32_t ui32Index, uint32_t ui32PollingRate, void *pvPool, uint32_t ui32PoolSize) { // // We only support a single USB controller. // ASSERT(ui32Index == 0); // // This should never be called if not in OTG mode. // ASSERT(g_iUSBMode == eUSBModeOTG); // // Force OTG mode in all cases since anything else is invalid, but a DEBUG // build will still ASSERT above if this value is incorrect. // g_iUSBMode = eUSBModeOTG; // // Remember that we have not yet determined whether we are device or // host. // g_iDualMode = eUSBModeNone; // // Set the default polling rate. // g_ui32PollRate = ui32PollingRate; // // Enable the USB controller. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0); // // Turn on USB Phy clock. // MAP_SysCtlUSBPLLEnable(); // // Initialize the host controller stack. // USBHCDInit(ui32Index, pvPool, ui32PoolSize); // // Configure the End point 0. // USBHostEndpointConfig(USB0_BASE, USB_EP_0, 64, 0, 0, (USB_EP_MODE_CTRL | USB_EP_SPEED_FULL | USB_EP_HOST_OUT)); // // Enable control interrupts. // MAP_USBIntEnableControl(USB0_BASE, USB_INTCTRL_RESET | USB_INTCTRL_DISCONNECT | USB_INTCTRL_SESSION | USB_INTCTRL_BABBLE | USB_INTCTRL_CONNECT | USB_INTCTRL_RESUME | USB_INTCTRL_SUSPEND | USB_INTCTRL_VBUS_ERR | USB_INTCTRL_MODE_DETECT | USB_INTCTRL_SOF); // // Make sure the mode OTG mode and not forced device or host. // USBOTGMode(USB0_BASE); // // Enable all endpoint interrupts. // MAP_USBIntEnableEndpoint(USB0_BASE, USB_INTEP_ALL); // // Initialize the power configuration. // USBHCDPowerConfigSet(ui32Index, USBHCDPowerConfigGet(ui32Index)); // // If power enable is automatic then then USBHostPwrEnable() has to be // called to allow the USB controller to control the power enable pin. // if(USBHCDPowerAutomatic(ui32Index)) { // // This will not turn on power but instead will allow the USB // controller to turn on power when needed. // USBHostPwrEnable(USB0_BASE); } // // Enable the USB interrupt. // if(CLASS_IS_TM4C129) { OS_INT_ENABLE(INT_USB0_TM4C129); } else { OS_INT_ENABLE(INT_USB0_TM4C123); } }
//***************************************************************************** // //! Initializes the USB controller for dual mode operation. //! //! \param ui32Index specifies the USB controller that is to be initialized for //! dual mode operation. This parameter must be set to 0. //! //! This function initializes the USB controller hardware into a state //! suitable for dual mode operation. Applications may use this function to //! ensure that the controller is in a neutral state and able to receive //! appropriate interrupts before host or device mode is chosen using a call //! to USBStackModeSet(). //! //! \return None. // //***************************************************************************** void USBDualModeInit(uint32_t ui32Index) { // // We only support a single USB controller. // ASSERT(ui32Index == 0); // // Configure the End point 0. // USBHostEndpointConfig(USB0_BASE, USB_EP_0, 64, 0, 0, (USB_EP_MODE_CTRL | USB_EP_SPEED_FULL | USB_EP_HOST_OUT)); // // Enable USB Interrupts. // MAP_USBIntEnableControl(USB0_BASE, USB_INTCTRL_RESET | USB_INTCTRL_DISCONNECT | USB_INTCTRL_SESSION | USB_INTCTRL_BABBLE | USB_INTCTRL_CONNECT | USB_INTCTRL_RESUME | USB_INTCTRL_SUSPEND | USB_INTCTRL_VBUS_ERR); // // Enable all endpoint interrupts. // MAP_USBIntEnableEndpoint(USB0_BASE, USB_INTEP_ALL); // // Initialize the USB tick module. // InternalUSBTickInit(); // // Enable the USB interrupt. // OS_INT_ENABLE(g_psDCDInst[0].ui32IntNum); // // Turn on session request to enable ID pin checking. // USBOTGSessionRequest(USB0_BASE, true); // // Initialize the power configuration. // USBHostPwrConfig(USB0_BASE, USBHCDPowerConfigGet(ui32Index)); // // If power enable is automatic then then USBHostPwrEnable() has to be // called to allow the USB controller to control the power enable pin. // if(USBHCDPowerAutomatic(ui32Index)) { // // This will not turn on power but instead will allow the USB // controller to turn on power when needed. // USBHostPwrEnable(USB0_BASE); } }
//***************************************************************************** // // This function is called periodically by USBHCDMain(). We use it to handle // the hub port state machine. // //***************************************************************************** void USBHHubMain(void) { uint16_t ui16Status, ui16Changed; uint_fast8_t ui8Port; bool bRetcode; // // If the hub is not present, just return. // if((g_sRootHub.ui32Flags & USBLIB_HUB_ACTIVE) == 0) { return; } // // Initialize the status variables. // ui16Status = 0; ui16Changed = 0; // // The hub is active and something changed. Check to see which port changed // state and handle as necessary. // for(ui8Port = 0; ui8Port <= g_sRootHub.ui8NumPortsInUse; ui8Port++) { // // Decrement any wait counter if there is one present. // if(g_sRootHub.psPorts[ui8Port].ui32Count != 0) { g_sRootHub.psPorts[ui8Port].ui32Count--; } // // Is this port waiting to be enumerated and is the last device // enumeration finished? // if((g_sRootHub.psPorts[ui8Port].iState == ePortConnected) && (!g_sRootHub.bEnumerationBusy) && (g_sRootHub.psPorts[ui8Port].ui32Count == 0)) { // // Yes - start the enumeration processing for this device. // HubDriverDeviceReset(ui8Port); } // // If the state is ePortResetWait then the hub is waiting before // accessing device as the USB 2.0 specification requires. // if((g_sRootHub.psPorts[ui8Port].iState == ePortResetWait) && (g_sRootHub.psPorts[ui8Port].ui32Count == 0)) { // // Start the enumeration process if the timeout has passed and // the hub is waiting to start enumerating the device. // g_sRootHub.psPorts[ui8Port].iState = ePortActive; // // Call the main host controller layer to have it enumerate the // newly connected device. // g_sRootHub.psPorts[ui8Port].ui32DevHandle = USBHCDHubDeviceConnected(0, 1, ui8Port, g_sRootHub.psPorts[ui8Port].ui32Speed); } // // If an enumeration is in progress and the loop is not on the port // being enumerated then skip the port. // if(g_sRootHub.bEnumerationBusy && (g_sRootHub.ui8EnumIdx != ui8Port)) { continue; } // // Did something change for this particular port? // if(g_ui32ChangeFlags & (1 << ui8Port)) { // // Yes - query the port status. // bRetcode = HubGetPortStatus(&g_sRootHub, ui8Port, &ui16Status, &ui16Changed); // // Clear this change with the USB interrupt temporarily disabled to // ensure that we do not clear a flag that the interrupt routine // has just set. // OS_INT_DISABLE(g_sRootHub.ui32IntNum); g_ui32ChangeFlags &= ~(1 << ui8Port); OS_INT_ENABLE(g_sRootHub.ui32IntNum); // // If there was an error, go on and look at the next bit. // if(!bRetcode) { continue; } // // Now consider what changed and handle it as necessary. // // // Was a device connected to or disconnected from the port? // if(ui16Changed & HUB_PORT_CHANGE_DEVICE_PRESENT) { DEBUG_OUTPUT("Connection change on port %d\n", ui8Port); // // Clear the condition. // HubClearPortFeature(&g_sRootHub, ui8Port, HUB_FEATURE_C_PORT_CONNECTION); // // Was a device connected or disconnected? // if(ui16Status & HUB_PORT_STATUS_DEVICE_PRESENT) { DEBUG_OUTPUT("Connected\n"); // // A device was connected. // HubDriverDeviceConnect(ui8Port); } else { DEBUG_OUTPUT("Disconnected\n"); // // A device was disconnected. // HubDriverDeviceDisconnect(ui8Port); } } // // Did a reset on the port complete? // if(ui16Changed & HUB_PORT_CHANGE_RESET) { // // Clear the condition. // HubClearPortFeature(&g_sRootHub, ui8Port, HUB_FEATURE_C_PORT_RESET); // // Yes - query the port status. // bRetcode = HubGetPortStatus(&g_sRootHub, ui8Port, &ui16Status, &ui16Changed); DEBUG_OUTPUT("Reset %s for port %d\n", ((ui16Status & HUB_PORT_STATUS_RESET) ? "asserted" : "deasserted"), ui8Port); // // Handle the reset case. // HubDriverReset(ui8Port, (ui16Status & HUB_PORT_STATUS_RESET) ? true : false); // // A device was connected. // if(ui16Status & HUB_PORT_STATUS_LOW_SPEED) { USBHubPortSpeedSet(ui8Port, USB_EP_SPEED_LOW); } else if(ui16Status & HUB_PORT_STATUS_HIGH_SPEED) { USBHubPortSpeedSet(ui8Port, USB_EP_SPEED_HIGH); } else { USBHubPortSpeedSet(ui8Port, USB_EP_SPEED_FULL); } } // // Did an over-current reset on the port complete? // if(ui16Changed & HUB_PORT_CHANGE_OVER_CURRENT) { DEBUG_OUTPUT("Port %d over current.\n", ui8Port); // // Currently we ignore this and just clear the condition. // HubClearPortFeature(&g_sRootHub, ui8Port, HUB_FEATURE_C_PORT_OVER_CURRENT); } // // Has the port been enabled or disabled? // if(ui16Changed & HUB_PORT_CHANGE_ENABLED) { DEBUG_OUTPUT("Enable change for port %d.\n", ui8Port); // // Currently we ignore this and just clear the condition. // HubClearPortFeature(&g_sRootHub, ui8Port, HUB_FEATURE_C_PORT_ENABLE); } // // Has the port been suspended or resumed? // if(ui16Changed & HUB_PORT_CHANGE_SUSPENDED) { DEBUG_OUTPUT("Suspend change for port %d.\n", ui8Port); // // Currently we ignore this and just clear the condition. // HubClearPortFeature(&g_sRootHub, ui8Port, HUB_FEATURE_C_PORT_SUSPEND); } } } }