class library to access fischertechnik interfaces via USB
Dependencies: FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp
ftlib/ftlibclassusb.cpp@1:4676e8b9b357, 2013-03-11 (annotated)
- Committer:
- networker
- Date:
- Mon Mar 11 08:04:37 2013 +0000
- Revision:
- 1:4676e8b9b357
- Parent:
- 0:7da612835693
first publication of this experimental class, just for sharing wip
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
networker |
0:7da612835693 | 1 | #include "mbed.h" |
networker |
0:7da612835693 | 2 | #include "ftusb.h" |
networker |
0:7da612835693 | 3 | #include "ftlibclass.h" |
networker |
0:7da612835693 | 4 | #include "ftlibclassusb.h" |
networker |
0:7da612835693 | 5 | #include "ftlibclasstxc.h" |
networker |
0:7da612835693 | 6 | |
networker |
0:7da612835693 | 7 | #ifdef USE_DOWNLOAD |
networker |
0:7da612835693 | 8 | #include "crc.h" |
networker |
0:7da612835693 | 9 | #endif |
networker |
0:7da612835693 | 10 | |
networker |
0:7da612835693 | 11 | #define VERSION_MAJOR LIBFT_VERSION_MAJOR |
networker |
0:7da612835693 | 12 | #define VERSION_MINOR LIBFT_VERSION_MINOR |
networker |
0:7da612835693 | 13 | #define VERSION_PATCH LIBFT_VERSION_PATCH |
networker |
0:7da612835693 | 14 | #define ABF_IF_COMPLETE 0x8b // 0xf2 |
networker |
0:7da612835693 | 15 | #define INTERFACE_QUERY_TIME_SERIAL 10000 |
networker |
0:7da612835693 | 16 | #define FT_ENDPOINT_INTERRUPT_IN 0x81 |
networker |
0:7da612835693 | 17 | #define FT_ENDPOINT_INTERRUPT_OUT 0x1 |
networker |
0:7da612835693 | 18 | #define FT_ENDPOINT_BULK_IN 0x82 |
networker |
0:7da612835693 | 19 | #define FT_ENDPOINT_BULK_OUT 0x2 |
networker |
0:7da612835693 | 20 | #define FT_RF_ENDPOINT_INTERRUPT_IN 0x82 |
networker |
0:7da612835693 | 21 | #define FT_RF_ENDPOINT_INTERRUPT_OUT 0x2 |
networker |
0:7da612835693 | 22 | #define FT_USB_TIMEOUT 1000 |
networker |
0:7da612835693 | 23 | #define FT_USB_TIMEOUT_LONG 10000 |
networker |
0:7da612835693 | 24 | #define PROGRAM_UPLOAD_PACKET_SIZE 128 |
networker |
0:7da612835693 | 25 | |
networker |
0:7da612835693 | 26 | #define GET_MAN 1 |
networker |
0:7da612835693 | 27 | #define GET_LONG 2 |
networker |
0:7da612835693 | 28 | #define GET_SN 3 |
networker |
0:7da612835693 | 29 | #define GET_FW 4 |
networker |
0:7da612835693 | 30 | #define GET_SHORT 5 |
networker |
0:7da612835693 | 31 | |
networker |
0:7da612835693 | 32 | #define usleep(x) wait_us(x) |
networker |
0:7da612835693 | 33 | #define sleep(x) wait(x) |
networker |
0:7da612835693 | 34 | |
networker |
0:7da612835693 | 35 | vector<ftusbdev*> ftusbdev::devs; |
networker |
0:7da612835693 | 36 | |
networker |
0:7da612835693 | 37 | int ftusbdev::GetNumFtDevicesFromRF(int device) { |
networker |
0:7da612835693 | 38 | unsigned iNum = 0; |
networker |
0:7da612835693 | 39 | int ret; |
networker |
0:7da612835693 | 40 | unsigned char buffer[35] = { 0 }; |
networker |
0:7da612835693 | 41 | for (int i=1; i<9; i++) { |
networker |
0:7da612835693 | 42 | ret = USBControlTransfer(device, 0xc0, 0x52, i<<8 | 0x05, 0, buffer, 35, 0, 0); |
networker |
0:7da612835693 | 43 | if (ret < 0) { |
networker |
0:7da612835693 | 44 | fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker |
0:7da612835693 | 45 | return ret; |
networker |
0:7da612835693 | 46 | } else if (buffer[0] == 0xfa && buffer[1] == 0) { // buffer[1] == 0xff => no device |
networker |
0:7da612835693 | 47 | iNum++; |
networker |
0:7da612835693 | 48 | unsigned snr = *(unsigned*)(buffer+3); //buffer[3] + buffer[4]*100 + buffer[5]*10000 + buffer[6]*1000000; |
networker |
0:7da612835693 | 49 | ftusbdev *d = new ftusbdev(device, FT_ROBO_IF_OVER_RF, snr, i); |
networker |
0:7da612835693 | 50 | d->fw = *(unsigned*)(buffer+20); |
networker |
0:7da612835693 | 51 | devs.push_back(d);//use datalink as type and assume little endianness |
networker |
0:7da612835693 | 52 | } |
networker |
0:7da612835693 | 53 | } |
networker |
0:7da612835693 | 54 | return iNum; |
networker |
0:7da612835693 | 55 | } |
networker |
0:7da612835693 | 56 | |
networker |
0:7da612835693 | 57 | unsigned ftusbdev::InitFtUsbDeviceList() { |
networker |
0:7da612835693 | 58 | char buffer[128]; |
networker |
0:7da612835693 | 59 | devs.clear(); |
networker |
0:7da612835693 | 60 | for (vector<_ftdev>::iterator i = ::devs.begin(); i < ::devs.end(); i++) { |
networker |
0:7da612835693 | 61 | unsigned sn = 0; |
networker |
0:7da612835693 | 62 | if (i->product == 0x1000) { //TXC |
networker |
0:7da612835693 | 63 | devs.push_back(new ftusbdevtx(i->device)); |
networker |
0:7da612835693 | 64 | continue; |
networker |
0:7da612835693 | 65 | } |
networker |
0:7da612835693 | 66 | if (GetString(i->device, GET_SN, buffer, 18) >= 0) { |
networker |
0:7da612835693 | 67 | sn = atoi(buffer); |
networker |
0:7da612835693 | 68 | } else { |
networker |
0:7da612835693 | 69 | printf("device %d did not respond\n", i->device); |
networker |
0:7da612835693 | 70 | continue; |
networker |
0:7da612835693 | 71 | } |
networker |
0:7da612835693 | 72 | if (i->product == RF_DATA_LINK_PRODUCT_ID) {//robo over RF |
networker |
0:7da612835693 | 73 | ftusbdev *dl = new ftusbdev(i->device, ftlib::FtproductIDToInterfaceID(i->product), sn, 0); //the RF call ID of the link is 0 but this is useless |
networker |
0:7da612835693 | 74 | devs.push_back(dl); |
networker |
0:7da612835693 | 75 | int pos = devs.size(); //position of first appended RF interface |
networker |
0:7da612835693 | 76 | int n = GetNumFtDevicesFromRF(i->device); |
networker |
0:7da612835693 | 77 | if (n > 0) { |
networker |
0:7da612835693 | 78 | dl->rf = devs[pos]->rf; //use the rf of the first child |
networker |
0:7da612835693 | 79 | } |
networker |
0:7da612835693 | 80 | } else { |
networker |
0:7da612835693 | 81 | if (i->product == EXT_IF_PRODUCT_ID) |
networker |
0:7da612835693 | 82 | devs.push_back(new ftusbdevext(i->device, ftlib::FtproductIDToInterfaceID(i->product), sn)); |
networker |
0:7da612835693 | 83 | else |
networker |
0:7da612835693 | 84 | devs.push_back(new ftusbdev(i->device, ftlib::FtproductIDToInterfaceID(i->product), sn)); |
networker |
0:7da612835693 | 85 | } |
networker |
0:7da612835693 | 86 | } |
networker |
0:7da612835693 | 87 | return FTLIB_ERR_SUCCESS; |
networker |
0:7da612835693 | 88 | } |
networker |
0:7da612835693 | 89 | |
networker |
0:7da612835693 | 90 | |
networker |
0:7da612835693 | 91 | ftusbdev* ftusbdev::GetFtUsbDeviceHandle(unsigned Num) { |
networker |
0:7da612835693 | 92 | if (Num < devs.size()) { |
networker |
0:7da612835693 | 93 | return devs[Num]; |
networker |
0:7da612835693 | 94 | } |
networker |
0:7da612835693 | 95 | return 0; |
networker |
0:7da612835693 | 96 | } |
networker |
0:7da612835693 | 97 | |
networker |
0:7da612835693 | 98 | ftusbdev* ftusbdev::GetFtUsbDeviceHandleSerialNr(unsigned dwSN, unsigned dwTyp) { |
networker |
0:7da612835693 | 99 | for (int i = 0; i < devs.size(); i++) |
networker |
0:7da612835693 | 100 | if (devs[i]->sn == dwSN) { |
networker |
0:7da612835693 | 101 | if (dwTyp == 0 || dwTyp == devs[i]->type) |
networker |
0:7da612835693 | 102 | return GetFtUsbDeviceHandle(i); |
networker |
0:7da612835693 | 103 | } |
networker |
0:7da612835693 | 104 | fprintf(stderr, "GetFtUsbDeviceSerialNr(%d, %d) not found\n", dwSN, dwTyp); |
networker |
0:7da612835693 | 105 | return 0; |
networker |
0:7da612835693 | 106 | } |
networker |
0:7da612835693 | 107 | |
networker |
0:7da612835693 | 108 | unsigned ftusbdev::OpenFtUsbDevice() { |
networker |
0:7da612835693 | 109 | FT_TRANSFER_AREA *area = new FT_TRANSFER_AREA; |
networker |
0:7da612835693 | 110 | memset(area, 0, sizeof(struct _FT_TRANSFER_AREA)); |
networker |
0:7da612835693 | 111 | area->RfModulNr = rf; |
networker |
0:7da612835693 | 112 | area->TransferAktiv = 0; |
networker |
0:7da612835693 | 113 | ta = area; |
networker |
0:7da612835693 | 114 | return 0; |
networker |
0:7da612835693 | 115 | } |
networker |
0:7da612835693 | 116 | |
networker |
0:7da612835693 | 117 | unsigned ftusbdev::CloseFtDevice() { |
networker |
0:7da612835693 | 118 | if (ta==0) |
networker |
0:7da612835693 | 119 | return FTLIB_ERR_DEVICE_NOT_OPEN; |
networker |
0:7da612835693 | 120 | while (ta->TransferAktiv != 0) { |
networker |
0:7da612835693 | 121 | fprintf(stderr, "Transfer ta still active\n"); |
networker |
0:7da612835693 | 122 | sleep(1); |
networker |
0:7da612835693 | 123 | } |
networker |
0:7da612835693 | 124 | delete ta; |
networker |
0:7da612835693 | 125 | ta = 0; |
networker |
0:7da612835693 | 126 | return 0; |
networker |
0:7da612835693 | 127 | } |
networker |
0:7da612835693 | 128 | |
networker |
0:7da612835693 | 129 | unsigned ftusbdev::GetFtFirmware() { |
networker |
0:7da612835693 | 130 | int ret; |
networker |
0:7da612835693 | 131 | unsigned char buffer[35] = { 0 }; |
networker |
0:7da612835693 | 132 | if (fw > 0) |
networker |
0:7da612835693 | 133 | return fw; |
networker |
0:7da612835693 | 134 | switch (type) { |
networker |
0:7da612835693 | 135 | case FT_ROBO_IF_USB: |
networker |
0:7da612835693 | 136 | case FT_ROBO_IO_EXTENSION: |
networker |
0:7da612835693 | 137 | case FT_ROBO_RF_DATA_LINK: |
networker |
0:7da612835693 | 138 | ret = USBControlTransfer(device, 0xc0, 0xf0, 0x1, 0, buffer, 5); |
networker |
0:7da612835693 | 139 | if (ret < 0) { |
networker |
0:7da612835693 | 140 | fprintf(stderr, "Error sending control msg 0xC0 0xF0\n"); |
networker |
0:7da612835693 | 141 | return 0; |
networker |
0:7da612835693 | 142 | } |
networker |
0:7da612835693 | 143 | fw = buffer[1] | buffer[2]<<8 | buffer[3]<<16 | buffer[4]<<24; |
networker |
0:7da612835693 | 144 | break; |
networker |
0:7da612835693 | 145 | case FT_ROBO_IF_OVER_RF: |
networker |
0:7da612835693 | 146 | ret = USBControlTransfer(device, 0xc0, 0x52, rf<<8 | 0x05, 0, buffer, 35); |
networker |
0:7da612835693 | 147 | if (ret < 0) { |
networker |
0:7da612835693 | 148 | fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker |
0:7da612835693 | 149 | return 0; |
networker |
0:7da612835693 | 150 | } |
networker |
0:7da612835693 | 151 | if (buffer[0] == 0xfa && buffer[1] == 0) { // buffer[1] == 0xff => no device |
networker |
0:7da612835693 | 152 | fw = buffer[23]<<24 | buffer[22]<<16 | buffer[21]<<8 | buffer[20]; |
networker |
0:7da612835693 | 153 | } |
networker |
0:7da612835693 | 154 | break; |
networker |
0:7da612835693 | 155 | default: |
networker |
0:7da612835693 | 156 | return FTLIB_ERR_NOT_SUPPORTED; |
networker |
0:7da612835693 | 157 | } |
networker |
0:7da612835693 | 158 | return fw; |
networker |
0:7da612835693 | 159 | } |
networker |
0:7da612835693 | 160 | |
networker |
0:7da612835693 | 161 | char * ftusbdev::GetFtLongNameStrg() { |
networker |
0:7da612835693 | 162 | const int sz = 128; |
networker |
0:7da612835693 | 163 | char *buffer = new char[sz]; |
networker |
0:7da612835693 | 164 | buffer[0] = '\0'; |
networker |
0:7da612835693 | 165 | |
networker |
0:7da612835693 | 166 | switch (type) { |
networker |
0:7da612835693 | 167 | case FT_ROBO_IF_USB: |
networker |
0:7da612835693 | 168 | case FT_ROBO_RF_DATA_LINK: |
networker |
0:7da612835693 | 169 | case FT_ROBO_IO_EXTENSION: |
networker |
0:7da612835693 | 170 | GetString(device, GET_LONG, buffer, sz); |
networker |
0:7da612835693 | 171 | break; |
networker |
0:7da612835693 | 172 | case FT_ROBO_IF_OVER_RF: |
networker |
0:7da612835693 | 173 | sprintf(buffer, " Robo Interface (RF:%d)", rf); |
networker |
0:7da612835693 | 174 | break; |
networker |
0:7da612835693 | 175 | } |
networker |
0:7da612835693 | 176 | return buffer; |
networker |
0:7da612835693 | 177 | } |
networker |
0:7da612835693 | 178 | |
networker |
0:7da612835693 | 179 | char * ftusbdev::GetFtShortNameStrg() { |
networker |
0:7da612835693 | 180 | const int sz = 128; |
networker |
0:7da612835693 | 181 | char *buffer = new char[sz]; |
networker |
0:7da612835693 | 182 | buffer[0] = '\0'; |
networker |
0:7da612835693 | 183 | |
networker |
0:7da612835693 | 184 | switch (type) { |
networker |
0:7da612835693 | 185 | case FT_ROBO_IF_USB: |
networker |
0:7da612835693 | 186 | case FT_ROBO_RF_DATA_LINK: |
networker |
0:7da612835693 | 187 | case FT_ROBO_IO_EXTENSION: |
networker |
0:7da612835693 | 188 | GetString(device, GET_SHORT, buffer, sz); |
networker |
0:7da612835693 | 189 | break; |
networker |
0:7da612835693 | 190 | case FT_ROBO_IF_OVER_RF: |
networker |
0:7da612835693 | 191 | sprintf(buffer, " (RF:%d)", rf); |
networker |
0:7da612835693 | 192 | break; |
networker |
0:7da612835693 | 193 | } |
networker |
0:7da612835693 | 194 | return buffer; |
networker |
0:7da612835693 | 195 | } |
networker |
0:7da612835693 | 196 | |
networker |
0:7da612835693 | 197 | char * ftusbdev::GetFtManufacturerStrg() { |
networker |
0:7da612835693 | 198 | const int sz = 128; |
networker |
0:7da612835693 | 199 | char *buffer = new char[sz]; |
networker |
0:7da612835693 | 200 | buffer[0] = '\0'; |
networker |
0:7da612835693 | 201 | GetString(device, GET_MAN, buffer, sz); |
networker |
0:7da612835693 | 202 | return buffer; |
networker |
0:7da612835693 | 203 | } |
networker |
0:7da612835693 | 204 | |
networker |
0:7da612835693 | 205 | void ftusbdev::poll() { |
networker |
0:7da612835693 | 206 | for (int i = 0; i < devs.size(); i++) { |
networker |
0:7da612835693 | 207 | if (devs[i]->triggered) { |
networker |
0:7da612835693 | 208 | if (devs[i]->guardedFtThreadBegin()) |
networker |
0:7da612835693 | 209 | devs[i]->triggered = 0; |
networker |
0:7da612835693 | 210 | } |
networker |
0:7da612835693 | 211 | } |
networker |
0:7da612835693 | 212 | //USBLoop(); |
networker |
0:7da612835693 | 213 | } |
networker |
0:7da612835693 | 214 | |
networker |
0:7da612835693 | 215 | void ftusbdev::FtThreadInit() {//setup buffers for this type of interface |
networker |
0:7da612835693 | 216 | num_write = ABF_IF_COMPLETE_NUM_WRITE; |
networker |
0:7da612835693 | 217 | num_read = ABF_IF_COMPLETE_NUM_READ; |
networker |
0:7da612835693 | 218 | out[0] = ABF_IF_COMPLETE; |
networker |
0:7da612835693 | 219 | ftdev::FtThreadInit(); |
networker |
0:7da612835693 | 220 | unsigned ret; |
networker |
0:7da612835693 | 221 | switch (type) { |
networker |
0:7da612835693 | 222 | case FT_ROBO_IF_OVER_RF: |
networker |
0:7da612835693 | 223 | case FT_ROBO_RF_DATA_LINK: |
networker |
0:7da612835693 | 224 | usb_endpoint_write = FT_RF_ENDPOINT_INTERRUPT_OUT; |
networker |
0:7da612835693 | 225 | usb_endpoint_read = FT_RF_ENDPOINT_INTERRUPT_IN; |
networker |
0:7da612835693 | 226 | ret = USBControlTransfer(device, 0xc0, 0xfb, rf << 8 | 0x02, 0x1, in, 2, 0, 0); |
networker |
0:7da612835693 | 227 | if (ret != 2) { |
networker |
0:7da612835693 | 228 | fprintf(stderr, "%d FtThread: Error initiating RF Module!\n"); |
networker |
0:7da612835693 | 229 | //ta->TransferAktiv = 0; |
networker |
0:7da612835693 | 230 | } |
networker |
0:7da612835693 | 231 | break; |
networker |
0:7da612835693 | 232 | default: //FT_ROBO_USB |
networker |
0:7da612835693 | 233 | usb_endpoint_write = FT_ENDPOINT_INTERRUPT_OUT; |
networker |
0:7da612835693 | 234 | usb_endpoint_read = FT_ENDPOINT_INTERRUPT_IN; |
networker |
0:7da612835693 | 235 | break; |
networker |
0:7da612835693 | 236 | } |
networker |
0:7da612835693 | 237 | } |
networker |
0:7da612835693 | 238 | |
networker |
0:7da612835693 | 239 | void ftusbdev::read_finished_cb(int device, int endpoint, int status, u8* data, int len, void* userData) { |
networker |
0:7da612835693 | 240 | //end of reply transfer |
networker |
0:7da612835693 | 241 | ftusbdev *fth = (ftusbdev*)userData; |
networker |
0:7da612835693 | 242 | fth->FtThreadEnd(); |
networker |
0:7da612835693 | 243 | } |
networker |
0:7da612835693 | 244 | |
networker |
0:7da612835693 | 245 | void ftusbdev::write_finished_cb(int device, int endpoint, int status, u8* data, int len, void* userData) { //end of request transfer, issue, reply transfer |
networker |
0:7da612835693 | 246 | ftusbdev *fth = (ftusbdev*)userData; |
networker |
0:7da612835693 | 247 | USBInterruptTransfer(fth->device, fth->usb_endpoint_read, fth->in, fth->num_read, read_finished_cb, fth); |
networker |
0:7da612835693 | 248 | } |
networker |
0:7da612835693 | 249 | |
networker |
0:7da612835693 | 250 | //here the real data exchange starts |
networker |
0:7da612835693 | 251 | void ftusbdev::FtThreadBegin() {//called every 10ms to issue a request, should be non-blocking |
networker |
0:7da612835693 | 252 | if (!test_and_set()) {//return when transferarea is in use |
networker |
0:7da612835693 | 253 | busy = false; //release the mutex, otherwise the thread effectively stops |
networker |
0:7da612835693 | 254 | return;//return because there is no point in sending a nonsense request, alternatively the lock can be ignored in which case the data may be inconsistent |
networker |
0:7da612835693 | 255 | } |
networker |
0:7da612835693 | 256 | //putc('(', stderr); |
networker |
0:7da612835693 | 257 | out[1] = ta->M_Main; |
networker |
0:7da612835693 | 258 | out[2] = (ta->MPWM_Main[0] & 0x7) | (ta->MPWM_Main[1]<<3 & 0x38) | (ta->MPWM_Main[2]<<6 & 0xC0); |
networker |
0:7da612835693 | 259 | out[3] = (ta->MPWM_Main[2] & 0x1) | (ta->MPWM_Main[3]<<1 & 0xE) | (ta->MPWM_Main[4]<<4 & 0x70) | (ta->MPWM_Main[5]<<7 & 0x80); |
networker |
0:7da612835693 | 260 | out[4] = (ta->MPWM_Main[5] & 0x3) | (ta->MPWM_Main[6]<<2 & 0x1C) | (ta->MPWM_Main[7]<<5 & 0xE0); |
networker |
0:7da612835693 | 261 | out[5] = ta->M_Sub1; |
networker |
0:7da612835693 | 262 | out[6] = (ta->MPWM_Sub1[0] & 0x7) | (ta->MPWM_Sub1[1]<<3 & 0x38) | (ta->MPWM_Sub1[2]<<6 & 0xC0); |
networker |
0:7da612835693 | 263 | out[7] = (ta->MPWM_Sub1[2] & 0x1) | (ta->MPWM_Sub1[3]<<1 & 0xE) | (ta->MPWM_Sub1[4]<<4 & 0x70) | (ta->MPWM_Sub1[5]<<7 & 0x80); |
networker |
0:7da612835693 | 264 | out[8] = (ta->MPWM_Sub1[5] & 0x3) | (ta->MPWM_Sub1[6]<<2 & 0x1C) | (ta->MPWM_Sub1[7]<<5 & 0xE0); |
networker |
0:7da612835693 | 265 | out[9] = ta->M_Sub2; |
networker |
0:7da612835693 | 266 | out[10] = (ta->MPWM_Sub2[0] & 0x7) | (ta->MPWM_Sub2[1]<<3 & 0x38) | (ta->MPWM_Sub2[2]<<6 & 0xC0); |
networker |
0:7da612835693 | 267 | out[11] = (ta->MPWM_Sub2[2] & 0x1) | (ta->MPWM_Sub2[3]<<1 & 0xE) | (ta->MPWM_Sub2[4]<<4 & 0x70) | (ta->MPWM_Sub2[5]<<7 & 0x80); |
networker |
0:7da612835693 | 268 | out[12] = (ta->MPWM_Sub2[5] & 0x3) | (ta->MPWM_Sub2[6]<<2 & 0x1C) | (ta->MPWM_Sub2[7]<<5 & 0xE0); |
networker |
0:7da612835693 | 269 | out[13] = ta->M_Sub3; |
networker |
0:7da612835693 | 270 | out[14] = (ta->MPWM_Sub3[0] & 0x7) | (ta->MPWM_Sub3[1]<<3 & 0x38) | (ta->MPWM_Sub3[2]<<6 & 0xC0); |
networker |
0:7da612835693 | 271 | out[15] = (ta->MPWM_Sub3[2] & 0x1) | (ta->MPWM_Sub3[3]<<1 & 0xE) | (ta->MPWM_Sub3[4]<<4 & 0x70) | (ta->MPWM_Sub3[5]<<7 & 0x80); |
networker |
0:7da612835693 | 272 | out[16] = (ta->MPWM_Sub3[5] & 0x3) | (ta->MPWM_Sub3[6]<<2 & 0x1C) | (ta->MPWM_Sub3[7]<<5 & 0xE0); |
networker |
0:7da612835693 | 273 | out[17] = 0; |
networker |
0:7da612835693 | 274 | if (messages && messages->nrOfMessages()>0) { |
networker |
0:7da612835693 | 275 | out[18] = 0; |
networker |
0:7da612835693 | 276 | *(SMESSAGE*)(out+19) = messages->pop(); |
networker |
0:7da612835693 | 277 | } else { |
networker |
0:7da612835693 | 278 | memset(out+18, 0, 7); |
networker |
0:7da612835693 | 279 | } |
networker |
0:7da612835693 | 280 | if (messages && messages->nrOfMessages()>0) { |
networker |
0:7da612835693 | 281 | out[25] = 0; |
networker |
0:7da612835693 | 282 | *(SMESSAGE*)(out+26) = messages->pop(); |
networker |
0:7da612835693 | 283 | } else { |
networker |
0:7da612835693 | 284 | memset(out+25, 0, 7); |
networker |
0:7da612835693 | 285 | } |
networker |
0:7da612835693 | 286 | increment();//release the lock on shared memeory |
networker |
0:7da612835693 | 287 | USBInterruptTransfer(device, usb_endpoint_write, out, num_write, write_finished_cb, this); //return immediately and call the callback when finished |
networker |
0:7da612835693 | 288 | } |
networker |
0:7da612835693 | 289 | #if 0 //use the parent version |
networker |
0:7da612835693 | 290 | void ftusbdev::FtThreadEnd() {//called by the receiver/dma callback when the reply is complete |
networker |
0:7da612835693 | 291 | if (!test_and_set()) {//skip when busy |
networker |
0:7da612835693 | 292 | busy = false; |
networker |
0:7da612835693 | 293 | return; |
networker |
0:7da612835693 | 294 | } |
networker |
0:7da612835693 | 295 | ta->ChangeEg = ta->E_Main != in[0] || ta->E_Sub1 != in[1] || ta->E_Sub2 != in[2] || ta->E_Sub3 != in[3]; |
networker |
0:7da612835693 | 296 | ta->E_Main = in[0]; |
networker |
0:7da612835693 | 297 | ta->E_Sub1 = in[1]; |
networker |
0:7da612835693 | 298 | ta->E_Sub2 = in[2]; |
networker |
0:7da612835693 | 299 | ta->E_Sub3 = in[3]; |
networker |
0:7da612835693 | 300 | ta->ChangeAn = 1; //assume that analog always changes (noise) |
networker |
0:7da612835693 | 301 | ta->AX = in[4]; |
networker |
0:7da612835693 | 302 | ta->AY = in[5]; |
networker |
0:7da612835693 | 303 | ta->A1 = in[6]; |
networker |
0:7da612835693 | 304 | ta->A2 = in[7]; |
networker |
0:7da612835693 | 305 | ta->AX |= (in[8] & 0x3) << 8; |
networker |
0:7da612835693 | 306 | ta->AY |= (in[8] & 0xC) << 6; |
networker |
0:7da612835693 | 307 | ta->A1 |= (in[8] & 0x30) << 4; |
networker |
0:7da612835693 | 308 | ta->A2 |= (in[8] & 0xC0) << 2; |
networker |
0:7da612835693 | 309 | ta->AZ = in[9]; |
networker |
0:7da612835693 | 310 | ta->D1 = in[10]; |
networker |
0:7da612835693 | 311 | ta->D2 = in[11]; |
networker |
0:7da612835693 | 312 | ta->AV = in[12]; |
networker |
0:7da612835693 | 313 | ta->AZ |= (in[13] & 0x3) << 8; |
networker |
0:7da612835693 | 314 | ta->D1 |= (in[13] & 0xC) << 6; |
networker |
0:7da612835693 | 315 | ta->D2 |= (in[13] & 0x30) << 4; |
networker |
0:7da612835693 | 316 | ta->AV |= (in[13] & 0xC0) << 2; |
networker |
0:7da612835693 | 317 | if (ta->IRKeys != in[14]) |
networker |
0:7da612835693 | 318 | ta->ChangeIr = 1; |
networker |
0:7da612835693 | 319 | ta->IRKeys = in[14]; |
networker |
0:7da612835693 | 320 | ta->BusModules = in[15]; |
networker |
0:7da612835693 | 321 | // 16 |
networker |
0:7da612835693 | 322 | ta->AXS1 = in[17]; |
networker |
0:7da612835693 | 323 | ta->AXS2 = in[18]; |
networker |
0:7da612835693 | 324 | ta->AXS3 = in[19]; |
networker |
0:7da612835693 | 325 | ta->AXS1 |= (in[20] & 0x3) << 8; |
networker |
0:7da612835693 | 326 | ta->AXS2 |= (in[20] & 0xC) << 6; |
networker |
0:7da612835693 | 327 | ta->AXS3 |= (in[20] & 0x30) << 4; |
networker |
0:7da612835693 | 328 | // 21 |
networker |
0:7da612835693 | 329 | ta->AVS1 = in[22]; |
networker |
0:7da612835693 | 330 | ta->AVS2 = in[23]; |
networker |
0:7da612835693 | 331 | ta->AVS3 = in[24]; |
networker |
0:7da612835693 | 332 | ta->AVS1 |= (in[25] & 0x3) << 8; |
networker |
0:7da612835693 | 333 | ta->AVS2 |= (in[25] & 0xC) << 6; |
networker |
0:7da612835693 | 334 | ta->AVS3 |= (in[25] & 0x30) << 4; |
networker |
0:7da612835693 | 335 | // 26...42 |
networker |
0:7da612835693 | 336 | ta->AV *= 3; |
networker |
0:7da612835693 | 337 | ta->AVS1 *= 3; |
networker |
0:7da612835693 | 338 | ta->AVS2 *= 3; |
networker |
0:7da612835693 | 339 | ta->AVS3 *= 3; |
networker |
0:7da612835693 | 340 | //message processing |
networker |
0:7da612835693 | 341 | if (messages && ne.CallbackMessage) { //just to check if communication was enabled |
networker |
0:7da612835693 | 342 | if (in[28]) |
networker |
0:7da612835693 | 343 | ne.CallbackMessage((SMESSAGE*)(in+29)); |
networker |
0:7da612835693 | 344 | if (in[35]) |
networker |
0:7da612835693 | 345 | ne.CallbackMessage((SMESSAGE*)(in+36)); |
networker |
0:7da612835693 | 346 | } |
networker |
0:7da612835693 | 347 | increment(); |
networker |
0:7da612835693 | 348 | interface_connected = 1; |
networker |
0:7da612835693 | 349 | if (ne.NotificationCallback) { |
networker |
0:7da612835693 | 350 | (*ne.NotificationCallback)(ne.Context); |
networker |
0:7da612835693 | 351 | } |
networker |
0:7da612835693 | 352 | busy = false; |
networker |
0:7da612835693 | 353 | } |
networker |
0:7da612835693 | 354 | #endif |
networker |
0:7da612835693 | 355 | |
networker |
0:7da612835693 | 356 | void ftusbdev::FtThreadFinish() {//called by StopFtTransferArea |
networker |
0:7da612835693 | 357 | if (type == FT_ROBO_IF_OVER_RF || type == FT_ROBO_RF_DATA_LINK) { |
networker |
0:7da612835693 | 358 | int ret = USBControlTransfer(device, 0xc0, 0x21, rf << 8, 0, in, 1); |
networker |
0:7da612835693 | 359 | if (ret != 1 || in[0] != 0xd7) { |
networker |
0:7da612835693 | 360 | fprintf(stderr, "Error uninitiating RF Module!\n"); |
networker |
0:7da612835693 | 361 | } |
networker |
0:7da612835693 | 362 | } |
networker |
0:7da612835693 | 363 | ftdev::FtThreadFinish(); |
networker |
0:7da612835693 | 364 | } |
networker |
0:7da612835693 | 365 | |
networker |
0:7da612835693 | 366 | unsigned ftusbdev::SetFtDeviceCommMode (unsigned dwMode, unsigned dwParameter, unsigned short *puiValue) { |
networker |
0:7da612835693 | 367 | unsigned char buf[3]; |
networker |
0:7da612835693 | 368 | unsigned ret = USBControlTransfer(device, 0xc0, 0xf0, 0x0040, dwMode|(dwParameter<<8), buf, 3); |
networker |
0:7da612835693 | 369 | if (puiValue && dwMode == IF_COM_PARAMETER) |
networker |
0:7da612835693 | 370 | *puiValue = buf[1]; |
networker |
0:7da612835693 | 371 | return ret; |
networker |
0:7da612835693 | 372 | } |
networker |
0:7da612835693 | 373 | |
networker |
0:7da612835693 | 374 | void ftusbdevext::FtThreadInit() {//setup buffers for this type of interface |
networker |
0:7da612835693 | 375 | usb_endpoint_write = FT_ENDPOINT_INTERRUPT_OUT; |
networker |
0:7da612835693 | 376 | usb_endpoint_read = FT_ENDPOINT_INTERRUPT_IN; |
networker |
0:7da612835693 | 377 | ftdev::FtThreadInit(); |
networker |
0:7da612835693 | 378 | out[0] = 0xf2; |
networker |
0:7da612835693 | 379 | num_write = 6; |
networker |
0:7da612835693 | 380 | num_read = 6; |
networker |
0:7da612835693 | 381 | } |
networker |
0:7da612835693 | 382 | |
networker |
0:7da612835693 | 383 | void ftusbdevext::FtThreadEnd() {//called by the receiver/dma callback when the reply is complete |
networker |
0:7da612835693 | 384 | if (!test_and_set()) {//skip when busy |
networker |
0:7da612835693 | 385 | busy = false; |
networker |
0:7da612835693 | 386 | return; |
networker |
0:7da612835693 | 387 | } |
networker |
0:7da612835693 | 388 | ta->ChangeEg = ta->E_Main != in[0]; |
networker |
0:7da612835693 | 389 | ta->E_Main = in[0]; |
networker |
0:7da612835693 | 390 | ta->ChangeAn = 1; //assume that analog always changes (noise) |
networker |
0:7da612835693 | 391 | ta->AX = in[1]; |
networker |
0:7da612835693 | 392 | ta->A1 = in[2]; |
networker |
0:7da612835693 | 393 | ta->AV = in[3]; |
networker |
0:7da612835693 | 394 | ta->AX |= (in[4] & 0x3) << 8; |
networker |
0:7da612835693 | 395 | ta->A1 |= (in[4] & 0xC) << 6; |
networker |
0:7da612835693 | 396 | ta->AV |= (in[4] & 0x30) << 4; |
networker |
0:7da612835693 | 397 | ta->AV *= 3; |
networker |
0:7da612835693 | 398 | increment(); |
networker |
0:7da612835693 | 399 | interface_connected = 1; |
networker |
0:7da612835693 | 400 | //printf("%02X) ", ta->E_Main); |
networker |
0:7da612835693 | 401 | if (ne.NotificationCallback) { |
networker |
0:7da612835693 | 402 | // printf("%02X\r", transfer_area.E_Main); |
networker |
0:7da612835693 | 403 | (*ne.NotificationCallback)(ne.Context); |
networker |
0:7da612835693 | 404 | } |
networker |
0:7da612835693 | 405 | busy = false; |
networker |
0:7da612835693 | 406 | } |
networker |
0:7da612835693 | 407 | |
networker |
0:7da612835693 | 408 | unsigned ftusbdev::SetFtDistanceSensorMode(unsigned dwMode, unsigned dwTol1, unsigned dwTol2, unsigned dwLevel1, unsigned dwLevel2, unsigned dwRepeat1, unsigned dwRepeat2) { |
networker |
0:7da612835693 | 409 | int ret; |
networker |
0:7da612835693 | 410 | unsigned char buffer[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 34 |
networker |
0:7da612835693 | 411 | |
networker |
0:7da612835693 | 412 | buffer[1] = dwTol1; |
networker |
0:7da612835693 | 413 | buffer[2] = dwTol2; |
networker |
0:7da612835693 | 414 | buffer[3] = dwLevel1; |
networker |
0:7da612835693 | 415 | buffer[4] = dwLevel1>>8; |
networker |
0:7da612835693 | 416 | buffer[5] = dwLevel2; |
networker |
0:7da612835693 | 417 | buffer[6] = dwLevel2>>8; |
networker |
0:7da612835693 | 418 | buffer[7] = dwRepeat1; |
networker |
0:7da612835693 | 419 | buffer[8] = dwRepeat2; |
networker |
0:7da612835693 | 420 | |
networker |
0:7da612835693 | 421 | switch (type) { |
networker |
0:7da612835693 | 422 | case FT_ROBO_IF_USB: |
networker |
0:7da612835693 | 423 | ret = USBControlTransfer(device, 0x40, 0xf1, 0x1, dwMode, buffer+1, 8); |
networker |
0:7da612835693 | 424 | if (ret != 8) { |
networker |
0:7da612835693 | 425 | fprintf(stderr, "Error sending control msg 0x40 0xf1\n"); |
networker |
0:7da612835693 | 426 | return ret; |
networker |
0:7da612835693 | 427 | } |
networker |
0:7da612835693 | 428 | break; |
networker |
0:7da612835693 | 429 | case FT_ROBO_RF_DATA_LINK: |
networker |
0:7da612835693 | 430 | case FT_ROBO_IF_OVER_RF: |
networker |
0:7da612835693 | 431 | ret = USBControlTransfer(device, 0x40, 0x53, rf<<8 | 0x01, 0, buffer, 34); |
networker |
0:7da612835693 | 432 | if (ret != 34) { |
networker |
0:7da612835693 | 433 | fprintf(stderr, "Error sending control msg 0x40 0x53\n"); |
networker |
0:7da612835693 | 434 | return ret; |
networker |
0:7da612835693 | 435 | } |
networker |
0:7da612835693 | 436 | break; |
networker |
0:7da612835693 | 437 | default: |
networker |
0:7da612835693 | 438 | return FTLIB_ERR_NOT_SUPPORTED; |
networker |
0:7da612835693 | 439 | } |
networker |
0:7da612835693 | 440 | usleep(100000); // wait before continue, else it doesn't always work |
networker |
0:7da612835693 | 441 | return FTLIB_ERR_SUCCESS; |
networker |
0:7da612835693 | 442 | } |
networker |
0:7da612835693 | 443 | |
networker |
0:7da612835693 | 444 | unsigned ftusbdev::pgm_message(unsigned code, unsigned dwMemBlock) { |
networker |
0:7da612835693 | 445 | unsigned char buffer[2]; |
networker |
0:7da612835693 | 446 | if (type != FT_ROBO_IF_USB) return FTLIB_ERR_NOT_SUPPORTED; |
networker |
0:7da612835693 | 447 | int ret = USBControlTransfer(device, 0xc0, code, dwMemBlock, 0, buffer, 1); |
networker |
0:7da612835693 | 448 | if (ret < 0) { |
networker |
0:7da612835693 | 449 | fprintf(stderr, "Error sending control msg 0xC0 %02X\n", code); |
networker |
0:7da612835693 | 450 | return ret; |
networker |
0:7da612835693 | 451 | } |
networker |
0:7da612835693 | 452 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker |
0:7da612835693 | 453 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker |
0:7da612835693 | 454 | } |