Changing USB mode of device

That did it, thanks! TCP works great. Quite amazing how little work is required to get all this going, you guys build an amazing product and have amazing support!

I’ll write up a small tutorial on how to get things going with the info provided for Linux’s usb_modeswitch…

I am so impressed how you could do a driver for this USB modem. ::slight_smile:

I am looking forward to see the tutorial. I would also love to see a video on how you use this modem to access the internet on FEZ Cobra. It is very important to show the community this amazing feature.

Mike…

I am trying to connect a At&T Serra modem (USB Connect Mercury)

28:27:St:Device connected…
28:27:St:ID: 600781056, Interface: 255, Type: 14

I took your code and put it on the latest 4.1 and it is missing assembly references etc…
How do I proceed

        static void DeviceConnectedEvent(USBH_Device device)
        {
                DispPrint("Device connected...");
                DispPrint("ID: " + device.ID + ", Interface: " + device.INTERFACE_INDEX + ", Type: " + device.TYPE);

                u= new USBH_RawDevice(device);
                USBH_Descriptors.Configuration cd = u.GetConfigurationDescriptors(0);
                u.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);
                // you have look for endpoint # 5 (bEndpointAddress must be 5), look into the "cd" in Visual Studio debugger or write a a for loop...
                USBH_Descriptors.Endpoint e = cd.interfaces[some endpoint].endpoints[some endpoint];
                Pipe p = u.OpenPipe(e);
                p.Write(MessageContent );
         }

Any updates please…I wanted to get this modem working. and I am stuck

Missing assembly references? What exactly is the error? You can just add them…
Also, you have to look at how your device works. This might be different!
Do you have a USB network analyzer on your PC? You can see the traffic and what packets they use to switch the mode…
Do you have other description of your modem? (part numbers or documentations, source code…)

I dig around somemore and looks like this gets printed

            else if (device.TYPE == USBH_DeviceType.Sierra_Installer)
            {
                DispPrint("Sierra_Installer Connected");
            }

Since you guys detect this. Looks like it would work.
Would you point me to some sample code that I can run after this

I think after changing the mode of the sierra, it will not be standard serial port, so you cannot use it.
We are looking to see how to support this…

Hey all,

I am trying to do something very similar for my senior design project for school. I would appreciate any help with a problem I am having.

I am trying to interface a Telit UC864-G via usb to my FEZ Cobra.
(Module) http://www.semiconductorstore.com/cart/pc/viewPrd.asp?idproduct=43555
(Interface board I am using) http://www.semiconductorstore.com/cart/pc/viewPrd.asp?idproduct=42899

I have read all of the hardware and software datasheets for the module and am fairly certain that I have it hooked up correctly. It works pretty well when connected to my pc using their proprietary drivers. What I am less certain of is writing my own custom driver to allow interfacing with my Cobra.

In the datasheet it says there are 4 serial interfaces to the modem available via usb. This seems correct because when the device is connected to my windows PC using their proprietary drivers there are 4 new devices in device manager: 3 serial ports and 1 modem.

The devices are the following:
MODEM USB SERIAL PORT
AUX USB SERIAL PORT
NMEA USB SERIAL PORT
DIAGNOSTICS INTERFACE SERIAL PORT

To start off I examined the output of this program, which seems to me immensely helpful
http://www.fezzer.com/project/164/usb-discovery-helper/

The output is listed below, and I think I have identified the various different devices by observing their hardware profiles on my PC versus the output of this program:

[quote][Device, Port 0]
Type: Unknown
ProductID: 4100
VendorID: 7111
=== Interface ===
Class: Vendor Specific
SubClass: 255
Number: 0 italic[/italic]
Protocol: 255
Type: 4
– Endpoint –
Attributes: 3
Address: 129
Type: 5
Interval: 128

– Endpoint –
Attributes: 2
Address: 130
Type: 5
Interval: 0

– Endpoint –
Attributes: 2
Address: 2
Type: 5
Interval: 0

=== Interface ===
Class: Vendor Specific
SubClass: 255
Number: 1 [italic](DIAGNOSTICS INTERFACE)[/italic]
Protocol: 255
Type: 4
– Endpoint –
Attributes: 2
Address: 132
Type: 5
Interval: 0

