/**
  Copyright (c) 2007 Freescale Semiconductor
  Freescale Confidential Proprietary
  \file     	USB_User_API.c
  \brief    	Functions for the USB API
  \author   	Freescale Semiconductor
  \author     Jose Ruiz
  \author   	Guadalajara Applications Laboratory RTAC Americas
  \version    0.3
  \date     	17/October/2007
  \warning    (If needed)

  * History:
  
  30/July/2007      Start of bridge coding
  15/October/2007   Modifications for new version of bridges
  17/October/2007   Macros added and funcion names changed
  06/December/2007  Added variables to easily know the                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
*/

#include "USB_User_API.h"

/* Global Variables */
UINT8 gu8DataOUTready=0;

/* User Buffers */
UINT8 EP1_Buffer[UEP1_SIZE];
UINT8 EP2_Buffer[UEP2_SIZE];
UINT8 EP3_Buffer[UEP3_SIZE];
UINT8 EP4_Buffer[UEP4_SIZE];

/* User Out buffer recieved data size */
UINT8 EP1_OUT_SIZE;
UINT8 EP2_OUT_SIZE;
UINT8 EP3_OUT_SIZE;
UINT8 EP4_OUT_SIZE;

/* Shared Buffers (SIE & Core) */
//UINT8 EP1_BDT_Buffer[UEP1_SIZE] @0x1880;
//UINT8 EP2_BDT_Buffer[UEP2_SIZE] @0x1890;
//UINT8 EP3_BDT_Buffer[UEP3_SIZE] @0x18A0;
//UINT8 EP4_BDT_Buffer[UEP4_SIZE] @0x18C0;

UINT8 EP1_BDT_Buffer[UEP1_SIZE] @0x18A0;
UINT8 EP2_BDT_Buffer[UEP2_SIZE] @0x18B0;
UINT8 EP3_BDT_Buffer[UEP3_SIZE] @0x18C0;
UINT8 EP4_BDT_Buffer[UEP4_SIZE] @0x18D0;

        

//////////////////////////////////////////////////////////////
void Endpoint_Init(void)
{   
    // EndPoint 1 Configuration
    EPCTL1 = EP_OUT|HSHK_EN;                
    EP1_Set.Cnt = UEP1_SIZE; 
//    EP1_Set.Addr =  0x08;
    EP1_Set.Addr =  0x10;
    EP1_Set.Stat._byte = _SIE|_DATA0|_DTS; 
    
    // EndPoint 2 Configuration
    EPCTL2 = EP_IN|HSHK_EN;   
//    EP2_Set.Addr =  0x0C;
    EP2_Set.Addr =  0x14;
    EP2_Set.Stat._byte = _CPU|_DATA1;
    
    // EndPoint 3 Configuration
    EPCTL3 = EP_OUT|HSHK_EN;              
    EP3_Set.Cnt = UEP3_SIZE;   
//    EP3_Set.Addr =  0x10;
    EP3_Set.Addr =  0x18;
    EP3_Set.Stat._byte = _SIE|_DATA0|_DTS;
    
    // EndPoint 4 Configuration
    EPCTL4 = EP_IN|HSHK_EN;                
//    EP4_Set.Addr =  0x18;
    EP4_Set.Addr =  0x1c;
    EP4_Set.Stat._byte = _CPU|_DATA1;
}

//////////////////////////////////////////////////////////////
UINT8 CheckEndPointOUT(UINT8 u8Endp) 
{
    if(gu8DataOUTready & (1<<u8Endp))
    {
        gu8DataOUTready&= ~(1<<u8Endp);   // Clear EndPoint Flag
        return(1);
    } 
    else
        return(0);
}

/////////////////////////////////////////////////////////////
void EndPoint_IN(UINT8 u8Endp,UINT8 u8EPSize)
{
    BUFF_DSC   *pu8BDT;
    UINT8 *pu8UserBuffer;
    UINT8 *pu8SIEBuffer;
    UINT8 u8Counter;
    
    switch(u8Endp) 
    {
      case 1:
        pu8BDT=&EP1_Set;
        pu8UserBuffer=&EP1_Buffer[0];
        pu8SIEBuffer=&EP1_BDT_Buffer[0];
        break;  

      case 2:
        pu8BDT=&EP2_Set;
        pu8UserBuffer=&EP2_Buffer[0];
        pu8SIEBuffer=&EP2_BDT_Buffer[0];
        break;  
        
      case 3:
        pu8BDT=&EP3_Set;
        pu8UserBuffer=&EP3_Buffer[0];
        pu8SIEBuffer=&EP3_BDT_Buffer[0];
        break;
        
      case 4:
        pu8BDT=&EP4_Set;
        pu8UserBuffer=&EP4_Buffer[0];
        pu8SIEBuffer=&EP4_BDT_Buffer[0];
        break;

    }
      
    while(pu8BDT->Stat.SieCtlBit.OWN);       // while Buffer is owned by SIE
      
    /* Copy buffer to USB RAM */
    for (u8Counter = 0; u8Counter < u8EPSize; u8Counter++)
   	         *pu8SIEBuffer++ = *pu8UserBuffer++;
    
    /* Set Packet Size and activate EP */
    pu8BDT->Cnt = u8EPSize;
    USB_Buf_Rdy(pu8BDT);
}

//////////////////////////////////////////////////////////////
void EndPoint_OUT(UINT8 u8Endp)
{
    BUFF_DSC   *pu8BDT;
    UINT8 *pu8UserBuffer;
    UINT8 *pu8SIEBuffer;
    UINT8 u8Counter;
    
    switch(u8Endp) 
    {
      case 1:
        pu8BDT=&EP1_Set;
        pu8UserBuffer=&EP1_Buffer[0];
        pu8SIEBuffer=&EP1_BDT_Buffer[0];
        EP1_OUT_SIZE=pu8BDT->Cnt;
        break;

      case 2:
        pu8BDT=&EP2_Set;
        pu8UserBuffer=&EP2_Buffer[0];
        pu8SIEBuffer=&EP2_BDT_Buffer[0];
        EP2_OUT_SIZE=pu8BDT->Cnt;
        break;
        
      case 3:
        pu8BDT=&EP3_Set;
        pu8UserBuffer=&EP3_Buffer[0];
        pu8SIEBuffer=&EP3_BDT_Buffer[0];
        EP3_OUT_SIZE=pu8BDT->Cnt;
        break;
        
      case 4:
        pu8BDT=&EP4_Set;
        pu8UserBuffer=&EP4_Buffer[0];
        pu8SIEBuffer=&EP4_BDT_Buffer[0];
        EP4_OUT_SIZE=pu8BDT->Cnt;
        break;
     }
    
    if(!pu8BDT->Stat.McuCtlBit.OWN)
    {
        /* Copy buffer to User RAM */
        for (u8Counter = 0; u8Counter < pu8BDT->Cnt; u8Counter++)
   	        *pu8UserBuffer++ = *pu8SIEBuffer++;

        USB_Buf_Rdy(pu8BDT);
        gu8DataOUTready|= (1<<u8Endp);
    }
}