Example self-announcing webserver which controls a servo through a smallHTML userinterface.

Dependencies:   mbed

Revision:
0:a259777c45a3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drv/serial/usb/usbserialif.cpp	Sat Aug 14 15:56:01 2010 +0000
@@ -0,0 +1,278 @@
+
+/*
+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;
+
+#define DONGLE_STATE_UNKNOWN 0
+#define DONGLE_STATE_CDFS    1
+#define DONGLE_STATE_SERIAL  2
+
+USB_INT08U dongleState;
+
+USB_INT32S SerialInit()
+{
+  dongleState = DONGLE_STATE_UNKNOWN;
+  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 (dongleState == DONGLE_STATE_CDFS);
+}
+
+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 = pEpOut->transfer((volatile USB_INT08U*)magic, 31);
+    while(rc == PROCESSING)
+    {
+      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");
+    dongleState = DONGLE_STATE_CDFS;
+  }
+  else if(  m_vid == 0x12d1 &&//Huawei : Change
+            m_pid == 0x1001 )
+  {
+    PRINT_Log("\r\nHuawei device found in Serial mode\r\n");
+    dongleState = DONGLE_STATE_SERIAL;
+  }
+  else if(  m_vid  == 0x0af0 &&//Voda?Qualcomm? : Change
+            m_pid == 0x7501 )
+  {
+    PRINT_Log("\r\nVodafone K3760 found, checking mode...\r\n");
+    dongleState = DONGLE_STATE_UNKNOWN;
+  }
+  else if(  m_vid  == 0x12d1 &&//Voda?Qualcomm? : Change
+            m_pid == 0x1003 )
+  {
+    PRINT_Log("\r\nHuawei device found, checking mode...\r\n");
+    dongleState = DONGLE_STATE_UNKNOWN;
+  }
+  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 ) {       
+                   dongleState = DONGLE_STATE_SERIAL;
+                 }
+                 else 
+                 if (desc_ptr[5] == 0xFF &&             
+                     desc_ptr[6] == 0xFF &&     
+                     desc_ptr[7] == 0xFF ) {       
+                   dongleState = DONGLE_STATE_CDFS;
+                 }
+                 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( (dongleState == DONGLE_STATE_CDFS) && (pEpOut == NULL) /*desc_ptr[2] == 1*/) //EP 1
+                   {
+                     pEpOut = new UsbEndpoint((desc_ptr[2] & 0x7F), false, ReadLE16U(&desc_ptr[4]));
+                   }
+                                      /* Move to next descriptor start      */
+                 }
+                 desc_ptr += desc_ptr[0];  
+                 break;
+
+            default:                                 /* If the descriptor is neither interface nor endpoint */
+                 desc_ptr += desc_ptr[0];                             /* Move to next descriptor start      */
+                 break;
+        }
+    }
+    if (dongleState == DONGLE_STATE_SERIAL) {
+        PRINT_Log("Virtual Serial Port device %04x:%04x connected, vid=%d, pid=%d\n", m_vid, m_pid);
+      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 &&
+            m_pid == 0x1001 )*/
+      {
+        pEpOut = new UsbEndpoint((0x01 & 0x7F), false, 64);
+        pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64); 
+        PRINT_Log("Huawei E1550\r\n");
+      }   
+        
+        PRINT_Log("Virtual Serial Port device %04x:%04x connected\n", m_vid, m_pid);
+        return (OK);
+    }
+    else if (dongleState == DONGLE_STATE_CDFS) {
+        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