/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : ch9SetConfig
* Returned Value : None
* Comments       :
*     Chapter 9 SetConfig command
*     We setup a TX packet of 0 length ready for the IN token
*     Once we get the TOK_DNE interrupt for the IN token, then
*     we change the configuration number and go to the CONFIG state.
* 
*END*--------------------------------------------------------------------*/
void    mvUsbCh9SetConfig(_usb_device_handle handle,
                        boolean setup, SETUP_STRUCT* setup_ptr)
{ /* Body */
   static uint_8            new_config;

   ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_ADDR, "%s: setup=%d, config=%d\n", 
                                    __FUNCTION__, (int)setup, setup_ptr->VALUE);

   if (setup) 
   {
      new_config = setup_ptr->VALUE;
      /*******************************************************
       * if hardware assitance is enabled for set_address (see
       * hardware rev for details) we need to do the set_address
       * before queuing the status phase.
       *******************************************************/
       _usb_device_set_status(handle, ARC_USB_STATUS_CURRENT_CONFIG, new_config);
      /* ack */
      _usb_device_send_data(handle, 0, 0, 0);
   } 
   else 
   {
      _usb_device_set_status(handle, ARC_USB_STATUS_CURRENT_CONFIG, new_config);
      _usb_device_set_status(handle, ARC_USB_STATUS_DEVICE_STATE, ARC_USB_STATE_CONFIG);        
   }
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : ch9SetAddress
* Returned Value : None
* Comments       :
*     Chapter 9 SetAddress command
*     We setup a TX packet of 0 length ready for the IN token
*     Once we get the TOK_DNE interrupt for the IN token, then
*     we change the ADDR register and go to the ADDRESS state.
*
*END*--------------------------------------------------------------------*/
void    mvUsbCh9SetAddress(_usb_device_handle handle,
                        boolean setup, SETUP_STRUCT* setup_ptr)
{ /* Body */
   static uint_8            new_address;

   ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_ADDR, "usbDisk %s: setup=%d, address=%d\n",
                                    __FUNCTION__, (int)setup, setup_ptr->VALUE);

   if (setup)
   {
      new_address = setup_ptr->VALUE;
      /*******************************************************
       * if hardware assitance is enabled for set_address (see
       * hardware rev for details) we need to do the set_address
       * before queuing the status phase.
       *******************************************************/
#ifdef SET_ADDRESS_HARDWARE_ASSISTANCE
       _usb_device_set_status(handle, ARC_USB_STATUS_ADDRESS, new_address);
#endif
      /* ack */
      _usb_device_send_data(handle, 0, 0, 0);
   }
   else
   {
#ifndef SET_ADDRESS_HARDWARE_ASSISTANCE
      _usb_device_set_status(handle, ARC_USB_STATUS_ADDRESS, new_address);
#endif
      _usb_device_set_status(handle, ARC_USB_STATUS_DEVICE_STATE, ARC_USB_STATE_ADDRESS);
   }
}
示例#3
0
/**************************************************************************//*!
 *
 * @name  USB_Class_Hid_Event
 *
 * @brief The function initializes HID endpoint
 *
 * @param handle          handle to Identify the controller
 * @param event           pointer to event structure
 * @param val             gives the configuration value
 *
 * @return None
 *
 *****************************************************************************/
void USB_Class_Hid_Event(uint8_t event, void* val,void * arg)
{
    uint8_t index;

    USB_EP_STRUCT_PTR ep_struct_ptr;

    HID_DEVICE_STRUCT_PTR  devicePtr;

    devicePtr = (HID_DEVICE_STRUCT_PTR)arg;

    if(event == USB_APP_ENUM_COMPLETE)
    {
        uint8_t count = 0;
        uint8_t component;

        /* get the endpoints from the descriptor module */
        USB_ENDPOINTS *ep_desc_data = devicePtr->ep_desc_data;

        /* intialize all non control endpoints */
        while(count < ep_desc_data->count)
        {
            ep_struct_ptr= (USB_EP_STRUCT*) &ep_desc_data->ep[count];
            component = (uint8_t)(ep_struct_ptr->ep_num |
                (ep_struct_ptr->direction << COMPONENT_PREPARE_SHIFT));
            (void)_usb_device_init_endpoint(devicePtr->handle, ep_struct_ptr, TRUE);

            /* register callback service for endpoint 1 */
            (void)_usb_device_register_service(devicePtr->handle,
                (uint8_t)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                USB_Service_Hid, arg);
            /* set the EndPoint Status as Idle in the device layer */
            /* (no need to specify direction for this case) */
            (void)_usb_device_set_status(devicePtr->handle,
                  (uint8_t)(USB_STATUS_ENDPOINT|component),
                  (uint16_t)USB_STATUS_IDLE);
            count++;
        }
    }
    else if(event == USB_APP_BUS_RESET)
    {
        /* clear producer and consumer */
        for(index = 0; index < devicePtr->hid_endpoint_data.count; index++)
        {
            devicePtr->hid_endpoint_data.ep[index].bin_consumer = 0x00;
            devicePtr->hid_endpoint_data.ep[index].bin_producer = 0x00;
        }
    }

    if(devicePtr->hid_class_callback.callback != NULL)
    {
        devicePtr->hid_class_callback.callback(event,val,
        devicePtr->hid_class_callback.arg);
    }
}
示例#4
0
 /**************************************************************************//*!
 *
 * @name  USB_Class_PHDC_Event
 *
 * @brief Initializes non control endpoints
 *
 * @param handle
 * @param event          : event notified by the layer below
 * @param value          : additional parameter used by the event
 *
 * @return               : None
 ******************************************************************************
 * Initializes non control endpoints when Enumeration complete event is
 * received.
 *****************************************************************************/
