class library to access fischertechnik interfaces via USB
Dependencies: FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp
ftlib/ftlibclassdev.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 "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 | } |