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

Dependencies:   mbed

Committer:
dirkx
Date:
Sat Aug 14 15:56:01 2010 +0000
Revision:
0:a259777c45a3

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dirkx 0:a259777c45a3 1
dirkx 0:a259777c45a3 2 /*
dirkx 0:a259777c45a3 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
dirkx 0:a259777c45a3 4
dirkx 0:a259777c45a3 5 Permission is hereby granted, free of charge, to any person obtaining a copy
dirkx 0:a259777c45a3 6 of this software and associated documentation files (the "Software"), to deal
dirkx 0:a259777c45a3 7 in the Software without restriction, including without limitation the rights
dirkx 0:a259777c45a3 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
dirkx 0:a259777c45a3 9 copies of the Software, and to permit persons to whom the Software is
dirkx 0:a259777c45a3 10 furnished to do so, subject to the following conditions:
dirkx 0:a259777c45a3 11
dirkx 0:a259777c45a3 12 The above copyright notice and this permission notice shall be included in
dirkx 0:a259777c45a3 13 all copies or substantial portions of the Software.
dirkx 0:a259777c45a3 14
dirkx 0:a259777c45a3 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dirkx 0:a259777c45a3 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dirkx 0:a259777c45a3 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
dirkx 0:a259777c45a3 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dirkx 0:a259777c45a3 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dirkx 0:a259777c45a3 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
dirkx 0:a259777c45a3 21 THE SOFTWARE.
dirkx 0:a259777c45a3 22 */
dirkx 0:a259777c45a3 23
dirkx 0:a259777c45a3 24 /*
dirkx 0:a259777c45a3 25 USB-Serial device driver
dirkx 0:a259777c45a3 26 Donatien Garnier 2010
dirkx 0:a259777c45a3 27 */
dirkx 0:a259777c45a3 28
dirkx 0:a259777c45a3 29 #include "usbserialif.h"
dirkx 0:a259777c45a3 30 #include "drv/usb/UsbEndpoint.h"
dirkx 0:a259777c45a3 31
dirkx 0:a259777c45a3 32 #include "netCfg.h"
dirkx 0:a259777c45a3 33 #if NET_USB_SERIAL
dirkx 0:a259777c45a3 34
dirkx 0:a259777c45a3 35 UsbEndpoint* pEpIn;
dirkx 0:a259777c45a3 36 UsbEndpoint* pEpOut;
dirkx 0:a259777c45a3 37
dirkx 0:a259777c45a3 38 #define DONGLE_STATE_UNKNOWN 0
dirkx 0:a259777c45a3 39 #define DONGLE_STATE_CDFS 1
dirkx 0:a259777c45a3 40 #define DONGLE_STATE_SERIAL 2
dirkx 0:a259777c45a3 41
dirkx 0:a259777c45a3 42 USB_INT08U dongleState;
dirkx 0:a259777c45a3 43
dirkx 0:a259777c45a3 44 USB_INT32S SerialInit()
dirkx 0:a259777c45a3 45 {
dirkx 0:a259777c45a3 46 dongleState = DONGLE_STATE_UNKNOWN;
dirkx 0:a259777c45a3 47 Host_Init(); // Initialize the host controller
dirkx 0:a259777c45a3 48 USB_INT32S rc = Host_EnumDev(); // Enumerate the device connected
dirkx 0:a259777c45a3 49 if (rc != OK)
dirkx 0:a259777c45a3 50 {
dirkx 0:a259777c45a3 51 fprintf(stderr, "Could not enumerate device: %d\n", rc);
dirkx 0:a259777c45a3 52 return rc;
dirkx 0:a259777c45a3 53 }
dirkx 0:a259777c45a3 54 return OK;
dirkx 0:a259777c45a3 55 }
dirkx 0:a259777c45a3 56
dirkx 0:a259777c45a3 57 bool SerialHasToSwitch()
dirkx 0:a259777c45a3 58 {
dirkx 0:a259777c45a3 59 return (dongleState == DONGLE_STATE_CDFS);
dirkx 0:a259777c45a3 60 }
dirkx 0:a259777c45a3 61
dirkx 0:a259777c45a3 62 uint16_t m_vid;
dirkx 0:a259777c45a3 63 uint16_t m_pid;
dirkx 0:a259777c45a3 64
dirkx 0:a259777c45a3 65 USB_INT32S SerialSendMagic()
dirkx 0:a259777c45a3 66 {
dirkx 0:a259777c45a3 67 bool scsi = false;
dirkx 0:a259777c45a3 68 //Size 31
dirkx 0:a259777c45a3 69 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 };
dirkx 0:a259777c45a3 70 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 };
dirkx 0:a259777c45a3 71 char* magic;
dirkx 0:a259777c45a3 72 USB_INT32S rc;
dirkx 0:a259777c45a3 73 if((m_vid == 0x12d1) && (m_pid == 0x1446))
dirkx 0:a259777c45a3 74 {
dirkx 0:a259777c45a3 75 PRINT_Log("\r\nHuawei magic packet sent.\r\n");
dirkx 0:a259777c45a3 76 magic = (char*) magicHuawei;
dirkx 0:a259777c45a3 77 scsi = true;
dirkx 0:a259777c45a3 78 }
dirkx 0:a259777c45a3 79 else if((m_vid == 0x12d1) && (m_pid == 0x1003))
dirkx 0:a259777c45a3 80 {
dirkx 0:a259777c45a3 81 PRINT_Log("\r\nHuawei magic control packet sent.\r\n");
dirkx 0:a259777c45a3 82 rc = Host_CtrlSend( 0 /*USB_TYPE_STANDARD | USB_RECIP_DEVICE*/, 0x03 /*USB_REQ_SET_FEATURE*/, 00000001, 0, 0, NULL);
dirkx 0:a259777c45a3 83 }
dirkx 0:a259777c45a3 84 else if(m_vid == 0x0af0)
dirkx 0:a259777c45a3 85 {
dirkx 0:a259777c45a3 86 PRINT_Log("\r\nVoda magic packet sent.\r\n");
dirkx 0:a259777c45a3 87 magic = (char*) magicVoda;
dirkx 0:a259777c45a3 88 scsi = true;
dirkx 0:a259777c45a3 89 }
dirkx 0:a259777c45a3 90 else
dirkx 0:a259777c45a3 91 {
dirkx 0:a259777c45a3 92 return -1;
dirkx 0:a259777c45a3 93 }
dirkx 0:a259777c45a3 94
dirkx 0:a259777c45a3 95 if(scsi)
dirkx 0:a259777c45a3 96 {
dirkx 0:a259777c45a3 97 rc = pEpOut->transfer((volatile USB_INT08U*)magic, 31);
dirkx 0:a259777c45a3 98 while(rc == PROCESSING)
dirkx 0:a259777c45a3 99 {
dirkx 0:a259777c45a3 100 rc = pEpOut->status();
dirkx 0:a259777c45a3 101 }
dirkx 0:a259777c45a3 102 }
dirkx 0:a259777c45a3 103
dirkx 0:a259777c45a3 104 delete pEpOut;
dirkx 0:a259777c45a3 105 pEpOut = NULL;
dirkx 0:a259777c45a3 106 return rc;
dirkx 0:a259777c45a3 107 }
dirkx 0:a259777c45a3 108
dirkx 0:a259777c45a3 109 USB_INT32S SerialCheckVidPid()
dirkx 0:a259777c45a3 110 {
dirkx 0:a259777c45a3 111 volatile USB_INT08U *desc_ptr;
dirkx 0:a259777c45a3 112 desc_ptr = TDBuffer;
dirkx 0:a259777c45a3 113
dirkx 0:a259777c45a3 114 ser_int_found = 0;
dirkx 0:a259777c45a3 115
dirkx 0:a259777c45a3 116 m_vid = *((USB_INT16U*)&desc_ptr[8]);
dirkx 0:a259777c45a3 117 m_pid = *((USB_INT16U*)&desc_ptr[10]);
dirkx 0:a259777c45a3 118
dirkx 0:a259777c45a3 119 if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_DEVICE) {
dirkx 0:a259777c45a3 120 PRINT_Log("\r\nLen = %02x\r\n",desc_ptr[0]);
dirkx 0:a259777c45a3 121 PRINT_Log("\r\nDesc code %02x\r\n",desc_ptr[1]);
dirkx 0:a259777c45a3 122 return (ERR_BAD_CONFIGURATION);
dirkx 0:a259777c45a3 123 }
dirkx 0:a259777c45a3 124
dirkx 0:a259777c45a3 125 if( m_vid == 0x12d1 &&//Huawei : Change
dirkx 0:a259777c45a3 126 m_pid == 0x1446 )
dirkx 0:a259777c45a3 127 {
dirkx 0:a259777c45a3 128 PRINT_Log("\r\nHuawei device found in CDFS mode\r\n");
dirkx 0:a259777c45a3 129 dongleState = DONGLE_STATE_CDFS;
dirkx 0:a259777c45a3 130 }
dirkx 0:a259777c45a3 131 else if( m_vid == 0x12d1 &&//Huawei : Change
dirkx 0:a259777c45a3 132 m_pid == 0x1001 )
dirkx 0:a259777c45a3 133 {
dirkx 0:a259777c45a3 134 PRINT_Log("\r\nHuawei device found in Serial mode\r\n");
dirkx 0:a259777c45a3 135 dongleState = DONGLE_STATE_SERIAL;
dirkx 0:a259777c45a3 136 }
dirkx 0:a259777c45a3 137 else if( m_vid == 0x0af0 &&//Voda?Qualcomm? : Change
dirkx 0:a259777c45a3 138 m_pid == 0x7501 )
dirkx 0:a259777c45a3 139 {
dirkx 0:a259777c45a3 140 PRINT_Log("\r\nVodafone K3760 found, checking mode...\r\n");
dirkx 0:a259777c45a3 141 dongleState = DONGLE_STATE_UNKNOWN;
dirkx 0:a259777c45a3 142 }
dirkx 0:a259777c45a3 143 else if( m_vid == 0x12d1 &&//Voda?Qualcomm? : Change
dirkx 0:a259777c45a3 144 m_pid == 0x1003 )
dirkx 0:a259777c45a3 145 {
dirkx 0:a259777c45a3 146 PRINT_Log("\r\nHuawei device found, checking mode...\r\n");
dirkx 0:a259777c45a3 147 dongleState = DONGLE_STATE_UNKNOWN;
dirkx 0:a259777c45a3 148 }
dirkx 0:a259777c45a3 149 else
dirkx 0:a259777c45a3 150 {
dirkx 0:a259777c45a3 151 PRINT_Log("\r\nDevice %04x : %04x found.\r\n",m_vid,m_pid);
dirkx 0:a259777c45a3 152 }
dirkx 0:a259777c45a3 153 return OK;
dirkx 0:a259777c45a3 154 }
dirkx 0:a259777c45a3 155
dirkx 0:a259777c45a3 156 USB_INT32S SerialParseConfig()
dirkx 0:a259777c45a3 157 {
dirkx 0:a259777c45a3 158 volatile USB_INT08U *desc_ptr;
dirkx 0:a259777c45a3 159
dirkx 0:a259777c45a3 160 desc_ptr = TDBuffer;
dirkx 0:a259777c45a3 161
dirkx 0:a259777c45a3 162 if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {
dirkx 0:a259777c45a3 163 return (ERR_BAD_CONFIGURATION);
dirkx 0:a259777c45a3 164 }
dirkx 0:a259777c45a3 165 desc_ptr += desc_ptr[0];
dirkx 0:a259777c45a3 166
dirkx 0:a259777c45a3 167 int epOut = 0;
dirkx 0:a259777c45a3 168 int epIn = 0;
dirkx 0:a259777c45a3 169
dirkx 0:a259777c45a3 170 pEpOut = NULL;
dirkx 0:a259777c45a3 171 pEpIn = NULL;
dirkx 0:a259777c45a3 172 while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) {
dirkx 0:a259777c45a3 173
dirkx 0:a259777c45a3 174 switch (desc_ptr[1]) {
dirkx 0:a259777c45a3 175 case USB_DESCRIPTOR_TYPE_INTERFACE:
dirkx 0:a259777c45a3 176 PRINT_Log("\r\nIf %02x:%02x:%02x.\r\n",desc_ptr[5],desc_ptr[6],desc_ptr[7]);
dirkx 0:a259777c45a3 177 if (desc_ptr[5] == 0xFF &&
dirkx 0:a259777c45a3 178 desc_ptr[6] == 0xFF &&
dirkx 0:a259777c45a3 179 desc_ptr[7] == 0xFF ) {
dirkx 0:a259777c45a3 180 dongleState = DONGLE_STATE_SERIAL;
dirkx 0:a259777c45a3 181 }
dirkx 0:a259777c45a3 182 else
dirkx 0:a259777c45a3 183 if (desc_ptr[5] == 0xFF &&
dirkx 0:a259777c45a3 184 desc_ptr[6] == 0xFF &&
dirkx 0:a259777c45a3 185 desc_ptr[7] == 0xFF ) {
dirkx 0:a259777c45a3 186 dongleState = DONGLE_STATE_CDFS;
dirkx 0:a259777c45a3 187 }
dirkx 0:a259777c45a3 188 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
dirkx 0:a259777c45a3 189 break;
dirkx 0:a259777c45a3 190
dirkx 0:a259777c45a3 191 case USB_DESCRIPTOR_TYPE_ENDPOINT: /* If it is an endpoint descriptor */
dirkx 0:a259777c45a3 192 PRINT_Log("\r\nEp %02x of size %d.\r\n", desc_ptr[2], (ReadLE16U(&desc_ptr[4]) ));
dirkx 0:a259777c45a3 193 if ( SerialHasToSwitch() )
dirkx 0:a259777c45a3 194 {
dirkx 0:a259777c45a3 195 if( (dongleState == DONGLE_STATE_CDFS) && (pEpOut == NULL) /*desc_ptr[2] == 1*/) //EP 1
dirkx 0:a259777c45a3 196 {
dirkx 0:a259777c45a3 197 pEpOut = new UsbEndpoint((desc_ptr[2] & 0x7F), false, ReadLE16U(&desc_ptr[4]));
dirkx 0:a259777c45a3 198 }
dirkx 0:a259777c45a3 199 /* Move to next descriptor start */
dirkx 0:a259777c45a3 200 }
dirkx 0:a259777c45a3 201 desc_ptr += desc_ptr[0];
dirkx 0:a259777c45a3 202 break;
dirkx 0:a259777c45a3 203
dirkx 0:a259777c45a3 204 default: /* If the descriptor is neither interface nor endpoint */
dirkx 0:a259777c45a3 205 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
dirkx 0:a259777c45a3 206 break;
dirkx 0:a259777c45a3 207 }
dirkx 0:a259777c45a3 208 }
dirkx 0:a259777c45a3 209 if (dongleState == DONGLE_STATE_SERIAL) {
dirkx 0:a259777c45a3 210 PRINT_Log("Virtual Serial Port device %04x:%04x connected, vid=%d, pid=%d\n", m_vid, m_pid);
dirkx 0:a259777c45a3 211 if(m_vid==0x0af0) //Voda
dirkx 0:a259777c45a3 212 {
dirkx 0:a259777c45a3 213 pEpOut = new UsbEndpoint((0x0a & 0x7F), false, 64);
dirkx 0:a259777c45a3 214 pEpIn = new UsbEndpoint((0x8b & 0x7F), true, 64);
dirkx 0:a259777c45a3 215 PRINT_Log("Voda K3760\r\n");
dirkx 0:a259777c45a3 216 }
dirkx 0:a259777c45a3 217 else //if ( ( m_vid == 0x12d1 ) && ( m_pid == 0x1003 ) )
dirkx 0:a259777c45a3 218 /*{*/
dirkx 0:a259777c45a3 219 if ( ( m_vid == 0x12d1 ) && ( m_pid == 0x1003 ) )
dirkx 0:a259777c45a3 220 {
dirkx 0:a259777c45a3 221 pEpOut = new UsbEndpoint((0x02 & 0x7F), false, 64);
dirkx 0:a259777c45a3 222 pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64);
dirkx 0:a259777c45a3 223 PRINT_Log("Huawei E220\r\n");
dirkx 0:a259777c45a3 224 }
dirkx 0:a259777c45a3 225 else /*if ( m_vid == 0x12d1 &&
dirkx 0:a259777c45a3 226 m_pid == 0x1001 )*/
dirkx 0:a259777c45a3 227 {
dirkx 0:a259777c45a3 228 pEpOut = new UsbEndpoint((0x01 & 0x7F), false, 64);
dirkx 0:a259777c45a3 229 pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64);
dirkx 0:a259777c45a3 230 PRINT_Log("Huawei E1550\r\n");
dirkx 0:a259777c45a3 231 }
dirkx 0:a259777c45a3 232
dirkx 0:a259777c45a3 233 PRINT_Log("Virtual Serial Port device %04x:%04x connected\n", m_vid, m_pid);
dirkx 0:a259777c45a3 234 return (OK);
dirkx 0:a259777c45a3 235 }
dirkx 0:a259777c45a3 236 else if (dongleState == DONGLE_STATE_CDFS) {
dirkx 0:a259777c45a3 237 PRINT_Log("CDFS dongle connected, reset\n");
dirkx 0:a259777c45a3 238 return (OK);
dirkx 0:a259777c45a3 239 } else {
dirkx 0:a259777c45a3 240 PRINT_Log("Not a Virtual Serial Port device\n");
dirkx 0:a259777c45a3 241 return (ERR_NO_MS_INTERFACE);
dirkx 0:a259777c45a3 242 }
dirkx 0:a259777c45a3 243 }
dirkx 0:a259777c45a3 244
dirkx 0:a259777c45a3 245
dirkx 0:a259777c45a3 246 USB_INT32S SerialRx( volatile USB_INT08U* buf, USB_INT32U len )
dirkx 0:a259777c45a3 247 {
dirkx 0:a259777c45a3 248 USB_INT32S rc;
dirkx 0:a259777c45a3 249 rc = pEpIn->transfer(buf, len);
dirkx 0:a259777c45a3 250 return rc;
dirkx 0:a259777c45a3 251 }
dirkx 0:a259777c45a3 252
dirkx 0:a259777c45a3 253 USB_INT32S SerialReceived()
dirkx 0:a259777c45a3 254 {
dirkx 0:a259777c45a3 255 return pEpIn->status();
dirkx 0:a259777c45a3 256 }
dirkx 0:a259777c45a3 257
dirkx 0:a259777c45a3 258 USB_INT32S SerialTx( volatile USB_INT08U* buf, USB_INT32U len )
dirkx 0:a259777c45a3 259 {
dirkx 0:a259777c45a3 260 USB_INT32S rc;
dirkx 0:a259777c45a3 261 rc = pEpOut->transfer(buf, len);
dirkx 0:a259777c45a3 262 // PRINT_Log("\r\nOut rc = %d\r\n",len);
dirkx 0:a259777c45a3 263 return rc;
dirkx 0:a259777c45a3 264 }
dirkx 0:a259777c45a3 265
dirkx 0:a259777c45a3 266 USB_INT32S SerialTransmitted()
dirkx 0:a259777c45a3 267 {
dirkx 0:a259777c45a3 268 USB_INT32S rc = pEpOut->status();
dirkx 0:a259777c45a3 269 /* if(rc>=0)
dirkx 0:a259777c45a3 270 {
dirkx 0:a259777c45a3 271 PRINT_Log("\r\nTransmitted %d\r\n",rc);
dirkx 0:a259777c45a3 272 }*/
dirkx 0:a259777c45a3 273 return rc;
dirkx 0:a259777c45a3 274 }
dirkx 0:a259777c45a3 275
dirkx 0:a259777c45a3 276 USB_INT32S SerialReg(USB_INT16U vid, USB_INT16U pid) {return 0;}
dirkx 0:a259777c45a3 277
dirkx 0:a259777c45a3 278 #endif