Norimasa Okamoto
/
GPSUSBHost
GPS USB dongle host
Diff: usbgps.cpp
- 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; +}