static void USB_Class_PHDC_Event(uint8_t event,
                                 void* val,void *arg)
{
    uint8_t ep_count;
    USB_EP_STRUCT ep_struct;
    PHDC_STRUCT_PTR phdc_obj_ptr = (PHDC_STRUCT_PTR)arg;

    if (phdc_obj_ptr == NULL)
    {
        #if _DEBUG
            printf("USB_Class_PHDC_Event:phdc_object_ptr is NULL\n");
        #endif
        return;
    }
    /* if enum is complete initialize non-control endpoints */
    if(event == USB_APP_ENUM_COMPLETE)
    {
        /* initialize all receive endpoints */
        for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_rx; ep_count++)
        {
            uint8_t component = (uint8_t)(phdc_obj_ptr->ep_data.ep_rx[ep_count].endpoint |
                (USB_RECV << COMPONENT_PREPARE_SHIFT));

            /* initialize ep_struct */
            ep_struct.ep_num = phdc_obj_ptr->ep_data.ep_rx[ep_count].endpoint;
            ep_struct.size = phdc_obj_ptr->ep_data.ep_rx[ep_count].size;
            ep_struct.type = phdc_obj_ptr->ep_data.ep_rx[ep_count].type;
            ep_struct.direction = USB_RECV;

            /* initialize endpoint */
            (void)_usb_device_init_endpoint(phdc_obj_ptr->controller_handle,
             &ep_struct,TRUE);

            phdc_obj_ptr->service_buff_ptr = (uint8_t *)USB_mem_alloc_zero(ep_struct.size);
            if (NULL == phdc_obj_ptr->service_buff_ptr)
            {
                #if _DEBUG
                    printf("USB_Class_PHDC_Event: Memalloc failed\n");
                #endif
                return ;
            }

            /* set endpt status as idle in the device layer */
            (void)_usb_device_set_status(phdc_obj_ptr->controller_handle,
                (uint8_t)(USB_STATUS_ENDPOINT |component),
                (uint16_t)USB_STATUS_IDLE);
            phdc_obj_ptr->ep_data.ep_rx[ep_count].buff_ptr = NULL;
            phdc_obj_ptr->ep_data.ep_rx[ep_count].buffer_size = 0;
        }

        /* initialize all transmit endpoints */
        for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_tx; ep_count++)
        {
            uint8_t component = (uint8_t)(phdc_obj_ptr->ep_data.ep_tx[ep_count].endpoint |
                (USB_SEND << COMPONENT_PREPARE_SHIFT));

            /* initialize ep_struct */
            ep_struct.ep_num = phdc_obj_ptr->ep_data.ep_tx[ep_count].endpoint;
            ep_struct.size = phdc_obj_ptr->ep_data.ep_tx[ep_count].size;
            ep_struct.type = phdc_obj_ptr->ep_data.ep_tx[ep_count].type;
            ep_struct.direction = USB_SEND;

            /* initialize endpoint */
            (void)_usb_device_init_endpoint(phdc_obj_ptr->controller_handle,
             &ep_struct, TRUE);

            /* set endpt status as idle in the device layer */
            (void)_usb_device_set_status(phdc_obj_ptr->controller_handle,
                (uint8_t)(USB_STATUS_ENDPOINT |component),
                (uint16_t)USB_STATUS_IDLE);
        }
    }
    else if(event == USB_APP_BUS_RESET)
    {
        /* initialize producer and consumer to zero for transmit endpoints */
        for(ep_count = 0; ep_count < phdc_obj_ptr->ep_data.count_tx; ep_count++)
        {
            phdc_obj_ptr->ep_data.ep_tx[ep_count].bin_consumer = (uint8_t)0x00;
            phdc_obj_ptr->ep_data.ep_tx[ep_count].bin_producer = (uint8_t)0x00;
        }
    }

    if(phdc_obj_ptr->phdc_callback.callback != NULL)
    {
        phdc_obj_ptr->phdc_callback.callback(event,
            val,phdc_obj_ptr->phdc_callback.arg);
    }
}
void    mvUsbCh9ClearFeature(_usb_device_handle handle, boolean setup,
                            SETUP_STRUCT* setup_ptr)
{ /* Body */
    uint_8   endpoint, direction;
    uint_16  usb_status;

    ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_SETUP, "%s: setup=%d\n", __FUNCTION__, (int)setup);

    _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE_STATE, &usb_status);
    if ((usb_status != ARC_USB_STATE_CONFIG) && (usb_status != ARC_USB_STATE_ADDRESS))
    {
        USB_printf("ClearFeature: Wrong USB state %d\n", usb_status);
        _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
        return;
    } /* Endif */

    if(!setup)
        return;

    switch (setup_ptr->REQUESTTYPE)
    {
        case (REQ_DIR_OUT | REQ_RECIP_DEVICE):
            /* DEVICE */
            switch(setup_ptr->VALUE)
            {
                case DEVICE_REMOTE_WAKEUP:
                    /* clear remote wakeup */
                    _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE, &usb_status);
                    usb_status &= ~ARC_USB_REMOTE_WAKEUP;
                    _usb_device_set_status(handle, ARC_USB_STATUS_DEVICE, usb_status);
                    USB_printf("Clear REMOTE_WAKEUP feature\n");
                    break;

                case DEVICE_TEST_MODE:
                    /* Exit Test Mode */
                    _usb_device_set_status(handle, ARC_USB_STATUS_TEST_MODE, 0);
                    break;

                default:
                    USB_printf("ClearFeature: Unknown Device feature %d\n",
                                setup_ptr->VALUE);
                    _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                    return;
            } /* Endif */
            break;

        case (REQ_DIR_OUT | REQ_RECIP_ENDPOINT):
            /* ENDPOINT */
            if (setup_ptr->VALUE != ENDPOINT_HALT)
            {
                USB_printf("ClearFeature: Wrong Endpoint feature %d\n",
                            setup_ptr->VALUE);
                _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                return;
            } /* Endif */

            endpoint = setup_ptr->INDEX & ARC_USB_STATUS_ENDPOINT_NUMBER_MASK;
            if( (setup_ptr->INDEX & (1 << REQ_DIR_OFFSET)) == REQ_DIR_IN)
                direction = ARC_USB_SEND;
            else
                direction = ARC_USB_RECV;

            _usb_device_unstall_endpoint(handle, endpoint, direction);
            break;

        default:
            USB_printf("ClearFeature: Unknown REQUEST_TYPE %d\n",
                                setup_ptr->REQUESTTYPE);

            _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
            return;
    } /* Endswitch */

    /* status phase */
    _usb_device_send_data(handle, 0, 0, 0);
}
void    mvUsbCh9SetFeature(_usb_device_handle handle, boolean setup,
                          SETUP_STRUCT* setup_ptr)
{
   uint_16                  usb_status;
   uint_8                   endpoint, direction;
   USB_DEV_STATE_STRUCT*    usb_dev_ptr = (USB_DEV_STATE_STRUCT*)handle;

   ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_SETUP, "%s: setup=%d\n", __FUNCTION__, (int)setup);

   if (setup)
   {
      switch (setup_ptr->REQUESTTYPE)
      {
         case (REQ_DIR_OUT | REQ_RECIP_DEVICE):
            /* DEVICE */
            switch (setup_ptr->VALUE)
            {
               case DEVICE_REMOTE_WAKEUP:
                  /* set remote wakeup */
                  _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE, &usb_status);
                  usb_status |= ARC_USB_REMOTE_WAKEUP;
                  _usb_device_set_status(handle, ARC_USB_STATUS_DEVICE, usb_status);
                  USB_printf("Set REMOTE_WAKEUP feature\n");
                  break;

               case DEVICE_TEST_MODE:
                  /* Test Mode */
                  if( (setup_ptr->INDEX & 0x00FF) || (usb_dev_ptr->SPEED != ARC_USB_SPEED_HIGH) )
                  {
                     USB_printf("SetFeature: Wrong Test mode parameters: mode=%d, speed=%d\n",
                                (setup_ptr->INDEX & 0x00FF), usb_dev_ptr->SPEED);
                     _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                     return;
                  } /* Endif */

                  _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE_STATE, &usb_status);
                  if( (usb_status == ARC_USB_STATE_CONFIG)  ||
                      (usb_status == ARC_USB_STATE_ADDRESS) ||
                      (usb_status == ARC_USB_STATE_DEFAULT))
                  {
                      /* wait with Set Test mode */
                      ENTER_TEST_MODE = TRUE;
                      test_mode_index = (setup_ptr->INDEX & 0xFF00);
                      USB_printf("SetFeature: Prepare for Test mode 0x%x\n", test_mode_index);
                  }
                  else
                  {
                     USB_printf("SetFeature: Wrong USB state for Test mode: state=%d\n",
                                usb_status);
                     _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                     return;
                  } /* Endif */
                  break;

               default:
                    USB_printf("SetFeature: Unknown Device feature %d\n",
                                setup_ptr->VALUE);
                  _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                  return;
            } /* Endswitch */
            break;

         case (REQ_DIR_OUT | REQ_RECIP_ENDPOINT):
            /* ENDPOINT */
            if (setup_ptr->VALUE != ENDPOINT_HALT)
            {
                USB_printf("SetFeature: Unknown Endpoint feature %d\n",
                            setup_ptr->VALUE);
                _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                return;
            } /* Endif */

            endpoint = setup_ptr->INDEX & ARC_USB_STATUS_ENDPOINT_NUMBER_MASK;
            if( (setup_ptr->INDEX & (1 << REQ_DIR_OFFSET)) == REQ_DIR_IN)
                direction = ARC_USB_SEND;
            else
                direction = ARC_USB_RECV;

            _usb_device_stall_endpoint(handle, endpoint, direction);
            break;

         default:
            USB_printf("SetFeature: Unknown REQUEST_TYPE %d\n",
                       setup_ptr->REQUESTTYPE);

            _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
            return;
      } /* Endswitch */

      /* status phase */
      _usb_device_send_data(handle, 0, 0, 0);
   }
   else
   {
      if (ENTER_TEST_MODE)
      {
         /* Enter Test Mode */
          USB_printf("SetFeature: Activate Test mode 0x%x\n", test_mode_index);
         _usb_device_set_status(handle, ARC_USB_STATUS_TEST_MODE, test_mode_index);
      } /* Endif */
   } /* Endif */
}
示例#7
0
/*
** ===================================================================
**     Method      :  USB_Class_Mems_Event (component USB_MEMS_CLASS)
**
**     Description :
**         The funtion initializes Mems endpoint
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void USB_Class_Mems_Event(
uint_8 controller_ID,
uint_8 event,
void* val
)
{
    uint_8 index;

    if(event == USB_APP_ENUM_COMPLETE)
    {
        uint_8 count;
        /* get the endpoints from the descriptor module */
        USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
        USB_Desc_Get_Endpoints(controller_ID);

        count = ep_desc_data->count;
        /* deinitialize all endpoints in case they were initialized */
        while(count > 0)
        {
            USB_EP_STRUCT_PTR ep_struct_ptr=
            (USB_EP_STRUCT_PTR) (&ep_desc_data->ep[count - 1]);
            (void)_usb_device_deinit_endpoint(&controller_ID,
            ep_struct_ptr->ep_num, ep_struct_ptr->direction);
            count--;
        }

        /* intialize all non control endpoints */
        while(count < ep_desc_data->count)
        {
            USB_EP_STRUCT_PTR ep_struct=
            (USB_EP_STRUCT_PTR)&ep_desc_data->ep[count];

            (void)_usb_device_init_endpoint(&controller_ID, ep_struct->ep_num,
            ep_struct->size, ep_struct->direction, ep_struct->type, TRUE);

            /* register callback service for the endpoint */
            switch(ep_struct->type)
            {
            case USB_INTERRUPT_PIPE:
                (void)_usb_device_register_service(controller_ID,
                (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                USB_Service_Mems_Status_Interrupt);
                break;       
                
            case USB_BULK_PIPE :
               if(ep_struct->direction == USB_RECV)
               {
                     (void)_usb_device_register_service(controller_ID,
                     (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                     USB_Class_MEMS_Service_Dic_Bulk_Out);
               }
               else
               {
                      (void)_usb_device_register_service(controller_ID,
                      (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                      USB_Class_MEMS_Service_Dic_Bulk_In);
               }
               break;
                                
            default:
                break;
            }
            /* set the EndPoint Status as Idle in the device layer */
            (void)_usb_device_set_status(&controller_ID,
            (uint_8)(USB_STATUS_ENDPOINT | 1|
            (ep_struct->direction << USB_COMPONENT_DIRECTION_SHIFT)),
            USB_STATUS_IDLE);
            count++;
        }
    }
    else if(event == USB_APP_BUS_RESET)
    {
        /* clear producer and consumer on reset */
        for(index = 0; index < g_mems_endpoint_data.count; index++)
        {
            g_mems_endpoint_data.ep[index].bin_consumer = 0x00;
            g_mems_endpoint_data.ep[index].bin_producer = 0x00;
            g_mems_endpoint_data.ep[index].queue_num    = 0x00;
        }
    }

    if(g_mems_class_callback != NULL)
    {
        /* notify the event to the application */
        g_mems_class_callback(controller_ID, event, val);
    }
}
示例#8
0
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Event
 *
 * @brief The function initializes CDC endpoints
 *
 * @param controller_ID : Controller ID
 * @param event         : Event Type
 * @param val           : Pointer to configuration Value
 *
 * @return None
 *
 ******************************************************************************
 *
 *****************************************************************************/
void USB_Class_CDC_Event (
    uint_8 controller_ID,   /* [IN] Controller ID */
    uint_8 event,           /* [IN] Event Type */
    void* val               /* [OUT] Pointer to configuration Value */
)
{
    uint_8 index;
    USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)
        USB_Desc_Get_Endpoints(controller_ID);

    if(event == USB_APP_ENUM_COMPLETE)
    {
        uint_8 count = 0,ep_count = 0;
        uint_8 index_num = 0;

#ifdef COMPOSITE_DEV
        DEV_ARCHITECTURE_STRUCT_PTR dev_arc_ptr;
        CLASS_ARC_STRUCT_PTR dev_class_ptr;
        dev_arc_ptr = (DEV_ARCHITECTURE_STRUCT *)USB_Desc_Get_Class_Architecture(controller_ID);
        for(count = 0; count < dev_arc_ptr->cl_count; count++)
        {
            dev_class_ptr = (CLASS_ARC_STRUCT_PTR)dev_arc_ptr->value[count];
            /* Initializes sub_classes */
            ep_count = dev_class_ptr->value[0];
            if(dev_class_ptr->class_type == 0x02/*CDC_CC*/)
                break;
            index_num +=dev_class_ptr->value[0];
        }
#else
                ep_count = usb_ep_data->count;
#endif

                for(count=index_num; count<ep_count+index_num; count++)
                {
                        USB_EP_STRUCT_PTR ep_struct_ptr=
                                (USB_EP_STRUCT_PTR) (&usb_ep_data->ep[count]);
                        (void)_usb_device_deinit_endpoint(&controller_ID,
                                ep_struct_ptr->ep_num, ep_struct_ptr->direction);
                }

        /* intialize all non control endpoints */
        for(count=index_num; count<ep_count+index_num; count++)
        {
            USB_EP_STRUCT_PTR ep_struct=
                (USB_EP_STRUCT_PTR) (&usb_ep_data->ep[count]);

            (void)_usb_device_init_endpoint(&controller_ID, ep_struct->ep_num,
                        ep_struct->size, ep_struct->direction, ep_struct->type, FALSE);

            /* register callback service for Non Control EndPoints */
            switch(ep_struct->type)
            {
#if CIC_NOTIF_ELEM_SUPPORT
                case USB_INTERRUPT_PIPE :
                    (void)_usb_device_register_service(controller_ID,
                        (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                        USB_Class_CDC_Service_Cic_Notify);
                    break;
#endif
#if !DIC_ISOCHRONOUS_SETTING
                case USB_BULK_PIPE :
#ifdef MULTIPLE_DEVICES
                    if(ep_struct->direction == USB_RECV)
                    {
                        (void)_usb_device_register_service(controller_ID,
                            (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                            USB_Class_CDC_Service_Dic_Bulk_Out);
                    }
                    else
                    {
                        (void)_usb_device_register_service(controller_ID,
                            (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                            USB_Class_CDC_Service_Dic_Bulk_In);
                    }
#endif
                    break;
#else
                case USB_ISOCHRONOUS_PIPE :
                    if(ep_struct->direction == USB_RECV)
                    {
                        (void)_usb_device_register_service(controller_ID,
                            (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                            USB_Class_CDC_Service_Dic_Iso_Out);
                    }
                    else
                    {
                        (void)_usb_device_register_service(controller_ID,
                            (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                            USB_Class_CDC_Service_Dic_Iso_In);
                    }
                    break;
#endif
                default:
                    break;
            }
            /* set the EndPoint Status as Idle in the device layer */
            (void)_usb_device_set_status(&controller_ID,
                (uint_8)(USB_STATUS_ENDPOINT | ep_struct->ep_num |
                (ep_struct->direction << USB_COMPONENT_DIRECTION_SHIFT)),
                (uint_8)USB_STATUS_IDLE);
        }
    }
    else if(event == USB_APP_BUS_RESET)
    {
#if IMPLEMENT_QUEUING
        for(index = 0; index < usb_ep_data->count; index++)
        {
            g_cdc_ep[index].bin_consumer = 0x00;
            g_cdc_ep[index].bin_producer = 0x00;
        }
#endif
    }
    if(g_cdc_class_callback != NULL)
    {
        g_cdc_class_callback(controller_ID, event, val);
    }
}
示例#9
0
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Event
 *
 * @brief The funtion initializes CDC endpoints 
 *
 * @param handle   handle to Identify the controller
 * @param event           pointer to event structure
 * @param val             gives the configuration value 
 *
 * @return None       
 *
 *****************************************************************************/
 void USB_Class_CDC_Event(uint_8 event, void* val,pointer arg) 
{  
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr = (CDC_DEVICE_STRUCT_PTR)arg;
    
    if(event == USB_APP_ENUM_COMPLETE) 
    {
        uint_8 count = 0;
        USB_EP_STRUCT_PTR ep_struct_ptr;
        
        /* get the endpoints from the descriptor module */            
        USB_ENDPOINTS *usb_ep_data = cdc_obj_ptr->usb_ep_data;
        
        /* intialize all non control endpoints */            
        while(count < usb_ep_data->count) 
        {
            ep_struct_ptr = (USB_EP_STRUCT*) &usb_ep_data->ep[count];

            (void)_usb_device_init_endpoint(cdc_obj_ptr->controller_handle,
             ep_struct_ptr,TRUE);
  
            /* register callback service for Non Control EndPoints */
            switch(ep_struct_ptr->type) 
            {
                case USB_INTERRUPT_PIPE :
                    (void)_usb_device_register_service(cdc_obj_ptr->controller_handle,
                        (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                        USB_Service_Cdc_Notif,(void *)cdc_obj_ptr);
                    break;                              
                case USB_BULK_PIPE :
                    if(ep_struct_ptr->direction == USB_RECV) 
                    {
                        (void)_usb_device_register_service(cdc_obj_ptr->controller_handle,
                            (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                            USB_Service_Dic_Bulk_Out,(void *)cdc_obj_ptr);
                    } 
                    else
                    {
                        (void)_usb_device_register_service(cdc_obj_ptr->controller_handle,
                            (uint_8)(USB_SERVICE_EP0+ep_struct_ptr->ep_num),
                            USB_Service_Dic_Bulk_In,(void *)cdc_obj_ptr);
                    }
                    break;
                default : break;        
            }
                          
            /* set the EndPoint Status as Idle in the device layer */
            /* (no need to specify direction for this case) */
            (void)_usb_device_set_status(cdc_obj_ptr->controller_handle,
                (uint_8)(USB_STATUS_ENDPOINT|ep_struct_ptr->ep_num),
                (uint_8)USB_STATUS_IDLE);                                                                                                         
            count++;                                                    
        }/* EndWhile */
    }
    #if RNDIS_SUPPORT
    else if(event == USB_APP_BUS_RESET)
    {
        uint_8_ptr data; 
        uint_32 size;
        RNDIS_Reset_Command(cdc_obj_ptr, &data, &size);     
    }
    #endif        
    if(cdc_obj_ptr->cdc_class_cb.callback != NULL) 
    {
        cdc_obj_ptr->cdc_class_cb.callback(event,
            val,cdc_obj_ptr->cdc_class_cb.arg);
    } 
}
示例#10
0
/**************************************************************************//*!
 *
 * @name  USB_Class_Hid_Event
 *
 * @brief The function initializes HID endpoint
 *
 * @param controller_ID     : Controller ID
 * @param event             : Event Type
 * @param val               : Pointer to configuration Value
 *
 * @return None
 *
 ******************************************************************************
 * The funtion initializes the HID endpoints when Enumeration complete event is
 * received
 *****************************************************************************/
 void USB_Class_Hid_Event (
    uint_8 controller_ID,   /* [IN] Controller ID */
    uint_8 event,           /* [IN] Event Type */
    void* val               /* [IN] Pointer to configuration Value */
)
{
    uint_8 index;

    if(event == USB_APP_ENUM_COMPLETE)
    {
        uint_8 index_num = 0;
        uint_8 count = 0,ep_count = 0;
        USB_ENDPOINTS *ep_desc_data;  
        
#ifdef COMPOSITE_DEV
        DEV_ARCHITECTURE_STRUCT_PTR dev_arc_ptr;
        CLASS_ARC_STRUCT_PTR dev_class_ptr;   
        dev_arc_ptr = (DEV_ARCHITECTURE_STRUCT *)USB_Desc_Get_Class_Architecture(controller_ID);    
        for(count = 0; count < dev_arc_ptr->cl_count; count++)
        {
            dev_class_ptr = (CLASS_ARC_STRUCT_PTR)dev_arc_ptr->value[count];
            /* Initializes sub_classes */
            ep_count = dev_class_ptr->value[0];
            if(dev_class_ptr->class_type == 0x03/*HID_CC*/)
                break;
            index_num +=dev_class_ptr->value[0];
        }
        /* get the endpoints from the descriptor module */
        ep_desc_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID); 
#else
        /* get the endpoints from the descriptor module */
        ep_desc_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID); 
                    		    
		ep_count = ep_desc_data->count; 
#endif
		/* deinitialize all endpoints in case they were initialized */
		for(count=index_num;count<ep_count+index_num;count++) 
		{   
			USB_EP_STRUCT_PTR ep_struct_ptr= 
				(USB_EP_STRUCT_PTR) (&ep_desc_data->ep[count]);
			(void)_usb_device_deinit_endpoint(&controller_ID,
				ep_struct_ptr->ep_num, ep_struct_ptr->direction);  
		}

        /* intialize all non control endpoints */
        for(count=index_num;count<ep_count+index_num;count++)
        {
            USB_EP_STRUCT_PTR ep_struct=
                (USB_EP_STRUCT_PTR)&ep_desc_data->ep[count];

            (void)_usb_device_init_endpoint(&controller_ID, ep_struct->ep_num,
            		ep_struct->size, ep_struct->direction, ep_struct->type,
            		TRUE);

            /* register callback service for the endpoint */
            (void)_usb_device_register_service(controller_ID,
                                  (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num),
                                                             USB_Service_Hid);


            /* set the EndPoint Status as Idle in the device layer */
            (void)_usb_device_set_status(&controller_ID,
                (uint_8)(USB_STATUS_ENDPOINT | HID_ENDPOINT |
                (ep_struct->direction << USB_COMPONENT_DIRECTION_SHIFT)),
                USB_STATUS_IDLE);
        }

    }
    else if((event == USB_APP_BUS_RESET) || (event == USB_APP_CONFIG_CHANGED))
    {
        /* clear producer and consumer on reset */
        for(index = 0; index < g_hid_endpoint_data.count; index++)
        {
            g_hid_endpoint_data.ep[index].bin_consumer = 0x00;
            g_hid_endpoint_data.ep[index].bin_producer = 0x00;
            g_hid_endpoint_data.ep[index].queue_num    = 0x00;
        }
    }

    if(g_hid_class_callback != NULL)
    {
        /* notify the application of the event */
        g_hid_class_callback(controller_ID, event, val);
    }

}
示例#11
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _usb_otg_sm_b
* Returned Value   :
* Comments         : This function handles the substates of the B-state machine
*    
*
*END*----------------------------------------------------------------------*/
void _usb_otg_sm_b
(
    usb_otg_handle otg_handle
)
{
    usb_otg_state_struct_t * usb_otg_struct_ptr = (usb_otg_state_struct_t *)otg_handle;
    usb_otg_status_t           *otg_status        =  &usb_otg_struct_ptr->otg_status;

    if (!otg_status->id)
    {  
        _usb_otg_id_chg_a(otg_handle);
        return;
    }

    switch (usb_otg_struct_ptr->sub_state)
    {
    case USB_OTG_SM_B_IDLE_SESS_DETECT:
        usb_otg_struct_ptr->hnp_enabled = FALSE;
        if (otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL);                 
        }
        else
        {
            /* Disable pull-up. The B-Device is now in the B-Idle state */
            _usb_otg_callback_set_dp_pull_up(otg_handle, FALSE);
            if (otg_status->sess_end)
            {              
                usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SESS_END_DETECT;
                
                otg_status->b_timeout = TB_SESSEND_SRP; /* Program the SRP detect timeout as SESSEND SRP */
            }
        }
        break;
    case USB_OTG_SM_B_IDLE_SESS_END_DETECT:
        if (otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL);
        }
        else
        {              
            /* Read the Live SE0 bit */
            if ((otg_status->live_se0) && (otg_status->line_stable))
            {                                
                otg_status->b_timeout_en = TRUE;
                
                usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SE0_STABLE_WAIT;
            }            
        }
        break;
    case USB_OTG_SM_B_IDLE_SE0_STABLE_WAIT:
        if (otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL);
        }
        else
        {
            /* Line state change. restart SE0 detection */
            if (!otg_status->line_stable)
            {               
                otg_status->b_timeout_en = TRUE;
                
                otg_status->b_timeout = TB_SE0_SRP; /* reinitialize the the SE0 detect timer */
                
                /* Keep the current state */
            }
            else
            {
                if (otg_status->b_timeout == 0)
                {
                    /* The timeout expired during stable SE0 */
                    _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SRP_START_ARMED, OTG_B_IDLE_SRP_READY);               
                }
            }
        }
        break; 
        
    case USB_OTG_SM_B_IDLE_SRP_START_ARMED:
        if (otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL);
        }
        else
        {                
            /* Line state change. restart SE0 detection */
            if (!otg_status->line_stable)
            {
                otg_status->b_timeout = TB_SE0_SRP; /* reinitialize the the SE0 detect timer */              
                usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SESS_END_DETECT;
            }
            else
            {
                if (usb_otg_struct_ptr->srp_request || usb_otg_struct_ptr->power_up)
                {
                    usb_otg_struct_ptr->power_up = FALSE;
                    usb_otg_struct_ptr->srp_request = FALSE;
                    /* Start SRP */                                  
                    /* Start the D+ pulsing timeout */              
                    otg_status->b_timeout = TB_DATA_PLS; /* reinitialize the the SE0 detect timer */                 
                    otg_status->b_timeout_en = TRUE;
                    /* Enable D+ pullup */
                    _usb_otg_callback_set_dp_pull_up(otg_handle, TRUE);
                    usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_SRP_PULSE;                                                   
                }
            }
        }
        break;
    case USB_OTG_SM_B_SRP_PULSE:
        if (otg_status->b_timeout == 0)
        {
            /* The timeout expired. Remove the D+ pullup */
            _usb_otg_callback_set_dp_pull_up(otg_handle, FALSE);
            /* Wait for VBUS */
            otg_status->b_timeout = (TB_SRP_FAIL - TB_DATA_PLS);
            otg_status->b_timeout_en = TRUE;
            
            usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_SRP_VBUS_WAIT;
            
            /* Signal the event to the application */
            OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_SRP_INIT);               
        }
        break;
        
    case USB_OTG_SM_B_SRP_VBUS_WAIT:
        if (otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL);
        }
        else
        {
            if (otg_status->b_timeout == 0)
            {
                /* The timeout expired during VBUS wait */               
                
                /* Inform the application about the failed SRP and return to idle state */               
                /* and wait for SE0 condition on the bus to be able to restart the SRP */
                
                usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_IDLE_SE0_STABLE_WAIT;
                
                otg_status->b_timeout_en = TRUE;
                
                otg_status->b_timeout = TB_SE0_SRP; /* reinitialize the the SE0 detect timer */
                
                /* Signal the event to the application */
                OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_SRP_FAIL);
            }
        }
        break;
    case USB_OTG_SM_B_PERI_BUS_SUSP_DETECT:
        if (!otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); 
        }
        else
        {
            /* Enable the D+ pull-up. the B device is in the peripheral state */
            _usb_otg_callback_set_dp_pull_up(otg_handle, TRUE);
            usb_otg_struct_ptr->power_up = FALSE;

            /* Start monitoring the data lines. 
            * If the bus has inactivity for more than TB_AIDL_BDIS, then the A is considered disconnected and B can start HNP
            */ 
            usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_BUS_SUSP_WAIT;
            otg_status->b_timeout_en = TRUE;
            otg_status->b_timeout = TB_AIDL_BDIS; /* reinitialize the IDLE detect timer */             
        }
        break;
    case USB_OTG_SM_B_PERI_BUS_SUSP_WAIT:
        if (!otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); 
        }
        else
        {
            if (!otg_status->line_stable)
            {              
                /* Restart detection */
                otg_status->b_timeout_en = TRUE;
                otg_status->b_timeout = TB_AIDL_BDIS; /* reinitialize the IDLE detect timer */
            }
            else
            {
                if ((usb_otg_struct_ptr->hnp_enabled) && (otg_status->b_timeout == 0))
                {
                    usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_HNP_ARMED;    
                    /* Signal the event to the application */
                    OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_PERIPHERAL_HNP_READY); 
                }
            }
        }
        break;
    case USB_OTG_SM_B_PERI_HNP_ARMED:
        if (!otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); 
        }
        else
        {              
            if ((!otg_status->line_stable) || (!usb_otg_struct_ptr->hnp_enabled))
            {
                _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL_HNP_FAIL);
            }
            else
            {
                if ((usb_otg_struct_ptr->bus_request) && (usb_otg_struct_ptr->hnp_enabled))
                {
                    usb_otg_struct_ptr->bus_request = FALSE;
                    
                    /* Clear the Status at the USB device level */
                    _usb_device_set_status(usb_otg_struct_ptr->dev_inst_ptr, USB_STATUS_OTG, USB_STATUS_IDLE);
                    /* Start HNP. Turn off Pull-Up on D+ for the Host to detect SE0 */
                    _usb_otg_callback_set_dp_pull_up(otg_handle, FALSE);
                    /* Wait for data line to discharge (25us) */
                    otg_status->b_timeout = 1;
                    otg_status->b_timeout_en = TRUE;
                    usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_HNP_START;
                    /* Signal the event to the application */
                    OS_Event_set ((usb_otg_struct_ptr->otg_app_event), OTG_B_PERIPHERAL_HNP_START);                    
                }
            }
        }
        break;
    case USB_OTG_SM_B_PERI_HNP_START:
        if (!otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); 
        }
        else
        {
            if (otg_status->b_timeout == 0)
            {
                /* Line should have discharged by now */
                /* Start the host disconnect detect */
                otg_status->b_timeout = TB_ASE0_BRST;
                otg_status->b_timeout_en = TRUE;              
                usb_otg_struct_ptr->sub_state = USB_OTG_SM_B_PERI_HNP_ACONN;    
            }
        }
        break;
    case USB_OTG_SM_B_PERI_HNP_ACONN: 
        if (!otg_status->sess_valid)
        {
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); 
        }
        else
        {
            if (otg_status->b_timeout == 0)
            {
                /* A connect timeout detected. Go back to peripheral state */
                _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL_HNP_FAIL);
            }
            else
            {
                /* Check the Data line state */
                if ((!otg_status->live_se0) && (otg_status->live_jstate) && (otg_status->line_stable))
                {
                    /* J-STATE. Host has been released */
                    /* Enter the B-Host state */
                    usb_otg_struct_ptr->hnp_enabled = FALSE;
                    otg_status->a_conn = TRUE;
                    _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_HOST, OTG_B_HOST);
                }
                else
                {
                    if ((!otg_status->live_se0) && (!otg_status->live_jstate) && (otg_status->line_stable))
                    {
                        /* Host has retained the bus */
                        _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL_HNP_FAIL);               
                    }
                }
            }
        }
        break;
    case USB_OTG_SM_B_HOST:
        if (!otg_status->sess_valid)
        {
            otg_status->a_conn = FALSE;
            _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_IDLE_SESS_DETECT, OTG_B_IDLE); 
        }
        else
        {
            if ((otg_status->a_conn == FALSE) || usb_otg_struct_ptr->bus_release)
            {
                usb_otg_struct_ptr->bus_release = FALSE;
                otg_status->a_conn = FALSE;
                /* A-device disconnected or B has finished using the bus */
                _usb_otg_sm_b_substate_change(otg_handle, USB_OTG_SM_B_PERI_BUS_SUSP_DETECT, OTG_B_PERIPHERAL);
            } 
            else 
            {
                if ( usb_otg_struct_ptr->dev_inst_ptr != NULL )
                {
                    if (otg_status->hnp_req)
                    {
                        OS_Event_set((usb_otg_struct_ptr->otg_app_event), OTG_B_A_HNP_REQ);
                    }
                    if (otg_status->hnp_support && (otg_status->host_req_poll_timer >= T_HOST_REQ_POLL))
                    {
                        otg_status->host_req_poll_timer = 0;
                        _usb_otg_hnp_poll_req(usb_otg_struct_ptr);  
                    } 
                }
            }
        }
        break;
    default: break;
    }  
}
示例#12
0
/**************************************************************************//*!
 *
 * @name  msc_thirteen_cases_check
 *
 * @brief The function checks for thirteen error case of MSC and takes action 
 *        appropriately
 *
 * @param msc_check_event: structure containing all necessary parameter to 
 *        evaluate error scenarios
 *
 * @return error
 *                 
 *****************************************************************************/
