
#include "usb_lib.h"
#include "usb_conf.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "hw_config.h"

DEVICE Device_Table =
  {
    EP_NUM,
    1
  };

DEVICE_PROP Device_Property =
  {
    MUSB_init,
    MUSB_Reset,
    MUSB_Status_In,
    MUSB_Status_Out,
    MUSB_Data_Setup,
    MUSB_NoData_Setup,
    MUSB_Get_Interface_Setting,
    MUSB_GetDeviceDescriptor,
    MUSB_GetConfigDescriptor,
    MUSB_GetStringDescriptor,
    0,
    0x40 /*MAX PACKET SIZE*/
  };
USER_STANDARD_REQUESTS User_Standard_Requests =
  {
    MUSB_GetConfiguration,
    MUSB_SetConfiguration,
    MUSB_GetInterface,
    MUSB_SetInterface,
    MUSB_GetStatus,
    MUSB_ClearFeature,
    MUSB_SetEndPointFeature,
    MUSB_SetDeviceFeature,
    MUSB_SetDeviceAddress
  };

ONE_DESCRIPTOR Device_Descriptor =
  {
    (uint8_t*)MUSB_DeviceDescriptor,
    MUSB_SIZE_DEVICE_DESC
  };

ONE_DESCRIPTOR Config_Descriptor =
  {
    (uint8_t*)MUSB_ConfigDescriptor,
    MUSB_SIZE_CONFIG_DESC
  };

ONE_DESCRIPTOR String_Descriptor[3] =
  {
    {(uint8_t*)MUSB_StringLangID, MUSB_SIZE_STRING_LANGID},
    {(uint8_t*)MUSB_StringVendor, MUSB_SIZE_STRING_VENDOR},
    {(uint8_t*)MUSB_StringProduct, MUSB_SIZE_STRING_PRODUCT}
  };


/*******************************************************************************
* Function Name  : MUSB_init.
* Description    : MUSB init routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void MUSB_init(void)
{
  pInformation->Current_Configuration = 0;

  /* Connect the device */
  PowerOn();

  /* Perform basic device initialization operations */
  USB_SIL_Init();

  bDeviceState = UNCONNECTED;
}

/*******************************************************************************
* Function Name  : MUSB_Reset.
* Description    : MUSB reset routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void MUSB_Reset(void)
{
  // Set MUSB_DEVICE as not configured
  pInformation->Current_Configuration = 0;
  pInformation->Current_Interface = 0;// the default Interface

  // Current Feature initialization
  pInformation->Current_Feature = MUSB_ConfigDescriptor[7];
  SetBTABLE(BTABLE_ADDRESS);

  // Initialize Endpoint 0
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);

  // Initialize Endpoint 3
  SetEPType(ENDP3, EP_BULK);
  SetEPDoubleBuff(ENDP3);
  SetEPDblBuffAddr(ENDP3, ENDP3_TXADDR1, ENDP3_TXADDR2);
  SetEPDblBuffCount(ENDP3, EP_DBUF_IN, 64);
  ClearDTOG_TX(ENDP3); // USB PERIPHERAL
  SetEPTxStatus(ENDP3, EP_TX_NAK);

  // Set this device to response on default address
  SetDeviceAddress(0);
  bDeviceState = ATTACHED;
}
/*******************************************************************************
* Function Name  : MUSB_SetConfiguration.
* Description    : Update the device state to configured.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void MUSB_SetConfiguration(void)
{
  DEVICE_INFO *pInfo = &Device_Info;

  if (pInfo->Current_Configuration != 0)
  {
    /* Device configured */
    bDeviceState = CONFIGURED;
  }
}
/*******************************************************************************
* Function Name  : MUSB_SetConfiguration.
* Description    : Update the device state to addressed.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void MUSB_SetDeviceAddress (void)
{
  bDeviceState = ADDRESSED;
}
/*******************************************************************************
* Function Name  : MUSB_Status_In.
* Description    : MUSB status IN routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void MUSB_Status_In(void)
{
  // Notify, dass die mit OUT gesendeten Daten im Puffer liegen
  // (usb_control_msg USB_ENDPOINT_OUT )
}

/*******************************************************************************
* Function Name  : MUSB_Status_Out
* Description    : MUSB status OUT routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
uint8_t Func124_Arr[0x4]; // Read

void MUSB_Status_Out (void)
{
  // Notify, dass die mit IN angeforderden Daten gesendet wurden
  // (usb_control_msg USB_ENDPOINT_IN  (0x80))
}

/*******************************************************************************
* Function Name  : MUSB_Data_Setup
* Description    : Handle the data class specific requests.
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/

/*******************************************************************************
* Function Name  : MUSB_NoData_Setup
* Description    : handle the no data class specific requests
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
RESULT MUSB_NoData_Setup(uint8_t RequestNo)
{
  /*
  // CopyArr: usb_control_msg(USB_ENDPOINT_OUT, 122, 77, 88, NULL, 0)
  if(RequestNo==122)
  {
    if(Type_Recipient==(CLASS_REQUEST | INTERFACE_RECIPIENT))
	{
      if(pInformation->USBwValue0==77 && pInformation->USBwIndex0==88)
      {
        for(int i=0; i<sizeof(Func123_Arr); i++)
        {
          Func124_Arr[i] = Func123_Arr[i];
        }
        return USB_SUCCESS;
      }
    }
  }
    */
  return USB_UNSUPPORT;
}

/*******************************************************************************
* Function Name  : MUSB_GetDeviceDescriptor.
* Description    : Gets the device descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the device descriptor.
*******************************************************************************/
uint8_t *MUSB_GetDeviceDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &Device_Descriptor);
}

/*******************************************************************************
* Function Name  : MUSB_GetConfigDescriptor.
* Description    : Gets the configuration descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
uint8_t *MUSB_GetConfigDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &Config_Descriptor);
}

/*******************************************************************************
* Function Name  : MUSB_GetStringDescriptor
* Description    : Gets the string descriptors according to the needed index
* Input          : Length
* Output         : None.
* Return         : The address of the string descriptors.
*******************************************************************************/
uint8_t *MUSB_GetStringDescriptor(uint16_t Length)
{
  uint8_t wValue0 = pInformation->USBwValue0;
  const int nEntries = sizeof(String_Descriptor)/sizeof(*String_Descriptor);
  if (wValue0 > nEntries)
  {
    return NULL;
  }
  else
  {
    return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
  }
}

/*******************************************************************************
* Function Name  : MUSB_Get_Interface_Setting.
* Description    : tests the interface and the alternate setting according to the
*                  supported one.
* Input          : - Interface : interface number.
*                  - AlternateSetting : Alternate Setting number.
* Output         : None.
* Return         : USB_SUCCESS or USB_UNSUPPORT.
*******************************************************************************/
RESULT MUSB_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
{
  if (AlternateSetting > 0)
  {
    return USB_UNSUPPORT;
  }
  else if (Interface > 0)
  {
    return USB_UNSUPPORT;
  }
  return USB_SUCCESS;
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
