1
0
mirror of https://github.com/preble/libpinproc synced 2026-02-24 18:25:23 +01:00

Merge branch 'master' of git@github.com:preble/P-ROC

This commit is contained in:
gstellenberg
2009-05-30 14:14:20 -05:00
6 changed files with 74 additions and 59 deletions

View File

@@ -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);
}

View File

@@ -71,9 +71,18 @@ 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 {
kPRLogVerbose,
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
* @{

View File

@@ -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_

View File

@@ -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(kPRLogVerbose, "Driver Global words: %x %x\n", burst[0], burst[1]));
DEBUG(PRLog(kPRLogVerbose, "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(kPRLogVerbose, "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(kPRLogError, "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(kPRLogVerbose, "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(kPRLogVerbose, "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(kPRLogVerbose, "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(kPRLogError, "Disabled successfully.\n"));
else
DEBUG(PRLog("Failed to disable.\n"));
DEBUG(PRLog(kPRLogError, "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(kPRLogVerbose, "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(kPRLogVerbose, "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(kPRLogError, "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(kPRLogVerbose, "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(kPRLogVerbose, "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(kPRLogVerbose, "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(kPRLogVerbose, "Pushing onto unreq Q 0x%x\n", rd_buffer[0]));
unrequestedDataQueue.push(rd_buffer[0]);
break;
}

View File

@@ -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;
}
}

View File

@@ -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);
}
@@ -53,6 +57,10 @@ void PRLogSetCallback(PRLogCallback callback)
logCallback = callback;
}
void PRLogSetLevel(PRLogLevel level)
{
logLevel = level;
}
#define handleAsDevice ((PRDevice*)handle)