/*******************************************************************************
 * (c) Copyright 2012-2014 Microsemi SoC Products Group. All rights reserved.
 *
 * Smartfusion2 MSS USB Driver Stack
 *      USB Logical Layer (USB-LL)
 *          USBH driver
 *
 *  USBH driver public API.
 *
 * SVN $Revision: 6145 $
 * SVN $Date: 2014-02-18 19:11:44 +0530 (Tue, 18 Feb 2014) $
 */
/*=========================================================================*//**
  @mainpage Smartfusion2 MSS USB driver
                USBD driver

  @section intro_sec Introduction
  The USB Host Driver (USBH) is part of the USB-LL layer of the MSS USB driver
  stack. The USBH driver implements the core functionality of the USB host mode
  operations. The USBH driver is responsible for the following functionalities.
            Device attach and detach handling
            Enumeration and USB Standard requests
            Device Suspend, Resume and Reset handling
            USB transfers management
            USBH-Class call-back interface
            Application call-back interface

  @section theory_op Theory of Operation
  The following steps are involved in the operation of the USBH driver:
            Configuration
            Initialization
            USBH-Class Interface
            Application Interface
            Data transfer

  The USBH driver operation depends on user configuration provided in
  mss_usb_config.h.

  Configuration
  The following parameter must be defined in the mss_usb_config.h file to
  operate the MSS USB hardware block in USB Host mode.

    MSS_USB_HOST_MODE   Configures the MSS USB Driver Stack to operate in USB
    host mode.

  Initialization
  The USBH driver must be initialized by calling the MSS_USBH_init()
  initialization function with a parameter to provide the application call-back
  interface. Once initialized the USBH driver is ready to detect the attach event
  on the USB port. The application call-back interface is used to provide
  information about the events on the USB bus to the application. The
  MSS_USBH_task() is the main task of the USBH driver which implements the state
  machines for monitoring the USB bus activities. This function must be called
  repeatedly by the application to allow USBH driver to run its state machines.
  A timer/scheduler can be used to call this function at regular intervals or it
  can be called from the main continuous foreground loop of the application.
  The function MSS_USBH_1ms_tick() must be called to provide a 1milisecond time
  tick to the USBH driver. This time tick is used by the USBH driver to track
  the enumeration process and other housekeeping purposes. The
  MSS_USBH_get_milis() function is provided to get the number of milliseconds
  lapsed from the system reset. The MSS_USBH_test_mode() function is provided to
  force the MSS USB in test modes as required by the USB compliance test
  specification. This function has no use in normal operations with a attached
  USB device.

  USBH-Class Call-back Interface
  This driver encapsulates the generic USB protocol functionality from the USB
  class functionality. This driver needs the USBH-Class driver to implement a
  set of call-back functions to pass on the control to the USBH-Class driver for
  handling the USB class specific functionality. This driver provides a data
  type mss_usbh_class_cb_t which must be implemented by the USBH-Class driver.
  This data type is the collection of call-back functions which must be
  implemented by the USBH-Class driver. Implementing all the elements of this
  structure may not be necessary for a specific USB class. The USBH-Class driver
  must define a structure of type mss_usbh_class_cb_t and implement its required
  elements. The function MSS_USBH_register_class_driver() must be used to inform
  the USBH driver about this call-back interface and the supported USB Class
  information

  Application Call-back Interface
  The USBH driver uses interrupts to respond to the events on MSS USB. The
  USBH driver handles the enumeration of the attached device internally.
  The enumeration process can take long time (hundreds of miliseconds) to
  complete. The USBH driver uses application call-back interface to inform the
  application about the events on the USB bus as they happen. The application
  may implement these call-back functions to take application specific action
  on each event or to provide error/status messages to the user.

  Data transfer
  The USB host uses pipe, a representation of logical connection from endpoint
  on MSS USB to the endpoint on the target device. The transmit pipe or the
  receive pipe must first be configured before starting the data transfer on it.
  The functions MSS_USBH_configure_in_pipe() and MSS_USBH_configure_out_pipe()
  must be used to configure an IN(data moving from device to host) and an
  OUT(data moving from host to device) pipe respectively.

  The application must use MSS_USBH_write_out_pipe() function to start data
  transmission on a OUT pipe. This function prepares the MSS USB to transmit
  data to the device. However, actual transmission happens depending on the
  transfer type and the selected interval.  This function is non-blocking.
  The USBH-Class driver will be informed about data transmission completion or
  transmission errors by a call to its call-back function. Please refer
  USBH-Class Interface section above for more details.

  To receive data from attached USB device, application must use
  MSS_USBH_read_in_pipe() function. This function prepares the MSS USB to
  receive data from the attached device. However, actual data transfer happens
  depending on the transfer type and the selected interval. This function is
  non-blocking.  On receiving data or in case of errors during this operation
  the USBH-Class driver will be informed about it by calling a call-back function.
  Please refer the USBH-Class Interface section above for more details.

  All the control transfers happen on the control pipe. The control pipe is
  shared by the USBH driver and the USBH-Class driver. When the USBH-Class driver
  needs to perform control transfer on the attached device, it must first
  configure the control pipe using the MSS_USBH_configure_control_pipe() function.
  The  MSS_USBH_start_control_xfr() function can be used to start the control
  transfer After the control pope is configured. The data direction is determined
  by a parameter provided with this function. The USBH-Class driver will be
  informed about the data transfer completion or the error status by calling a
  call-back function. Please refer the USBH-Class Interface section above for
  more details. The control transfer can be started by a USBH-Class driver only
  when the control pipe is free.The MSS_USBH_get_cep_state() function can be
  used to know the current state of the control pipe. At the start of the control
  transfer the USBH driver must send a setup-packet to the attached device in
  the setup phase. The function MSS_USBH_construct_get_descr_command() can be
  used to construct the setup packet as per the USB specification for the
  transfer to be performed. This function formats the setup packet depending on
  the parameters provided with this function.

  The application may choose to keep the MSS USB in suspend state to conserve
  power to the USB device, and the MSS USB, In this state the MSS USB does not
  send any frames on the bus and there will be no bus activity. This will also
  ensure that the attached device enters suspend state as specified in the
  USB2.0 specification. The USBH driver provides the MSS_USBH_suspend() function
  to suspend the MSS USB. The  MSS_USBH_resume() function must be used to
  resume the normal operations.

 *//*=========================================================================*/
#ifndef __MSS_USB_HOST_H_
#define __MSS_USB_HOST_H_

#include "mss_usb_common_cif.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef MSS_USB_HOST_ENABLED

/***************************************************************************//**
 Constant values exported by USBH driver
*/
/***************************************************************************//**
 The following constants are used to identify the exact reason due to which the
 USBH driver is not supporting the attached device. One of these values is
 passed as a parameter to the call-back function usbh_tdev_not_supported when
 USBH driver detects respective condition.
*/
/*
 Devices operating at the USB full speed are not supported.
*/
#define FS_DEV_NOT_SUPPORTED                            -15

/*
 Devices operating at the USB low speed are not supported.
*/
#define LS_DEV_NOT_SUPPORTED                            -14

/*
 Device belonging to the USB HUB class is detected. The Hub class is not
 supported by the USBH driver.
*/
#define HUB_CLASS_NOT_SUPPORTED                         -13

/*
 Attached device class description does not match the class description
 supported by the registered class driver.
*/
#define CLASS_DRIVER_NOT_MATCHED                        -12

