diff --git a/include/pinproc.h b/include/pinproc.h index f2ddabe..fbbf097 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -39,7 +39,9 @@ #if defined(PR_BUILDING_PR) #define PR_EXPORT __declspec(dllexport) extern #else - #define PR_EXPORT __declspec(dllimport) extern + // TODO: Decide what to do here: + //#define PR_EXPORT __declspec(dllimport) extern + #define PR_EXPORT #endif #endif @@ -115,9 +117,15 @@ PR_EXPORT PRResult PRReset(PRHandle handle, uint32_t resetFlags); // I/O -/** Flush all pending write data out to the P-ROC */ +/** Flush all pending write data out to the P-ROC. */ PR_EXPORT PRResult PRFlushWriteData(PRHandle handle); +/** Write data out to the P-ROC immediately (does not require a call to PRFlushWriteData). */ +PR_EXPORT PRResult PRWriteData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer); + +/** Read data from the P-ROC. */ +PR_EXPORT PRResult PRReadData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer); + // Drivers /** @defgroup drivers Driver Manipulation * @{ diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index b67c4e2..84fbe0b 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -525,7 +525,7 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit // Wait for data to return. Give it 10 loops before giving up. while (requestedDataQueue.size() < numWords && i++ < 10) { - sleep (.01); // 10 milliseconds should be plenty of time. + PRSleep (10); // 10 milliseconds should be plenty of time. SortReturningData(); } @@ -677,7 +677,7 @@ PRResult PRDevice::VerifyChipID() max_count = 0; //std::cout << "Waiting for read data "; while (num_collected_bytes < (bufferWords*4) && max_count < 10) { - sleep(.01); + PRSleep(10); //std::cout << ". "; rc = CollectReadData(); max_count++; @@ -784,6 +784,51 @@ PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords) } } +PRResult PRDevice::WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) +{ + uint32_t * buffer; + + buffer = (uint32_t *)malloc((numWriteWords * 4) + 1); + buffer[0] = CreateBurstCommand(moduleSelect, startingAddr, numWriteWords); + memcpy(buffer+1, writeBuffer, numWriteWords * 4); + WriteData(buffer, numWriteWords + 1); + free (buffer); +} + +PRResult PRDevice::ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer) +{ + uint32_t rc; + uint8_t i; + + // Send out the request. + rc = RequestData(moduleSelect, startingAddr, numReadWords); + + i = 0; // Reset i so it can be used to prevent an infinite loop below + + // Wait for data to return. Give it 10 loops before giving up. + // Expect numReadWords + 1 word with the address. + while (requestedDataQueue.size() < (numReadWords + 1) && i++ < 10) + { + PRSleep (10); // 10 milliseconds should be plenty of time. + SortReturningData(); + } + + // Make sure all of the requested words are available before processing them. + // Too many words is just as bad as not enough words. + // If too many come back, can they be trusted? + if (requestedDataQueue.size() == numReadWords + 1) + { + requestedDataQueue.pop(); // Ignore address word. TODO: Verify the address. + for (i = 0; i < numReadWords; i++) + { + readBuffer[i] = requestedDataQueue.front(); + requestedDataQueue.pop(); + } + return kPRSuccess; + } + else return kPRFailure; +} + int32_t PRDevice::ReadData(uint32_t *buffer, int32_t num_words) { @@ -834,7 +879,7 @@ int32_t PRDevice::CollectReadData() { int32_t rc,i; rc = PRHardwareRead(collect_buffer, FTDI_BUFFER_SIZE-num_collected_bytes); - for (i=0; i 0) + { + FT_ResetDevice(ftHandle); + DEBUG(PRLog(kPRLogInfo,"FTDI Device Opened\n")); + return kPRSuccess; + } + else return kPRFailure; +} + +void PRHardwareClose() +{ + int i; + + for(i = 0; i < MAX_DEVICES; i++) { + if(ftHandles[i] != NULL) { + FT_Close(ftHandles[i]); + ftHandles[i] = NULL; + DEBUG(PRLog(kPRLogInfo,"Closed device\n")); + } + } +} + +int PRHardwareRead(uint8_t *buffer, int maxBytes) +{ + FT_STATUS ftStatus; + DWORD bytesToRead; + DWORD bytesRead; + int i; + + ftStatus = FT_GetQueueStatus(ftHandle,&bytesToRead); + if (ftStatus != FT_OK) return 0; + + if (maxBytes < bytesToRead) bytesToRead = maxBytes; + ftStatus = FT_Read(ftHandle, buffer, bytesToRead, &bytesRead); + if (ftStatus == FT_OK) { + DEBUG(PRLog(kPRLogVerbose,"Read %d bytes:\n",bytesRead)); + for (i=0; i #include "../include/pinproc.h" +#if defined(__WIN32__) + #include + #define PRSleep(milliseconds) Sleep(milliseconds) +#else + #define PRSleep(milliseconds) sleep(milliseconds/1000) +#endif + const int32_t FTDI_VENDOR_ID = 0x0403; const int32_t FTDI_FT245RL_PRODUCT_ID = 0x6001; diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 3fe7359..d9191dc 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -30,6 +30,7 @@ #include "../include/pinproc.h" #include "PRDevice.h" +#include #define MAX_TEXT (1024) @@ -110,6 +111,18 @@ PR_EXPORT PRResult PRFlushWriteData(PRHandle handle) return handleAsDevice->FlushWriteData(); } +/** Write data out to the P-ROC immediately (does not require a call to PRFlushWriteData */ +PR_EXPORT PRResult PRWriteData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) +{ + return handleAsDevice->WriteDataRaw(moduleSelect, startingAddr, numWriteWords, writeBuffer); +} + +/** Read data from the P-ROC. */ +PR_EXPORT PRResult PRReadData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer) +{ + return handleAsDevice->ReadDataRaw(moduleSelect, startingAddr, numReadWords, readBuffer); +} + // Events /** Get all of the available events that have been received. */