vusbo11.c 8.74 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             
***
*** $Workfile:vusbo11.c$
*** $Revision: 1.1 $
*** $Date: 2003/02/17 20:49:01 $
***
*** Description:      
***  This file contains the low-level VUSB32  On-The-Go routines.
***                                                               
**************************************************************************
*END*********************************************************************/
#ifndef __USB_OS_MQX__
   #include "types.h"
   #include "hostapi.h"
   #include "devapi.h"
   #include "otgapi.h"
   #include "usb.h"
   #include "vusb11.h"
   #include "usbprv.h"
   #include "usbdprv.h"
   #include "usbhprv.h"
   #include "usboprv.h"
#else
   #include "mqx.h"
   #include "bsp.h"
   #include "otgapi.h"
   #include "vusb11.h"
   #include "usbprv.h"
   #include "usbdprv.h"
   #include "usbhprv.h"
   #include "usboprv.h"
#endif

#ifndef __USB_OS_MQX__
USB_OTG_STATE_STRUCT_PTR otg_handle;
extern USB_DEV_STATE_STRUCT_PTR global_usb_device_state_struct_ptr;
#ifndef PERIPHERAL_ONLY
extern USB_HOST_STATE_STRUCT_PTR usb_host_state_struct_ptr;
#endif
#endif