/*
 The registered class driver is already in assigned state when new device
 attachment is detected.
*/
#define CLASS_DRIVER_NOT_FREE                           -11

/*
 The power requirement for the attached device, as described in the bMaxPower
 field of configuration descriptor, can not be supported by the USBH driver.
*/
#define CONF_DESC_POWER_LIM_EXCEED                      -10

/*
 The value received in bDescriptorType field in configuration descriptor is
 invalid.
*/
#define CONF_DESC_WRONG_DESC_TYPE                       -9

/*
 The value received in bLength field of the configuration descriptor does not
 match the standard value (9) as specified in the USB2.0 specification.
*/
#define CONF_DESC_WRONG_LENGTH                          -8

/*
 The value received in bMaxPacketSize0 field of the device descriptor is not 8
 for a LS device.
*/
#define DEV_DESC_LS_MAXPKTSZ0_NOT8                      -7

/*
 The value received in bMaxPacketSize0 field of the device descriptor is not 64
 for a HS device.
*/
#define DEV_DESC_HS_MAXPKTSZ0_NOT64                     -6

/*
 The value received in bcdDevice field of the device descriptor for a HS device
 does not indicate USB2.0
*/
#define DEV_DESC_HS_USBBCD_NOT200                       -5

/*
 The value received in the bMaxPacketSize0 field of the device descriptor is
 invalid. For LS device this value must be 8. For HS device this value must be
 64. For FS device this value must be 8, 16, 32, or 64.
*/
#define DEV_DESC_WRONG_MAXPKTSZ0                        -4

/*
 The value received in the bcdDevice field of the device descriptor is invalid.
 For HS device this value must indicate USB2.0.
*/
#define DEV_DESC_WRONG_USBBCD                           -3

/*
 The value received in the bDescriptorType field in device descriptor is invalid.
*/
#define DEV_DESC_WRONG_DESC_TYPE                        -2

/*
 The value received in the bLength field of the device descriptor does not match
 the standard value (18).
*/
#define DEV_DESC_WRONG_LENGTH                           -1

/***************************************************************************//**
 Data structures exported by USBH driver
*/

/***************************************************************************//**
dev_desc_t
  The dev_desc_t provides the prototype of the structure for the standard USB
  device descriptor. All the parameters of this structure are as per the
  standard setup packet defined in the USB2.0 specification.

  bLength
  The bLength parameter indicates the length of the device descriptor in bytes.
  The meaning of this parameter is exactly as defined by the USB2.0 specification.

  bDescriptorType
  The bDescriptorType parameter indicates the standard descriptor type of this
  descriptor. The meaning of this parameter is exactly as defined by the USB2.0
  specification.

  bcdUSB
  The bcdUSB parameter indicates the USB standard (BCD format) supported by the
  device. The meaning of this parameter is exactly as defined by the USB2.0
  specification.

  bDeviceClass
  The bDeviceClass parameter indicates the standard USB class supported by the
  device. The meaning of this parameter is exactly as defined by the USB2.0
  specification.

  bDeviceSubClass
  The bDeviceSubClass parameter indicates the standard USB sub-class supported
  by the device. The meaning of this parameter is exactly as defined by the
  USB2.0 specification.

  bDeviceProtocol
  The bDeviceProtocol parameter indicates the standard USB data transfer protocol
  supported by the device. The meaning of this parameter is exactly as defined
  by the USB2.0 specification.

  bMaxPacketSize0
  The bMaxPacketSize0 parameter indicates the Maximum packet size of the
  Endpoint0 on the device. The meaning of this parameter is exactly as defined
  by the USB2.0 specification.

  idVendor
  The idVendor parameter indicates Vendor ID of the connected device. The
  meaning of this parameter is exactly as defined by the USB2.0 specification.

  idProduct
  The idproduct parameter indicates Product ID of the connected device. The
  meaning of this parameter is exactly as defined by the USB2.0 specification.

  bcdDevice
  The bcdDevice parameter indicates release number (BCD format) of the connected
  device. The meaning of this parameter is exactly as defined by the USB2.0
  specification.

  iManufacturer
  The iManufacturer parameter indicates the index of the string descriptor
  describing the manufacture name of the connected device. The meaning of this
  parameter is exactly as defined by the USB2.0 specification.

  iProduct
  The iProduct parameter indicates index of string descriptor describing the
  product name of the connected device. The meaning of this parameter is exactly
  as defined by the USB2.0 specification.

  iSerialNumber
  The iSerialNumber parameter indicates the index of the string descriptor
  describing the serial number of the connected device. The meaning of this
  parameter is exactly as defined by the USB2.0 specification.

  bNumConfigurations
  The bNumConfigurations parameter indicates number of configurations supported
  by the connected device. The meaning of this parameter is exactly as defined
  by the USB2.0 specification.

  reserved
  The reserved parameter does not have a specific meaning. It is provided to
  make the structure word aligned.
*/
typedef struct
{
    uint8_t   bLength;
    uint8_t   bDescriptorType;
    uint16_t  bcdUSB;
    uint8_t   bDeviceClass;
    uint8_t   bDeviceSubClass;
    uint8_t   bDeviceProtocol;
    uint8_t   bMaxPacketSize0;
    uint16_t  idVendor;
    uint16_t  idProduct;
    uint16_t  bcdDevice;
    uint8_t   iManufacturer;
    uint8_t   iProduct;
    uint8_t   iSerialNumber;
    uint8_t   bNumConfigurations;
    uint16_t  reserved; /*Word alignment*/
}dev_desc_t;

/***************************************************************************//**
def_conf_desc_t
  The def_conf_desc_t provides the prototype of the structure for the standard
  USB configuration descriptor. All the parameters of this structure are as per
  the standard setup packet defined in the USB2.0 specification.

  bLength
  The bLength parameter indicates the length of the configuration descriptor in
  bytes. The meaning of this parameter is exactly as defined by the USB2.0
  specification.

  bDescriptorType
  The bDescriptorType parameter indicates the standard descriptor type of this
  descriptor. The meaning of this parameter is exactly as defined by the USB2.0
  specification.

  bTotalLength
  The bTotalLength parameter indicates the total length (in bytes) of the
  configuration descriptor including the class specific subordinate descriptors.
  The meaning of this parameter is exactly as defined by the USB2.0 specification.

  bNumInterface
  The bNumInterfaces parameter indicates the number of interfaces supported by
  this configuration. The meaning of this parameter is exactly as defined by
  the USB2.0 specification.

  bConfigurationValue
  The bConfigurationValue parameter indicates the value to be use as an argument
  to SET_CONFIGURATION request to select this configuration. The meaning of this
  parameter is exactly as defined by the USB2.0 specification.

  iConfiguration
  The iConfiguration parameter indicates the index of the string descriptor
  describing this configuration. The meaning of this parameter is exactly as
  defined by the USB2.0 specification.

  bmAttributes
  The bmAttributes parameter provides configuration characteristics of this
  configuration. The meaning of this parameter is exactly as defined by the
  USB2.0 specification.

  bMaxPower
  The bMaxPower parameter indicates the Maximum power consumption of the USB
  device from the bus in this specific configuration when the device is fully
  operational. The meaning of this parameter is exactly as defined by the
  USB2.0 specification.

  upended_desc
  The upended_desc parameter can be used to store the class specific subordinate
  descriptor information. This might be useful to retrieve some basic information
  about the selected configuration.
*/
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t wTotalLength;
    uint8_t bNumInterfaces;
    uint8_t bConfigurationValue;
    uint8_t iConfiguration;
    uint8_t bmAttributes;
    uint8_t bMaxPower;
    uint8_t upended_desc[11];
}def_conf_desc_t;

