GPS USB dongle host

Dependencies:   mbed

usbgps.cpp

Committer:
va009039
Date:
2012-05-04
Revision:
1:82eaa5761719
Parent:
0:1c6af92fdc79

File content as of revision 1:82eaa5761719:

#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 = sizeof(buf);
        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;
}