vusbd11un.c 4.76 KB
/*HEADER******************************************************************
**************************************************************************
*** 
*** Copyright (c) 2001-2002 ARC International.
*** All rights reserved                                          
***                                                              
*** This software embodies materials and concepts which are      
*** confidential to ARC International and is made
*** available solely pursuant to the terms of a written license   
*** agreement with ARC International             
***
*** File: vusbd11.c
***
*** Comments:      
***   This file contains the low-level VUSB1.1 routines.
***                                                               
**************************************************************************
*END*********************************************************************/

#include "os_bb.h"
#include "osint.h"
#include "../host.h"

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_dci_vusb11_unstall_endpoint
* Returned Value : None
* Comments       :
*     Unstalls and endpoint and clears out its BDTs
* 
*END*--------------------------------------------------------------------*/
void _usb_dci_vusb11_unstall_endpoint
   (
      /* [IN] Handle to the USB device */
      _usb_device_handle handle,
      
      /* [IN] Endpoint to clear */
      uint_8 ep
   )
{
   USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   
   usb_dev_ptr->XDSEND[ep].CTL &= ~VUSB_EP_CTRL_STALL;
   usb_dev_ptr->XDRECV[ep].CTL &= ~VUSB_EP_CTRL_STALL;

   _usb_dci_vusb11_cancel_transfer(handle, USB_SEND, ep);
   _usb_dci_vusb11_cancel_transfer(handle, USB_RECV, ep);
   
   /* clear stall bit */
   usb_dev_ptr->ENDPT_REGS[ep] &= ~VUSB_EP_CTRL_STALL;
   return;
}   

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_dci_vusb11_cancel_transfer
* Returned Value : None
* Comments       :
*     Cancels the BDTs on the specified endpoint in the specified direction.
* 
*END*--------------------------------------------------------------------*/
void _usb_dci_vusb11_cancel_transfer
   (
      /* [IN] Handle to the USB device */
      _usb_device_handle handle,
      
      /* [IN] Direction to cancel */
      uint_8             direction,
      
      /* [IN] Endpoint to cancel */
      uint_8             ep
   )
{
   USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
   XD_STRUCT_PTR            pxd;
   BDT_STRUCT_PTR           BDT_PTR;
   BDT_STRUCT               copy_bdt;
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

//PRINTF("dev_cancel_transfer: ep %d, dir %d\n", ep, direction);   
   if (direction == USB_SEND) {
      pxd = &usb_dev_ptr->XDSEND[ep];
   } else {
      pxd = &usb_dev_ptr->XDRECV[ep];
   }

   /* If packet pending: 
   **    If 2 packets pending, dont toggle ODDEVEN
   **    If OWNS bit is set, disable ep reset owns toggle next oddeven
   ** . 
   */   
   
   if (pxd->PACKETPENDING == 1) {
      BDT_PTR = &usb_dev_ptr->USB_BDT_PAGE[ep][direction]\
         [VUSB_TOGGLE_BIT(pxd->NEXTODDEVEN)];
      _usb_bdt_copy_swab_d(BDT_PTR, &copy_bdt);
      if (copy_bdt.REGISTER.BDTCTL & VUSB_BDT_OWNS_BIT) {
//PRINTF("dev_cancel_transfer: one pkt pending, clear BDT 0x%x\n", BDT_PTR);   
         /* clear current BDT for this direction */
         VUSB_CLEAR_CURRENT_BDT(&copy_bdt, pxd);
         _usb_bdt_copy_swab_d(&copy_bdt, BDT_PTR);
         pxd->NEXTODDEVEN = VUSB_TOGGLE_BIT(pxd->NEXTODDEVEN);
      }
   }

   if (pxd->PACKETPENDING == 2) {
      BDT_PTR = &usb_dev_ptr->USB_BDT_PAGE[ep][direction][pxd->NEXTODDEVEN];
      _usb_bdt_copy_swab_d(BDT_PTR, &copy_bdt);
      if (copy_bdt.REGISTER.BDTCTL & VUSB_BDT_OWNS_BIT) {
         /* clear current BDT for this direction */
//PRINTF("dev_cancel_transfer: two pkt pending, clear BDT 0x%x\n", BDT_PTR);   
         VUSB_CLEAR_CURRENT_BDT(&copy_bdt, pxd);
         _usb_bdt_copy_swab_d(&copy_bdt, BDT_PTR);
      }
      BDT_PTR = &usb_dev_ptr->USB_BDT_PAGE[ep][direction]\
         [VUSB_TOGGLE_BIT(pxd->NEXTODDEVEN)];
      _usb_bdt_copy_swab_d(BDT_PTR, &copy_bdt);
      if (copy_bdt.REGISTER.BDTCTL & VUSB_BDT_OWNS_BIT) {
//PRINTF("dev_cancel_transfer: two pkt pending, clear BDT 0x%x\n", BDT_PTR);   
         VUSB_CLEAR_CURRENT_BDT(&copy_bdt, pxd);
         _usb_bdt_copy_swab_d(&copy_bdt, BDT_PTR);
      }
   }
   
   /* clear owns bit and flag as dequeued */
   pxd->BDTCTL = (uint_8)VUSB_BDT_DEQUEUED;

   /*
   ** Check the endpoint control register image to see if the endpoint
   ** is disabled or stalled, and update the status byte.
   */
   if (pxd->CTL & VUSB_ENDPT_STALL_BIT) {
      usb_dev_ptr->XDRECV[ep].STATUS = USB_STATUS_STALLED;
   } else { 
      pxd->STATUS = USB_STATUS_IDLE;
   } /* Endif */
   
   return;  
}