/***************************************************************************//**
mss_usbh_class_cb_t
  The mss_usbh_class_cb_t provides the prototype of the structure that must be
  implemented by the USBH-Class driver to provide the call-back functions which
  will be called by the USBH driver to communicate events on the target device.

  class_id
  The class_id parameter is the placeholder for identifying the USBH-Class
  driver which is implementing this call-back interface. This parameter is used
  by the USBH driver to identify and assign the class driver to the attached
  device.The MSS_USBH_register_class_driver() function must be used to register
  a class driver with the the USBH driver. This parameter must be of the form:

    D31 - D24        D23 - D16             D15 - D8                 D7 - D0
    0x00        USB Std class code    USB Std sub-class code    USB Std Protocol code

  usbh_class_allocate
  The function pointed by the usbh_class_allocate element will be called when a
  match is found between the class code, sub-class code and protocol code of the
  attached device and the corresponding parameters provided by the USBH-Class
  driver in class_id parameter. The tdev_addr parameter provides the non-zero
  device address assigned to the attached device by the USBH driver.

  usbh_class_release
  The function pointed by the usbh_class_release element will be called when the
  device for which this USBH-Class driver is assigned is detached. The tdev_addr
  parameter provides the non-zero device address assigned to the attached device
  by the USBH driver.

  usbh_class_cep_xfr_done
  The function pointed by the usbh_class_cep_xfr_done element will be called
  when a control transfer started by this USBH-Class driver is complete. The
  tdev_addr parameter provides the non-zero device address assigned to the
  attached device by the USBH driver. The status parameter indicates whether or
  not the current control transfer was completed successfully. The count
  parameter provides the number of bytes transferred in the current control
  transfer. The status parameter provides the error status of current control
  transfer. A non-zero value indicates that there was an error.

  usbh_class_dataout_done
  The function pointed by the usbh_class_dataout_done element will be called
  when a transfer started on OUT pipe by this USBH-Class driver is complete.
  The tdev_addr parameter provides the non-zero device address assigned to the
  attached device by USBH driver. The status parameter indicates whether or not
  the current transfer was completed successfully. The count parameter provides
  the number of bytes transferred in the current control transfer. The status
  parameter provides the error status of the current control transfer. A
  non-zero value indicates that there was an error.

  usbh_class_datain_done
  The function pointed by the usbh_class_datain_done element will be called
  when a transfer started on the IN pipe by this USBH-Class driver is complete.
  The tdev_addr parameter provides the non-zero device address assigned to the
  attached device by the USBH driver. The status parameter indicates whether or
  not the current transfer was completed successfully. The count parameter
  provides the number of bytes transferred in the current control transfer.
  The status parameter provides the error status of current control transfer.
  A non-zero value indicates that there was an error.

  usbh_class_sof
  The function pointed by the usbh_class_sof element will be called when a new
  micro frame starts. The frame_number provides the number of the current
  micro frame.

*/
typedef struct mss_usb_host_class_cb {
    uint32_t class_id;
    uint8_t (*usbh_class_allocate)(uint8_t tdev_addr);
    uint8_t (*usbh_class_release)(uint8_t tdev_addr);
    uint8_t (*usbh_class_cep_xfr_done)(uint8_t tdev_addr,
                                       uint8_t status,
                                       uint32_t count);

    uint8_t (*usbh_class_dataout_done)(uint8_t tdev_addr,
                                       uint8_t status,
                                       uint32_t count); //add epnum to parameter

    uint8_t (*usbh_class_datain_done)(uint8_t tdev_addr,
                                      uint8_t status,
                                      uint32_t count);

    uint8_t (*usbh_class_sof)(uint32_t frame_number);
}mss_usbh_class_cb_t;

/***************************************************************************//**
mss_usbh_tdev_info_t
  The mss_usbh_tdev_info_t type provides the prototype for the detailed
  information of the attached device. Some of the parameters are only applicable
  when multi-point support is enabled on MSS USB. Multi-point support is
  currently not enabled in the USBH driver.

  addr
  The addr parameter provides the device address assigned to the attached device
  by the USBH driver.

  speed
  The speed parameter indicates the USB speed of operation at which the USBH
  driver is communicating with the attached device.

  state
  The state parameter provides the current state of the attached device. E.g.
  address, Configured etc.

  hub_addr
  The hub_addr parameter provides the address of the hub to which the device is
  attached. This parameter is meaningful only when Multi-Point support is
  enabled. Multi-point support is currently not enabled in the USBH driver.

  hub_port
  The hub_port parameter provides the port number of the hub to which the device
  is attached. This parameter is meaningful only when Multi-Point support is
  enabled. Multi-point support is currently not enabled in the USBH driver.

  hub_mtt
  The hub_mtt parameter indicates whether or not the hub to which the device is
  attached supports multiple transaction translators. This parameter is meaningful
  only when Multi-Point support is enabled. Multi-point support is currently not
  enabled in the USBH driver.

  maxpktsz0
  The maxpktsz0 parameter provides the maximum packet size of the control
  endpoint on the attached device.

  state
  The state parameter provides the current state of the attached device.
  E.g. address, Configured etc.

  class_handle
  The class_handle parameter is the class handle registered with the USBH driver
  using MSS_USBH_register_class_driver() function. This handle is used by the
  USBH driver to call the call-back functions implemented by the USBH-Class
  driver.
 */
typedef struct mss_usbh_target_info {
    uint8_t addr;
    mss_usb_device_speed_t speed;
    mss_usb_state_t state;
    uint8_t hub_addr;
    uint8_t hub_port;
    uint8_t hub_mtt;
    uint16_t tdev_maxpktsz0;
    mss_usbh_class_cb_t* class_handle;
} mss_usbh_tdev_info_t;

/***************************************************************************//**
mss_usbh_user_cb_t
  The mss_usbh_user_cb_t provides the prototype of the structure that must be
  implemented by the application to provide the call-back functions which will
  be called by the USBH driver to communicate events on the target device. These
  call-back functions can be used by the application to know the USBH driver
  state and information about the attached device from the USBH driver.
  These events are not specific to any USB class.

  usbh_tdev_attached
  The function pointed by the usbh_tdev_attached element will be called when a
  device attach even is detected by the USBH driver. At this point the device is
  not enumerated. The speed parameter indicates the USB speed of operation at
  which the USBH driver is going to communicate with the attached device.

  usbh_tdev_dettached
  The function pointed by the usbh_tdev_dettached element will be called when
  a device detach even is detected by the USBH driver.

  usbh_tdev_oc_error
  The function pointed by the usbh_tdev_oc_error element will be called when an
  over-current condition is detected by the USBH driver.

  usbh_tdev_enumerated
  The function pointed by the usbh_tdev_enumerated element will be called when
  the attached device is successfully enumerated. At this point the device
  descriptor is successfully read from the attached device. No class specific
  information is read from the device yet. The tdev_info parameter gives the
  information about the attached device.

  usbh_tdev_class_driver_assigned
  The function pointed by the usbh_tdev_class_driver_assigned element will be
  called when a matching class driver is assigned to the attached device.
  The class driver must be previously registered with the USBH driver using
  MSS_USBH_register_class_driver() function.

  usbh_tdev_not_supported
  The function pointed by the usbh_tdev_not_supported element will be called
  when a device which is not supported by the USBH driver is attached. The
  error_code parameter provides the exact reason why the device is not supported.
  E.g. devices belonging to Hub class are not supported.

  usbh_tdev_ permanent_error
  The function pointed by the usbh_tdev_permanent_error element will be called
  if there is error during data transfer operations with the attached device
  persists after retries. On detecting an error in data transfer with the
  attached device, the USBH driver retries for maximum three times.
*/
typedef struct mss_usbh_user_cb
{
  void (*usbh_tdev_attached)(mss_usb_device_speed_t speed);
  void (*usbh_tdev_dettached)(void);
  void (*usbh_tdev_oc_error)(void);
  void (*usbh_tdev_enumerated)(mss_usbh_tdev_info_t tdev_info);
  void (*usbh_tdev_class_driver_assigned) (void);
  void (*usbh_tdev_not_supported)(int8_t error_code);
  void (*usbh_tdev_permanent_error)(void);
} mss_usbh_user_cb_t;

