class library to access fischertechnik interfaces via USB
Dependencies: FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp
Diff: ftlib/ftlibclassdev.cpp
- Revision:
- 0:7da612835693
- Child:
- 1:4676e8b9b357
diff -r 000000000000 -r 7da612835693 ftlib/ftlibclassdev.cpp --- /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; +}