– Endpoint –
Attributes: 2
Address: 4
Type: 5
Interval: 0

=== Interface ===
Class: Vendor Specific
SubClass: 255
Number: 2 [italic](NMEA PORT)[/italic]
Protocol: 255
Type: 4
– Endpoint –
Attributes: 2
Address: 133
Type: 5
Interval: 0

– Endpoint –
Attributes: 2
Address: 5
Type: 5
Interval: 0

=== Interface ===
Class: Vendor Specific
SubClass: 255
Number: 3 [italic](AUXILLIARY PORT)[/italic]
Protocol: 255
Type: 4
– Endpoint –
Attributes: 2
Address: 131
Type: 5
Interval: 0

– Endpoint –
Attributes: 2
Address: 3
Type: 5
Interval: 0[/quote]

Now down to my problem:
I cannot seem to isolate those serial interfaces. I do not have a ton of experience writing drivers for USB devices, but my code below seems like it might be close to correct from what I have read (in this thread, and other places)


namespace FEZ_Cobra_Console_Application1
{
    class TelitDriver
    {
        USBH_RawDevice controller;

        USBH_Device modemModule;
        USBH_SerialUSB modemSerial;
        USBH_Device nmeaReadings; //GPS, in NMEA Format
        USBH_SerialUSB nmeaSerial;
        //USBH_Device diagnosticInterface;
        //USBH_Device auxilliaryPort;

        public TelitDriver()
        {
            USBHostController.DeviceConnectedEvent += DeviceConnectedEvent;
        }

        void DeviceConnectedEvent(USBH_Device device)
        {
            Debug.Print("[Device, Port " + device.PORT_NUMBER + "], ID: " + device.ID);
            controller = new USBH_RawDevice(device);
            //Debug.Print("Type: " + DeviceTypeToString(device.TYPE));
            Debug.Print("ProductID: " + controller.PRODUCT_ID);
            Debug.Print("VendorID: " + controller.VENDOR_ID);

            //dont need to verify types of anything because I am only using this device for now
            try
            {
                if (nmeaReadings == null)
                {
                    nmeaReadings = new USBH_Device(device.ID, 2, device.TYPE, 7111, 4100, 0);
                    nmeaSerial = new USBH_SerialUSB(nmeaReadings, 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
                }

                if (modemModule == null)
                {
                    modemModule = new USBH_Device(device.ID, 0, device.TYPE, 7111, 4100, 0);
                    modemSerial = new USBH_SerialUSB(modemModule, 115200, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
                }

                //Cannot get past this point to go ahead and initialize the modem, as in the PPP example online

            }
            catch (Exception ea)
            {
                Debug.Print("Problem initializing USB Modem: " + ea.Message);
            }
        }
    }
}

I keep getting exceptions when I try and make the serial port object. Does anyone have any idea what step I am missing here? Maybe it is appropriate to send something to the interfaces before I initialize the port? If so, what is that typically?

Any help is appreciated. Thanks

You have to use the USBH_RawDevice. Please see the example in the library documentation.

Then you can use the modem anyway you like. Send text messages for example, but note that you cannot use PPP. PPP needs a serial device (FTDI, CDC…)

For your case, try something like this:


static USBH_RawDevice myModem;
static USBH_RawDevice.Pipe writePipe;
static USBH_RawDevice.Pipe readPipe;

static void DeviceConnectedEvent(USBH_Device device)
{
    myModem = new USBH_RawDevice(device);

    // Get descriptors
    USBH_Descriptors.Configuration cd = myModem.GetConfigurationDescriptors(0);

    // set configuration
    myModem.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);

    // communication. Get these from interface and endpoints you provided. So double check below.
    writePipe = myModem.OpenPipe(cd.interfaces[0].endpoints[2]); // third endpoint with address 2
    readPipe = myModem.OpenPipe(cd.interfaces[0].endpoints[1]); // second endpoint with address 130