/*******************************************************************************
 * EXPORTED APIs from USBH driver
 *******************************************************************************/

/***************************************************************************//**
  @brief MSS_USBH_init()
  The MSS_USBH_init() function initializes the MSS USB driver in the USB host
  mode. This function initializes the internal data structures and readies the
  MSS USB hardware block to detect the device attachment event. This function
  also configures the control endpoint to keep it ready for communicating with
  the detected device on the USB port. The parameter app_cb provided with this
  function must be implemented by the application. This driver uses the app_cb
  to inform the application about the events on the USB bus by calling the
  appropriate callback element.

  The MSS_USBH_init() function must be called before any other function to
  initialize the USBH driver in the USB host mode.

  @param app_cb
  The app_cb parameter provides the pointer to the structure of type
  mss_usbh_user_cb_t. This structure is used to call the user call-back functions
  by the USBH driver. These call-back functions can be used to provide
  error/status messages to the user for the application specific handling of
  the events.

  @return
    This function does not return any value.

  Example:
  @code
        MSS_USBH_init();
        MSS_USBH_register_class_driver(MSS_USBH_MSC_get_handle());
  @endcode
*/
void
MSS_USBH_init
(
    mss_usbh_user_cb_t* app_cb
);


/***************************************************************************//**
  @brief MSS_USBH_task()
  The MSS_USBH_task() function is the main task of the USBH driver. This
  function must be called repeatedly by the application to allow the USBH driver
  to perform the housekeeping tasks. A timer/scheduler can be used to call this
  function at regular intervals or it can be called from the main continuous
  foreground loop of the application.

  @param
    This function does not take any parameters.

  @return
    This function does not return any value.

  Example:
  @code
        void
        Host_controller_task
        (
            void
        )
        {
              MSS_USBH_task();
              MSS_USBH_MSC_task();
              switch(c_state)
              {
                  case CONTROLLER_IDLE:
                      if(USBH_MSD_DEVICE_READY == MSS_USBH_MSC_get_state())
                      {
                          c_state = CONTROLLER_INQUIRY;
                      }
                  break;
                .
                .
                .
                  default:
                  break;
              }
        }

  @endcode
*/
void
MSS_USBH_task
(
    void
);

/***************************************************************************//**
  @brief MSS_USBH_register_class_driver()
  The MSS_USBH_register_class_driver() function must be used by the application
  to register a USBH-Class driver with the USBH driver. The application must
  first get the handle from the USBH-Class driver before assigning it to the
  USBH driver. Refer the USBH-Class section to know how to get a handle from the
  USBH-Class driver. This handle is used by the USBH driver to communicate with
  the USBH-Class driver.

  @param class_handle
  The class_handle parameter specifies the class driver handle to be registered
  with the USBH driver.

  @return
    This function does not return any value.

  Example:
  @code
        MSS_USBH_init();
        MSS_USBH_register_class_driver(MSS_USBH_MSC_get_handle());

  @endcode
*/
int8_t
MSS_USBH_register_class_driver
(
    void* class_handle
);

/***************************************************************************//**
  @brief MSS_USBH_configure_control_pipe()
  The MSS_USBH_configure_control_pipe() function is used to configure the
  control pipe for the control transactions with attached device with the
  address provided in target_addr parameter. This function also enables the
  control pipe interrupt.

  This function must be called before any other function for the control pipe.

  @param target_addr
  The target_addr parameter is address of the attached device with which the
  MSS USB needs to communicate.

  @return
    This function returns zero when execution was successful.

  Example:
  @code
        typedef enum {
            TDEV_R,
            TDEV_RHP1,
            TDEV_RHP2
        } tdev_id_t;

        MSS_USBH_configure_control_pipe(TDEV_R);

  @endcode
*/
int8_t
MSS_USBH_configure_control_pipe
(
    uint8_t target_addr
);

