NetServices Stack source
Dependents: HelloWorld ServoInterfaceBoardExample1 4180_Lab4
Diff: drv/serial/usb/usbserialif.cpp
- Revision:
- 0:632c9925f013
- Child:
- 2:a4f97773c90f
diff -r 000000000000 -r 632c9925f013 drv/serial/usb/usbserialif.cpp --- /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