diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 257b2e7..ccc707b 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -71,6 +71,49 @@ PRResult LoadConfiguration(YAML::Node& yamlDoc, const char *yamlFilePath) } +#define drawdot(subFrame) dots[subFrame*(kDMDColumns*kDMDRows/8) + ((row*kDMDColumns+col)/8)] |= 1 << (col % 8) +unsigned char frame[kDMDColumns*kDMDRows] = {0xff}; +void UpdateDots2(unsigned char *dots, unsigned int dotOffset) +{ + int row, col; + memset(dots, 0x00, 4*kDMDColumns*kDMDRows/8); + + if (1) //frame[0] == 0xff) + { + //FILE *f = fopen("../../../../DMDAnimator/Gir Robot.dmd", "rb"); + //FILE *f = fopen("../../../../DMDAnimator/Invader Zim.dmd", "rb"); + FILE *f = NULL; + switch((dotOffset / 100) % 4) + { + case 0: f = fopen("../../../../DMDAnimator/Gir.dmd", "rb"); break; + case 1: f = fopen("../../../../DMDAnimator/Invader Zim.dmd", "rb"); break; + case 2: f = fopen("../../../../DMDAnimator/Gir Robot.dmd", "rb"); break; + case 3: f = fopen("../../../../DMDAnimator/Gnomes.dmd", "rb"); break; + } + int n; + n = fread(frame, 1, 1, f); + n = fread(frame, 1, sizeof(frame), f); + fclose(f); + } + + for (row = kDMDRows - 1; row >= 0; row--) + { + // Loop through each of 16 bytes in a row + for (col = 0; col < kDMDColumns; col++) + { + int dot = frame[row * kDMDColumns + col]; + switch (dot) + { + case 0: + break; + case 1: drawdot(0); break; + case 2: drawdot(0); drawdot(2); break; + case 3: drawdot(0); drawdot(1); drawdot(2); drawdot(3); break; + } + } + } +} + time_t startTime; bool runLoopRun = true; @@ -89,7 +132,7 @@ void RunLoop(PRHandle proc) PRDriverWatchdogTickle(proc); // Create a dot pattern to test the DMD - UpdateDots(dots,dotOffset++); + UpdateDots2(dots,dotOffset++); PRDMDDraw(proc,dots); int numEvents = PRGetEvents(proc, events, maxEvents); @@ -159,7 +202,10 @@ int main(int argc, const char **argv) // Finally instantiate the P-ROC device: PRHandle proc = PRCreate(machineType); if (proc == kPRHandleInvalid) + { + fprintf(stderr, "Error during PRCreate: %s\n", PRGetLastErrorText()); return 1; + } PRReset(proc, kPRResetFlagUpdateDevice); // Reset the device structs and write them into the device. diff --git a/include/pinproc.h b/include/pinproc.h index 8f8c3e0..ccaf50b 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -77,12 +77,14 @@ typedef enum PRLogLevel { kPRLogWarning, kPRLogError } PRLogLevel; - + typedef void (*PRLogCallback)(PRLogLevel level, const char *text); /**< Function pointer type for a custom logging callback. See: PRLogSetCallback(). */ PR_EXPORT void PRLogSetCallback(PRLogCallback callback); /**< Replaces the default logging handler with the given callback function. */ PR_EXPORT void PRLogSetLevel(PRLogLevel level); +PR_EXPORT const char *PRGetLastErrorText(); + /** * @defgroup device Device Creation & Deletion * @{ diff --git a/src/PRCommon.h b/src/PRCommon.h index 6548ff8..b3a541f 100644 --- a/src/PRCommon.h +++ b/src/PRCommon.h @@ -31,6 +31,7 @@ # define DEBUG(block) block #endif -extern void PRLog(PRLogLevel level, const char *format, ...); +void PRLog(PRLogLevel level, const char *format, ...); +void PRSetLastErrorText(const char *format, ...); #endif // _PRCOMMON_H_ diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index cf13cc2..b4a2163 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -199,7 +199,7 @@ PRResult PRDevice::DriverUpdateState(PRDriverState *driverState) if (driverState->polarity != drivers[driverState->driverNum].polarity && machineType != kPRMachineCustom) { - DEBUG(PRLog(kPRLogError, "Refusing to update driver #%d; polarity differs on non-custom machine.\n", driverState->driverNum)); + PRSetLastErrorText("Refusing to update driver #%d; polarity differs on non-custom machine.", driverState->driverNum); return kPRFailure; } @@ -256,7 +256,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR if (switchNum > kPRSwitchPhysicalLast) // Always true due to data type. { - DEBUG(PRLog(kPRLogError, "Switch rule out of range 0-%d\n", kPRSwitchPhysicalLast)); + PRSetLastErrorText("Switch rule out of range 0-%d", kPRSwitchPhysicalLast); return kPRFailure; } @@ -264,7 +264,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR // the links. if (numDrivers > 0 && freeSwitchRuleIndexes.size() < numDrivers-1) // -1 because the first switch rule holds the first driver. { - DEBUG(PRLog(kPRLogError, "Not enough free switch rule indexes: %d available, need %d\n", freeSwitchRuleIndexes.size(), numDrivers)); + PRSetLastErrorText("Not enough free switch rule indexes: %d available, need %d", freeSwitchRuleIndexes.size(), numDrivers); return kPRFailure; } @@ -500,7 +500,7 @@ PRResult PRDevice::PrepareWriteData(uint32_t * words, int32_t numWords) { if (numWords > maxWriteWords) { - DEBUG(PRLog(kPRLogError, "%d words Exceeds write capabilities. Restrict write requests to %d words.", numWords, maxWriteWords)); + PRSetLastErrorText("%d words Exceeds write capabilities. Restrict write requests to %d words.", numWords, maxWriteWords); return kPRFailure; } @@ -509,7 +509,7 @@ PRResult PRDevice::PrepareWriteData(uint32_t * words, int32_t numWords) if (numPreparedWriteWords + numWords > maxWriteWords) { if (FlushWriteData() == kPRFailure); - return kPRFailure; + return kPRFailure; } memcpy(preparedWriteWords + numPreparedWriteWords, words, numWords * 4); @@ -557,7 +557,7 @@ PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords) if (bytesWritten != bytesToWrite) { - DEBUG(PRLog(kPRLogError, "Error in WriteData: wrote %d of %d bytes\n", bytesWritten, bytesToWrite)); + PRSetLastErrorText("Error in WriteData: wrote %d of %d bytes", bytesWritten, bytesToWrite); return kPRFailure; } else diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index d878560..3460012 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -264,7 +264,7 @@ PRResult PRHardwareOpen() // Open the FTDI device if (ftdi_init(&ftdic) != 0) { - DEBUG(PRLog(kPRLogError, "Failed to initialize FTDI.\n")); + PRSetLastErrorText("Failed to initialize FTDI."); return kPRFailure; } @@ -278,7 +278,7 @@ PRResult PRHardwareOpen() // We first enumerate all of the devices: int numDevices = ftdi_usb_find_all(&ftdic, &devlist, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID); if (numDevices < 0) { - DEBUG(PRLog(kPRLogError, "ftdi_usb_find_all failed: %d: %s\n", numDevices, ftdi_get_error_string(&ftdic))); + PRSetLastErrorText("ftdi_usb_find_all failed: %d: %s", numDevices, ftdi_get_error_string(&ftdic)); ftdi_deinit(&ftdic); return kPRFailure; } @@ -305,7 +305,7 @@ PRResult PRHardwareOpen() if ((rc = (int32_t)ftdi_usb_open(&ftdic, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID)) < 0) { - DEBUG(PRLog(kPRLogError, "ERROR: Unable to open ftdi device: %d: %s\n", rc, ftdi_get_error_string(&ftdic))); + PRSetLastErrorText("Unable to open ftdi device: %d: %s", rc, ftdi_get_error_string(&ftdic)); return kPRFailure; } else @@ -323,7 +323,7 @@ PRResult PRHardwareOpen() } else { - DEBUG(PRLog(kPRLogError, "FTDI type != TYPE_R: 0x%x\n", ftdic.type)); + PRSetLastErrorText("FTDI type != TYPE_R: 0x%x", ftdic.type); return kPRFailure; } } diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 9c2e39d..d8bb823 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -31,6 +31,8 @@ #include "../include/pinproc.h" #include "PRDevice.h" +#define MAX_TEXT (1024) + typedef void (*PRLogCallback)(PRLogLevel level, const char *text); PRLogCallback logCallback = NULL; @@ -41,11 +43,10 @@ void PRLog(PRLogLevel level, const char *format, ...) if (level < logLevel) return; - const int maxLogLineLength = 1024; - char line[maxLogLineLength]; + char line[MAX_TEXT]; va_list ap; va_start(ap, format); - vsnprintf(line, maxLogLineLength, format, ap); + vsnprintf(line, MAX_TEXT, format, ap); if (logCallback) logCallback(level, line); else @@ -62,6 +63,21 @@ void PRLogSetLevel(PRLogLevel level) logLevel = level; } +char lastErrorText[MAX_TEXT]; + +void PRSetLastErrorText(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + vsnprintf(lastErrorText, MAX_TEXT, format, ap); + PRLog(kPRLogError, "%s\n", lastErrorText); +} + +PR_EXPORT const char *PRGetLastErrorText() +{ + return lastErrorText; +} + #define handleAsDevice ((PRDevice*)handle) /** Create a new P-ROC device handle. Only one handle per device may be created. This handle must be destroyed with PRDelete() when it is no longer needed. */