/***************************************************************************//**
  @brief MSS_USBH_configure_in_pipe()
  The MSS_USBH_configure_in_pipe() function is used to configure the IN pipe
  for the IN transactions with the attached device with the address provided in
  the target_addr parameter. This function also enables the IN pipe interrupt.

  This function must be called before any other function for the IN pipe.

  @param target_addr
  The target_addr parameter is the address of the attached device with which
  MSS USB needs to communicate.

  @param inpipe_num
  The inpipe_num parameter indicates the IN pipe number (endpoint) on MSS USB
  which must be used for IN transfers with the attached device.

  @param target_ep
  The target_ep parameter indicates the IN endpoint number on the attached
  device with which MSS USB needs to communicate.

  @param fifo_addr
  The fifo_addr parameter is the address of the FIFO in the MSS USB internal RAM.
  The valid FIFO address values are from 0x00 to 0xFFF8. The FIFO Address must
  be a multiple of 8. If the value provided is not a multiple of 8, then the
  immediate lower value which is a multiple of 8 is taken as the FIFO address.
  E.g. If the provided value is 0x09, the actual value taken by the driver is
  0x08. If the provided value is less than 0x08 then the FIFO address is taken
  as 0x00.

  @param fifo_size
  The fifo_size parameter provides the endpoint FIFO size in the USB core
  internal RAM. The valid FIFO size values are 8, 16, 32, 64, 128, 512, 1024,
  2048, 4096. The MSS USB assigns 8 byte FIFO by default if the FIFO size is
  not configured.

  @param max_pkt_size
  The max_pkt_size parameter provides the maximum packet size of the USB
  transfer. This value must be equal to the maximum packet size as mentioned in
  the endpoint descriptor which is used during enumeration process.

  Note: This value must be less than or equal to the FIFO size value.


  @param num_usb_pkt
  The num_usb_pkt parameter has different meanings for different types of
  transfers.

  Low bandwidth ISO/interrupt transfers  This parameter must always be 1u.
  This parameter represents the number of packets transferred in one (micro) frame.

  High bandwidth ISO transfers  This parameter represents the number of packets
  transferred in one (Micro) frame. In this case, this parameter can have a
  value of 1 2 or 3. High bandwidth ISO transfers are not yet implemented.

  Bulk transfers.  For Bulk transfer this value must always be 1u. This
  parameter is  be used with the auto-amalgamation/auto-split feature where it
  indicates number of bulk packets to be auto-amalgamated/auto-split in bulk
  transfer. The auto-amalgamation/auto-split feature is implemented but not yet
  tested.

  @param dma_enable
  The dma_enable parameter specifies whether or not the internal DMA must be
  used for the data transfer from the provided buffer to the USB FIFO. Internal
  DMA is not enabled in the USB Host mode yet.

  @param dma_channel
  The dma_channel parameter specifies the internal DMA channel to be used for
  the data transfers. DMA channel will be associated with selected endpoint.
  A unique DMA channel must be selected to transfer data on individual endpoints.
  This parameter is ignored when dma_enable parameter indicates that the DMA
  must not be used.

  @param xfr_type
  The xfr_type parameter specifies the type of transfer to be performed on the
  specified endpoint. All other types of transfers (Interrupt, Isochronous,
  and Bulk) can be selected except the control transfer,

  @param add_zlp
  The add_zlp parameter indicates whether to expect a zero length packet (ZLP)
  if the transfer size is exact a multiple of wMaxPacketSize. This parameter is
  only applicable for bulk transfers. For all other transfer types this
  parameter is ignored.

  @param interval
  The interval parameter for interrupt and isochronous transfers defines the
  polling interval for the currently-selected IN pipe. For bulk transfers,
  this parameter indicates the number of frames/microframes after which the IN
  pipe must timeout on receiving a stream of NAK responses. The valid values for
  this parameter are as mentioned in the table below.

    Transfer Type            Speed                            Valid values
                                                    (No of frames/microframes)
    Interrupt                LS or FS                        1  255
                                HS                1,2,4,8,16,32,6432768 microframes

    Isochronous              FS or HS             1,2,4,8,16,32,6432768 frames/microframes

    Bulk                     FS or HS             1,2,4,8,16,32,6432768 frames/microframes


  @return
    This function returns zero when execution was successful.

  Example:
  @code
        case USBH_MSC_CONFIG_BULK_ENDPOINTS:
            MSS_USBH_configure_out_pipe(g_msd_tdev_addr,
                                        USBH_MSC_BULK_OUT_PIPE,
                                        g_tdev_out_ep.num,  //Targeted OUTEP Num
                                        USBH_MSC_BULK_OUT_PIPE_FIFOADDR,
                                        USBH_MSC_BULK_OUT_PIPE_FIFOSZ,
                                        g_tdev_out_ep.maxpktsz,
                                        1,
                                        DMA_DISABLE,
                                        MSS_USB_DMA_CHANNEL_NA,
                                        MSS_USB_XFR_BULK,
                                        NO_ZLP_TO_XFR,
                                        32768u);

            MSS_USBH_configure_in_pipe(g_msd_tdev_addr,
                                       USBH_MSC_BULK_IN_PIPE,
                                       g_tdev_in_ep.num,    //Targeted OutEP Num
                                       USBH_MSC_BULK_IN_PIPE_FIFOADDR,
                                       USBH_MSC_BULK_IN_PIPE_FIFOSZ,
                                       g_tdev_in_ep.maxpktsz,
                                       1,
                                       DMA_DISABLE,
                                       MSS_USB_DMA_CHANNEL_NA,
                                       MSS_USB_XFR_BULK,
                                       NO_ZLP_TO_XFR,
                                       32768u);

            g_msc_state = USBH_MSC_TEST_UNIT_READY_CPHASE;
        break;

  @endcode
*/
int8_t
MSS_USBH_configure_in_pipe
(
    uint8_t target_addr,
    uint8_t inpipe_num,
    uint8_t target_ep,
    uint16_t fifo_addr,
    uint16_t fifo_size,
    uint16_t max_pkt_size,
    uint8_t num_usb_pkt,
    uint8_t dma_enable,
    mss_usb_dma_channel_t dma_channel,
    mss_usb_xfr_type_t xfr_type,
    uint32_t add_zlp,
    uint32_t interval
);

/***************************************************************************//**
  @brief MSS_USBH_configure_out_pipe()
  The MSS_USBH_configure_out_pipe() function is used to configure the OUT pipe
  for the OUT transactions with attached device with the address provided in the
  target_addr parameter. This function also enables the OUT pipe interrupt.

  This function must be called before any other function for the OUT pipe.


  @param target_addr
  The target_addr parameter is the address of the attached device with which
  MSS USB needs to communicate.

  @param outpipe_num
  The outpipe_num parameter indicates the OUT pipe number (endpoint) on MSS USB
  which must be used for OUT transfers with the attached device.

  @param target_ep
  The target_ep parameter indicates the OUT endpoint number on the attached
  device with which MSS USB needs to communicate.

  @param fifo_addr
  The fifo_addr parameter is the address of the FIFO in the MSS USB internal ram.
  The valid FIFO address values are from 0x00 to 0xFFF8. The FIFO address must
  be a multiple of 8. If the value provided is not a multiple of 8, then the
  immediate lower value which is a multiple of 8 is taken as the FIFO address.
  E.g. If the provided value is 0x09, the actual value taken by the driver is
  0x08. If the provided value is less than 0x08 then the  FIFO address is taken
  as 0x00.

  @param fifo_size
  The fifo_size parameter provides the endpoint FIFO size in the USB core
  internal RAM. The valid FIFO size values are 8, 16, 32, 64, 128, 512, 1024,
  2048, 4096. The MSS USB assigns 8 byte FIFO by default if the FIFO size is
  not configured.

  @param max_pkt_size
  The max_pkt_size parameter provides the maximum packet size of the USB
  transfer. This value must be equal to the maximum packet size as mentioned in
  the endpoint descriptor which is used during enumeration process.

  Note: This value must be less than or equal to the FIFO size value.

  @param num_usb_pkt
  The num_usb_pkt parameter has different meanings for different types of
  transfers.

  Low bandwidth ISO/interrupt transfers  This parameter must always be 1u.
  This parameter represents the number of packets transferred in one (micro)
  frame.

  High bandwidth ISO transfers  This parameter represents the number of packets
  transferred in one (Micro) frame. In this case, this parameter can have a
  value of 1 2 or 3. High bandwidth ISO transfers are not yet implemented.

  Bulk transfers.  For Bulk transfer this value must always be 1u. This
  parameter will be used with the auto-amalgamation/auto-split feature where it
  indicates the number of bulk packets to be auto-amalgamated/auto-split in bulk
  transfer. The auto-amalgamation/auto-split feature is implemented but not yet
  tested.

  @param dma_enable
  The dma_enable parameter specifies whether or not the internal DMA must be
  used for the data transfer from the provided buffer to the USB FIFO. Internal
  DMA is not enabled in the USB Host mode yet.

  @param dma_channel
  The dma_channel parameter specifies the internal DMA channel to be used for
  the data transfers. The DMA channel will be associated with the specified
  endpoint. A unique DMA channel must be selected to transfer data on individual
  endpoints. This parameter is ignored when the dma_enable parameter indicates
  that the DMA must not be used.

  @param xfr_type
  The xfr_type parameter specifies the type of transfer to be performed on the
  specified endpoint. All other types of transfers (Interrupt, Isochronous,
  and Bulk) can be selected except control transfer.

  @param add_zlp
  The add_zlp parameter indicates whether to send a zero length packet (ZLP) if
  the transfer size is a exact multiple of wMaxPacketSize. This parameter is
  only applicable for Bulk transfers. For all other transfer types this
  parameter is ignored.

  @param interval
  The interval parameter for interrupt and isochronous transfers, defines the
  polling interval for the currently-selected OUT pipe. For the bulk transfers,
  this parameter indicates the number of frames/microframes after which the OUT
  Pipe must timeout on receiving a stream of NAK responses. The valid values for
  this parameter are as mentioned in the table below.

        Transfer Type                Speed              Valid values
                                                    (No of frames/microframes)
        Interrupt,,,                LS or FS.....       1  255
                                        HS..        1,2,4,8,16,32,6432768 microframes
        Isochronous.                FS or HS....    1,2,4,8,16,32,6432768  frames/microframes
        Bulk....                    FS or HS....    1,2,4,8,16,32,6432768  frames/microframes


  @return
    This function returns zero when execution was successful.

  Example:
  @code
        case USBH_MSC_CONFIG_BULK_ENDPOINTS:
            //Configure BULK TX/RX Endpoints
            MSS_USBH_configure_out_pipe(g_msd_tdev_addr,
                                        USBH_MSC_BULK_OUT_PIPE,
                                        g_tdev_out_ep.num,  //Targeted OUTEP Num
                                        USBH_MSC_BULK_OUT_PIPE_FIFOADDR,
                                        USBH_MSC_BULK_OUT_PIPE_FIFOSZ,
                                        g_tdev_out_ep.maxpktsz,
                                        1,
                                        DMA_DISABLE,
                                        MSS_USB_DMA_CHANNEL_NA,
                                        MSS_USB_XFR_BULK,
                                        NO_ZLP_TO_XFR,
                                        32768u);

            MSS_USBH_configure_in_pipe(g_msd_tdev_addr,
                                       USBH_MSC_BULK_IN_PIPE,
                                       g_tdev_in_ep.num,    //Targeted OutEP Num
                                       USBH_MSC_BULK_IN_PIPE_FIFOADDR,
                                       USBH_MSC_BULK_IN_PIPE_FIFOSZ,
                                       g_tdev_in_ep.maxpktsz,
                                       1,
                                       DMA_DISABLE,
                                       MSS_USB_DMA_CHANNEL_NA,
                                       MSS_USB_XFR_BULK,
                                       NO_ZLP_TO_XFR,
                                       32768u);

            g_msc_state = USBH_MSC_TEST_UNIT_READY_CPHASE;
        break;

  @endcode
*/
int8_t
MSS_USBH_configure_out_pipe
(
    uint8_t target_addr,
    uint8_t outpipe_num,
    uint8_t target_ep,
    uint16_t fifo_addr,
    uint16_t fifo_size,
    uint16_t max_pkt_size,
    uint8_t num_usb_pkt,
    uint8_t dma_enable,
    mss_usb_dma_channel_t dma_channel,
    mss_usb_xfr_type_t xfr_type,
    uint32_t add_zlp,
    uint32_t interval
);

