Norimasa Okamoto
/
GPSUSBHost
GPS USB dongle host
usbgps.cpp@1:82eaa5761719, 2012-05-04 (annotated)
- Committer:
- va009039
- Date:
- Fri May 04 06:58:31 2012 +0000
- Revision:
- 1:82eaa5761719
- Parent:
- 0:1c6af92fdc79
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:1c6af92fdc79 | 1 | #include "mbed.h" |
va009039 | 0:1c6af92fdc79 | 2 | #include "usbgps.h" |
va009039 | 0:1c6af92fdc79 | 3 | |
va009039 | 0:1c6af92fdc79 | 4 | #define PL2303_SET_LINE_CODING 0x20 |
va009039 | 0:1c6af92fdc79 | 5 | |
va009039 | 0:1c6af92fdc79 | 6 | usbgps::usbgps() |
va009039 | 0:1c6af92fdc79 | 7 | { |
va009039 | 0:1c6af92fdc79 | 8 | m_init = false; |
va009039 | 0:1c6af92fdc79 | 9 | m_connect = false; |
va009039 | 0:1c6af92fdc79 | 10 | } |
va009039 | 0:1c6af92fdc79 | 11 | |
va009039 | 0:1c6af92fdc79 | 12 | int usbgps::readable() |
va009039 | 0:1c6af92fdc79 | 13 | { |
va009039 | 0:1c6af92fdc79 | 14 | if (!m_init) { |
va009039 | 0:1c6af92fdc79 | 15 | _init(); |
va009039 | 0:1c6af92fdc79 | 16 | } |
va009039 | 0:1c6af92fdc79 | 17 | for(int i = 0; i < 2; i++) { |
va009039 | 0:1c6af92fdc79 | 18 | if (!_receive.empty()) { |
va009039 | 0:1c6af92fdc79 | 19 | return 1; |
va009039 | 0:1c6af92fdc79 | 20 | } |
va009039 | 0:1c6af92fdc79 | 21 | _receive_proc(); |
va009039 | 0:1c6af92fdc79 | 22 | } |
va009039 | 0:1c6af92fdc79 | 23 | return 0; |
va009039 | 0:1c6af92fdc79 | 24 | } |
va009039 | 0:1c6af92fdc79 | 25 | |
va009039 | 0:1c6af92fdc79 | 26 | void usbgps::_init() |
va009039 | 0:1c6af92fdc79 | 27 | { |
va009039 | 0:1c6af92fdc79 | 28 | m_init = true; |
va009039 | 0:1c6af92fdc79 | 29 | Host_Init(); /* Initialize the host controller */ |
va009039 | 0:1c6af92fdc79 | 30 | USB_INT32S rc = Host_EnumDev(); /* Enumerate the device connected */ |
va009039 | 0:1c6af92fdc79 | 31 | if (rc != OK) { |
va009039 | 0:1c6af92fdc79 | 32 | PRINT_Log("Could not enumerate device: %d\n", rc); |
va009039 | 0:1c6af92fdc79 | 33 | return; |
va009039 | 0:1c6af92fdc79 | 34 | } |
va009039 | 0:1c6af92fdc79 | 35 | rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 18); |
va009039 | 0:1c6af92fdc79 | 36 | if (rc != OK) { |
va009039 | 0:1c6af92fdc79 | 37 | PRINT_Err(rc); |
va009039 | 0:1c6af92fdc79 | 38 | return; |
va009039 | 0:1c6af92fdc79 | 39 | } |
va009039 | 0:1c6af92fdc79 | 40 | if (0x067b == ReadLE16U(TDBuffer+8) && // Vender ID 067Bh |
va009039 | 0:1c6af92fdc79 | 41 | 0x2303 == ReadLE16U(TDBuffer+10)) { // Product ID 2303h |
va009039 | 0:1c6af92fdc79 | 42 | PRINT_Log("GT-730F/L GPS USB Dongle connected\n"); |
va009039 | 0:1c6af92fdc79 | 43 | } else { |
va009039 | 0:1c6af92fdc79 | 44 | PRINT_Log("not gps usb\n"); |
va009039 | 0:1c6af92fdc79 | 45 | return; |
va009039 | 0:1c6af92fdc79 | 46 | } |
va009039 | 0:1c6af92fdc79 | 47 | EDBulkIn->Control = 1 | /* USB address */ |
va009039 | 0:1c6af92fdc79 | 48 | ((0x83 & 0x7F) << 7) | /* Endpoint address */ |
va009039 | 0:1c6af92fdc79 | 49 | (2 << 11) | /* direction */ |
va009039 | 0:1c6af92fdc79 | 50 | (64 << 16); /* MaxPkt Size */ |
va009039 | 0:1c6af92fdc79 | 51 | |
va009039 | 0:1c6af92fdc79 | 52 | const USB_INT08U data[] = {0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x08}; // default 38400bps,8bit |
va009039 | 0:1c6af92fdc79 | 53 | rc = Host_CtrlSend(USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, |
va009039 | 0:1c6af92fdc79 | 54 | PL2303_SET_LINE_CODING, 0, 0, sizeof(data), (USB_INT08U*)data); |
va009039 | 0:1c6af92fdc79 | 55 | if (rc != OK) { |
va009039 | 0:1c6af92fdc79 | 56 | PRINT_Err(rc); |
va009039 | 0:1c6af92fdc79 | 57 | return; |
va009039 | 0:1c6af92fdc79 | 58 | } |
va009039 | 0:1c6af92fdc79 | 59 | USB_INT08U temp[7]; |
va009039 | 0:1c6af92fdc79 | 60 | rc = Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, |
va009039 | 0:1c6af92fdc79 | 61 | 0x21, 0, 0, sizeof(temp), temp); |
va009039 | 0:1c6af92fdc79 | 62 | if (rc != OK) { |
va009039 | 0:1c6af92fdc79 | 63 | PRINT_Err(rc); |
va009039 | 0:1c6af92fdc79 | 64 | return; |
va009039 | 0:1c6af92fdc79 | 65 | } |
va009039 | 0:1c6af92fdc79 | 66 | m_connect = true; |
va009039 | 0:1c6af92fdc79 | 67 | } |
va009039 | 0:1c6af92fdc79 | 68 | |
va009039 | 0:1c6af92fdc79 | 69 | void usbgps::_receive_proc() |
va009039 | 0:1c6af92fdc79 | 70 | { |
va009039 | 0:1c6af92fdc79 | 71 | if (!m_connect) { |
va009039 | 0:1c6af92fdc79 | 72 | return; |
va009039 | 0:1c6af92fdc79 | 73 | } |
va009039 | 0:1c6af92fdc79 | 74 | USB_INT08U buf[64]; |
va009039 | 0:1c6af92fdc79 | 75 | USB_INT32S rc = Host_ProcessTD(EDBulkIn, TD_IN, buf, sizeof(buf)); |
va009039 | 0:1c6af92fdc79 | 76 | if (rc == OK) { |
va009039 | 1:82eaa5761719 | 77 | int len = sizeof(buf); |
va009039 | 0:1c6af92fdc79 | 78 | if (TDHead->CurrBufPtr) { |
va009039 | 0:1c6af92fdc79 | 79 | len = TDHead->CurrBufPtr - (int)buf; |
va009039 | 0:1c6af92fdc79 | 80 | } |
va009039 | 0:1c6af92fdc79 | 81 | for(int i = 0; i < len; i++) { |
va009039 | 0:1c6af92fdc79 | 82 | _receive.push(buf[i]); |
va009039 | 0:1c6af92fdc79 | 83 | } |
va009039 | 0:1c6af92fdc79 | 84 | } |
va009039 | 0:1c6af92fdc79 | 85 | } |
va009039 | 0:1c6af92fdc79 | 86 | |
va009039 | 0:1c6af92fdc79 | 87 | int usbgps::_getc() |
va009039 | 0:1c6af92fdc79 | 88 | { |
va009039 | 0:1c6af92fdc79 | 89 | if (!m_init) { |
va009039 | 0:1c6af92fdc79 | 90 | _init(); |
va009039 | 0:1c6af92fdc79 | 91 | } |
va009039 | 0:1c6af92fdc79 | 92 | for(int i = 0; i < 2; i++) { |
va009039 | 0:1c6af92fdc79 | 93 | if (!_receive.empty()) { |
va009039 | 0:1c6af92fdc79 | 94 | int c = _receive.front(); |
va009039 | 0:1c6af92fdc79 | 95 | _receive.pop(); |
va009039 | 0:1c6af92fdc79 | 96 | return c; |
va009039 | 0:1c6af92fdc79 | 97 | } |
va009039 | 0:1c6af92fdc79 | 98 | _receive_proc(); |
va009039 | 0:1c6af92fdc79 | 99 | } |
va009039 | 0:1c6af92fdc79 | 100 | return -1; |
va009039 | 0:1c6af92fdc79 | 101 | } |
va009039 | 0:1c6af92fdc79 | 102 | |
va009039 | 0:1c6af92fdc79 | 103 | int usbgps::_putc(int c) |
va009039 | 0:1c6af92fdc79 | 104 | { |
va009039 | 0:1c6af92fdc79 | 105 | return c; |
va009039 | 0:1c6af92fdc79 | 106 | } |