NetServices Stack source

Dependents:   HelloWorld ServoInterfaceBoardExample1 4180_Lab4

Revision:
0:632c9925f013
Child:
2:a4f97773c90f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drv/serial/usb/usbserialif.cpp	Fri Jun 11 16:05:15 2010 +0000
@@ -0,0 +1,326 @@
+
+/*
+Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+ 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+ 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/*
+  USB-Serial device driver
+  Donatien Garnier 2010
+*/
+
+#include "usbserialif.h"
+#include "drv/usb/UsbEndpoint.h"
+
+#include "netCfg.h"
+#if NET_USB_SERIAL
+
+UsbEndpoint* pEpIn;
+UsbEndpoint* pEpOut;
+
+USB_INT08U ser_int_found;
+USB_INT32S SerialInit()
+{
+  Host_Init();               // Initialize the  host controller
+  USB_INT32S rc = Host_EnumDev();       // Enumerate the device connected
+  if (rc != OK)
+  {
+      fprintf(stderr, "Could not enumerate device: %d\n", rc);
+      return rc;
+  }
+  return OK;
+}
+
+bool SerialHasToSwitch()
+{
+  return (ser_int_found == 3);
+}
+
+uint16_t m_vid;
+uint16_t m_pid;
+
+USB_INT32S SerialSendMagic()
+{
+  bool scsi = false;
+  //Size 31
+  const unsigned char magicHuawei[] = { 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0,    0, 0, 0, 0,    0, 0,    0x11, 0x6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  const unsigned char magicVoda[] = {   0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12, 0x01, 0, 0, 0, 0x80, 0, 0x06, 0x01, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  char* magic;
+  USB_INT32S rc;
+  if((m_vid == 0x12d1) && (m_pid == 0x1446))
+  {
+    PRINT_Log("\r\nHuawei magic packet sent.\r\n");
+    magic = (char*) magicHuawei;
+    scsi = true;
+  }
+  else if((m_vid == 0x12d1) && (m_pid == 0x1003))
+  {
+    PRINT_Log("\r\nHuawei magic control packet sent.\r\n");
+    rc = Host_CtrlSend( 0 /*USB_TYPE_STANDARD | USB_RECIP_DEVICE*/, 0x03 /*USB_REQ_SET_FEATURE*/, 00000001, 0, 0, NULL);
+  }
+  else if(m_vid == 0x0af0)
+  {
+    PRINT_Log("\r\nVoda magic packet sent.\r\n");
+    magic = (char*) magicVoda;  
+    scsi = true;
+  }
+  else
+  {
+   return -1;
+  }
+  
+  
+  if(scsi)
+  {
+    //rc = Host_ProcessTD(EDBulkOut, TD_OUT, (volatile USB_INT08U*)magic, 31);
+    rc = pEpOut->transfer((volatile USB_INT08U*)magic, 31);
+    while(rc == PROCESSING)
+    {
+     // __WFI();
+      rc = pEpOut->status();
+    }
+  
+  }
+  
+  
+  delete pEpOut;
+  pEpOut = NULL;
+  return rc;
+}
+
+USB_INT32S SerialCheckVidPid()
+{
+  volatile  USB_INT08U  *desc_ptr;
+  desc_ptr     = TDBuffer;
+  
+  ser_int_found = 0;
+  
+  m_vid = *((USB_INT16U*)&desc_ptr[8]);
+  m_pid = *((USB_INT16U*)&desc_ptr[10]);
+  
+  if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_DEVICE) {   
+      PRINT_Log("\r\nLen = %02x\r\n",desc_ptr[0]);
+      PRINT_Log("\r\nDesc code %02x\r\n",desc_ptr[1]);
+      return (ERR_BAD_CONFIGURATION);
+  }
+  
+  if( m_vid == 0x12d1 &&//Huawei : Change
+      m_pid == 0x1446 )
+  {
+    PRINT_Log("\r\nHuawei device found in CDFS mode\r\n");
+    ser_int_found=3;
+  }
+  else if(  m_vid == 0x12d1 &&//Huawei : Change
+            m_pid == 0x1001 )
+  {
+    PRINT_Log("\r\nHuawei device found in Serial mode\r\n");
+    ser_int_found=1;
+  }
+  else if(  m_vid  == 0x0af0 &&//Voda?Qualcomm? : Change
+            m_pid == 0x7501 )
+  {
+    PRINT_Log("\r\nVodafone K3760 found, checking mode...\r\n");
+    ser_int_found=3;
+  }
+  else if(  m_vid  == 0x12d1 &&//Voda?Qualcomm? : Change
+            m_pid == 0x1003 )
+  {
+    PRINT_Log("\r\nHuawei device found, checking mode...\r\n");
+    ser_int_found=3;
+  }
+  else
+  {
+    PRINT_Log("\r\nDevice %04x : %04x found.\r\n",m_vid,m_pid);                
+  }
+  return OK;
+}
+
+USB_INT32S SerialParseConfig()
+{
+    volatile  USB_INT08U  *desc_ptr;
+
+    desc_ptr     = TDBuffer;
+
+    if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {    
+        return (ERR_BAD_CONFIGURATION);
+    }
+    desc_ptr += desc_ptr[0];
+    
+    int epOut = 0;
+    int epIn = 0;
+
+    pEpOut = NULL;
+    pEpIn = NULL;
+    while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) {
+
+        switch (desc_ptr[1]) {
+            case USB_DESCRIPTOR_TYPE_INTERFACE: 
+                 PRINT_Log("\r\nIf %02x:%02x:%02x.\r\n",desc_ptr[5],desc_ptr[6],desc_ptr[7]);
+                 if (desc_ptr[5] == 0xFF &&             
+                     desc_ptr[6] == 0xFF &&     
+                     desc_ptr[7] == 0xFF ) {       
+                     //if(ser_int_found==1)
+                     ser_int_found=2;
+                 }
+                 desc_ptr    += desc_ptr[0];                      /* Move to next descriptor start      */
+                 break;
+
+            case USB_DESCRIPTOR_TYPE_ENDPOINT:                        /* If it is an endpoint descriptor    */
+                 PRINT_Log("\r\nEp %02x of size %d.\r\n", desc_ptr[2], (ReadLE16U(&desc_ptr[4]) ));
+                 if ( SerialHasToSwitch() )
+                 {
+                   if( pEpOut == NULL /*desc_ptr[2] == 1*/) //EP 1
+                   {
+                   #if 0
+                         EDBulkOut->Control = 1                             |      /* USB address           */
+                                              ((desc_ptr[2] & 0x7F) << 7)   |      /* Endpoint address      */
+                                              (1 << 11)                     |      /* direction             */
+                                              (ReadLE16U(&desc_ptr[4]) << 16);     /* MaxPkt Size           */
+                   #endif
+                     pEpOut = new UsbEndpoint((desc_ptr[2] & 0x7F), false, ReadLE16U(&desc_ptr[4]));
+                   }
+                   desc_ptr += desc_ptr[0];                     /* Move to next descriptor start      */
+                 }
+                 else if ((desc_ptr[3] & 0x03) == 0x02) {                  /* If it is Bulk endpoint             */
+                     if (desc_ptr[2] & 0x80) {                        /* If it is In endpoint               */
+                       if(epIn == 0)
+                       {
+                         PRINT_Log("\r\nEp %02x is in ep.\r\n", desc_ptr[2]);
+                       #if 0
+                         EDBulkIn->Control =  1                             |      /* USB address           */
+                                              ((desc_ptr[2] & 0x7F) << 7)   |      /* Endpoint address      */
+                                              (2 << 11)                     |      /* direction             */
+                                              (ReadLE16U(&desc_ptr[4]) << 16);     /* MaxPkt Size           */
+                       #endif
+                       // pEpIn = new UsbEndpoint((desc_ptr[2] & 0x7F), true, ReadLE16U(&desc_ptr[4]));
+                       }
+                       epIn++;
+                       desc_ptr += desc_ptr[0];                     /* Move to next descriptor start      */
+                     } else {                                         /* If it is Out endpoint              */
+                       if(epOut == 0)
+                       {
+                         PRINT_Log("\r\nEp %02x is out ep.\r\n", desc_ptr[2]);
+                       #if 0
+                         EDBulkOut->Control = 1                             |      /* USB address           */
+                                              ((desc_ptr[2] & 0x7F) << 7)   |      /* Endpoint address      */
+                                              (1 << 11)                     |      /* direction             */
+                                              (ReadLE16U(&desc_ptr[4]) << 16);     /* MaxPkt Size           */
+                       #endif
+                        // pEpOut = new UsbEndpoint((desc_ptr[2] & 0x7F), false, ReadLE16U(&desc_ptr[4]));
+                       }
+                       epOut++;
+                       desc_ptr += desc_ptr[0];                     /* Move to next descriptor start      */
+                     }
+                 } else {                                             /* If it is not bulk end point        */
+                     desc_ptr += desc_ptr[0];                         /* Move to next descriptor start      */
+                 }
+                 break;
+
+            default:                                 /* If the descriptor is neither interface nor endpoint */
+                 desc_ptr += desc_ptr[0];                             /* Move to next descriptor start      */
+                 break;
+        }
+    }
+    if (ser_int_found==2) {
+        PRINT_Log("Virtual Serial Port device %04x:%04x connected, vid=%d, pid=%d, E220=%d\n", m_vid, m_pid, ( m_vid  == 0x12d1 ), ( m_pid == 0x1003 ), (( m_vid  == 0x12d1 ) && ( m_pid == 0x1003 )));
+      if(m_vid==0x0af0) //Voda
+      {
+        pEpOut = new UsbEndpoint((0x0a & 0x7F), false, 64);
+        pEpIn = new UsbEndpoint((0x8b & 0x7F), true, 64);
+        PRINT_Log("Voda K3760\r\n");
+      }
+      else //if ( ( m_vid  == 0x12d1 ) && ( m_pid == 0x1003 ) )
+      /*{*/
+      if ( ( m_vid  == 0x12d1 ) && ( m_pid == 0x1003 ) )
+      {
+        pEpOut = new UsbEndpoint((0x02 & 0x7F), false, 64);
+        pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64);
+        PRINT_Log("Huawei E220\r\n");
+      }
+      /*else
+      {
+        if(( m_vid  == 0x12d1 ))
+           PRINT_Log("VID OK\r\n");
+        else
+           PRINT_Log("VID NOK\r\n");
+        if(( m_pid  == 0x1003 ))
+           PRINT_Log("VID OK\r\n");
+        else
+           PRINT_Log("VID NOK\r\n");
+        PRINT_Log("\r\n....\r\n\r\n");
+        error("\r\n\r\n");
+      }*/
+      //} 
+      #if 1
+      else /*if (  m_vid  == 0x12d1 &&
+            m_pid == 0x1001 )*/
+      {
+        pEpOut = new UsbEndpoint((0x01 & 0x7F), false, 64);
+        pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64); 
+        PRINT_Log("Huawei E1550\r\n");
+      }   
+      #endif
+        
+        PRINT_Log("Virtual Serial Port device %04x:%04x connected\n", m_vid, m_pid);
+        return (OK);
+    }
+    else if (ser_int_found==3) {
+        PRINT_Log("CDFS dongle connected, reset\n");
+        return (OK);
+    } else {
+        PRINT_Log("Not a Virtual Serial Port device\n");
+        return (ERR_NO_MS_INTERFACE);
+    }
+}
+
+
+USB_INT32S SerialRx( volatile USB_INT08U* buf, USB_INT32U len )
+{
+    USB_INT32S rc;
+    rc = pEpIn->transfer(buf, len);
+    return rc;
+}
+
+USB_INT32S SerialReceived()
+{
+  return pEpIn->status();
+}
+
+USB_INT32S SerialTx( volatile USB_INT08U* buf, USB_INT32U len )
+{
+    USB_INT32S rc;
+    rc = pEpOut->transfer(buf, len);
+  //  PRINT_Log("\r\nOut rc = %d\r\n",len);
+    return rc;
+}
+
+USB_INT32S SerialTransmitted()
+{
+  USB_INT32S rc = pEpOut->status();
+/*  if(rc>=0)
+  {
+      PRINT_Log("\r\nTransmitted %d\r\n",rc);
+  }*/
+  return rc;
+}
+
+USB_INT32S SerialReg(USB_INT16U vid, USB_INT16U pid) {return 0;}
+
+#endif