class library to access fischertechnik interfaces via USB

Dependencies:   FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp

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?

UserRevisionLine numberNew 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 }