Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

Committer:
jmitc91516
Date:
Wed Jan 13 13:17:05 2016 +0000
Revision:
0:47c880c1463d
Child:
1:a5258871b33d
First revision of 5 inch display version of GC500_2. Dated 13 Jan 2016

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jmitc91516 0:47c880c1463d 1 /**
jmitc91516 0:47c880c1463d 2 * A class to communicate with a USB GC.
jmitc91516 0:47c880c1463d 3 *
jmitc91516 0:47c880c1463d 4 * *** Important note - when reading data from the USB device, you must do this into memory allocated using ***
jmitc91516 0:47c880c1463d 5 * *** the 'getSafeMem' function of the USBHost class. If you read it into 'normal' memory, your code will crash. ***
jmitc91516 0:47c880c1463d 6 * *** This is my experience so far, at least. This applies, e.g. to all the 'Get...' functions below. ***
jmitc91516 0:47c880c1463d 7 * *** (There may, of course, be a simple explanation for this, but if so, I am not currently aware of it.) ***
jmitc91516 0:47c880c1463d 8 * *** This is why (currently) all the 'Get...' functions allocate a buffer from safe memory, ***
jmitc91516 0:47c880c1463d 9 * *** read the data into it, then copy the data into the buffer provided by the caller. ***
jmitc91516 0:47c880c1463d 10 */
jmitc91516 0:47c880c1463d 11
jmitc91516 0:47c880c1463d 12 #include "USBHostGC.h"
jmitc91516 0:47c880c1463d 13
jmitc91516 0:47c880c1463d 14 extern void EasyGUIDebugPrint(char *stuffToPrint, short X, short Y);
jmitc91516 0:47c880c1463d 15
jmitc91516 0:47c880c1463d 16
jmitc91516 0:47c880c1463d 17 USBHostGC::USBHostGC()
jmitc91516 0:47c880c1463d 18 {
jmitc91516 0:47c880c1463d 19 debugWindow = NULL;
jmitc91516 0:47c880c1463d 20
jmitc91516 0:47c880c1463d 21 usbHost = USBHost::getHostInst();
jmitc91516 0:47c880c1463d 22
jmitc91516 0:47c880c1463d 23 reportBuffer = NULL;
jmitc91516 0:47c880c1463d 24
jmitc91516 0:47c880c1463d 25 NoDeviceConnected(); // So far...
jmitc91516 0:47c880c1463d 26
jmitc91516 0:47c880c1463d 27 alreadyInSetDeviceReport = false;
jmitc91516 0:47c880c1463d 28 }
jmitc91516 0:47c880c1463d 29
jmitc91516 0:47c880c1463d 30 USBHostGC::~USBHostGC()
jmitc91516 0:47c880c1463d 31 {
jmitc91516 0:47c880c1463d 32 NoDeviceConnected();
jmitc91516 0:47c880c1463d 33 }
jmitc91516 0:47c880c1463d 34
jmitc91516 0:47c880c1463d 35 void USBHostGC::NoDeviceConnected(void)
jmitc91516 0:47c880c1463d 36 {
jmitc91516 0:47c880c1463d 37 deviceIsGC = false;
jmitc91516 0:47c880c1463d 38 intfGC = -1;
jmitc91516 0:47c880c1463d 39 intInEndpointGC = NULL;
jmitc91516 0:47c880c1463d 40 usbGCDeviceConnected = NULL;
jmitc91516 0:47c880c1463d 41
jmitc91516 0:47c880c1463d 42 if (reportBuffer != NULL) {
jmitc91516 0:47c880c1463d 43 usbHost->returnSafeMem(reportBuffer);
jmitc91516 0:47c880c1463d 44 reportBuffer = NULL;
jmitc91516 0:47c880c1463d 45 }
jmitc91516 0:47c880c1463d 46 }
jmitc91516 0:47c880c1463d 47
jmitc91516 0:47c880c1463d 48 void USBHostGC::DebugPrint(const char* debugText)
jmitc91516 0:47c880c1463d 49 {
jmitc91516 0:47c880c1463d 50 if(debugWindow != NULL) {
jmitc91516 0:47c880c1463d 51 swim_put_text(debugWindow, debugText);
jmitc91516 0:47c880c1463d 52 }
jmitc91516 0:47c880c1463d 53 }
jmitc91516 0:47c880c1463d 54
jmitc91516 0:47c880c1463d 55 void USBHostGC::AllocateReportBuffer(void)
jmitc91516 0:47c880c1463d 56 {
jmitc91516 0:47c880c1463d 57 int reportSize = GC_MESSAGE_LENGTH;
jmitc91516 0:47c880c1463d 58
jmitc91516 0:47c880c1463d 59 if (intInEndpointGC != NULL) {
jmitc91516 0:47c880c1463d 60 int intInEndpointSize = intInEndpointGC->getSize();
jmitc91516 0:47c880c1463d 61 if (intInEndpointSize > reportSize) {
jmitc91516 0:47c880c1463d 62 reportSize = intInEndpointSize;
jmitc91516 0:47c880c1463d 63 }
jmitc91516 0:47c880c1463d 64 }
jmitc91516 0:47c880c1463d 65
jmitc91516 0:47c880c1463d 66 reportBuffer = usbHost->getSafeMem(reportSize);
jmitc91516 0:47c880c1463d 67 }
jmitc91516 0:47c880c1463d 68
jmitc91516 0:47c880c1463d 69 bool USBHostGC::AttachGCDevice(USBDeviceConnected* usbDeviceConnected)
jmitc91516 0:47c880c1463d 70 {
jmitc91516 0:47c880c1463d 71 intInEndpointGC = usbDeviceConnected->getEndpoint(intfGC, INTERRUPT_ENDPOINT, IN);
jmitc91516 0:47c880c1463d 72 if (!intInEndpointGC) {
jmitc91516 0:47c880c1463d 73 DebugPrint("AttachGCDevice - interrupt endpoint in not found - returning false\n");
jmitc91516 0:47c880c1463d 74 NoDeviceConnected();
jmitc91516 0:47c880c1463d 75 return false;
jmitc91516 0:47c880c1463d 76 }
jmitc91516 0:47c880c1463d 77
jmitc91516 0:47c880c1463d 78 usbDeviceConnected->setName("GC", intfGC);
jmitc91516 0:47c880c1463d 79
jmitc91516 0:47c880c1463d 80 usbHost->registerDriver(usbDeviceConnected, intfGC, this, &USBHostGC::NoDeviceConnected);
jmitc91516 0:47c880c1463d 81
jmitc91516 0:47c880c1463d 82 intInEndpointGC->attach(this, &USBHostGC::RXHandler);
jmitc91516 0:47c880c1463d 83
jmitc91516 0:47c880c1463d 84 if (reportBuffer == NULL) {
jmitc91516 0:47c880c1463d 85 AllocateReportBuffer();
jmitc91516 0:47c880c1463d 86 }
jmitc91516 0:47c880c1463d 87
jmitc91516 0:47c880c1463d 88 usbHost->interruptRead(usbDeviceConnected, intInEndpointGC, reportBuffer, intInEndpointGC->getSize(), false);
jmitc91516 0:47c880c1463d 89
jmitc91516 0:47c880c1463d 90 usbGCDeviceConnected = usbDeviceConnected;
jmitc91516 0:47c880c1463d 91
jmitc91516 0:47c880c1463d 92 return true;
jmitc91516 0:47c880c1463d 93 }
jmitc91516 0:47c880c1463d 94
jmitc91516 0:47c880c1463d 95 void USBHostGC::RXHandler(void)
jmitc91516 0:47c880c1463d 96 {
jmitc91516 0:47c880c1463d 97 responseReceived = true;
jmitc91516 0:47c880c1463d 98
jmitc91516 0:47c880c1463d 99 if (usbGCDeviceConnected) {
jmitc91516 0:47c880c1463d 100 usbHost->interruptRead(usbGCDeviceConnected, intInEndpointGC, reportBuffer, intInEndpointGC->getSize(), false);
jmitc91516 0:47c880c1463d 101 }
jmitc91516 0:47c880c1463d 102 }
jmitc91516 0:47c880c1463d 103
jmitc91516 0:47c880c1463d 104 bool USBHostGC::ExecutingSetDeviceReport(void)
jmitc91516 0:47c880c1463d 105 {
jmitc91516 0:47c880c1463d 106 return alreadyInSetDeviceReport;
jmitc91516 0:47c880c1463d 107 }
jmitc91516 0:47c880c1463d 108
jmitc91516 0:47c880c1463d 109 USB_TYPE USBHostGC::SetDeviceReport(USBDeviceConnected * dev, const char* report, char* response)
jmitc91516 0:47c880c1463d 110 {
jmitc91516 0:47c880c1463d 111 // Neither this function, nor the GC itself, are re-entrant...
jmitc91516 0:47c880c1463d 112 if(alreadyInSetDeviceReport) {
jmitc91516 0:47c880c1463d 113 return USB_TYPE_PROCESSING;
jmitc91516 0:47c880c1463d 114 }
jmitc91516 0:47c880c1463d 115
jmitc91516 0:47c880c1463d 116 alreadyInSetDeviceReport = true;
jmitc91516 0:47c880c1463d 117
jmitc91516 0:47c880c1463d 118 if (reportBuffer == NULL) {
jmitc91516 0:47c880c1463d 119 AllocateReportBuffer();
jmitc91516 0:47c880c1463d 120 }
jmitc91516 0:47c880c1463d 121
jmitc91516 0:47c880c1463d 122 int i;
jmitc91516 0:47c880c1463d 123 for (i = 0; (i < GC_MESSAGE_LENGTH) && (report[i]); ++i) {
jmitc91516 0:47c880c1463d 124 reportBuffer[i] = (uint8_t) report[i];
jmitc91516 0:47c880c1463d 125 }
jmitc91516 0:47c880c1463d 126 //reportBuffer[i++] = (uint8_t) GC_CR; // Append <CR> - make *sure* it is the same code the GC expects
jmitc91516 0:47c880c1463d 127 // Fill remainder of buffer with nulls, to pad out to 10 bytes
jmitc91516 0:47c880c1463d 128 for ( ; i < GC_MESSAGE_LENGTH; ++i) {
jmitc91516 0:47c880c1463d 129 reportBuffer[i] = 0;
jmitc91516 0:47c880c1463d 130 }
jmitc91516 0:47c880c1463d 131 //reportBuffer[GC_MESSAGE_LENGTH - 1] = (uint8_t) GC_CR;
jmitc91516 0:47c880c1463d 132
jmitc91516 0:47c880c1463d 133 responseReceived = false; // Synchronise with RXHandler
jmitc91516 0:47c880c1463d 134
jmitc91516 0:47c880c1463d 135 //EasyGUIDebugPrint("SetDeviceReport - before controlWrite", 20,80);
jmitc91516 0:47c880c1463d 136 USB_TYPE t = usbHost->controlWrite( dev,
jmitc91516 0:47c880c1463d 137 1, // Non-zero - tells GC - set report, not set configuration
jmitc91516 0:47c880c1463d 138 SET_CONFIGURATION,
jmitc91516 0:47c880c1463d 139 0,
jmitc91516 0:47c880c1463d 140 0, reportBuffer, GC_MESSAGE_LENGTH);
jmitc91516 0:47c880c1463d 141 //EasyGUIDebugPrint("SetDeviceReport - after controlWrite", 20,100);
jmitc91516 0:47c880c1463d 142
jmitc91516 0:47c880c1463d 143 while (!responseReceived) {
jmitc91516 0:47c880c1463d 144 // wait...
jmitc91516 0:47c880c1463d 145 }
jmitc91516 0:47c880c1463d 146
jmitc91516 0:47c880c1463d 147 //EasyGUIDebugPrint("SetDeviceReport - after wait for response", 20,120);
jmitc91516 0:47c880c1463d 148
jmitc91516 0:47c880c1463d 149 // RXHandler has now received the response - return it to the caller
jmitc91516 0:47c880c1463d 150
jmitc91516 0:47c880c1463d 151 for (i = 0; i < GC_MESSAGE_LENGTH; ++i) {
jmitc91516 0:47c880c1463d 152 response[i] = reportBuffer[i];
jmitc91516 0:47c880c1463d 153 }
jmitc91516 0:47c880c1463d 154 response[i] = '\0';
jmitc91516 0:47c880c1463d 155
jmitc91516 0:47c880c1463d 156 alreadyInSetDeviceReport = false;
jmitc91516 0:47c880c1463d 157
jmitc91516 0:47c880c1463d 158 return t;
jmitc91516 0:47c880c1463d 159 }
jmitc91516 0:47c880c1463d 160
jmitc91516 0:47c880c1463d 161 // Part of IUSBEnumerator interface
jmitc91516 0:47c880c1463d 162 /* virtual */ void USBHostGC::setVidPid(uint16_t vid, uint16_t pid)
jmitc91516 0:47c880c1463d 163 {
jmitc91516 0:47c880c1463d 164 char buff[100];
jmitc91516 0:47c880c1463d 165 sprintf(buff, "setVidPid(%d %X, %d %X)\n", vid, vid, pid, pid);
jmitc91516 0:47c880c1463d 166 DebugPrint(buff);
jmitc91516 0:47c880c1463d 167
jmitc91516 0:47c880c1463d 168 deviceIsGC = ((vid == GC_VENDOR_ID) && (pid == GC_PRODUCT_ID));
jmitc91516 0:47c880c1463d 169
jmitc91516 0:47c880c1463d 170 DebugPrint(deviceIsGC ? "Device is a GC\n" : "Device is *not* a GC\n");
jmitc91516 0:47c880c1463d 171 }
jmitc91516 0:47c880c1463d 172
jmitc91516 0:47c880c1463d 173 // Part of IUSBEnumerator interface - must return true if the interface should be parsed
jmitc91516 0:47c880c1463d 174 /* virtual */ bool USBHostGC::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol)
jmitc91516 0:47c880c1463d 175 {
jmitc91516 0:47c880c1463d 176 char buff[100];
jmitc91516 0:47c880c1463d 177 sprintf(buff, "parseInterface(%d %X, %d %X, %d %X, %d %X)\n", intf_nb, intf_nb, intf_class, intf_class, intf_subclass, intf_subclass, intf_protocol, intf_protocol);
jmitc91516 0:47c880c1463d 178 DebugPrint(buff);
jmitc91516 0:47c880c1463d 179
jmitc91516 0:47c880c1463d 180 // setVidPid should have been called before this -
jmitc91516 0:47c880c1463d 181 // assume it will have identified whether or not the device is a GC
jmitc91516 0:47c880c1463d 182 if (deviceIsGC) {
jmitc91516 0:47c880c1463d 183 if ((intfGC == -1) &&
jmitc91516 0:47c880c1463d 184 (intf_class == HID_CLASS)) {
jmitc91516 0:47c880c1463d 185 // Don't care about subclass and protocol in this case
jmitc91516 0:47c880c1463d 186
jmitc91516 0:47c880c1463d 187 intfGC = intf_nb;
jmitc91516 0:47c880c1463d 188 DebugPrint(" **** GC found **** \n");
jmitc91516 0:47c880c1463d 189 }
jmitc91516 0:47c880c1463d 190 DebugPrint("GC found - parseInterface returning true\n");
jmitc91516 0:47c880c1463d 191 return true;
jmitc91516 0:47c880c1463d 192 }
jmitc91516 0:47c880c1463d 193
jmitc91516 0:47c880c1463d 194 DebugPrint("No GC found - parseInterface returning false\n");
jmitc91516 0:47c880c1463d 195 return false;
jmitc91516 0:47c880c1463d 196 }
jmitc91516 0:47c880c1463d 197
jmitc91516 0:47c880c1463d 198 // Part of IUSBEnumerator interface - must return true if the endpoint will be used
jmitc91516 0:47c880c1463d 199 /* virtual */ bool USBHostGC::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir)
jmitc91516 0:47c880c1463d 200 {
jmitc91516 0:47c880c1463d 201 char buff[100];
jmitc91516 0:47c880c1463d 202 sprintf(buff, "useEndPoint(%d %X, %d %X, %d %X)\n", intf_nb, intf_nb, type, type, dir, dir);
jmitc91516 0:47c880c1463d 203 DebugPrint(buff);
jmitc91516 0:47c880c1463d 204
jmitc91516 0:47c880c1463d 205 if (deviceIsGC) {
jmitc91516 0:47c880c1463d 206 if ((intfGC == intf_nb) &&
jmitc91516 0:47c880c1463d 207 (type == INTERRUPT_ENDPOINT) &&
jmitc91516 0:47c880c1463d 208 (dir == IN)) {
jmitc91516 0:47c880c1463d 209 DebugPrint("GC endpoint found - useEndPoint returning true\n");
jmitc91516 0:47c880c1463d 210 return true;
jmitc91516 0:47c880c1463d 211 }
jmitc91516 0:47c880c1463d 212 }
jmitc91516 0:47c880c1463d 213
jmitc91516 0:47c880c1463d 214 // 'else'
jmitc91516 0:47c880c1463d 215 DebugPrint("GC endpoint not found - useEndpoint returning false\n");
jmitc91516 0:47c880c1463d 216 return false;
jmitc91516 0:47c880c1463d 217 }