class library to access fischertechnik interfaces via USB
Dependencies: FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp
ftlib/ftlibclassdev.cpp
- Committer:
- networker
- Date:
- 2013-03-11
- Revision:
- 1:4676e8b9b357
- Parent:
- 0:7da612835693
File content as of revision 1:4676e8b9b357:
#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; }