【same7】 examples_usb\host_examples\usb_host_msc host 示例代碼

目錄

1.2 USBH_notify_connection

1.3 USBH_enumeration_step1

1.4 USBH_enumeration_step5

1.5 USBH_enumeration_step14

1.6 USBH_enumeration_step15

2.0  uhi_msc.c 解析


 

\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();
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章