Ejemplo n.º 1
0
/**
* @brief  MSC_BOT_Init
*         Initialize the BOT Process
* @param  pdev: device instance
* @retval None
*/
void MSC_BOT_Init (USB_OTG_CORE_HANDLE  *pdev)
{
  MSC_BOT_State = BOT_IDLE;
  MSC_BOT_Status = BOT_STATE_NORMAL;
  USBD_STORAGE_fops->Init(0);

  DCD_EP_Flush(pdev, MSC_OUT_EP);
  DCD_EP_Flush(pdev, MSC_IN_EP);
  /* Prapare EP to Receive First BOT Cmd */
  DCD_EP_PrepareRx (pdev,
                    MSC_OUT_EP,
                    (uint8_t *)&MSC_BOT_cbw,
                    BOT_CBW_LENGTH);
}
Ejemplo n.º 2
0
/**
 * @brief  USBD_CDC_DataIn
 *         Data sent on non-control IN endpoint
 * @param  pdev: device instance
 * @param  epnum: endpoint number
 * @retval status
 */
static uint8_t  USBD_CDC_DataIn (void *pdev, uint8_t epnum)
{
	uint16_t i;

	if (USBD_CDC_InFlight != 0) {
		USBD_CDC_InFlight = 0;
	}

	if (ringbuffer_isempty(&USBD_CDC_D2H_FIFO) == 0)
	{
		for (i = 0; i < CDC_DATA_IN_PACKET_SIZE && ringbuffer_isempty(&USBD_CDC_D2H_FIFO) == 0; i++) {
			USBD_CDC_D2H_Buff[i] = ringbuffer_pop(&USBD_CDC_D2H_FIFO);
		}
		dbgwdg_feed();
		DCD_EP_Tx (pdev,
					USBD_Dev_CDC_D2H_EP,
					(uint8_t*)USBD_CDC_D2H_Buff,
					i);
		USBD_CDC_InFlight = 1;
	}

	if (USBD_CDC_InFlight == 0) {
		DCD_EP_Flush(pdev, epnum);
	}

	return USBD_OK;
}
Ejemplo n.º 3
0
static uint8_t  usbd_video_SOF (void *pdev)
{     

  if (play_status == 1)
  {
	  DCD_EP_Flush(pdev,USB_ENDPOINT_IN(1));
	  DCD_EP_Tx (pdev,USB_ENDPOINT_IN(1), (uint8_t*)0x0002, 2);//header
	  play_status = 2;
  }
  return USBD_OK;
}
Ejemplo n.º 4
0
static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE  *pdev)
{
  // Open EP0 OUT
  DCD_EP_Open(pdev,
              0x00,
              USB_OTG_MAX_EP0_SIZE,
              EP_TYPE_CTRL);

  // Open EP0 IN
  DCD_EP_Open(pdev,
              0x80,
              USB_OTG_MAX_EP0_SIZE,
              EP_TYPE_CTRL);

  DCD_EP_Flush(pdev, 0x00);
  DCD_EP_Flush(pdev, 0x80);

  /* Upon Reset call usr call back */
  pdev->dev.device_status = USB_OTG_DEFAULT;
  pdev->dev.cb->DeviceReset(pdev->cfg.speed);

  return USBD_OK;
}
Ejemplo n.º 5
0
//CLASS SPECIFIC REQUEST
static void VIDEO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req)
{  
  /* Send the current mute state */

  DCD_EP_Flush (pdev,USB_ENDPOINT_OUT(0));

  if(req->wValue == 256)
  {
	  //Probe Request
	  USBD_CtlSendData (pdev, (uint8_t*)&videoProbeControl, req->wLength);
  }
  else if (req->wValue == 512)
  {
	  //Commit Request

	  USBD_CtlSendData (pdev, (uint8_t*)&videoCommitControl, req->wLength);
  }
}
Ejemplo n.º 6
0
/**
  * @brief  usbd_cdc_Init
  *         DeInitialize the CDC layer
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  usbd_cdc_DeInit (void  *pdev,
                                 uint8_t cfgidx)
{
  usbd_cdc_Change_Open_State(0);

  if (cdcConfigured) {
    if (USB_Tx_State) {
      DCD_EP_Flush(pdev, CDC_IN_EP);
    }

    /* Close EP IN */
    DCD_EP_Close(pdev,
                 CDC_IN_EP);

    /* Close EP OUT */
    DCD_EP_Close(pdev,
                 CDC_OUT_EP);

    /* Close Command IN EP */
    DCD_EP_Close(pdev,
                 CDC_CMD_EP);

    /* Restore default state of the Interface physical components */
    APP_FOPS.pIf_DeInit();
  }

  usbd_cdc_Change_Open_State(0);

  cdcConfigured = 0;
  USB_Tx_State = 0;
  USB_Rx_State = 0;
  USB_Rx_Buffer_head = 0;
  USB_Rx_Buffer_tail = 0;
  USB_Rx_Buffer_length = USB_RX_BUFFER_SIZE;
  USB_Tx_Buffer_tail = 0;
  USB_Tx_Buffer_head = 0;

  return USBD_OK;
}
Ejemplo n.º 7
0
static uint8_t  USBD_CDC_SOF (void *pdev)
{
	if (CdcFrameCount >= CDC_IN_FRAME_INTERVAL)
	{
		if (USBD_CDC_InFlight == 0)
		{
			if (USBD_CDC_D2H_FIFO.ready == 0xAB)
			{
				USBD_CDC_IsReady = 1;

				if (ringbuffer_isempty(&USBD_CDC_D2H_FIFO) == 0)
				{
					uint16_t i;
					for (i = 0; i < CDC_DATA_IN_PACKET_SIZE && ringbuffer_isempty(&USBD_CDC_D2H_FIFO) == 0; i++) {
						USBD_CDC_D2H_Buff[i] = ringbuffer_pop(&USBD_CDC_D2H_FIFO);
					}
					DCD_EP_Tx (pdev,
								USBD_Dev_CDC_D2H_EP,
								(uint8_t*)USBD_CDC_D2H_Buff,
								i);
					USBD_CDC_InFlight = 1;
					CdcFrameCount = 0;
				}
			}
		}
		else if (CdcFrameCount > 100) // timeout on waiting
		{
			led_1_tog();
			CdcFrameCount = 0;
			USBD_CDC_InFlight = 0;
			DCD_EP_Flush(pdev, USBD_Dev_CDC_D2H_EP);
		}
	}

	CdcFrameCount++;

	return USBD_OK;
}
Ejemplo n.º 8
0
static void usbd_cdc_Schedule_In(void *pdev)
{
  uint32_t USB_Tx_length;
  USB_Tx_length = ring_data_contig(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_head, USB_Tx_Buffer_tail);

  if (USB_Tx_State) {
    if (USB_Serial_Open) {
      USB_Tx_failed_counter++;
      if (USB_Tx_failed_counter >= 500) {
        usbd_cdc_Change_Open_State(0);
        // Completely flush TX buffer
        DCD_EP_Flush(pdev, CDC_IN_EP);
        // Send ZLP
        DCD_EP_Tx(pdev, CDC_IN_EP, NULL, 0);
        if (USB_Tx_length)
          USB_Tx_Buffer_tail = ring_wrap(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_tail + USB_Tx_length);

        USB_Tx_State = 0;
      }
    }
    return;
  }

  if (!USB_Tx_length)
    return;

  USB_Tx_State = 1;
  USB_Tx_failed_counter = 0;

  USB_Tx_length = MIN(USB_Tx_length, CDC_DATA_IN_PACKET_SIZE);
  DCD_EP_Tx (pdev,
             CDC_IN_EP,
             (uint8_t*)&USB_Tx_Buffer[USB_Tx_Buffer_tail],
             USB_Tx_length);

  USB_Tx_Buffer_tail = ring_wrap(USB_TX_BUFFER_SIZE, USB_Tx_Buffer_tail + USB_Tx_length);
}
Ejemplo n.º 9
0
/**
* @brief  USBD_MSC_Setup
*         Handle the MSC specific requests
* @param  pdev: device instance
* @param  req: USB request
* @retval status
*/
uint8_t  USBD_MSC_Setup (void  *pdev, USB_SETUP_REQ *req)
{
  
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
  {

  /* Class request */
  case USB_REQ_TYPE_CLASS :
    switch (req->bRequest)
    {
    case BOT_GET_MAX_LUN :

      if((req->wValue  == 0) && 
         (req->wLength == 1) &&
         ((req->bmRequest & 0x80) == 0x80))
      {
        USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun();
        if(USBD_MSC_MaxLun > 0)
        {
           USBD_CtlSendData (pdev,
                             &USBD_MSC_MaxLun,
                              1);
        }
        else
        {
          USBD_CtlError(pdev , req);
          return USBD_FAIL; 
          
        }
      }
      else
      {
         USBD_CtlError(pdev , req);
         return USBD_FAIL; 
      }
      break;
      
    case BOT_RESET :
      if((req->wValue  == 0) && 
         (req->wLength == 0) &&
        ((req->bmRequest & 0x80) != 0x80))
      {      
         MSC_BOT_Reset(pdev);
      }
      else
      {
         USBD_CtlError(pdev , req);
         return USBD_FAIL; 
      }
      break;

    default:
       USBD_CtlError(pdev , req);
       return USBD_FAIL; 
    }
    break;
  /* Interface & Endpoint request */
  case USB_REQ_TYPE_STANDARD:
    switch (req->bRequest)
    {
    case USB_REQ_GET_INTERFACE :
      USBD_CtlSendData (pdev,
                        &USBD_MSC_AltSet,
                        1);
      break;
      
    case USB_REQ_SET_INTERFACE :
      USBD_MSC_AltSet = (uint8_t)(req->wValue);
      break;
    
    case USB_REQ_CLEAR_FEATURE:  
      
      /* Flush the FIFO and Clear the stall status */    
      DCD_EP_Flush(pdev, (uint8_t)req->wIndex);
      
      /* Re-activate the EP */      
      DCD_EP_Close (pdev , (uint8_t)req->wIndex);
      if((((uint8_t)req->wIndex) & 0x80) == 0x80)
      {
        DCD_EP_Open(pdev,
                    ((uint8_t)req->wIndex),
                    MSC_EPIN_SIZE,
                    USB_OTG_EP_BULK);
      }
      else
      {
        DCD_EP_Open(pdev,
                    ((uint8_t)req->wIndex),
                    MSC_EPOUT_SIZE,
                    USB_OTG_EP_BULK);
      }
      
      /* Handle BOT error */
      MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
      break;
      
    }  
    break;
   
  default:
    break;
  }
  return USBD_OK;
}
Ejemplo n.º 10
0
int process_usbmessage(void)
{
	int result = 0;
	switch(application_mode)
	{
		case STAND_ALONE:
		{
			if(local_buff_length == 5)
			{
				//d (from "deca")
				if((local_buff[0] == 100) && (result == 0)) //d (from "deca")
				{
					if(local_buff[4] == 63)
					{
						int i = sizeof(SOFTWARE_VER_STRINGUSB);
						//change mode to  USB_TO_SPI and send a reply "y"
						tx_buff[0] = 121;
						memcpy(&tx_buff[1], SOFTWARE_VER_STRINGUSB, i);
						tx_buff[i+2] = 0;
						tx_buff_length = i + 2;
						application_mode = USB_TO_SPI;
						result = 2;
						//led_off(LED_ALL);
						led_on(LED_PC7); //turn on LED to indicate connection to PC application
					}
				}
			}
		}
		break;


		case USB_TO_SPI:
		{
			//first byte specifies the SPI speed and SPI read/write operation
			//bit 0 = 1 for write, 0 for read
			//bit 1 = 1 for high speed, 0 for low speed

			//<STX>   <ETX>
			//
			//to read from the device (e.g. 4 bytes), total length is = 1 + 1 + length_of_command (2) + length_of_data_to_read (2) + header length (1/2) + 1
			//
			//to write to the device (e.g. 4 bytes),  total length is = 1 + 1 + length_of_command (2) + length_of_data_to_write (2) + header length (1/2) + data length + 1
			//
			//LBS comes first:   0x2, 0x2, 0x7, 0x0, 0x04, 0x00, 0x3

			if(local_buff_length)
			{
				//0x2 = STX - start of SPI transaction data
				if(local_buff[0] == 0x2)
				{
					//configure SPI speed
					configSPIspeed(((local_buff[1]>>1) & 0x1));

					if((local_buff[1] & 0x1) == 0) //SPI read
					{
						int msglength = local_buff[2] + (local_buff[3]<<8);
						int datalength = local_buff[4] + (local_buff[5]<<8);

						//led_on(LED_PC6);
						tx_buff[0] = 0x2;
						tx_buff[datalength+2] = 0x3;

						//max data we can read in a single SPI transaction is 4093 as the USB/VCP tx buffer is only 4096 bytes long
						if((local_buff[msglength-1] != 0x3) || (datalength > 4093))
						{
							tx_buff[1] = 0x1; // if no ETX (0x3) indicate error
						}
						else
						{
							// do the read from the SPI
							readfromspi(msglength-7, &local_buff[6], datalength, &tx_buff[2]);  // result is stored in the buffer

							tx_buff[1] = 0x0; // no error
						}

						tx_buff_length = datalength + 3;
						result = 2;
					}

					if((local_buff[1] & 0x1) == 1) //SPI write
					{
						int msglength = local_buff[2] + (local_buff[3]<<8);
						int datalength = local_buff[4] + (local_buff[5]<<8);
						int headerlength = msglength - 7 - datalength;

						if(local_buff_length == msglength) //we got the whole message (sent from the PC)
						{
							local_buff_offset = 0;

							led_off(LED_PC6);
							tx_buff[0] = 0x2;
							tx_buff[2] = 0x3;

							if(local_buff[msglength-1] != 0x3)
							{
								tx_buff[1] = 0x1; // if no ETX (0x3) indicate error
							}
							else
							{
								// do the write to the SPI
								writetospi(headerlength, &local_buff[6], datalength, &local_buff[6+headerlength]);  // result is stored in the buffer

								tx_buff[1] = 0x0; // no error
							}

							tx_buff_length = 3;
							result = 2;
						}
						else //wait for the whole message
						{
							led_on(LED_PC6);
						}
					}
				}

				if((local_buff[0] == 100) && (result == 0)) //d (from "deca")
				{
					if(local_buff[4] == 63)
					{
						int i = sizeof(SOFTWARE_VER_STRINGUSB);
						//change mode to  USB_TO_SPI and send a reply "y"
						tx_buff[0] = 121;
						memcpy(&tx_buff[1], SOFTWARE_VER_STRINGUSB, i);
						tx_buff[i+2] = 0;
						tx_buff_length = i + 2;
						application_mode = USB_TO_SPI;
						result = 2;
						//led_off(LED_ALL);
						led_on(LED_PC7); //turn on LED to indicate connection to PC application
					}

				}

				if((local_buff[0] == 114) && (result == 0)) //r - flush the USB buffers...
				{
					DCD_EP_Flush(&USB_OTG_dev, CDC_IN_EP);
					result = 0;
				}
			}
		}
		break;

		case USB_PRINT_ONLY:
			if(local_buff_length && (result == 0))
			{
				if((local_buff[0] == 0x5) && (local_buff[5] == 0x5))
				{
					uint16 txantennadelay = local_buff[1] + (local_buff[2]<<8);
					uint16 rxantennadelay = local_buff[3] + (local_buff[4]<<8);
					instanceconfigantennadelays(txantennadelay, rxantennadelay);
				}
				if((local_buff[0] == 0x7) && (local_buff[5] == 0x7))
				{
					//not used in EVK
				}
				if((local_buff[0] == 0x6) && (local_buff[2] == 0x6))
				{
					uint8 switchS1 = local_buff[1];

					//disable DW1000 IRQ
					port_DisableEXT_IRQ(); //disable IRQ until we configure the device
					//turn DW1000 off
					dwt_forcetrxoff();
					//re-configure the instance
					inittestapplication(switchS1);
					//save the new setting
					s1configswitch = switchS1;
					//set the LDC
					setLCDline1(switchS1);
					//enable DW1000 IRQ
					port_EnableEXT_IRQ(); //enable IRQ before starting

					ranging = 0;

				}
				//d (from "deca")
				if(local_buff[0] == 100) //d (from "deca")
				{
					if(local_buff[4] == 63)
					{
						int i = sizeof(SOFTWARE_VER_STRINGUSB);
						//send a reply "n"
						tx_buff[0] = 110;
						memcpy(&tx_buff[1], SOFTWARE_VER_STRINGUSB, i);
						tx_buff[i+2] = 0;
						tx_buff_length = i + 2;
						result = 2;
					}
					if(local_buff[4] == 36) //"$"
					{
						//send a reply "n"
						tx_buff[0] = 110;
						memcpy(&tx_buff[1], version, version_size);
						tx_buff[version_size+1] = s1configswitch & 0xff;
						tx_buff[version_size+2] = '\r';
						tx_buff[version_size+3] = '\n';
						tx_buff_length = version_size + 4;
						result = 2;
					}
					if(local_buff[4] == 33) //"!"
					{
						//send back the DW1000 partID and lotID
						uint32 partID = dwt_getpartid();
						uint32 lotID = dwt_getlotid();
						tx_buff[0] = 110;
						memcpy(&tx_buff[1], &partID, 4);
						memcpy(&tx_buff[5], &lotID, 4);
						tx_buff[9] = '\r';
						tx_buff[10] = '\n';
						tx_buff_length = 11;
						result = 2;
					}
				}
			}
			break;

		default:
			break;
	}
Ejemplo n.º 11
0
//handle request from HOST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//send data to PC
static uint8_t  usbd_video_DataIn (void *pdev, uint8_t epnum)
{
  static uint16_t packets_cnt = 0xffff;
  static uint8_t header[2] = {2,0};//length + data
  uint16_t i;
  static uint32_t picture_pos;

  static uint16_t packets_in_frame = 1;
  static uint16_t last_packet_size = 0;
  
  uint8_t packet[VIDEO_PACKET_SIZE];

  static uint8_t tx_enable_flag = 0;//разрешение передачи

  DCD_EP_Flush(pdev,USB_ENDPOINT_IN(1));//very important

  if (tx_enable_flag) packets_cnt++;
  
  if (tx_enable_flag == 0)//если передача закончилась//if previous transmission ended
  {
    if (jpeg_encode_done)//если кодирование закончилось//if frame endoding ended
    {
      tx_enable_flag = 1;
      switch_buffers();//переключить буферы для двойной буферизации//switch double buffering buffers
      new_frame_cap_enabled = 1;//начать новый захват кадра//start new frame capture
      
      //start of new UVC frame
      //начало нового кадра UVC
      packets_cnt = 0;
      header[1]^= 1;//toggle bit0 every new frame
      picture_pos = 0;
      
      packets_in_frame = (last_jpeg_frame_size/ ((uint16_t)VIDEO_PACKET_SIZE -2))+1;//-2 - без учета заголовка
      last_packet_size = (last_jpeg_frame_size - ((packets_in_frame-1) * ((uint16_t)VIDEO_PACKET_SIZE-2)) + 2);//+2 - учитывая заголовок
    }
  }

  packet[0] = header[0];
  packet[1] = header[1];

  //fill payload buffer
  for (i=2;i<VIDEO_PACKET_SIZE;i++)
  {
    packet[i] = read_pointer[picture_pos];
    picture_pos++;
  }
  
  if (play_status == 2)
  {
    if (packets_cnt< (packets_in_frame - 1))
    {
      DCD_EP_Tx (pdev,USB_ENDPOINT_IN(1), (uint8_t*)&packet, (uint32_t)VIDEO_PACKET_SIZE);
    }
    else if (tx_enable_flag == 1)//только если передача разрешена//only if transmisson enabled
    {
      //last packet in UVC frame
      //последний пакет в кадре UVC
      DCD_EP_Tx (pdev,USB_ENDPOINT_IN(1), (uint8_t*)&packet, (uint32_t)last_packet_size);
      tx_enable_flag = 0;//stop TX data
    }
    else
    {
      DCD_EP_Tx (pdev,USB_ENDPOINT_IN(1), (uint8_t*)&header, 2);//header only
      picture_pos = 0;
    }
  }
  else
  {
    packets_cnt = 0xffff;
    picture_pos = 0;
  }
  
  
  //STM_EVAL_LEDToggle(LED6);
  return USBD_OK;
}
Ejemplo n.º 12
0
static uint8_t  usbd_video_Setup (void  *pdev, 
                                  USB_SETUP_REQ *req)
{
  uint16_t len;
  uint8_t  *pbuf;
  
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
  {
  case USB_REQ_TYPE_CLASS :    
    switch (req->bRequest)
    {
    case GET_CUR:
    case GET_DEF:
    case GET_MIN:
    case GET_MAX:
      VIDEO_Req_GetCurrent(pdev, req);
      break;

    case SET_CUR:
    	VIDEO_Req_SetCurrent(pdev, req);
      break;

    default:
      USBD_CtlError (pdev, req);
      return USBD_FAIL;
    }
    break;

    
    /* Standard Requests -------------------------------*/
  case USB_REQ_TYPE_STANDARD:
    switch (req->bRequest)
    {
    case USB_REQ_GET_DESCRIPTOR: 
      if( (req->wValue >> 8) == CS_DEVICE)
      {
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
        pbuf = usbd_video_Desc;   
#else
        pbuf = usbd_video_CfgDesc + 18;
#endif 
        len = MIN(USB_VIDEO_DESC_SIZ , req->wLength);
      }
      
      USBD_CtlSendData (pdev, pbuf, len);
      break;
      
    case USB_REQ_GET_INTERFACE :
      USBD_CtlSendData (pdev, (uint8_t *)&usbd_video_AltSet, 1);
      break;
      
    case USB_REQ_SET_INTERFACE :
      if ((uint8_t)(req->wValue) < VIDEO_TOTAL_IF_NUM)
      {
        usbd_video_AltSet = (uint8_t)(req->wValue);

        if (usbd_video_AltSet == 1) {
        	STM_EVAL_LEDOn(LED5);
        	play_status = 1;
        } else {
        	STM_EVAL_LEDOff(LED5);
        	DCD_EP_Flush (pdev,USB_ENDPOINT_IN(1));
        	play_status = 0;
        }
      }
      else
      {
        /* Call the error management function (command will be nacked */
        USBD_CtlError (pdev, req);
      }
      break;
    }
  }
  return USBD_OK;
}
Ejemplo n.º 13
0
/**
  * @brief  usbd_cdc_Setup
  *         Handle the CDC specific requests
  * @param  pdev: instance
  * @param  req: usb requests
  * @retval status
  */
static uint8_t  usbd_cdc_msc_Setup (void  *pdev,
                                USB_SETUP_REQ *req)
{
  uint16_t len=USB_CDC_MSC_DESC_SIZ;
  uint8_t  *pbuf=usbd_cdc_msc_CfgDesc + 9;

  switch (req->bmRequest & USB_REQ_TYPE_MASK)
  {
    /* CDC Class Requests -------------------------------*/
  case USB_REQ_TYPE_CLASS :
    switch (req->bRequest)
    {
    case BOT_GET_MAX_LUN :

      if((req->wValue  == 0) &&
         (req->wLength == 1) &&
         ((req->bmRequest & 0x80) == 0x80))
      {
        USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun();
        if(USBD_MSC_MaxLun > 0)
        {
           USBD_CtlSendData (pdev,
                             &USBD_MSC_MaxLun,
                              1);
        }
        else
        {
          USBD_CtlError(pdev , req);
          return USBD_FAIL;

        }
      }
      else
      {
         USBD_CtlError(pdev , req);
         return USBD_FAIL;
      }
      break;

    case BOT_RESET :
      if((req->wValue  == 0) &&
         (req->wLength == 0) &&
        ((req->bmRequest & 0x80) != 0x80))
      {
         MSC_BOT_Reset(pdev);
      }
      else
      {
         USBD_CtlError(pdev , req);
         return USBD_FAIL;
      }
      break;

    // CDC
    default:
      /* Check if the request is a data setup packet */
      if (req->wLength)
      {
        /* Check if the request is Device-to-Host */
        if (req->bmRequest & 0x80)
        {
          /* Get the data to be sent to Host from interface layer */
          APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);

          /* Send the data to the host */
          USBD_CtlSendData (pdev,
                            CmdBuff,
                            req->wLength);
        }
        else /* Host-to-Device requeset */
        {
          /* Set the value of the current command to be processed */
          cdcCmd = req->bRequest;
          cdcLen = req->wLength;

          /* Prepare the reception of the buffer over EP0
          Next step: the received data will be managed in usbd_cdc_EP0_TxSent()
          function. */
          USBD_CtlPrepareRx (pdev,
                             CmdBuff,
                             req->wLength);
        }
      }
      else /* No Data request */
      {
        /* Transfer the command to the interface layer */
        APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);

	// check for DTE present changes - NEZ
	if (req->bRequest == SET_CONTROL_LINE_STATE) {
	    USB_DTE_Present = req->wValue & 0x01;

	    if (!USB_DTE_Present) {
		DCD_EP_Flush (pdev, CDC_IN_EP);
		USB_Tx_State = 0;
	    }
	}
      }

      return USBD_OK;
      break;	// default
    }
    break;  // case USB_REQ_TYPE_CLASS

    /* Standard Requests -------------------------------*/
  case USB_REQ_TYPE_STANDARD:
    switch (req->bRequest)
    {
    case USB_REQ_GET_DESCRIPTOR:
      if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
      {
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
        pbuf = usbd_cdc_Desc;
#else
        pbuf = usbd_cdc_msc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
#endif
        len = MIN(USB_CDC_MSC_DESC_SIZ , req->wLength);
      }

      USBD_CtlSendData (pdev,
                        pbuf,
                        len);
      break;

    case USB_REQ_GET_INTERFACE :
      if ((uint8_t)req->wValue == CDC_IN_EP || (uint8_t)req->wValue == CDC_OUT_EP) {
	  USBD_CtlSendData (pdev,
			    (uint8_t *)&usbd_cdc_AltSet,
			    1);
      }
      else {
	  USBD_CtlSendData (pdev,
			    &USBD_MSC_AltSet,
			    1);
	  break;
      }
      break;

    case USB_REQ_SET_INTERFACE :
      if ((uint8_t)req->wValue == CDC_IN_EP || (uint8_t)req->wValue == CDC_OUT_EP) {
	  if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
	  {
	    usbd_cdc_AltSet = (uint8_t)(req->wValue);
	  }
	  else
	  {
	    /* Call the error management function (command will be nacked */
	    USBD_CtlError (pdev, req);
	  }
      }
      else {
	  USBD_MSC_AltSet = (uint8_t)(req->wValue);
      }
      break;

      case USB_REQ_CLEAR_FEATURE:
	  /* Flush the FIFO and Clear the stall status */
	  DCD_EP_Flush(pdev, (uint8_t)req->wIndex);

	  /* Re-activate the EP */
	  DCD_EP_Close (pdev , (uint8_t)req->wIndex);
	  if((((uint8_t)req->wIndex) & 0x80) == 0x80)
	  {
	    DCD_EP_Open(pdev,
			((uint8_t)req->wIndex),
			MSC_EPIN_SIZE,
			USB_OTG_EP_BULK);
	  }
	  else
	  {
	    DCD_EP_Open(pdev,
			((uint8_t)req->wIndex),
			MSC_EPOUT_SIZE,
			USB_OTG_EP_BULK);
	  }

	  /* Handle BOT error */
	  MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
	  break;
    }
  }
  return USBD_OK;
}