GPS USB dongle host

Dependencies:   mbed

Revision:
0:1c6af92fdc79
Child:
1:82eaa5761719
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbgps.cpp	Mon Apr 30 14:24:46 2012 +0000
@@ -0,0 +1,106 @@
+#include "mbed.h"
+#include "usbgps.h"
+
+#define PL2303_SET_LINE_CODING 0x20
+
+usbgps::usbgps()
+{
+    m_init = false;
+    m_connect = false;
+}
+
+int usbgps::readable()
+{
+    if (!m_init) {
+        _init();
+    }
+    for(int i = 0; i < 2; i++) {
+        if (!_receive.empty()) {
+            return 1;
+        }
+        _receive_proc();
+    }
+    return 0;
+}
+
+void usbgps::_init()
+{
+    m_init = true;
+    Host_Init();               /* Initialize the  host controller                                    */
+    USB_INT32S rc = Host_EnumDev(); /* Enumerate the device connected                                            */
+    if (rc != OK) {
+        PRINT_Log("Could not enumerate device: %d\n", rc);
+        return;
+    }
+    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 18);
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return;
+    }
+    if (0x067b == ReadLE16U(TDBuffer+8) && // Vender ID 067Bh
+        0x2303 == ReadLE16U(TDBuffer+10)) { // Product ID 2303h
+        PRINT_Log("GT-730F/L GPS USB Dongle connected\n");
+    } else {
+        PRINT_Log("not gps usb\n");
+        return;
+    }
+    EDBulkIn->Control =  1                    |      /* USB address           */
+                         ((0x83 & 0x7F) << 7) |      /* Endpoint address      */
+                         (2 << 11)            |      /* direction             */
+                         (64 << 16);                 /* MaxPkt Size           */
+
+    const USB_INT08U data[] = {0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x08}; // default 38400bps,8bit
+    rc = Host_CtrlSend(USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
+                       PL2303_SET_LINE_CODING, 0, 0, sizeof(data), (USB_INT08U*)data);
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return;
+    }
+    USB_INT08U temp[7];
+    rc = Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
+                       0x21, 0, 0, sizeof(temp), temp);
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return;
+    }
+    m_connect = true;
+}
+
+void usbgps::_receive_proc()
+{
+    if (!m_connect) {
+        return;
+    }
+    USB_INT08U buf[64];
+    USB_INT32S rc = Host_ProcessTD(EDBulkIn, TD_IN, buf, sizeof(buf));
+    if (rc == OK) {
+        int len = 0;
+        if (TDHead->CurrBufPtr) {
+            len = TDHead->CurrBufPtr - (int)buf;
+        }
+        for(int i = 0; i < len; i++) {
+            _receive.push(buf[i]);
+        }
+    }
+}
+
+int usbgps::_getc()
+{
+    if (!m_init) {
+        _init();
+    }
+    for(int i = 0; i < 2; i++) {
+        if (!_receive.empty()) {
+            int c = _receive.front();
+            _receive.pop();
+            return c;
+        }
+        _receive_proc();
+    }
+    return -1;
+}
+
+int usbgps::_putc(int c)
+{
+    return c;
+}