/***************************************************************************//**
  @brief MSS_USBH_write_out_pipe()
  The MSS_USBH_write_out_pipe() function writes the data provided by the user
  into the previously configured out pipe FIFO. The data is ready to be
  transferred after calling this function. The Data will be transferred by the
  MSS USB according to the transfer type and interval parameter set for this
  OUT pipe using MSS_USBH_configure_out_pipe() function. This function is
  non-blocking.A call-back function will be called to indicate the status of
  this transfer after the status phase of the current OUT transaction is complete.

  @param target_addr
  The target_addr parameter is the address of the attached device with which the
  MSS USB needs to communicate.

  @param outpipe_num
  The outpipe_num parameter indicates the OUT pipe number (endpoint) on the MSS
  USB which must be used for the OUT transfers with the attached device.

  @param target_ep
  The target_ep parameter indicates the OUT endpoint number on the attached
  device with which MSS USB needs to communicate.

  @param max_pkt_size
  The max_pkt_size parameter provides the maximum packet size of the USB
  transfer. This value must be equal to the maximum packet size as mentioned in
  the endpoint descriptor which is used during enumeration process.

  @param buf
  The buf parameter is the address of the buffer provided by the user from which
  the data is copied to the selected pipe buffer.

  @param length
  The length parameter specifies the length of the data buffer in bytes.

  @return
  This function does not return a value.

  Example:
  @code
        case USBH_MSC_TEST_UNIT_READY_CPHASE:
            MSS_USBH_MSC_construct_cbw_cb6byte(USB_MSC_SCSI_TEST_UNIT_READY,
                                               0u,
                                               &g_bot_cbw);

            MSS_USBH_write_out_pipe(g_msd_tdev_addr,
                                    USBH_MSC_BULK_OUT_PIPE,
                                    g_tdev_out_ep.num,
                                    g_tdev_out_ep.maxpktsz,
                                    (uint8_t*)&g_bot_cbw,
                                    31u); //std_cbw_len

            g_msc_state = USBH_MSC_TEST_UNIT_READY_SPHASE;
        break;

  @endcode
*/
int8_t
MSS_USBH_write_out_pipe
(
    uint8_t target_addr,
    uint8_t outpipe_num,
    uint8_t tdev_ep_num,
    uint16_t maxpktsz,
    uint8_t* buf,
    uint32_t length
);

/***************************************************************************//**
  @brief MSS_USBH_read_in_pipe()
  The MSS_USBH_read_in_pipe() function writes the data provided by the user into
  the previously configured out pipe FIFO. The data is ready to be transferred
  after calling this function. The data will be transferred by the MSS USB
  according to the transfer type and the interval parameter set for this OUT
  pipe using theMSS_USBH_configure_in_pipe() function.  This function is
  non-blocking. A call-back function will be called to indicate the status of
  this transfer after the status phase of the current IN transaction is complete.

  @param target_addr
  The target_addr parameter is the address of the attached device with which the
  MSS USB needs to communicate.

  @param outpipe_num
  The outpipe_num parameter indicates the OUT pipe number (endpoint) on MSS USB
  which must be used for the OUT transfers with the attached device.

  @param target_ep
  The target_ep parameter indicates the OUT endpoint number on the attached
  device with which the MSS USB needs to communicate.

  @param max_pkt_size
  The max_pkt_size parameter provides the maximum packet size of the USB
  transfer. This value must be equal to the maximum packet size as mentioned in
  the endpoint descriptor which is used during enumeration process.

  @param buf
  The buf parameter is the address of the buffer provided by the user from which
  the data is copied to the selected pipe buffer.

  @param length
  The length parameter specifies the length of the data buffer in bytes.

  @return
  This function does not return a value.

  Example:
  @code
    case USBH_MSC_TEST_UNIT_READY_SPHASE:
            if(g_usbh_msc_dataout_event)
            {
                g_usbh_msc_dataout_event = 0;
                g_msc_state = USBH_MSC_TEST_UNIT_READY_WAITCOMPLETE;
                MSS_USBH_read_in_pipe(g_msd_tdev_addr,
                                      USBH_MSC_BULK_IN_PIPE,
                                      g_tdev_in_ep.num,
                                      g_tdev_in_ep.maxpktsz,
                                      (uint8_t*)&g_bot_csw,
                                      13u);
            }
        break;

  @endcode
*/
int8_t
MSS_USBH_read_in_pipe
(
    uint8_t target_addr,
    uint8_t inpipe_num,
    uint8_t tdev_ep_num,
    uint16_t tdev_ep_maxpktsz,
    uint8_t* buf,
    uint32_t length
);