    // now in your main application you can
    //writePipe.TransferData(...);
    //readPipe.TransferData(...);
}

Mike, thank you very much for your quick reply

That is unfortunate that I will not be able to use ppp via usb. Thanks for the alternative suggestion

I will take the suggestion a step further:
Then might it be possible/practical to extend the serial class with my own, overriding the implementation with my own virtual layer that uses the pipes? Then I could feed that to the ppp?

Unfortunately, this is something that we have to change natively. There is no workaround.

Mike,

from the discussions in this thread, I learned very much, so I implemented a function (see below) to manage my usb modem (huawei E122), expecially I added a function to find the end point without knowing the specific address.

static USBH_Descriptors.Endpoint FindEndPoint(byte _Verso,USBH_Descriptors.Endpoint[] EPs)
        {
            //_Verso=0x00 for DIR_OUT
            //_Verso=0x80 for DIR_IN
            foreach (USBH_Descriptors.Endpoint e in EPs)
            {
                if ((e.bmAttributes & 0x03) == 0x02 && (e.bEndpointAddress & 0x80) == _Verso)
                    return e;
            }
            return null;
        }

//.........

case USBH_DeviceType.MassStorage:
                    if (device.PRODUCT_ID == 0x1446 && device.VENDOR_ID == 0x12D1 && device.INTERFACE_INDEX==0)
                    {
                        byte[] init_string = { 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
         
                        USBH_RawDevice u = new USBH_RawDevice(device);
                        USBH_Descriptors.Configuration cd = u.GetConfigurationDescriptors(0);
                        u.SendSetupTransfer(0x00, 0x09, cd.bConfigurationValue, 0x00);
                        USBH_Descriptors.Endpoint e = FindEndPoint(0x00,cd.interfaces[device.INTERFACE_INDEX].endpoints);//[0x01];
                        if (e != null)
                        {
                            USBH_RawDevice.Pipe p = u.OpenPipe(e);
                            p.TransferData(init_string, 0, init_string.Length);
                        }
                    }
                    break;
//.......

It works fine but when I send the messageContent to change the configuration I can see two massstorage and three modems (Product ID: 4097) but with Type:0 (Unknown), so when I try to execute the following code to send AT command it generates an Exception. Can you help me to understand because I receive a device type 0 and why it generates the exception?


try
                        {
                            //USBH_Device modem = new USBH_Device(device.ID,
                            // device.INTERFACE_INDEX,
                            // USBH_DeviceType.Serial_CDC, device.VENDOR_ID,
                            // device.PRODUCT_ID, device.PORT_NUMBER);

                            serialUSB = new USBH_SerialUSB(device, 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
                            serialUSB.Open();
                            serialUSB.Write(new byte[] { 0x41, 0x54, 0x5A, 0x0D, 0x0A }, 0, 4);
                            //SendATW(serialUSB, "AT");
                            //serialUSBThread = new Thread(SerialUSBThread);
                            //serialUSBThread.Start();
                        }catch (Exception ex)
                        {
                            Debug.Print(ex.Message);
                        }

Example of the log:

Device connected
ID: 1073769084,Vendor ID: 4817, Product ID: 4097 Interface: 0, Type: 0
#### Exception System.Exception - 0xffffffff (3) ####
#### Message:
#### GHIElectronics.NETMF.USBHost.USBH_SerialUSB::Write_Helper [IP: 0000] ####
#### GHIElectronics.NETMF.USBHost.USBH_SerialUSB::Write [IP: 001a] ####
#### ITE_DominoTest.Program::DeviceConnectedEvent [IP: 0225] ####
#### GHIElectronics.NETMF.USBHost.USBH_DeviceConnectionEventHandler::Invoke [IP: 53e1a] ####
#### GHIElectronics.NETMF.USBHost.USBHostController::nativeEventDispatcher_OnInterrupt [IP: 0037] ####
#### GHIElectronics.NETMF.System.InternalEvent::nativeEventDispatcher_OnInterrupt [IP: 0054] ####
A first chance exception of type ‘System.Exception’ occurred in GHIElectronics.NETMF.USBHost.dll
Exception was thrown: System.Exception

It seems there are no standard USB to serial devices on this modem so you get unkown devices…
You can use the read/write endpoints directly, like you used them earlier when switching the modem mode. By doing this you can send ATcommands…etc