Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: drv/serial/usb/usbserialif.cpp
- Revision:
- 0:355018f44c9f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drv/serial/usb/usbserialif.cpp Wed Jul 21 19:25:56 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