/***************************************************************************//**
  @brief MSS_USBH_get_tdev_state()
  The MSS_USBH_get_tdev_state() function can be used to find out the current
  state of the attached device. E.g. ADDRESS, CONFIGURED etc. (as defined by USB2.0).

  @param target_addr
  The target_addr parameter is the address of the attached device with which
  the MSS USB needs to communicate.

  @return
    This function returns a value of type mss_usb_state_t indicating the current
    state of the attached device.

  Example:
  @code
    static mss_usb_state_t msd_tdev_state = MSS_USB_NOT_ATTACHED_STATE;
    msd_tdev_state = MSS_USBH_get_tdev_state(g_msd_tdev_addr);
  @endcode

*/
mss_usb_state_t
MSS_USBH_get_tdev_state
(
    uint8_t target_addr
);

/***************************************************************************//**
  @brief MSS_USBH_suspend()
  The MSS_USBH_suspend() function can be used to suspend the MSS USB. The MSS
  USB will complete the current transaction then stop the transaction scheduler
  and frame counter. No further transactions will be started and no SOF packets
  will be generated.

  @param
    This function does not take any parameters.

  @return
    This function does not return any value.

  Example:
  @code
  @endcode
*/
void
MSS_USBH_suspend
(
    void
);

/***************************************************************************//**
  @brief MSS_USBH_resume()
  The MSS_USBH_resume() function can be used to resume the previously suspended
  MSS USB. If the MSS USB was in suspend mode then it will start the transaction
  scheduler and frame counter after calling this function.

  @param
    This function does not take any parameters.

  @return
    This function does not return any value.

  Example:
  @code
  @endcode
*/
void
MSS_USBH_resume
(
    void
);

/***************************************************************************//**
  @brief MSS_USBH_1ms_tick()
  The MSS_USBH_1ms_tick() function must be used to provide the 1ms time tick to
  the USBH driver. This time reference is used by the USBH driver to keep track
  of different time delays required during enumeration process. This way the
  application need not wait for the enumeration to complete which may take long
  time.

  @param
    This function does not take any parameters.

  @return
    This function does not return any value.

  Example:
  @code

        void SysTick_Handler(void)
        {

        // This function must be called. This function provides the time stamp
        // which is used to keep track of activities such as USB Reset, Settling time etc.
        // in Enumeration process.
        // The USBH driver and USBH-MSC class driver housekeeping task is also run based
        // on this timestamp.
        //
        // This avoids the application to wait for the enumeration process to complete
        // which might take time in 100s of miliseconds depending on target device.
        //
        // You may choose a general purpose timer instead of Systick.

            MSS_USBH_task();
            MSS_USBH_MSC_task();
            MSS_USBH_1ms_tick();
        }
  @endcode
*/
void
MSS_USBH_1ms_tick
(
    void
);

/***************************************************************************//**
  @brief MSS_USBH_get_milis()
  The MSS_USBH_get_milis() function is used to find out the number of
  milliseconds elapsed from the time when last reset occurred.

  @param
  This function does not take any parameters.

  @return
  This function returns a 32-bit unsigned integer value. This value indicates
  the number of milliseconds elapsed from the time when the last reset occurred.
  This integer value will overflow after approximately 49Hrs after reset.

  Example:
  @code
        case USBH_MSC_WAIT_SET_CONFIG:
            if(g_usbh_msc_cep_event)
            {
                g_usbh_msc_cep_event = 0;
                wait_mili = MSS_USBH_get_milis();
                g_msc_state = USBH_MSC_WAIT_DEV_SETTLE;
            }
        break;

        case USBH_MSC_WAIT_DEV_SETTLE:
            if((MSS_USBH_get_milis() - wait_mili) > 60)
            {
                g_msc_state = USBH_MSC_GET_MAX_LUN;
            }
        break;

  @endcode
*/
uint32_t
MSS_USBH_get_milis
(
    void
);

/***************************************************************************//**
  @brief MSS_USBH_construct_get_descr_command()
  The MSS_USBH_construct_get_descr_command() function is be used to construct
  the setup packet which is to be sent on the USB bus. This function formats the
  provided parameters into a USB standard format GET_DESCRIPTOR request and
  stores it in the location provided by the buf parameter.

  @param buf
  The buf parameter is the address of the buffer where the formatted
  GET_DESCRIPTOR request is stored.

  @param xfr_dir
  The xfr_dir parameter indicates the direction of the data transfer on the USB
  bus. The value USB_STD_REQ_DATA_DIR_IN indicates that the direction of the
  data transfer is from the USB device to USB host (USB IN transaction). The
  value USB_STD_REQ_DATA_DIR_OUT indicates that the direction of the data
  transfer is from the USB host to the USB device (USB OUT transaction).

  @param req_type
  The req_type parameter indicates the request type. The request type can be
  one of the following: standard request, class request or vendor request.

  @param recip_type
  The recip_type parameter indicates the recipient type on the USB device. The
  request recipient on the attached device can be one of the following: device,
  endpoint or interface.

  @param request
  The request parameter indicates the request that needs to be sent to the
  attached device.

  @param desc_type
  The desc_type parameter indicates the descriptor type that needs to be
  requested from the attached device.

  @param strng_idx
  The strng_idx parameter indicates the index of the string descriptor when the
  desc_type parameter indicates STRING TYPE.

  @param length
  The length parameter indicates the number of bytes to be received from
  attached device as part of the requested descriptor.

  @return
    This function does not return any value.

  Example:
  @code
        MSS_USBH_configure_control_pipe(g_msd_tdev_addr);
        memset(std_req_buf, 0u, 8*(sizeof(uint8_t)));
        MSS_USBH_construct_get_descr_command(std_req_buf,
                                             USB_STD_REQ_DATA_DIR_IN,
                                             USB_STANDARD_REQUEST,
                                             USB_STD_REQ_RECIPIENT_DEVICE,
                                             USB_STD_REQ_GET_DESCRIPTOR,
                                             USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                             0, //stringID
                                             32u);//config_Desc_length

        g_msc_state = USBH_MSC_WAIT_GET_CLASS_DESCR;
        MSS_USBH_start_control_xfr(std_req_buf,
                                   (uint8_t*)&g_msd_conf_desc,
                                   USB_STD_REQ_DATA_DIR_IN,
                                   32u);        //config_Desc_length
  @endcode
*/
void
MSS_USBH_construct_get_descr_command
(
    uint8_t* buf,
    uint8_t xfr_dir,
    uint8_t req_type,
    uint8_t recip_type,
    uint8_t request,
    uint8_t desc_type,
    uint8_t strng_idx,
    uint16_t length
);

