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 "USBHost.h"
networker 0:7da612835693 3 #include "ftlibclassdev.h"
networker 0:7da612835693 4
networker 0:7da612835693 5 #define usleep(x) wait_us(x)
networker 0:7da612835693 6 #define sleep(x) wait(x)
networker 0:7da612835693 7
networker 0:7da612835693 8 //incorrect: should clear outputs when thread is NOT running
networker 0:7da612835693 9 unsigned ftdev::ResetFtTransfer() {
networker 0:7da612835693 10 if (ta) {
networker 0:7da612835693 11 ta->M_Main = 0;
networker 0:7da612835693 12 ta->M_Sub1 = 0;
networker 0:7da612835693 13 ta->M_Sub2 = 0;
networker 0:7da612835693 14 ta->M_Sub3 = 0;
networker 0:7da612835693 15 return FTLIB_ERR_SUCCESS;
networker 0:7da612835693 16 }
networker 0:7da612835693 17 return FTLIB_ERR_DEVICE_NOT_OPEN;
networker 0:7da612835693 18 }
networker 0:7da612835693 19
networker 0:7da612835693 20 unsigned ftdev::IsFtTransferActiv() {
networker 0:7da612835693 21 if (transferAktiv > 0)
networker 0:7da612835693 22 return FTLIB_ERR_THREAD_IS_RUNNING;
networker 0:7da612835693 23 return FTLIB_ERR_THREAD_NOT_RUNNING;
networker 0:7da612835693 24 }
networker 0:7da612835693 25
networker 0:7da612835693 26 //not sure about this conversion
networker 0:7da612835693 27 char * ftdev::GetFtFirmwareStrg() {
networker 0:7da612835693 28 unsigned ifw = GetFtFirmware();
networker 0:7da612835693 29 char *s = new char[16];
networker 0:7da612835693 30 int byte1 = ifw & 0xff;
networker 0:7da612835693 31 int byte2 = (ifw & 0xff00) >> 8;
networker 0:7da612835693 32 int byte3 = (ifw & 0xff0000) >> 16;
networker 0:7da612835693 33 int byte4 = (ifw & 0xff000000) >> 24;
networker 0:7da612835693 34 snprintf(s, 16, "%d.%02d.%02d.%02d", byte4, byte3, byte2, byte1);
networker 0:7da612835693 35 return s;
networker 0:7da612835693 36 }
networker 0:7da612835693 37
networker 0:7da612835693 38 //not sure about this conversion
networker 0:7da612835693 39 char * ftdev::GetFtSerialNrStrg() {
networker 0:7da612835693 40 DWORD ifw = GetFtSerialNr();
networker 0:7da612835693 41 char *s = new char[16];
networker 0:7da612835693 42 int byte1, byte2, byte3, byte4;
networker 0:7da612835693 43 byte1 = ifw % 100;
networker 0:7da612835693 44 ifw /= 100;
networker 0:7da612835693 45 byte2 = ifw % 100;
networker 0:7da612835693 46 ifw /= 100;
networker 0:7da612835693 47 byte3 = ifw % 100;
networker 0:7da612835693 48 ifw /= 100;
networker 0:7da612835693 49 byte4 = ifw % 100;
networker 0:7da612835693 50 ifw /= 100;
networker 0:7da612835693 51 snprintf(s, 16, "%d.%02d.%02d.%02d", byte4, byte3, byte2, byte1);
networker 0:7da612835693 52 return s;
networker 0:7da612835693 53 }
networker 0:7da612835693 54
networker 0:7da612835693 55 unsigned ftdev::StartFtTransferArea(NOTIFICATION_EVENTS* ev) {
networker 0:7da612835693 56 int err = IsFtTransferActiv();
networker 0:7da612835693 57 if (err == FTLIB_ERR_THREAD_IS_RUNNING)
networker 0:7da612835693 58 return err;
networker 0:7da612835693 59 if (ta==0)
networker 0:7da612835693 60 return FTLIB_ERR_DEVICE_NOT_OPEN;
networker 0:7da612835693 61 if (ev)
networker 0:7da612835693 62 ne = *ev; //copy the entire struct
networker 0:7da612835693 63 else
networker 0:7da612835693 64 memset(&ne, 0, sizeof(NOTIFICATION_EVENTS));
networker 0:7da612835693 65 FtThreadInit();//setup buffers and serial handlers
networker 0:7da612835693 66 transferAktiv = FTX1RUN;
networker 0:7da612835693 67 return FTLIB_ERR_SUCCESS;
networker 0:7da612835693 68 }
networker 0:7da612835693 69
networker 0:7da612835693 70 unsigned ftdev::StartFtTransferAreaWithCommunication(NOTIFICATION_EVENTS* ev) {
networker 0:7da612835693 71 if (type == FT_INTELLIGENT_IF || type == FT_INTELLIGENT_IF_SLAVE || type == FT_ROBO_IF_IIM)
networker 0:7da612835693 72 return FTLIB_ERR_NOT_SUPPORTED;
networker 0:7da612835693 73 if (messages == 0)
networker 0:7da612835693 74 messages = new msgbuffer<SMESSAGE, 10>;
networker 0:7da612835693 75 int ret = StartFtTransferArea(ev);
networker 0:7da612835693 76 if (ret) {
networker 0:7da612835693 77 delete messages;
networker 0:7da612835693 78 messages = 0;
networker 0:7da612835693 79 }
networker 0:7da612835693 80 return ret;
networker 0:7da612835693 81 }
networker 0:7da612835693 82
networker 0:7da612835693 83 unsigned ftdev::StopFtTransferArea() {
networker 0:7da612835693 84 while (!guardedStop()) {
networker 0:7da612835693 85 USBLoop();//otherwise this loop gets stuck
networker 0:7da612835693 86 printf("waiting for thread to finish\r");
networker 0:7da612835693 87 }
networker 0:7da612835693 88 FtThreadFinish();
networker 0:7da612835693 89 if (messages) {
networker 0:7da612835693 90 delete messages;
networker 0:7da612835693 91 messages = 0;
networker 0:7da612835693 92 }
networker 0:7da612835693 93 busy = false;
networker 0:7da612835693 94 printf("\nthread stopped\n");
networker 0:7da612835693 95 return FTLIB_ERR_SUCCESS;
networker 0:7da612835693 96 }
networker 0:7da612835693 97
networker 0:7da612835693 98 bool ftdev::guardedFtThreadBegin() {//called every 10ms by the main loop to issue a request, should be non-blocking, guarded by busy flag to avoid multiple pending requests
networker 0:7da612835693 99 // printf("busy:%d-%d ", busy, triggered);
networker 0:7da612835693 100 __disable_irq();
networker 0:7da612835693 101 if (busy) {
networker 0:7da612835693 102 if (triggered > 100) { //interface has not responded within 100 slots or response was missed
networker 0:7da612835693 103 printf("Missed reply??? releasing busy\n");
networker 0:7da612835693 104 busy = false; //release the busy flag to reenable the request-reply process
networker 0:7da612835693 105 }
networker 0:7da612835693 106 __enable_irq();
networker 0:7da612835693 107 return false; //skip the timeslot when previous was not yet handled
networker 0:7da612835693 108 }
networker 0:7da612835693 109 busy = true;
networker 1:4676e8b9b357 110 //printf("trig=%d\n", triggered);
networker 0:7da612835693 111 __enable_irq();
networker 0:7da612835693 112 FtThreadBegin();//here the request is sent to the interface
networker 0:7da612835693 113 return true;
networker 0:7da612835693 114 }
networker 0:7da612835693 115
networker 0:7da612835693 116 bool ftdev::guardedStop() {//called every 10ms by the main loop to issue a request, should be non-blocking, guarded by busy flag to avoid multiple pending requests
networker 0:7da612835693 117 __disable_irq();
networker 0:7da612835693 118 if (busy) {
networker 0:7da612835693 119 if (triggered > 100) { //interface has not responded within 10 slots or response was missed
networker 0:7da612835693 120 printf("busy ");
networker 0:7da612835693 121 }
networker 0:7da612835693 122 __enable_irq();
networker 0:7da612835693 123 return false; //skip the timeslot when previous was not yet handled
networker 0:7da612835693 124 }
networker 0:7da612835693 125 busy = true;
networker 0:7da612835693 126 __enable_irq();
networker 0:7da612835693 127 triggered = 0;
networker 0:7da612835693 128 transferAktiv = FTX1STOP;
networker 0:7da612835693 129 return true;
networker 0:7da612835693 130 }
networker 0:7da612835693 131
networker 0:7da612835693 132 bool ftdev::test_and_set() {
networker 0:7da612835693 133 bool tmp;
networker 0:7da612835693 134 __disable_irq();
networker 0:7da612835693 135 if (tmp = (lock>0))
networker 0:7da612835693 136 lock--;
networker 0:7da612835693 137 __enable_irq();
networker 0:7da612835693 138 return tmp;
networker 0:7da612835693 139 }
networker 0:7da612835693 140
networker 0:7da612835693 141 void ftdev::increment() {
networker 0:7da612835693 142 __disable_irq();
networker 0:7da612835693 143 lock++;
networker 0:7da612835693 144 __enable_irq();
networker 0:7da612835693 145 }
networker 0:7da612835693 146
networker 0:7da612835693 147 void ftdev::FtThreadEnd() {//called by the receiver/dma callback when the reply is complete
networker 0:7da612835693 148 if (!test_and_set()) {//skip when busy
networker 0:7da612835693 149 busy = false;
networker 0:7da612835693 150 printf("ftdev::FtThreadEnd: release busy\n");
networker 0:7da612835693 151 return;
networker 0:7da612835693 152 }
networker 0:7da612835693 153 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 154 ta->E_Main = in[0];
networker 0:7da612835693 155 ta->E_Sub1 = in[1];
networker 0:7da612835693 156 ta->E_Sub2 = in[2];
networker 0:7da612835693 157 ta->E_Sub3 = in[3];
networker 0:7da612835693 158 ta->ChangeAn = 1; //assume that analog always changes (noise)
networker 0:7da612835693 159 ta->AX = in[4];
networker 0:7da612835693 160 ta->AY = in[5];
networker 0:7da612835693 161 ta->A1 = in[6];
networker 0:7da612835693 162 ta->A2 = in[7];
networker 0:7da612835693 163 ta->AX |= (in[8] & 0x3) << 8;
networker 0:7da612835693 164 ta->AY |= (in[8] & 0xC) << 6;
networker 0:7da612835693 165 ta->A1 |= (in[8] & 0x30) << 4;
networker 0:7da612835693 166 ta->A2 |= (in[8] & 0xC0) << 2;
networker 0:7da612835693 167 ta->AZ = in[9];
networker 0:7da612835693 168 ta->D1 = in[10];
networker 0:7da612835693 169 ta->D2 = in[11];
networker 0:7da612835693 170 ta->AV = in[12];
networker 0:7da612835693 171 ta->AZ |= (in[13] & 0x3) << 8;
networker 0:7da612835693 172 ta->D1 |= (in[13] & 0xC) << 6;
networker 0:7da612835693 173 ta->D2 |= (in[13] & 0x30) << 4;
networker 0:7da612835693 174 ta->AV |= (in[13] & 0xC0) << 2;
networker 0:7da612835693 175 if (ta->IRKeys != in[14])
networker 0:7da612835693 176 ta->ChangeIr = 1;
networker 0:7da612835693 177 ta->IRKeys = in[14];
networker 0:7da612835693 178 ta->BusModules = in[15];
networker 0:7da612835693 179 // 16
networker 0:7da612835693 180 ta->AXS1 = in[17];
networker 0:7da612835693 181 ta->AXS2 = in[18];
networker 0:7da612835693 182 ta->AXS3 = in[19];
networker 0:7da612835693 183 ta->AXS1 |= (in[20] & 0x3) << 8;
networker 0:7da612835693 184 ta->AXS2 |= (in[20] & 0xC) << 6;
networker 0:7da612835693 185 ta->AXS3 |= (in[20] & 0x30) << 4;
networker 0:7da612835693 186 // 21
networker 0:7da612835693 187 ta->AVS1 = in[22];
networker 0:7da612835693 188 ta->AVS2 = in[23];
networker 0:7da612835693 189 ta->AVS3 = in[24];
networker 0:7da612835693 190 ta->AVS1 |= (in[25] & 0x3) << 8;
networker 0:7da612835693 191 ta->AVS2 |= (in[25] & 0xC) << 6;
networker 0:7da612835693 192 ta->AVS3 |= (in[25] & 0x30) << 4;
networker 0:7da612835693 193 // 26...42
networker 0:7da612835693 194 ta->AV *= 3;
networker 0:7da612835693 195 ta->AVS1 *= 3;
networker 0:7da612835693 196 ta->AVS2 *= 3;
networker 0:7da612835693 197 ta->AVS3 *= 3;
networker 0:7da612835693 198 //message processing
networker 0:7da612835693 199 if (messages && ne.CallbackMessage) { //just to check if communication was enabled
networker 0:7da612835693 200 if (in[28])
networker 0:7da612835693 201 ne.CallbackMessage((SMESSAGE*)(in+29));
networker 0:7da612835693 202 if (in[35])
networker 0:7da612835693 203 ne.CallbackMessage((SMESSAGE*)(in+36));
networker 0:7da612835693 204 }
networker 0:7da612835693 205 increment();
networker 0:7da612835693 206 interface_connected = 1;
networker 0:7da612835693 207 if (ne.NotificationCallback) {
networker 0:7da612835693 208 (*ne.NotificationCallback)(ne.Context);
networker 0:7da612835693 209 }
networker 0:7da612835693 210 busy = false;
networker 0:7da612835693 211 printf("ftdev::FtThreadEnd: release busy at exit\n");
networker 0:7da612835693 212 }
networker 0:7da612835693 213
networker 0:7da612835693 214 unsigned ftdev::SendFtMessage(unsigned char bHwId, unsigned char bSubId, unsigned dwMessage, unsigned dwWaitTime, unsigned dwOption) {
networker 0:7da612835693 215 SMESSAGE m;
networker 0:7da612835693 216 m.L.ucHwId = bHwId;
networker 0:7da612835693 217 m.L.ucSubId = bSubId;
networker 0:7da612835693 218 m.L.dw = dwMessage;
networker 0:7da612835693 219 //waittime ignored
networker 0:7da612835693 220 if (messages)
networker 0:7da612835693 221 return messages->push(m, dwOption) < 0 ? FTLIB_ERR_MSG_BUFFER_FULL_TIMEOUT : 0;
networker 0:7da612835693 222 return FTLIB_ERR_MSG_HWID_WRONG; //not the correct error code
networker 0:7da612835693 223 }
networker 0:7da612835693 224
networker 0:7da612835693 225 unsigned ftdev::ClearFtMessageBuffer() {
networker 0:7da612835693 226 if (messages)
networker 0:7da612835693 227 messages->clear();
networker 0:7da612835693 228 return 0;
networker 0:7da612835693 229 }