#ifndef __USB_OS_MQX__
extern volatile boolean IN_ISR;
#endif

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_otg_vusb11_init
* Returned Value : USB_OK or error code
* Comments       :
*     Initialises the OTG Hardware.  
* 
*END*--------------------------------------------------------------------*/
uint_8 _usb_otg_vusb11_init
   (
      /* [IN] handle to the usb otg */
      _usb_otg_handle handle
   )
{ /* Body */
   USB_OTG_STATE_STRUCT_PTR usb_otg_ptr;
   
   usb_otg_ptr = (USB_OTG_STATE_STRUCT_PTR)handle;
   
   usb_otg_ptr->USB_REG_PTR = (USB_STRUCT_PTR)
      (_bsp_get_usb_base(usb_otg_ptr->DEV_NUM));
   
   usb_otg_ptr->OTG_REG_PTR = (OTG_STRUCT_PTR)((uint_32)usb_otg_ptr->USB_REG_PTR 
      - BSP_VUSB11_OTG_USB_OFFSET);
   
   /* mask all OTG interupts */
   usb_otg_ptr->OTG_REG_PTR->OTG_INT_ENABLE = 0x0;
   /* Clear all OTG interrupts */
   usb_otg_ptr->OTG_REG_PTR->OTG_INT_STAT = 0xFF;
   
   /*  Turn off all the signals; 
   ** The following are initial condition for A-device and B-device.
   **  !drv_vbus; !charg_vbus; !loc_conn; loc_sof
   */
   usb_otg_ptr->OTG_REG_PTR->OTG_CTL = OTG_CTL_OTG_ENABLE;

#ifdef __USB_OS_MQX__                                          
   if (!(USB_install_isr(_bsp_get_usb_vector(usb_otg_ptr->DEV_NUM), 
      _usb_otg_vusb11_isr, (pointer)usb_otg_ptr))
   {
      return USBERR_INSTALL_ISR;
   } /* Endbody */
#else
   USB_install_isr(_bsp_get_usb_vector(usb_otg_ptr->DEV_NUM), 
      _usb_otg_vusb11_isr, (pointer)usb_otg_ptr);
#endif

#ifdef PERIPHERAL_ONLY
    usb_otg_ptr->STATE_STRUCT.STATE = B_IDLE;
#else
   /*
   ** The identification (id) input is FALSE when a Mini-A plug is inserted 
   ** in the device’s Mini-AB receptacle. Otherwise, this input is TRUE.
   */
   if (ID_FALSE(usb_otg_ptr->OTG_REG_PTR)) {
      usb_otg_ptr->STATE_STRUCT.STATE = A_IDLE;
   } else {
      usb_otg_ptr->STATE_STRUCT.STATE = OTG_START;
   } /* Endif */
#endif   
   /* Enable the OTG specific interrupts */
   usb_otg_ptr->OTG_REG_PTR->OTG_INT_ENABLE = OTG_INT_ENABLE_A_VBUS |  
                                              OTG_INT_ENABLE_B_SESS|  
                                              OTG_CTL_OTG_ENABLE   |
                                              OTG_INT_ENABLE_SESS_VLD| 
                                              OTG_INT_ENABLE_ID;       
#ifndef __USB_OS_MQX__   
   /* keep a global copy  of the handle */
   otg_handle = (USB_OTG_STATE_STRUCT_PTR)handle;
#endif
   /* start the state machine once to keep going */
   _usb_otg_state_machine((pointer)usb_otg_ptr);
   return USB_OK;
} /* Endbody */   

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_otg_vusb11_shutdown
* Returned Value : None
* Comments       :
*     Shutdown the otg  device.
* 
*END*--------------------------------------------------------------------*/
void _usb_otg_vusb11_shutdown
   (
      /* [IN] Handle to the USB otg */
      _usb_otg_handle   handle
   )
{ /* Body */
      USB_OTG_STATE_STRUCT_PTR   usb_otg_ptr;
      usb_otg_ptr = (USB_OTG_STATE_STRUCT_PTR)handle;
      /* mask all OTG interupts */
      usb_otg_ptr->OTG_REG_PTR->OTG_INT_ENABLE = 0x0;
      /* Clear all OTG interrupts */
      usb_otg_ptr->OTG_REG_PTR->OTG_INT_STAT = 0xFF;
      /*  Turn off all the OTG signals */
      usb_otg_ptr->OTG_REG_PTR->OTG_CTL = 0x0;
} /* EndBody */

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_otg_vusb11_isr
* Returned Value : None
* Comments       :
*     Service all OTG and VUSB32 interrupts.
* 
*END*--------------------------------------------------------------------*/
#ifndef __USB_OS_MQX__
OTG_INTERRUPT_ROUTINE_KEYWORD void _usb_otg_vusb11_isr
   (
      void
   )
#else
void _usb_otg_vusb11_isr
   (
      _usb_otg_handle handle
   )
#endif
{ /* Body */
   USB_OTG_STATE_STRUCT_PTR      usb_otg_ptr;
   uint_32                       otg_status;
   OTG_STATE_MACHINE_STRUCT_PTR  s_ptr;

#ifndef __USB_OS_MQX__   
   usb_otg_ptr = (USB_OTG_STATE_STRUCT_PTR)otg_handle;
   IN_ISR = TRUE;
#else
   usb_otg_ptr = (USB_OTG_STATE_STRUCT_PTR)handle;
#endif
   s_ptr = &usb_otg_ptr->STATE_STRUCT;
   otg_status = (usb_otg_ptr->OTG_REG_PTR->OTG_INT_STAT & 
      usb_otg_ptr->OTG_REG_PTR->OTG_INT_ENABLE);
   
   do {
      /* Clear all enabled interrupts */
      usb_otg_ptr->OTG_REG_PTR->OTG_INT_STAT = otg_status;
      
      /* If we have OTG interrupt call the state machine */
      if (otg_status) {
         s_ptr->OTG_INT_STATUS = otg_status;
         /*
         ** If any timers expired  it will process the event and
         ** any other signals at that time. We don't need to call
         ** the state machine if this is the case.
         */
         if (!_usb_otg_process_timers((pointer)usb_otg_ptr)) {
            /* clear timer interrupt */
            otg_status &= ~OTG_INT_ENABLE_1_MSEC ;
            if (otg_status) {
               _usb_otg_state_machine((pointer)usb_otg_ptr);
            } /* Endif */
         } /* Endif */
         s_ptr->OTG_INT_STATUS = 0;
      } /* Endif */
      
#ifndef PERIPHERAL_ONLY
      /* A_DEVICE */
      if (s_ptr->HOST_UP) {
         /* Check data line pulsing by B device */
         if ((s_ptr->STATE == A_IDLE) && 
            (!s_ptr->A_BUS_REQ) &&  
            (usb_otg_ptr->USB_REG_PTR->INTSTATUS & VUSB_INT_STAT_ATTACH) && 
            (s_ptr->A_SRP_TMR == -1)) 
         {
            s_ptr->A_DATA_PULSE_DET = TRUE;
            return ;
         } /* Endif */
         if (s_ptr->A_SRP_TMR == -1) {
            if ((s_ptr->STATE == B_WAIT_ACON) && 
               (usb_otg_ptr->USB_REG_PTR->INTSTATUS & VUSB_INT_STAT_ATTACH))
            {
               s_ptr->JSTATE_COUNT++;
               /* Clear the Attach interrupt 10 times and assert JSTATE 
               ** to TRUE on 11th time. 
               */
               usb_otg_ptr->USB_REG_PTR->INTSTATUS = VUSB_INT_STAT_ATTACH;
               
               if (s_ptr->JSTATE_COUNT == 10) {
                  s_ptr->JSTATE = TRUE;
                  s_ptr->JSTATE_COUNT = 0;
               } /* Endif */
            } /* Endif */
#ifndef __USB_OS_MQX__
            _usb_hci_vusb11_isr();
#else
            _usb_hci_vusb11_isr((pointer)usb_host_state_struct_ptr); 
#endif
         } /* Endif */
      }/* Endif */
#endif
      /* B_DEVICE */
      if (s_ptr->DEVICE_UP){
         if ((s_ptr->STATE == B_IDLE) && 
            (usb_otg_ptr->USB_REG_PTR->INTSTATUS & VUSB_INT_STAT_RESET)) 
         {
            return;
         } /* Endif */
#ifndef __USB_OS_MQX__
         _usb_dci_vusb11_isr();
#else
         _usb_dci_vusb11_isr((pointer)global_usb_device_state_struct_ptr); 
#endif
      }/* Endif */
      
      /* check the interrupt again */
      otg_status = (usb_otg_ptr->OTG_REG_PTR->OTG_INT_STAT & 
                           usb_otg_ptr->OTG_REG_PTR->OTG_INT_ENABLE);
   } while(otg_status);
#ifndef __USB_OS_MQX__   
   IN_ISR = FALSE;
#endif
} /* Endbody */
/* EOF */