/***************************************************************************//**
  @brief MSS_USBH_start_control_xfr()
  The MSS_USBH_start_control_xfr() function must be used to start a control
  transfer with the attached USB device. This is a non-blocking function.
  This function prepares the control pipe for the control transfer. A call-back
  function will be called to indicate the status of the transfer after the
  status phase of the control transfer is complete.

  @param cbuf_addr
  The cbuf_addf parameter is the address of the buffer where the USB request
  setup packet is available.

  @param dbuf_addr
  The dbuf_addf parameter is the address of the buffer for the data phase of
  the control transfer. The USBD driver will put the data received from attached
  device in this buffer for the USB IN transfers. The data from this buffer will
  be sent to the attached device for the USB OUT transfers.

  @param data_dir
  The data_dir parameter indicates the direction of the data flow in the data
  phase of the control transfer. The value USB_STD_REQ_DATA_DIR_IN indicates
  that the direction of the data transfer is from the USB device to the USB host
  (USB IN transaction). The value USB_STD_REQ_DATA_DIR_OUT indicates that the
  direction of the data transfer is from the USB host to the USB device
  (USB OUT transaction).

  @param data_len
  The data_len parameter indicates the number of bytes to be transferred during
  the data phase of the control transfer.

  @return
    This function returns zero when execution was successful.

  Example:
  @code
        MSS_USBH_configure_control_pipe(g_msd_tdev_addr);
        memset(std_req_buf, 0u, 8*(sizeof(uint8_t)));
        MSS_USBH_construct_get_descr_command(std_req_buf,
                                             USB_STD_REQ_DATA_DIR_IN,
                                             USB_STANDARD_REQUEST,
                                             USB_STD_REQ_RECIPIENT_DEVICE,
                                             USB_STD_REQ_GET_DESCRIPTOR,
                                             USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                             0, //stringID
                                             32u);//config_Desc_length

        g_msc_state = USBH_MSC_WAIT_GET_CLASS_DESCR;
        MSS_USBH_start_control_xfr(std_req_buf,
                                   (uint8_t*)&g_msd_conf_desc,
                                   USB_STD_REQ_DATA_DIR_IN,
                                   32u);        //config_Desc_length

@endcode
*/
uint8_t
MSS_USBH_start_control_xfr
(
    uint8_t* cbuf_addr,
    uint8_t* dbuf_addr,
    uint8_t  data_dir,
    uint32_t data_len
);

/***************************************************************************//**
  @brief MSS_USBH_get_cep_state()
  The MSS_USBH_get_cep_state() function can be used to find out the current
  state of the control pipe. A new control transfer can be started when the
  control pipe is in the MSS_USB_CEP_IDLE state.

  @param
  This function does not take any parameters.

  @return
  This function returns a value of type mss_usb_ep_state_t indicating the current
  state of the control pipe.

  Example:
  @code
        mss_usb_ep_state_t cep_st;
        cep_st = MSS_USBH_get_cep_state();
        if(MSS_USB_CEP_IDLE == cep_st)
        {
            MSS_USBH_configure_control_pipe(g_msd_tdev_addr);
            memset(std_req_buf, 0u, 8*(sizeof(uint8_t)));
            MSS_USBH_construct_get_descr_command(std_req_buf,
                                                 USB_STD_REQ_DATA_DIR_IN,
                                                 USB_STANDARD_REQUEST,
                                                 USB_STD_REQ_RECIPIENT_DEVICE,
                                                 USB_STD_REQ_GET_DESCRIPTOR,
                                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                                 0, //stringID
                                                 32u);//config_Desc_length

            g_msc_state = USBH_MSC_WAIT_GET_CLASS_DESCR;
            MSS_USBH_start_control_xfr(std_req_buf,
                                       (uint8_t*)&g_msd_conf_desc,
                                       USB_STD_REQ_DATA_DIR_IN,
                                       32u);        //config_Desc_length
        }
  @endcode
*/
mss_usb_ep_state_t
MSS_USBH_get_cep_state
(
    void
);

/***************************************************************************//**
  @brief MSS_USBH_test_mode()
  The MSS_USBH_test_mode() function can be used to initiate one of the compliance
  test modes in the MSS USB. This function is useful only for compliance test
  procedures. The MSS USB goes into the specified test mode once this function
  is executed. A hard reset is required to resume normal operations.

  @param test_case
  The test_case parameter indicates the compliance test that need to be executed.
  The compliance tests could be one of the following:
        Test-J (USB_TEST_MODE_SELECTOR_TEST_J),
        Test-K (USB_TEST_MODE_SELECTOR_TEST_K),
        SE0-NAK (USB_TEST_MODE_SELECTOR_TEST_SE0NAK),
        Test-Packet (USB_TEST_MODE_SELECTOR_TEST_PACKET)

  @return
    This function does not return any value.
  Example:
  @code
        case '1':
            MSS_USBH_test_mode(USB_TEST_MODE_SELECTOR_TEST_PACKET);
            MSS_UART_polled_tx_string(&g_mss_uart1,(uint8_t *)"\n\n\r Test-Packet started...");
        break;

        case '2':
            MSS_USBH_test_mode(USB_TEST_MODE_SELECTOR_TEST_J);
            MSS_UART_polled_tx_string(&g_mss_uart1,(uint8_t *)"\n\n\r Test-J started...");
        break;

        case '3':
            MSS_USBH_test_mode(USB_TEST_MODE_SELECTOR_TEST_K);
            MSS_UART_polled_tx_string(&g_mss_uart1,(uint8_t *)"\n\n\r Test-K started...");
        break;

        case '4':
            MSS_USBH_test_mode(USB_TEST_MODE_SELECTOR_TEST_SE0NAK);
            MSS_UART_polled_tx_string(&g_mss_uart1,(uint8_t *)"\n\n\r Test-SE0-NAK started...");
        break;

        case '5':
            MSS_USBH_test_mode(USB_TEST_MODE_SELECTOR_TEST_FORCE_ENA);
            MSS_UART_polled_tx_string(&g_mss_uart1,(uint8_t *)"\n\n\r Test-Force-Host started...");
        break;

        default:
            invalid_selection_menu();
        break;

  @endcode
*/
void
MSS_USBH_test_mode
(
    uint8_t test_case
);

/***************************************************************************//**
  @brief MSS_USBH_get_std_dev_descr()
  The MSS_USBH_get_std_dev_descr() function can be used to get the 8 byte USB
  standard device descriptor from the attached device. This function is provided
  specifically for the Standard Descriptor test case of USB-IF compliance
  procedure. This function might not be useful In general scenarios.

  @param buffer
  The buffer parameter is the pointer to the buffer where the USB standard
  device descriptor received from the attached device will be stored.

  @return
    This function returns zero on successful execution.

  Example:
  @code
        mss_usb_ep_state_t cep_st;
        cep_st = MSS_USBH_get_cep_state();
        if(MSS_USB_CEP_IDLE == cep_st)
        {
            MSS_USBH_configure_control_pipe(g_msd_tdev_addr);
            memset(std_req_buf, 0u, 8*(sizeof(uint8_t)));
            MSS_USBH_construct_get_descr_command(std_req_buf,
                                                 USB_STD_REQ_DATA_DIR_IN,
                                                 USB_STANDARD_REQUEST,
                                                 USB_STD_REQ_RECIPIENT_DEVICE,
                                                 USB_STD_REQ_GET_DESCRIPTOR,
                                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                                 0, //stringID
                                                 32u);//config_Desc_length

            g_msc_state = USBH_MSC_WAIT_GET_CLASS_DESCR;
            MSS_USBH_start_control_xfr(std_req_buf,
                                       (uint8_t*)&g_msd_conf_desc,
                                       USB_STD_REQ_DATA_DIR_IN,
                                       32u);        //config_Desc_length
        }
  @endcode
*/
int8_t
MSS_USBH_get_std_dev_descr
(
    uint8_t* buffer
);

#endif //MSS_USB_HOST_ENABLED

#ifdef __cplusplus
}
#endif

#endif  /* __MSS_USB_HOST_H_ */
