目錄
\samv7\libraries\libusb\host\core\USBH.c
void USBH_start(void)
{
USBH_device_root.address = UHC_USB_ADD_NOT_VALID;
USBH_sof_timeout = 0; // No callback registered on a SOF timeout
USBH_HAL_EnableUsbHost();
}
1.2 USBH_notify_connection
//文件:\samv7\libraries\libusb\common\core\USBH_HAL.c
/**
* \internal
* \brief Function called by USBHS interrupt handler to manage USB interrupts
*
* USB host interrupt events are split into four sections:
* - USB line events
* (VBus error, device dis/connection, SOF, reset, suspend, resume, wakeup)
* - control endpoint events
* (setup reception, end of data transfer, underflow, overflow, stall, error)
* - bulk/interrupt/isochronous endpoints events
* (end of data transfer, stall, error)
*
* Note:
* Here, the global interrupt mask is not cleared when an USB interrupt
* is enabled because this one can not occurred during the USB ISR
* (=during INTX is masked).
* See Technical reference $3.8.3 Masking interrupt requests
* in peripheral modules.
*/
void USBHS_Handler(void)
{
volatile uint32_t statusInt = (status & USBHS_IsHostIntEnable(USBHS, 0xFFFFFFFF));
....
else if (statusInt & USBHS_HSTIMR_DDISCIE)
{
USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DDISCIC);
USBHS_HostIntDisable(USBHS, USBHS_HSTIDR_DDISCIEC);
TRACE_INFO("Disconnect--\n\r");
// Stop reset signal, in case of disconnection during reset
USBHS_StopReset();
// Disable wakeup/resumes interrupts,
// in case of disconnection during suspend mode
USBHS_HostIntDisable(USBHS, (USBHS_HSTIDR_HWUPIEC
| USBHS_HSTIDR_RSMEDIEC
| USBHS_HSTIDR_RXRSMIEC));
uhd_sleep_mode(UHD_STATE_DISCONNECT);
USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DCONNIC);
USBHS_HostIntEnable(USBHS, USBHS_HSTIER_DCONNIES);
USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_HWUPIC);
USBHS_HostIntEnable(USBHS, USBHS_HSTIER_HWUPIES);
#ifdef USB_HOST_HS_SUPPORT
USBHS_SetHostHighSpeed(USBHS);
#endif
//otg_freeze_clock();
uhd_suspend_start = 0;
uhd_resume_start = 0;
USBH_notify_connection(false);
}
else if (statusInt & USBHS_HSTIMR_DCONNIE) //連續設備
{
TRACE_INFO("Connect-- ");
USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DCONNIC);
USBHS_HostIntDisable(USBHS, USBHS_HSTIDR_DCONNIEC);
USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_DDISCIC);
USBHS_HostIntEnable(USBHS, USBHS_HSTIER_DDISCIES);
USBHS_EnableSOF(USBHS);
uhd_sleep_mode(UHD_STATE_IDLE);
uhd_suspend_start = 0;
uhd_resume_start = 0;
USBH_notify_connection(true);
}
}
//函數:USBH_notify_connection(false); 斷電
//函數:USBH_notify_connection(true); 插入USB設備
//路徑: \samv7\libraries\libusb\host\core\USBH.c
void USBH_notify_connection(bool b_plug)
{
// Device connection on root
USBH_connection_tree(b_plug, &USBH_device_root);
}
/**
* \brief Manage a device plug or unplug on the USB tree
*
* \param b_plug true, if it is a device connection
* \param dev Information about device connected or disconnected
*/
static void USBH_connection_tree(bool b_plug, USBH_device_t *dev)
{
uint8_t i;
if (b_plug)
{
TRACE_INFO_WP("DevAdd ");
USBH_enum_try = 1;
USBH_dev_enum->conf_desc = NULL;
USBH_dev_enum->address = 0;
UHC_CONNECTION_EVENT(USBH_dev_enum, true);
USBH_enumeration_step1();
}
else
{
TRACE_INFO_WP("DevRem");
if (USBH_dev_enum == dev)
{
// Eventually stop enumeration timeout on-going on this device
USBH_sof_timeout = 0;
}
// Abort all transfers (endpoint control and other) and free pipe(s)
USBH_HAL_FreePipe(dev->address, 0xFF);
......
}
1.3 USBH_enumeration_step1
static void USBH_enumeration_reset(uhd_callback_reset_t callback)
{
// Reset USB line
{
USBH_HAL_Reset(callback);
}
}
void USBH_HAL_Reset(uhd_callback_reset_t callback)
{
uhd_reset_callback = callback;
USBHS_Reset();
}
//文件:samv7\libraries\libusb\common\core\USBH_HAL.c
//其中回調函數在中斷USBHS_Handler 執行
void USBHS_Handler(void)
{
// USB bus reset detection
else if (statusInt & USBHS_HSTISR_RSTI)
{
TRACE_INFO_WP("RST ");
USBHS_ClearHostStatus(USBHS, USBHS_HSTICR_RSTIC);
if (uhd_reset_callback != NULL)
{
uhd_reset_callback();
}
}
}
1.4 USBH_enumeration_step5
static void USBH_enumeration_step5(void)
{
USBGenericRequest req;
TRACE_INFO_WP("Enum5 ");
req.bmRequestType = USB_REQ_RECIP_DEVICE | USB_REQ_TYPE_STANDARD |
USB_REQ_DIR_IN;
req.bRequest = USB_REQ_GET_DESCRIPTOR;
req.wValue = (USBGenericDescriptor_DEVICE << 8);
req.wIndex = 0;
req.wLength = offsetof(USBH_device_t, dev_desc.bMaxPacketSize0)
+ sizeof(USBH_dev_enum->dev_desc.bMaxPacketSize0);
// After a USB reset, the reallocation is required
USBH_HAL_FreePipe(0, 0);
if (!USBH_HAL_ConfigureControlPipe(0, 64))
{
USBH_enumeration_error(UHC_ENUM_HARDWARE_LIMIT);
return;
}
if (!USBH_HAL_SetupReq(0,
&req, //傳遞函數
(uint8_t *)&USBH_dev_enum->dev_desc,
sizeof(USBDeviceDescriptor),
NULL,
USBH_enumeration_step6))
{
}
}
//函數 USBH_HAL_SetupReq
bool USBH_HAL_SetupReq(
uint8_t Addr,
USBGenericRequest *req,
uint8_t *payload,
uint16_t payload_size,
uhd_callback_setup_run_t callback_run,
uhd_callback_setup_end_t callback_end)
{
}
1.5 USBH_enumeration_step14
static void USBH_enumeration_step14(
USBHS_Add_t add,
USBH_XfrStatus_t status,
uint16_t payload_trans)
{
USBGenericRequest req;
uint8_t i;
bool b_conf_supported = false;
UNUSED(add);
TRACE_INFO_WP("Enum14 ");
// Check if unless one USB interface is supported by UHIs
for (i = 0; i < UHC_NB_UHI; i++)
{
switch (USBH_uhis[i].install(USBH_dev_enum))
{
case UHC_ENUM_SUCCESS:
TRACE_INFO("Device Driver installed");
b_conf_supported = true;
break;
case UHC_ENUM_UNSUPPORTED:
TRACE_INFO(" \n\rUnsupported Device");
TRACE_INFO(" \n\rRestarting enumeration");
break;
default:
}
}
}
1.6 USBH_enumeration_step15
static void USBH_enumeration_step15(
USBHS_Add_t add,
USBH_XfrStatus_t status,
uint16_t payload_trans)
{
// Enable all UHIs supported
for (i = 0; i < UHC_NB_UHI; i++)
{
USBH_uhis[i].enable(USBH_dev_enum);
}
}
//samv7\examples_usb\host_examples\usb_host_msc\conf\conf_usb_host.h
//! Array of UHI APIs Define the list of UHI supported by USB host.
#define USB_HOST_UHI UHI_MSC
//! Array of all UHI available
static uhi_api_t USBH_uhis[] = {USB_HOST_UHI};
//文件:\samv7\libraries\libusb\host\msc\uhi_msc.h
//! Global define which contains standard UHI API for UHC.
//! It must be added in USB_HOST_UHI define from conf_usb_host.h file.
#define UHI_MSC { \
.install = uhi_msc_install, \
.enable = uhi_msc_enable, \
.uninstall = uhi_msc_uninstall, \
.sof_notify = NULL, \
}
結構體:
typedef struct
{
/**
* \brief Install interface
* Allocate interface endpoints if supported.
*
* \param USBH_device_t Device to request
*
* \return status of the install
*/
USBH_enum_status_t (*install)(USBH_device_t *);
/**
* \brief Enable the interface.
*
* Enable a USB interface corresponding to UHI.
*
* \param USBH_device_t Device to request
*/
void (*enable)(USBH_device_t *);
/**
* \brief Uninstall the interface (if installed)
*
* \param USBH_device_t Device to request
*/
void (*uninstall)(USBH_device_t *);
/**
* \brief Signal that a SOF has occurred
*/
void (*sof_notify)(bool b_micro);
} uhi_api_t;
2.0 uhi_msc.c 解析
void uhi_msc_enable(USBH_device_t *dev)
{
if (uhi_msc_dev.dev != dev)
{
return; // No interface to enable
}
// ** Process to enable device **
// Setup request - Get Number of LUN
// For each LUN {
// MSC request - Inquiry
// MSC request - Read capacity*
// }
// *It is required by specific U-disk which does not respect USB MSC norm.
b_uhi_msc_free = false;
uhi_msc_enable_step1();
}