uint_8 msc_thirteen_cases_check(PTR_MSC_THIRTEEN_CASE_STRUCT msc_check_event)
{
	uint_8 error;
	
    if(!msc_check_event->host_expected_data_len)
	{	/* host expects no data transfer */
		*(msc_check_event->csw_residue_ptr) = 0;
		
		if(!msc_check_event->device_expected_data_len)
		{	/* CASE 1: Device intends no data transfer : Thin Diagonal Case*/
			*(msc_check_event->csw_status_ptr) = COMMAND_PASSED;
		}
		else 
		{	/* if(msc_check_event->device_expected_direction) :
		       	CASE 2: Device intends to send data to host
		       else
		     	CASE 3: Device intends to receive data from host */        
			*(msc_check_event->csw_status_ptr) = PHASE_ERROR;
		}		
	}
	else if(msc_check_event->host_expected_direction)
	{	/* host expects to receive data from device (USB_SEND direction)*/
		if(!msc_check_event->device_expected_data_len)
		{	/* CASE 4:  Device intends no data transfer */
			*(msc_check_event->csw_residue_ptr) = 
				msc_check_event->host_expected_data_len - 
				msc_check_event->device_expected_data_len;
			/* sending zero bytes of data */
			error = USB_MSC_Bulk_Send_Data(msc_check_event->controller_ID,
				msc_check_event->buffer_ptr,
				msc_check_event->device_expected_data_len);	
			
			if(error == USB_OK)
			{
				*(msc_check_event->csw_status_ptr) = COMMAND_PASSED;	
			}
			else
			{
				*(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
		        g_msc_scsi.request_sense.sense_key = MEDIUM_ERROR;
		        g_msc_scsi.request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
			}
			
			/* BULK IN PIPE TO BE STALLED for status phase */
			error = USBERR_ENDPOINT_STALLED;	
		}
		else if(msc_check_event->device_expected_direction)
		{	/* device intends to send data to host */
			if(msc_check_event->host_expected_data_len > 
				msc_check_event->device_expected_data_len)
			{	/* CASE 5: Host intends more data to receive than device 
						   intends to send*/
				*(msc_check_event->csw_residue_ptr) = 
				msc_check_event->host_expected_data_len - 
				msc_check_event->device_expected_data_len;
				
				if(g_msc_scsi.thirteen_case_struct.lba_txrx_select == TRUE)	
				{
					error = USB_MSC_LBA_Transfer(msc_check_event->controller_ID,USB_SEND,
						&msc_check_event->lba_info);
				}
				else
				{
					error = USB_MSC_Bulk_Send_Data(msc_check_event->controller_ID,
						msc_check_event->buffer_ptr,
						msc_check_event->device_expected_data_len);	
				}

				if(msc_check_event->device_expected_data_len% 
					BULK_IN_ENDP_PACKET_SIZE == 0)
				{   /*need to send zero bytes of data to tell host that 
				      device does not have any more data. This is needed
				      only if the bytes send to host are integral multiple
				      of max packet size of Bulk In endpoint */
					error |= USB_MSC_Bulk_Send_Data(msc_check_event->controller_ID,
						msc_check_event->buffer_ptr,0);									
				}
				
				
				if(error == USB_OK)
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_PASSED;	
				}
				else
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
			        g_msc_scsi.request_sense.sense_key = MEDIUM_ERROR;
			        g_msc_scsi.request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
				}
			}
			else if(msc_check_event->host_expected_data_len == 
				msc_check_event->device_expected_data_len)
			{	/* CASE 6: Host intends exact amount of data to receive 
			               as device intends to send : Thin Diagonal Case*/
				*(msc_check_event->csw_residue_ptr) = 0;

				if(g_msc_scsi.thirteen_case_struct.lba_txrx_select == TRUE)	
				{
					error = USB_MSC_LBA_Transfer(msc_check_event->controller_ID,USB_SEND,
						&msc_check_event->lba_info);
				}
				else
				{
					error = USB_MSC_Bulk_Send_Data(msc_check_event->controller_ID,
						msc_check_event->buffer_ptr,
						msc_check_event->device_expected_data_len);						
				}

				if(error == USB_OK)
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_PASSED;	
				}
				else
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
			        g_msc_scsi.request_sense.sense_key = MEDIUM_ERROR;
			        g_msc_scsi.request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
				}
			}
			else
			{
				/* CASE 7: Host intends less data to receive than device 
						   intends to send*/
				*(msc_check_event->csw_residue_ptr) = 0;
				
				if(g_msc_scsi.thirteen_case_struct.lba_txrx_select == TRUE)	
				{
					error = USB_MSC_LBA_Transfer(msc_check_event->controller_ID,USB_SEND,
						&msc_check_event->lba_info);
				}
				else
				{
					error = USB_MSC_Bulk_Send_Data(msc_check_event->controller_ID,
						msc_check_event->buffer_ptr,
						msc_check_event->host_expected_data_len);					
				}
				
				if(error == USB_OK)
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_PASSED;	
				}
				else
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
			        g_msc_scsi.request_sense.sense_key = MEDIUM_ERROR;
			        g_msc_scsi.request_sense.add_sense_code = UNRECOVERED_READ_ERROR;
				}
			}								
		}
		else
		{	/* CASE 8: Device intends to receive data from host */
			*(msc_check_event->csw_residue_ptr) = 
				msc_check_event->host_expected_data_len;
			/* device has no data to send */
			error = USB_MSC_Bulk_Send_Data(msc_check_event->controller_ID,
				msc_check_event->buffer_ptr,0);
			*(msc_check_event->csw_status_ptr) = PHASE_ERROR;
			/* BULK IN PIPE TO BE STALLED for status phase */
			error = USBERR_ENDPOINT_STALLED;																			   
		}
	}
	else
	{	/* host expects to send data to device (USB_RECV direction)*/
		if(!msc_check_event->device_expected_data_len)
		{	/* CASE 9:  Device intends no data transfer */
	    uint_8 component = BULK_OUT_ENDPOINT | 
	        	(USB_RECV<<COMPONENT_PREPARE_SHIFT);	        
			(void)_usb_device_set_status(&(msc_check_event->controller_ID),
				(uint_8)(component|USB_STATUS_ENDPOINT),
				(uint_16)USB_STATUS_STALLED);
			*(msc_check_event->csw_residue_ptr) = 
				msc_check_event->host_expected_data_len;
			*(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
			/* BULK OUT PIPE STALLED */
			error = USBERR_ENDPOINT_STALLED;					
		}
		else if(msc_check_event->device_expected_direction)
		{	/*CASE10: device intends to send data to host */		
	       	uint_8 component = BULK_OUT_ENDPOINT | 
        		(USB_RECV<<COMPONENT_PREPARE_SHIFT);
	       	/* now, stalling the status phase - CASE 5th of THIRTEEN CASES*/           
			(void)_usb_device_set_status(&(msc_check_event->controller_ID),
				(uint_8)(component|USB_STATUS_ENDPOINT),
				(uint_16)USB_STATUS_STALLED);
			*(msc_check_event->csw_residue_ptr) = 
				msc_check_event->host_expected_data_len;
			*(msc_check_event->csw_status_ptr) = PHASE_ERROR;
			/* BULK OUT PIPE STALLED */
			error = USBERR_ENDPOINT_STALLED;
		}
		else
		{	/*Device intends to receive data from host */
			if(msc_check_event->host_expected_data_len > 
				msc_check_event->device_expected_data_len)
			{	/* CASE 11: Host intends more data to send than device 
						    intends to receive*/
				*(msc_check_event->csw_residue_ptr) = 
					msc_check_event->host_expected_data_len - 
					msc_check_event->device_expected_data_len;
				
				if(g_msc_scsi.thirteen_case_struct.lba_txrx_select == TRUE)	
				{
					error = USB_MSC_LBA_Transfer(msc_check_event->controller_ID,USB_RECV,
						&msc_check_event->lba_info);
				}
				else
				{
					error = USB_MSC_Bulk_Recv_Data(&(msc_check_event->controller_ID),
						msc_check_event->buffer_ptr,
						msc_check_event->device_expected_data_len);										
				}				
				
				if(error == USB_OK)
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_PASSED;	
				}
				else
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
			        g_msc_scsi.request_sense.sense_key = MEDIUM_ERROR;
			        g_msc_scsi.request_sense.add_sense_code = WRITE_FAULT;
				}
				/* BULK OUT PIPE TO BE STALLED for status phase */
				error = USBERR_ENDPOINT_STALLED;					
			}
			else if(msc_check_event->host_expected_data_len == 
				msc_check_event->device_expected_data_len)
			{	/* CASE 12: Host intends exact amount of data to send 
			                as device intends to receive : Thin Diagonal Case*/
				*(msc_check_event->csw_residue_ptr) = 0;				

				if(g_msc_scsi.thirteen_case_struct.lba_txrx_select == TRUE)	
				{
					error = USB_MSC_LBA_Transfer(msc_check_event->controller_ID,USB_RECV,
						&msc_check_event->lba_info);
				}
				else
				{
					error = USB_MSC_Bulk_Recv_Data(&(msc_check_event->controller_ID),
						msc_check_event->buffer_ptr,
						msc_check_event->device_expected_data_len);	
				}
				
				if(error == USB_OK)
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_PASSED;	
				}
				else
				{
					*(msc_check_event->csw_status_ptr) = COMMAND_FAILED;
			        g_msc_scsi.request_sense.sense_key = MEDIUM_ERROR;
			        g_msc_scsi.request_sense.add_sense_code = WRITE_FAULT;
				}
			}
			else
			{
				/* CASE 13: Host intends less data to send than device 
						    intends to receive*/
				*(msc_check_event->csw_residue_ptr) = 0;
				if(g_msc_scsi.thirteen_case_struct.lba_txrx_select == TRUE)	
				{
					msc_check_event->lba_info.lba_transfer_num = 
					  msc_check_event->host_expected_data_len / 
					    g_msc_scsi.device_info.length_of_each_lba_of_device;   
					error = USB_MSC_LBA_Transfer(msc_check_event->controller_ID,USB_RECV,
						&msc_check_event->lba_info);
				}
				else
				{
					error = USB_MSC_Bulk_Recv_Data(&(msc_check_event->controller_ID),
						msc_check_event->buffer_ptr,
						msc_check_event->host_expected_data_len);
				}
				if(error != USB_OK)
				{
			        g_msc_scsi.request_sense.sense_key = MEDIUM_ERROR;
			        g_msc_scsi.request_sense.add_sense_code = WRITE_FAULT;
				}
				*(msc_check_event->csw_status_ptr) = PHASE_ERROR;						    
			}								
		}		
	}
	return error;
}
示例#13
0
/*
** ===================================================================
**     Method      :  usb_device_USB_DCI_Set_Address (component USB_DEVICE_STACK)
**     Description :
**         This function configures Controller to send data on an SEND
**         endpoint
**     Parameters  :
**         NAME            - DESCRIPTION
**         handle          - [IN] USB Device handle
**         address         - [IN] Address of the USB device
**     Returns     : Nothing
** ===================================================================
*/
void  USB_DCI_Set_Address(_usb_device_handle handle, uint_8 address)
{
    UNUSED(handle);
    _usb_device_set_status(&g_dci_controller_Id, USB_STATUS_DEVICE_STATE,
        USB_STATE_ADDRESS);
}