class library to access fischertechnik interfaces via USB

Dependencies:   FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp

Revision:
0:7da612835693
Child:
1:4676e8b9b357
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ftlib/ftlibclassdev.cpp	Wed Jun 15 19:12:25 2011 +0000
@@ -0,0 +1,229 @@
+#include "mbed.h"
+#include "USBHost.h"
+#include "ftlibclassdev.h"
+
+#define usleep(x)    wait_us(x)
+#define sleep(x)    wait(x)
+
+//incorrect: should clear outputs when thread is NOT running
+unsigned ftdev::ResetFtTransfer() {
+    if (ta) {
+        ta->M_Main = 0;
+        ta->M_Sub1 = 0;
+        ta->M_Sub2 = 0;
+        ta->M_Sub3 = 0;
+        return FTLIB_ERR_SUCCESS;
+    }
+    return FTLIB_ERR_DEVICE_NOT_OPEN;
+}
+
+unsigned ftdev::IsFtTransferActiv() {
+    if (transferAktiv > 0)
+        return FTLIB_ERR_THREAD_IS_RUNNING;
+    return FTLIB_ERR_THREAD_NOT_RUNNING;
+}
+
+//not sure about this conversion
+char * ftdev::GetFtFirmwareStrg() {
+    unsigned ifw = GetFtFirmware();
+    char *s = new char[16];
+    int byte1 = ifw & 0xff;
+    int byte2 = (ifw & 0xff00) >> 8;
+    int byte3 = (ifw & 0xff0000) >> 16;
+    int byte4 = (ifw & 0xff000000) >> 24;
+    snprintf(s, 16, "%d.%02d.%02d.%02d", byte4, byte3, byte2, byte1);
+    return s;
+}
+
+//not sure about this conversion
+char * ftdev::GetFtSerialNrStrg() {
+    DWORD ifw = GetFtSerialNr();
+    char *s = new char[16];
+    int byte1, byte2, byte3, byte4;
+    byte1 = ifw % 100;
+    ifw /= 100;
+    byte2 = ifw % 100;
+    ifw /= 100;
+    byte3 = ifw % 100;
+    ifw /= 100;
+    byte4 = ifw % 100;
+    ifw /= 100;
+    snprintf(s, 16, "%d.%02d.%02d.%02d", byte4, byte3, byte2, byte1);
+    return s;
+}
+
+unsigned ftdev::StartFtTransferArea(NOTIFICATION_EVENTS* ev) {
+    int err = IsFtTransferActiv();
+    if (err == FTLIB_ERR_THREAD_IS_RUNNING)
+        return err;
+    if (ta==0)
+        return FTLIB_ERR_DEVICE_NOT_OPEN;
+    if (ev)
+        ne = *ev; //copy the entire struct
+    else
+        memset(&ne, 0, sizeof(NOTIFICATION_EVENTS));
+    FtThreadInit();//setup buffers and serial handlers
+    transferAktiv = FTX1RUN;
+    return FTLIB_ERR_SUCCESS;
+}
+
+unsigned ftdev::StartFtTransferAreaWithCommunication(NOTIFICATION_EVENTS* ev) {
+    if (type == FT_INTELLIGENT_IF || type == FT_INTELLIGENT_IF_SLAVE || type == FT_ROBO_IF_IIM)
+        return FTLIB_ERR_NOT_SUPPORTED;
+    if (messages == 0)
+        messages = new msgbuffer<SMESSAGE, 10>;
+    int ret = StartFtTransferArea(ev);
+    if (ret) {
+        delete messages;
+        messages = 0;
+    }
+    return ret;
+}
+
+unsigned ftdev::StopFtTransferArea() {
+    while (!guardedStop()) {
+        USBLoop();//otherwise this loop gets stuck
+        printf("waiting for thread to finish\r");
+    }
+    FtThreadFinish();
+    if (messages) {
+        delete messages;
+        messages = 0;
+    }
+    busy = false;
+    printf("\nthread stopped\n");
+    return FTLIB_ERR_SUCCESS;
+}
+
+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
+  // printf("busy:%d-%d ", busy, triggered);
+    __disable_irq();
+    if (busy) {
+        if (triggered > 100) { //interface has not responded within 100 slots or response was missed
+            printf("Missed reply??? releasing busy\n");
+            busy = false; //release the busy flag to reenable the request-reply process
+        }
+        __enable_irq();
+        return false; //skip the timeslot when previous was not yet handled
+    }
+    busy = true;
+    printf("trig=%d\n", triggered);
+    __enable_irq();
+    FtThreadBegin();//here the request is sent to the interface
+    return true;
+}
+
+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
+    __disable_irq();
+    if (busy) {
+        if (triggered > 100) { //interface has not responded within 10 slots or response was missed
+            printf("busy ");
+        }
+        __enable_irq();
+        return false; //skip the timeslot when previous was not yet handled
+    }
+    busy = true;
+    __enable_irq();
+    triggered = 0;
+    transferAktiv = FTX1STOP;
+    return true;
+}
+
+bool ftdev::test_and_set() {
+    bool tmp;
+    __disable_irq();
+    if (tmp = (lock>0))
+        lock--;
+    __enable_irq();
+    return tmp;
+}
+
+void ftdev::increment() {
+    __disable_irq();
+    lock++;
+    __enable_irq();
+}
+
+void ftdev::FtThreadEnd() {//called by the receiver/dma callback when the reply is complete
+    if (!test_and_set()) {//skip when busy
+        busy = false;
+        printf("ftdev::FtThreadEnd: release busy\n");
+        return;
+    }
+    ta->ChangeEg = ta->E_Main != in[0] || ta->E_Sub1 != in[1] || ta->E_Sub2 != in[2] || ta->E_Sub3 != in[3];
+    ta->E_Main = in[0];
+    ta->E_Sub1 = in[1];
+    ta->E_Sub2 = in[2];
+    ta->E_Sub3 = in[3];
+    ta->ChangeAn = 1; //assume that analog always changes (noise)
+    ta->AX = in[4];
+    ta->AY = in[5];
+    ta->A1 = in[6];
+    ta->A2 = in[7];
+    ta->AX |= (in[8] & 0x3) << 8;
+    ta->AY |= (in[8] & 0xC) << 6;
+    ta->A1 |= (in[8] & 0x30) << 4;
+    ta->A2 |= (in[8] & 0xC0) << 2;
+    ta->AZ = in[9];
+    ta->D1 = in[10];
+    ta->D2 = in[11];
+    ta->AV = in[12];
+    ta->AZ |= (in[13] & 0x3) << 8;
+    ta->D1 |= (in[13] & 0xC) << 6;
+    ta->D2 |= (in[13] & 0x30) << 4;
+    ta->AV |= (in[13] & 0xC0) << 2;
+    if (ta->IRKeys != in[14])
+        ta->ChangeIr = 1;
+    ta->IRKeys = in[14];
+    ta->BusModules = in[15];
+    // 16
+    ta->AXS1 = in[17];
+    ta->AXS2 = in[18];
+    ta->AXS3 = in[19];
+    ta->AXS1 |= (in[20] & 0x3) << 8;
+    ta->AXS2 |= (in[20] & 0xC) << 6;
+    ta->AXS3 |= (in[20] & 0x30) << 4;
+    // 21
+    ta->AVS1 = in[22];
+    ta->AVS2 = in[23];
+    ta->AVS3 = in[24];
+    ta->AVS1 |= (in[25] & 0x3) << 8;
+    ta->AVS2 |= (in[25] & 0xC) << 6;
+    ta->AVS3 |= (in[25] & 0x30) << 4;
+    // 26...42
+    ta->AV *= 3;
+    ta->AVS1 *= 3;
+    ta->AVS2 *= 3;
+    ta->AVS3 *= 3;
+    //message processing
+    if (messages && ne.CallbackMessage) { //just to check if communication was enabled
+        if (in[28])
+            ne.CallbackMessage((SMESSAGE*)(in+29));
+        if (in[35])
+            ne.CallbackMessage((SMESSAGE*)(in+36));
+    }
+    increment();
+    interface_connected = 1;
+    if (ne.NotificationCallback) {
+        (*ne.NotificationCallback)(ne.Context);
+    }
+    busy = false;
+        printf("ftdev::FtThreadEnd: release busy at exit\n");
+}
+
+unsigned ftdev::SendFtMessage(unsigned char bHwId, unsigned char bSubId, unsigned dwMessage, unsigned dwWaitTime, unsigned dwOption) {
+    SMESSAGE m;
+    m.L.ucHwId = bHwId;
+    m.L.ucSubId = bSubId;
+    m.L.dw = dwMessage;
+    //waittime ignored
+    if (messages)
+        return messages->push(m, dwOption) < 0 ? FTLIB_ERR_MSG_BUFFER_FULL_TIMEOUT : 0;
+    return FTLIB_ERR_MSG_HWID_WRONG; //not the correct error code
+}
+
+unsigned ftdev::ClearFtMessageBuffer() {
+    if (messages)
+        messages->clear();
+    return 0;
+}