From 87c73a1f06ab6d1631b3236587f40d92796fc388 Mon Sep 17 00:00:00 2001 From: Adam Preble Date: Sat, 30 May 2009 14:43:48 -0400 Subject: [PATCH] Added log levels. Fixed bug in PRDevice::Open() if VerifyChipID() worked the first time. --- examples/pinproctest/pinproctest.cpp | 2 +- include/pinproc.h | 10 +++- src/PRCommon.h | 2 +- src/PRDevice.cpp | 82 ++++++++++++++-------------- src/PRHardware.cpp | 22 ++++---- src/pinproc.cpp | 10 +++- 6 files changed, 69 insertions(+), 59 deletions(-) diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index d45d768..ce6f356 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -51,7 +51,7 @@ #define kDMDSubFrames (4) // For color depth of 16 /** Demonstration of the custom logging callback. */ -void TestLogger(const char *text) +void TestLogger(PRLogLevel level, const char *text) { fprintf(stderr, "TEST: %s", text); } diff --git a/include/pinproc.h b/include/pinproc.h index 340675c..0282a11 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -71,9 +71,17 @@ typedef int32_t PRResult; /**< See: #kPRSuccess and #kPRFailure. */ typedef void * PRHandle; /**< Opaque type used to reference an individual P-ROC device. Created with PRCreate() and destroyed with PRDelete(). This value is used as the first parameter to all P-ROC API function calls. */ #define kPRHandleInvalid (0) /**< Value returned by PRCreate() on failure. Indicates an invalid #PRHandle. */ -typedef void (*PRLogCallback)(const char *text); /**< Function pointer type for a custom logging callback. See: PRLogSetCallback(). */ +typedef enum PRLogLevel { + kPRLogInfo, + 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); + /** * @defgroup device Device Creation & Deletion * @{ diff --git a/src/PRCommon.h b/src/PRCommon.h index 6beb403..6548ff8 100644 --- a/src/PRCommon.h +++ b/src/PRCommon.h @@ -31,6 +31,6 @@ # define DEBUG(block) block #endif -extern void PRLog(const char *format, ...); +extern void PRLog(PRLogLevel level, const char *format, ...); #endif // _PRCOMMON_H_ diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 9e6f541..cf0d7de 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -47,13 +47,13 @@ PRDevice* PRDevice::Create(PRMachineType machineType) if (dev == NULL) { - DEBUG(PRLog("Error allocating memory for P-ROC device\n")); + DEBUG(PRLog(kPRLogError, "Error allocating memory for P-ROC device\n")); return NULL; } if (!dev->Open()) { - DEBUG(PRLog("Error opening P-ROC device.\n")); + DEBUG(PRLog(kPRLogError, "Error opening P-ROC device.\n")); delete dev; return NULL; } @@ -150,7 +150,7 @@ PRResult PRDevice::DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalCo uint32_t burst[burstWords]; int32_t rc; - DEBUG(PRLog("Installing driver globals\n")); + DEBUG(PRLog(kPRLogInfo, "Installing driver globals\n")); this->driverGlobalConfig = *driverGlobalConfig; rc = CreateDriverUpdateGlobalConfigBurst(burst, driverGlobalConfig); @@ -158,8 +158,8 @@ PRResult PRDevice::DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalCo driverGlobalConfig->watchdogEnable, driverGlobalConfig->watchdogResetTime); - DEBUG(PRLog("Driver Global words: %x %x\n", burst[0], burst[1])); - DEBUG(PRLog("Watchdog words: %x %x\n", burst[2], burst[3])); + DEBUG(PRLog(kPRLogInfo, "Driver Global words: %x %x\n", burst[0], burst[1])); + DEBUG(PRLog(kPRLogInfo, "Watchdog words: %x %x\n", burst[2], burst[3])); return PrepareWriteData(burst, burstWords); } @@ -176,10 +176,10 @@ PRResult PRDevice::DriverUpdateGroupConfig(PRDriverGroupConfig *driverGroupConfi int32_t rc; driverGroups[driverGroupConfig->groupNum] = *driverGroupConfig; - DEBUG(PRLog("Installing driver group\n")); + DEBUG(PRLog(kPRLogInfo, "Installing driver group\n")); rc = CreateDriverUpdateGroupConfigBurst(burst, driverGroupConfig); - DEBUG(PRLog("Words: %x %x\n", burst[0], burst[1])); + DEBUG(PRLog(kPRLogInfo, "Words: %x %x\n", burst[0], burst[1])); return PrepareWriteData(burst, burstWords); } @@ -195,18 +195,18 @@ PRResult PRDevice::DriverUpdateState(PRDriverState *driverState) uint32_t burst[burstWords]; int32_t rc; - DEBUG(PRLog("Updating driver #%d\n", driverState->driverNum)); + DEBUG(PRLog(kPRLogInfo, "Updating driver #%d\n", driverState->driverNum)); if (driverState->polarity != drivers[driverState->driverNum].polarity && machineType != kPRMachineCustom) { - DEBUG(PRLog("Refusing to update driver #%d; polarity differs on non-custom machine.\n", driverState->driverNum)); + DEBUG(PRLog(kPRLogInfo, "Refusing to update driver #%d; polarity differs on non-custom machine.\n", driverState->driverNum)); return kPRFailure; } drivers[driverState->driverNum] = *driverState; rc = CreateDriverUpdateBurst(burst, &drivers[driverState->driverNum]); - DEBUG(PRLog("Words: %x %x %x\n", burst[0], burst[1], burst[2])); + DEBUG(PRLog(kPRLogInfo, "Words: %x %x %x\n", burst[0], burst[1], burst[2])); return PrepareWriteData(burst, burstWords); } @@ -241,8 +241,8 @@ PRResult PRDevice::SwitchUpdateConfig(PRSwitchConfig *switchConfig) this->switchConfig = *switchConfig; CreateSwitchUpdateConfigBurst(burst, switchConfig); - DEBUG(PRLog("Configuring Switch Logic")); - DEBUG(PRLog("Words: %x %x\n",burst[0],burst[1])); + DEBUG(PRLog(kPRLogInfo, "Configuring Switch Logic")); + DEBUG(PRLog(kPRLogInfo, "Words: %x %x\n",burst[0],burst[1])); rc = PrepareWriteData(burst, burstWords); return rc; @@ -256,7 +256,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR if (switchNum > kPRSwitchPhysicalLast) // Always true due to data type. { - DEBUG(PRLog("Switch rule out of range 0-%d\n", kPRSwitchPhysicalLast)); + DEBUG(PRLog(kPRLogError, "Switch rule out of range 0-%d\n", 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("Not enough free switch rule indexes: %d available, need %d\n", freeSwitchRuleIndexes.size(), numDrivers)); + DEBUG(PRLog(kPRLogError, "Not enough free switch rule indexes: %d available, need %d\n", freeSwitchRuleIndexes.size(), numDrivers)); return kPRFailure; } @@ -283,7 +283,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR uint16_t firstRuleIndex = newRuleIndex; PRSwitchRuleInternal *newRule = GetSwitchRuleByIndex(newRuleIndex); if (newRule->eventType != eventType) - DEBUG(PRLog("Unexpected state: switch rule at 0x%x has event type 0x%x (expected 0x%x).\n", newRuleIndex, newRule->eventType, eventType)); + DEBUG(PRLog(kPRLogWarning, "Unexpected state: switch rule at 0x%x has event type 0x%x (expected 0x%x).\n", newRuleIndex, newRule->eventType, eventType)); newRule->notifyHost = rule->notifyHost; newRule->changeOutput = false; newRule->linkActive = false; @@ -313,20 +313,20 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR CreateSwitchUpdateRulesBurst(burst, newRule); } - DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3])); + DEBUG(PRLog(kPRLogInfo, "Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3])); // Write the rule: res = PrepareWriteData(burst, burstSize); if (res != kPRSuccess) { - DEBUG(PRLog("Error while writing switch update, attempting to revert switch rule to a safe state...")); + DEBUG(PRLog(kPRLogError, "Error while writing switch update, attempting to revert switch rule to a safe state...")); newRule = GetSwitchRuleByIndex(firstRuleIndex); newRule->changeOutput = false; newRule->linkActive = false; CreateSwitchUpdateRulesBurst(burst, newRule); if (PrepareWriteData(burst, burstSize) == kPRSuccess) - DEBUG(PRLog("Disabled successfully.\n")); + DEBUG(PRLog(kPRLogInfo, "Disabled successfully.\n")); else - DEBUG(PRLog("Failed to disable.\n")); + DEBUG(PRLog(kPRLogInfo, "Failed to disable.\n")); return res; } @@ -337,7 +337,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR else { CreateSwitchUpdateRulesBurst(burst, newRule); - DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3])); + DEBUG(PRLog(kPRLogInfo, "Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3])); // Write the rule: res = PrepareWriteData(burst, burstSize); @@ -355,8 +355,8 @@ int32_t PRDevice::DMDUpdateConfig(PRDMDConfig *dmdConfig) this->dmdConfig = *dmdConfig; CreateDMDUpdateConfigBurst(burst, dmdConfig); - DEBUG(PRLog("Configuring DMD")); - DEBUG(PRLog("Words: %x %x %x %x %x %x %x\n",burst[0],burst[1],burst[2],burst[3], + DEBUG(PRLog(kPRLogInfo, "Configuring DMD")); + DEBUG(PRLog(kPRLogInfo, "Words: %x %x %x %x %x %x %x\n",burst[0],burst[1],burst[2],burst[3], burst[4],burst[5],burst[6])); rc = PrepareWriteData(burst, burstWords); @@ -417,24 +417,21 @@ PRResult PRDevice::Open() { // Try to verify the P-ROC IS in the FPGA before initializing the FPGA's FTDI interface // just in case it was already initialized from a previous application execution. - DEBUG(PRLog("Verifying P-ROC ID: \n")); + DEBUG(PRLog(kPRLogInfo, "Verifying P-ROC ID: \n")); if (VerifyChipID() == kPRFailure) { // Since the FPGA didn't appear to be responding properly, send the FPGA's FTDI // initialization sequence. This is a set of bytes the FPGA is waiting to receive // before it allows access deeper into the chip. This keeps garbage from getting // in and wreaking havoc before software is up and running. - DEBUG(PRLog("Initializing P-ROC...\n")); + DEBUG(PRLog(kPRLogInfo, "Initializing P-ROC...\n")); res = FlushReadBuffer(); uint32_t temp_word = P_ROC_INIT_PATTERN_A; res = WriteData(&temp_word, 1); temp_word = P_ROC_INIT_PATTERN_B; res = WriteData(&temp_word, 1); res = VerifyChipID(); - } - else - { - DEBUG(PRLog("Failed to verify chip ID.")); - res = kPRFailure; + if (res == kPRFailure) + DEBUG(PRLog(kPRLogWarning, "Unable to read Chip ID - P-ROC could not be initialized.\n")); } } @@ -474,19 +471,20 @@ PRResult PRDevice::VerifyChipID() if (wordsRead == 5) { //std::cout << rc << " words read. \n" - DEBUG(PRLog("FPGA Chip ID: 0x%x\n", buffer[1])); - DEBUG(PRLog("FPGA Chip Version/Rev: %d.%d\n", buffer[2] >> 16, buffer[2] & 0xffff)); - DEBUG(PRLog("Watchdog Settings: 0x%x\n", buffer[3])); - DEBUG(PRLog("Switches: 0x%x\n", buffer[4])); + DEBUG(PRLog(kPRLogInfo, "FPGA Chip ID: 0x%x\n", buffer[1])); + DEBUG(PRLog(kPRLogInfo, "FPGA Chip Version/Rev: %d.%d\n", buffer[2] >> 16, buffer[2] & 0xffff)); + DEBUG(PRLog(kPRLogInfo, "Watchdog Settings: 0x%x\n", buffer[3])); + DEBUG(PRLog(kPRLogInfo, "Switches: 0x%x\n", buffer[4])); rc = kPRSuccess; } else { - DEBUG(PRLog("Error reading Chip IP and Version. Incorrect number of bytes received from read_data().\n")); + DEBUG(PRLog(kPRLogError, "Error reading Chip IP and Version. Incorrect number of bytes received from read_data().\n")); rc = kPRFailure; } } - else { - DEBUG(PRLog("Unable to read Chip ID - P-ROC not yet initialized.\n")); + else + { + // Return failure without logging; calling function must log. rc = kPRFailure; } return (rc); @@ -502,7 +500,7 @@ PRResult PRDevice::PrepareWriteData(uint32_t * words, int32_t numWords) { if (numWords > maxWriteWords) { - DEBUG(PRLog("%d words Exceeds write capabilities. Restrict write requests to %d words.", numWords, maxWriteWords)); + DEBUG(PRLog(kPRLogError, "%d words Exceeds write capabilities. Restrict write requests to %d words.", numWords, maxWriteWords)); return kPRFailure; } @@ -559,7 +557,7 @@ PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords) if (bytesWritten != bytesToWrite) { - DEBUG(PRLog("Error in WriteData: wrote %d of %d bytes\n", bytesWritten, bytesToWrite)); + DEBUG(PRLog(kPRLogInfo, "Error in WriteData: wrote %d of %d bytes\n", bytesWritten, bytesToWrite)); return kPRFailure; } else @@ -596,7 +594,7 @@ int32_t PRDevice::ReadData(uint32_t *buffer, int32_t num_words) else { rc = 0; } - DEBUG(PRLog("Read num bytes: %d\n", rc)); + DEBUG(PRLog(kPRLogInfo, "Read num bytes: %d\n", rc)); return (rc); } @@ -628,7 +626,7 @@ int32_t PRDevice::CollectReadData() num_collected_bytes += rc; if (rc > 0) { - DEBUG(PRLog("Collected bytes: %d\n", rc)); + DEBUG(PRLog(kPRLogInfo, "Collected bytes: %d\n", rc)); } return (rc); } @@ -643,7 +641,7 @@ PRResult PRDevice::SortReturningData() while (num_words >= 2) { rc = ReadData(rd_buffer, 1); - DEBUG(PRLog("New returning word: 0x%x\n", rd_buffer[0])); + DEBUG(PRLog(kPRLogInfo, "New returning word: 0x%x\n", rd_buffer[0])); switch ( (rd_buffer[0] & P_ROC_COMMAND_MASK) >> P_ROC_COMMAND_SHIFT) { @@ -659,7 +657,7 @@ PRResult PRDevice::SortReturningData() } case P_ROC_UNREQUESTED_DATA: { ReadData(rd_buffer,1); - DEBUG(PRLog("Pushing onto unreq Q 0x%x\n", rd_buffer[0])); + DEBUG(PRLog(kPRLogInfo, "Pushing onto unreq Q 0x%x\n", rd_buffer[0])); unrequestedDataQueue.push(rd_buffer[0]); break; } diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index 3a7fe27..d878560 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("Failed to initialize FTDI.\n")); + DEBUG(PRLog(kPRLogError, "Failed to initialize FTDI.\n")); return kPRFailure; } @@ -278,22 +278,22 @@ 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("ftdi_usb_find_all failed: %d: %s\n", numDevices, ftdi_get_error_string(&ftdic))); + DEBUG(PRLog(kPRLogError, "ftdi_usb_find_all failed: %d: %s\n", numDevices, ftdi_get_error_string(&ftdic))); ftdi_deinit(&ftdic); return kPRFailure; } else { - DEBUG(PRLog("Number of FTDI devices found: %d\n", numDevices)); + DEBUG(PRLog(kPRLogInfo, "Number of FTDI devices found: %d\n", numDevices)); for (curdev = devlist; curdev != NULL; i++) { - DEBUG(PRLog("Checking device %d\n", i)); + DEBUG(PRLog(kPRLogInfo, "Checking device %d\n", i)); if ((rc = (int32_t)ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, NULL, 0)) < 0) { - DEBUG(PRLog(" ftdi_usb_get_strings failed: %d: %s\n", rc, ftdi_get_error_string(&ftdic))); + DEBUG(PRLog(kPRLogInfo, " ftdi_usb_get_strings failed: %d: %s\n", rc, ftdi_get_error_string(&ftdic))); } else { - DEBUG(PRLog(" Device #%d:\n", i)); - DEBUG(PRLog(" Manufacturer: %s\n", manufacturer)); - DEBUG(PRLog(" Description: %s\n", description)); + DEBUG(PRLog(kPRLogInfo, " Device #%d:\n", i)); + DEBUG(PRLog(kPRLogInfo, " Manufacturer: %s\n", manufacturer)); + DEBUG(PRLog(kPRLogInfo, " Description: %s\n", description)); } curdev = curdev->next; } @@ -305,7 +305,7 @@ PRResult PRHardwareOpen() if ((rc = (int32_t)ftdi_usb_open(&ftdic, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID)) < 0) { - DEBUG(PRLog("ERROR: Unable to open ftdi device: %d: %s\n", rc, ftdi_get_error_string(&ftdic))); + DEBUG(PRLog(kPRLogError, "ERROR: Unable to open ftdi device: %d: %s\n", rc, ftdi_get_error_string(&ftdic))); return kPRFailure; } else @@ -314,7 +314,7 @@ PRResult PRHardwareOpen() if (ftdic.type == TYPE_R) { uint32_t chipid; ftdi_read_chipid(&ftdic,&chipid); - DEBUG(PRLog("FTDI chip_id = 0x%x\n", chipid)); + DEBUG(PRLog(kPRLogInfo, "FTDI chip_id = 0x%x\n", chipid)); // Set some defaults: ftdi_read_data_set_chunksize(&ftdic, 4096); ftdi_set_latency_timer(&ftdic, 2); // This helps make reads much faster. 16 appeared to be the default. @@ -323,7 +323,7 @@ PRResult PRHardwareOpen() } else { - DEBUG(PRLog("FTDI type != TYPE_R: 0x%x\n", ftdic.type)); + DEBUG(PRLog(kPRLogError, "FTDI type != TYPE_R: 0x%x\n", ftdic.type)); return kPRFailure; } } diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 8245a47..698755e 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -31,19 +31,23 @@ #include "../include/pinproc.h" #include "PRDevice.h" -typedef void (*PRLogCallback)(const char *text); +typedef void (*PRLogCallback)(PRLogLevel level, const char *text); PRLogCallback logCallback = NULL; +PRLogLevel logLevel = kPRLogError; -void PRLog(const char *format, ...) +void PRLog(PRLogLevel level, const char *format, ...) { + if (level < logLevel) + return; + const int maxLogLineLength = 1024; char line[maxLogLineLength]; va_list ap; va_start(ap, format); vsnprintf(line, maxLogLineLength, format, ap); if (logCallback) - logCallback(line); + logCallback(level, line); else fprintf(stderr, line); }