diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index b9c274f..932d924 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -1,7 +1,7 @@ -/* +/* * The MIT License * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -9,11 +9,11 @@ * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following - * conditions: - * + * conditions: + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -36,153 +36,153 @@ /** Demonstration of the custom logging callback. */ void TestLogger(const char *text) { - fprintf(stderr, "TEST: %s", text); + fprintf(stderr, "TEST: %s", text); } void ConfigureDrivers(PRHandle proc) { - int i; - - PRDriverGlobalConfig globals; - globals.enableOutputs = false; - globals.globalPolarity = false; - globals.useClear = false; - globals.strobeStartSelect = false; - globals.startStrobeTime = 4; // milliseconds per output loop - globals.matrixRowEnableIndex1 = 12; - globals.matrixRowEnableIndex0 = 6; - globals.activeLowMatrixRows = true; - globals.tickleWatchdog = false; - globals.encodeEnables = false; - - // We want to start up safely, so we'll update the global driver config twice. - // When we toggle enableOutputs like this P-ROC will reset the polarity: - + int i; + + PRDriverGlobalConfig globals; + globals.enableOutputs = false; + globals.globalPolarity = false; + globals.useClear = false; + globals.strobeStartSelect = false; + globals.startStrobeTime = 4; // milliseconds per output loop + globals.matrixRowEnableIndex1 = 12; + globals.matrixRowEnableIndex0 = 6; + globals.activeLowMatrixRows = true; + globals.tickleWatchdog = false; + globals.encodeEnables = false; + + // We want to start up safely, so we'll update the global driver config twice. + // When we toggle enableOutputs like this P-ROC will reset the polarity: + // Enable now without the outputs enabled: - PRDriverUpdateGlobalConfig(proc, &globals); - - // Now enable the outputs: (TODO: Why?) - globals.enableOutputs = true; - PRDriverUpdateGlobalConfig(proc, &globals); - - // Configure the groups: - - PRDriverGroupConfig group; - for (i = 0; i < 6; i++) - { - PRDriverGetGroupConfig(proc, i + 4, &group); - group.slowTime = 0; - group.enableIndex = i; - group.rowActivateIndex = i; - group.rowEnableSelect = 0; - group.matrixed = false; - group.polarity = false; - group.active = 1; - group.disableStrobeAfter = false; - - PRDriverUpdateGroupConfig(proc, &group); - } - - for (i = 6; i < 14; i++) { - PRDriverGetGroupConfig(proc, i + 4, &group); - group.slowTime = 400; - group.enableIndex = 7; - group.rowActivateIndex = i - 6; - group.rowEnableSelect = 0; - group.matrixed = 1; - group.polarity = 0; - group.active = 1; - group.disableStrobeAfter = 1; - PRDriverUpdateGroupConfig(proc, &group); + PRDriverUpdateGlobalConfig(proc, &globals); + + // Now enable the outputs: (TODO: Why?) + globals.enableOutputs = true; + PRDriverUpdateGlobalConfig(proc, &globals); + + // Configure the groups: + + PRDriverGroupConfig group; + for (i = 0; i < 6; i++) + { + PRDriverGetGroupConfig(proc, i + 4, &group); + group.slowTime = 0; + group.enableIndex = i; + group.rowActivateIndex = i; + group.rowEnableSelect = 0; + group.matrixed = false; + group.polarity = false; + group.active = 1; + group.disableStrobeAfter = false; + + PRDriverUpdateGroupConfig(proc, &group); + } + + for (i = 6; i < 14; i++) { + PRDriverGetGroupConfig(proc, i + 4, &group); + group.slowTime = 400; + group.enableIndex = 7; + group.rowActivateIndex = i - 6; + group.rowEnableSelect = 0; + group.matrixed = 1; + group.polarity = 0; + group.active = 1; + group.disableStrobeAfter = 1; + PRDriverUpdateGroupConfig(proc, &group); } } void ConfigureSwitches(PRHandle proc) { - int i; - - // Create a basic driver for all of the switches to default to: - PRDriverState defaultDriver; - memset(&defaultDriver, 0x0, sizeof(defaultDriver)); // Set all fields to 0. - - for (i = 0; i <= kPRSwitchPhysicalLast; i++) - { - PRSwitchRule sw; - sw.switchNum = i; - sw.notifyHost = true; - sw.changeOutput = false; - sw.linkActive = false; - sw.linkAddress = 0; - sw.eventType = kPREventTypeSwitchClosedDebounced; - sw.driver = defaultDriver; - PRSwitchesUpdateRules(proc, &sw, 1); - sw.eventType = kPREventTypeSwitchOpenDebounced; - PRSwitchesUpdateRules(proc, &sw, 1); - } + int i; + + // Create a basic driver for all of the switches to default to: + PRDriverState defaultDriver; + memset(&defaultDriver, 0x0, sizeof(defaultDriver)); // Set all fields to 0. + + for (i = 0; i <= kPRSwitchPhysicalLast; i++) + { + PRSwitchRule sw; + sw.switchNum = i; + sw.notifyHost = true; + sw.changeOutput = false; + sw.linkActive = false; + sw.linkAddress = 0; + sw.eventType = kPREventTypeSwitchClosedDebounced; + sw.driver = defaultDriver; + PRSwitchesUpdateRules(proc, &sw, 1); + sw.eventType = kPREventTypeSwitchOpenDebounced; + PRSwitchesUpdateRules(proc, &sw, 1); + } } bool runLoopRun = true; void RunLoop(PRHandle proc) { - const int maxEvents = 16; - PREvent events[maxEvents]; - while (runLoopRun) - { - int numEvents = PRGetEvents(proc, events, maxEvents); - for (int i = 0; i < numEvents; i++) - { - PREvent *event = &events[i]; - const char *stateText = "Unknown"; - switch (event->type) - { - case kPREventTypeSwitchOpenDebounced: stateText = "open"; break; - case kPREventTypeSwitchClosedDebounced: stateText = "closed"; break; - case kPREventTypeSwitchOpenNondebounced: stateText = "open(ndb)"; break; - case kPREventTypeSwitchClosedNondebounced: stateText = "closed(ndb)"; break; - } - printf("switch % 3d: %s\n", event->value, stateText); - } - usleep(10*1000); // Sleep for 10ms so we aren't pegging the CPU. - } + const int maxEvents = 16; + PREvent events[maxEvents]; + while (runLoopRun) + { + int numEvents = PRGetEvents(proc, events, maxEvents); + for (int i = 0; i < numEvents; i++) + { + PREvent *event = &events[i]; + const char *stateText = "Unknown"; + switch (event->type) + { + case kPREventTypeSwitchOpenDebounced: stateText = "open"; break; + case kPREventTypeSwitchClosedDebounced: stateText = "closed"; break; + case kPREventTypeSwitchOpenNondebounced: stateText = "open(ndb)"; break; + case kPREventTypeSwitchClosedNondebounced: stateText = "closed(ndb)"; break; + } + printf("switch % 3d: %s\n", event->value, stateText); + } + usleep(10*1000); // Sleep for 10ms so we aren't pegging the CPU. + } } void sigint(int) { - runLoopRun = false; - signal(SIGINT, SIG_DFL); // Re-install the default signal handler. - printf("Exiting...\n"); + runLoopRun = false; + signal(SIGINT, SIG_DFL); // Re-install the default signal handler. + printf("Exiting...\n"); } int main(const char **argv, int argc) { - // Set a signal handler so that we can exit gracefully on Ctrl-C: - signal(SIGINT, sigint); - - // Assign a custom logging callback to demonstrate capturing log information from P-ROC: - PRLogSetCallback(TestLogger); - - // Finally instantiate the P-ROC device: - PRHandle proc = PRCreate(kPRMachineWPC); - if (proc == kPRHandleInvalid) - return 1; - - printf("Configuring P-ROC...\n"); - - ConfigureDrivers(proc); - ConfigureSwitches(proc); - - printf("Running. Hit Ctrl-C to exit.\n"); - - // Pulse a coil to test: + // Set a signal handler so that we can exit gracefully on Ctrl-C: + signal(SIGINT, sigint); + + // Assign a custom logging callback to demonstrate capturing log information from P-ROC: + PRLogSetCallback(TestLogger); + + // Finally instantiate the P-ROC device: + PRHandle proc = PRCreate(kPRMachineWPC); + if (proc == kPRHandleInvalid) + return 1; + + printf("Configuring P-ROC...\n"); + + ConfigureDrivers(proc); + ConfigureSwitches(proc); + + printf("Running. Hit Ctrl-C to exit.\n"); + + // Pulse a coil to test: // PRDriverDisable(proc, 80); // PRDriverPulse(proc, 53, 100); - - RunLoop(proc); - // Destroy the P-ROC device handle: - PRDelete(proc); - proc = kPRHandleInvalid; - - return 0; -} \ No newline at end of file + RunLoop(proc); + + // Destroy the P-ROC device handle: + PRDelete(proc); + proc = kPRHandleInvalid; + + return 0; +} diff --git a/include/pinproc.h b/include/pinproc.h index 95ebd4f..7661e64 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -1,7 +1,7 @@ -/* +/* * The MIT License * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -9,11 +9,11 @@ * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following - * conditions: - * + * conditions: + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -25,7 +25,7 @@ */ /** @file pinproc.h * @brief libpinproc, P-ROC Layer 1 API (Preliminary) - * + * */ #ifndef _PINPROC_H_ @@ -35,26 +35,26 @@ /** @cond */ #if defined(__WIN32__) - #undef PR_EXPORT - #if defined(PR_BUILDING_PR) - #define PR_EXPORT __declspec(dllexport) extern - #else - #define PR_EXPORT __declspec(dllimport) extern - #endif + #undef PR_EXPORT + #if defined(PR_BUILDING_PR) + #define PR_EXPORT __declspec(dllexport) extern + #else + #define PR_EXPORT __declspec(dllimport) extern + #endif #endif #if !defined(PR_EXPORT) - #define PR_EXPORT extern + #define PR_EXPORT extern #endif #if !defined(PR_EXTERN_C_BEGIN) - #if defined(__cplusplus) - #define PR_EXTERN_C_BEGIN extern "C" { - #define PR_EXTERN_C_END } - #else - #define PR_EXTERN_C_BEGIN - #define PR_EXTERN_C_END - #endif + #if defined(__cplusplus) + #define PR_EXTERN_C_BEGIN extern "C" { + #define PR_EXTERN_C_END } + #else + #define PR_EXTERN_C_BEGIN + #define PR_EXTERN_C_END + #endif #endif /** @endcond */ @@ -67,20 +67,20 @@ PR_EXTERN_C_BEGIN typedef int32_t bool_t; // FIXME: This needs better platform independence. typedef int32_t PRResult; /**< See: #kPRSuccess and #kPRFailure. */ -#define kPRSuccess (1) /**< Success value for #PRResult. */ -#define kPRFailure (0) /**< Failure value for #PRResult. */ +#define kPRSuccess (1) /**< Success value for #PRResult. */ +#define kPRFailure (0) /**< Failure value for #PRResult. */ + +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 * 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(). */ PR_EXPORT void PRLogSetCallback(PRLogCallback callback); /**< Replaces the default logging handler with the given callback function. */ typedef enum PRMachineType { - kPRMachineInvalid = 0, - kPRMachineCustom = 1, - kPRMachineWPC = 2, - kPRMachineStern = 3, // May be split into kPRMachineWhitestar and kPRMachineSAM. + kPRMachineInvalid = 0, + kPRMachineCustom = 1, + kPRMachineWPC = 2, + kPRMachineStern = 3, // May be split into kPRMachineWhitestar and kPRMachineSAM. } PRMachineType; // PRHandle Creation and Deletion @@ -92,18 +92,18 @@ PR_EXPORT void PRDelete(PRHandle handle); /**< Destroys an existin // Events // Closed == 0, Open == 1 typedef enum PREventType { - kPREventTypeInvalid = 0, - kPREventTypeSwitchClosedDebounced = 1, /**< The switch has gone from open to closed and the signal has been debounced. */ - kPREventTypeSwitchOpenDebounced = 2, /**< The switch has gone from closed to open and the signal has been debounced. */ - kPREventTypeSwitchClosedNondebounced = 3, /**< The switch has gone from open to closed and the signal has not been debounced. */ - kPREventTypeSwitchOpenNondebounced = 4, /**< The switch has gone from closed to open and the signal has not been debounced. */ - kPREventTypetLast = kPREventTypeSwitchOpenNondebounced + kPREventTypeInvalid = 0, + kPREventTypeSwitchClosedDebounced = 1, /**< The switch has gone from open to closed and the signal has been debounced. */ + kPREventTypeSwitchOpenDebounced = 2, /**< The switch has gone from closed to open and the signal has been debounced. */ + kPREventTypeSwitchClosedNondebounced = 3, /**< The switch has gone from open to closed and the signal has not been debounced. */ + kPREventTypeSwitchOpenNondebounced = 4, /**< The switch has gone from closed to open and the signal has not been debounced. */ + kPREventTypetLast = kPREventTypeSwitchOpenNondebounced } PREventType; typedef struct PREvent { - PREventType type; /**< The type of event that has occurred. Usually a switch event at this point. */ - uint32_t value; /**< For switch events, the switch number that has changed. */ - uint32_t time; /**< Time (in milliseconds) that this event occurred. */ + PREventType type; /**< The type of event that has occurred. Usually a switch event at this point. */ + uint32_t value; /**< For switch events, the switch number that has changed. */ + uint32_t time; /**< Time (in milliseconds) that this event occurred. */ } PREvent; /** Get all of the available events that have been received. */ @@ -113,40 +113,40 @@ PR_EXPORT int PRGetEvents(PRHandle handle, PREvent *eventsOut, int maxEvents); // Drivers typedef struct PRDriverGlobalConfig { - bool_t enableOutputs; // Formerly enable_direct_outputs - bool_t globalPolarity; - bool_t useClear; - bool_t strobeStartSelect; - uint8_t startStrobeTime; - uint8_t matrixRowEnableIndex1; - uint8_t matrixRowEnableIndex0; - bool_t activeLowMatrixRows; - bool_t encodeEnables; - bool_t tickleWatchdog; + bool_t enableOutputs; // Formerly enable_direct_outputs + bool_t globalPolarity; + bool_t useClear; + bool_t strobeStartSelect; + uint8_t startStrobeTime; + uint8_t matrixRowEnableIndex1; + uint8_t matrixRowEnableIndex0; + bool_t activeLowMatrixRows; + bool_t encodeEnables; + bool_t tickleWatchdog; } PRDriverGlobalConfig; typedef struct PRDriverGroupConfig { - uint8_t groupNum; - uint16_t slowTime; - uint8_t enableIndex; - uint8_t rowActivateIndex; - uint8_t rowEnableSelect; - bool_t matrixed; - bool_t polarity; - bool_t active; - bool_t disableStrobeAfter; + uint8_t groupNum; + uint16_t slowTime; + uint8_t enableIndex; + uint8_t rowActivateIndex; + uint8_t rowEnableSelect; + bool_t matrixed; + bool_t polarity; + bool_t active; + bool_t disableStrobeAfter; } PRDriverGroupConfig; typedef struct PRDriverState { - uint16_t driverNum; - uint32_t outputDriveTime; - bool_t polarity; - bool_t state; - bool_t waitForFirstTimeSlot; - uint32_t timeslots; - uint8_t patterOnTime; - uint8_t patterOffTime; - bool_t patterEnable; + uint16_t driverNum; + uint32_t outputDriveTime; + bool_t polarity; + bool_t state; + bool_t waitForFirstTimeSlot; + uint32_t timeslots; + uint8_t patterOnTime; + uint8_t patterOffTime; + bool_t patterEnable; } PRDriverState; /** Update registers for the global driver configuration. */ @@ -175,23 +175,23 @@ PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t // Switches -/** @defgroup switchconsts Switch Constants +/** @defgroup switchconsts Switch Constants * @{ */ -#define kPRSwitchPhysicalFirst (0) /**< Switch number of the first physical switch. */ +#define kPRSwitchPhysicalFirst (0) /**< Switch number of the first physical switch. */ #define kPRSwitchPhysicalLast (223) /**< Switch number of the last physical switch. */ #define kPRSwitchVirtualFirst (224) /**< Switch number of the first virtual switch. */ -#define kPRSwitchVirtualLast (255) /**< Switch number of the last virtual switch. */ +#define kPRSwitchVirtualLast (255) /**< Switch number of the last virtual switch. */ /** @} */ typedef struct PRSwitchRule { - uint16_t switchNum; /**< Number of the physical switch, or for linked driver changes the virtual switch number (224 and up). */ - PREventType eventType; /**< The event type that this rule generates. Determines closed/open, debounced/non-debounced. */ - bool_t notifyHost; - bool_t changeOutput; /**< True if this switch rule should affect a driver output change. */ - bool_t linkActive; /**< True if this switch rule has additional linked driver updates. */ - uint32_t linkAddress; /**< Switch number of the linked driver update. */ - PRDriverState driver; /**< Driver state change to affect once this rule is triggered. */ + uint16_t switchNum; /**< Number of the physical switch, or for linked driver changes the virtual switch number (224 and up). */ + PREventType eventType; /**< The event type that this rule generates. Determines closed/open, debounced/non-debounced. */ + bool_t notifyHost; + bool_t changeOutput; /**< True if this switch rule should affect a driver output change. */ + bool_t linkActive; /**< True if this switch rule has additional linked driver updates. */ + uint32_t linkAddress; /**< Switch number of the linked driver update. */ + PRDriverState driver; /**< Driver state change to affect once this rule is triggered. */ } PRSwitchRule; /** Updates the rules for the given switch and PREventType combinations. */ @@ -202,15 +202,15 @@ PR_EXPORT PRResult PRSwitchesUpdateRules(PRHandle handle, PRSwitchRule *rules, i // DMD typedef struct PRDMDGlobalConfig { - uint8_t numRows; - uint16_t numColumns; - uint8_t numSubFrames; - uint16_t cyclesPerRow; - bool_t enable; - uint8_t rclkLowCycles[8]; - uint8_t latchHighCycles[8]; - uint16_t deHighCycles[8]; - uint8_t dotclkHalfPeriod[8]; + uint8_t numRows; + uint16_t numColumns; + uint8_t numSubFrames; + uint16_t cyclesPerRow; + bool_t enable; + uint8_t rclkLowCycles[8]; + uint8_t latchHighCycles[8]; + uint16_t deHighCycles[8]; + uint8_t dotclkHalfPeriod[8]; } PRDMDConfig; /** Sets the configuration registers for the DMD driver. */ diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 95a24ee..c458875 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -1,7 +1,7 @@ -/* +/* * The MIT License * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -9,11 +9,11 @@ * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following - * conditions: - * + * conditions: + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -32,300 +32,300 @@ PRDevice::PRDevice(PRMachineType machineType) : machineType(machineType), ftdiInitialized(false) { - Reset(); + Reset(); } PRDevice::~PRDevice() { - Close(); + Close(); } PRDevice* PRDevice::Create(PRMachineType machineType) { - PRDevice *dev = new PRDevice(machineType); - - if (dev == NULL) - { - DEBUG(PRLog("Error allocating memory for P-ROC device\n")); - return NULL; - } - - if (!dev->Open()) - { - DEBUG(PRLog("Error opening P-ROC device.\n")); - delete dev; - return NULL; - } - - dev->Reset(); + PRDevice *dev = new PRDevice(machineType); - return dev; + if (dev == NULL) + { + DEBUG(PRLog("Error allocating memory for P-ROC device\n")); + return NULL; + } + + if (!dev->Open()) + { + DEBUG(PRLog("Error opening P-ROC device.\n")); + delete dev; + return NULL; + } + + dev->Reset(); + + return dev; } void PRDevice::Reset() { - bool defaultPolarity = machineType != kPRMachineWPC; - int i; - memset(&driverGlobalConfig, 0x00, sizeof(PRDriverGlobalConfig)); - for (i = 0; i < maxDrivers; i++) - { - PRDriverState *driver = &drivers[i]; - memset(driver, 0x00, sizeof(PRDriverState)); - driver->driverNum = i; - driver->polarity = defaultPolarity; - } - for (i = 0; i < maxDriverGroups; i++) - { - PRDriverGroupConfig *group = &driverGroups[i]; - memset(group, 0x00, sizeof(PRDriverGroupConfig)); - group->groupNum = i; - group->polarity = defaultPolarity; - } - for (i = 0; i < maxSwitchRules; i++) - { - PRSwitchRule *switchRule = &switchRules[i]; - memset(switchRule, 0x00, sizeof(PRSwitchRule)); - switchRule->switchNum = i; - switchRule->driver.polarity = defaultPolarity; - } - - unrequestedDataQueue.empty(); - requestedDataQueue.empty(); - num_collected_bytes = 0; - - // TODO: Assign defaults based on machineType. Some may have already been done above. + bool defaultPolarity = machineType != kPRMachineWPC; + int i; + memset(&driverGlobalConfig, 0x00, sizeof(PRDriverGlobalConfig)); + for (i = 0; i < maxDrivers; i++) + { + PRDriverState *driver = &drivers[i]; + memset(driver, 0x00, sizeof(PRDriverState)); + driver->driverNum = i; + driver->polarity = defaultPolarity; + } + for (i = 0; i < maxDriverGroups; i++) + { + PRDriverGroupConfig *group = &driverGroups[i]; + memset(group, 0x00, sizeof(PRDriverGroupConfig)); + group->groupNum = i; + group->polarity = defaultPolarity; + } + for (i = 0; i < maxSwitchRules; i++) + { + PRSwitchRule *switchRule = &switchRules[i]; + memset(switchRule, 0x00, sizeof(PRSwitchRule)); + switchRule->switchNum = i; + switchRule->driver.polarity = defaultPolarity; + } + + unrequestedDataQueue.empty(); + requestedDataQueue.empty(); + num_collected_bytes = 0; + + // TODO: Assign defaults based on machineType. Some may have already been done above. } int PRDevice::GetEvents(PREvent *events, int maxEvents) { - SortReturningData(); - - // The unrequestedDataQueue only has unrequested switch event data. Pop - // events out 1 at a time, interpret them, and populate the outgoing list with them. - int i; - for (i = 0; (i < maxEvents) && !unrequestedDataQueue.empty(); i++) - { - uint32_t event_data = unrequestedDataQueue.front(); - unrequestedDataQueue.pop(); - - events[i].value = event_data & P_ROC_EVENT_SWITCH_NUM_MASK; - bool open = (event_data & P_ROC_EVENT_SWITCH_STATE_MASK) >> P_ROC_EVENT_SWITCH_STATE_SHIFT; - bool debounced = (event_data & P_ROC_EVENT_SWITCH_DEBOUNCED_MASK) >> P_ROC_EVENT_SWITCH_DEBOUNCED_SHIFT; - if (open) - events[i].type = debounced ? kPREventTypeSwitchOpenDebounced : kPREventTypeSwitchOpenNondebounced; - else - events[i].type = debounced ? kPREventTypeSwitchClosedDebounced : kPREventTypeSwitchOpenNondebounced; - } - return i; + SortReturningData(); + + // The unrequestedDataQueue only has unrequested switch event data. Pop + // events out 1 at a time, interpret them, and populate the outgoing list with them. + int i; + for (i = 0; (i < maxEvents) && !unrequestedDataQueue.empty(); i++) + { + uint32_t event_data = unrequestedDataQueue.front(); + unrequestedDataQueue.pop(); + + events[i].value = event_data & P_ROC_EVENT_SWITCH_NUM_MASK; + bool open = (event_data & P_ROC_EVENT_SWITCH_STATE_MASK) >> P_ROC_EVENT_SWITCH_STATE_SHIFT; + bool debounced = (event_data & P_ROC_EVENT_SWITCH_DEBOUNCED_MASK) >> P_ROC_EVENT_SWITCH_DEBOUNCED_SHIFT; + if (open) + events[i].type = debounced ? kPREventTypeSwitchOpenDebounced : kPREventTypeSwitchOpenNondebounced; + else + events[i].type = debounced ? kPREventTypeSwitchClosedDebounced : kPREventTypeSwitchOpenNondebounced; + } + return i; } PRResult PRDevice::DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalConfig) { - const int burstWords = 2; - uint32_t burst[burstWords]; - int32_t rc; - - DEBUG(PRLog("Installing driver globals\n")); - - this->driverGlobalConfig = *driverGlobalConfig; - rc = CreateDriverUpdateGlobalConfigBurst(burst, driverGlobalConfig); - + const int burstWords = 2; + uint32_t burst[burstWords]; + int32_t rc; + + DEBUG(PRLog("Installing driver globals\n")); + + this->driverGlobalConfig = *driverGlobalConfig; + rc = CreateDriverUpdateGlobalConfigBurst(burst, driverGlobalConfig); + DEBUG(PRLog("Words: %x %x\n", burst[0], burst[1])); - return WriteData(burst, burstWords); + return WriteData(burst, burstWords); } PRResult PRDevice::DriverGetGroupConfig(uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig) { - *driverGroupConfig = driverGroups[groupNum]; - return kPRSuccess; + *driverGroupConfig = driverGroups[groupNum]; + return kPRSuccess; } PRResult PRDevice::DriverUpdateGroupConfig(PRDriverGroupConfig *driverGroupConfig) { - const int burstWords = 2; - uint32_t burst[burstWords]; - int32_t rc; - - driverGroups[driverGroupConfig->groupNum] = *driverGroupConfig; - DEBUG(PRLog("Installing driver group\n")); - rc = CreateDriverUpdateGroupConfigBurst(burst, driverGroupConfig); - + const int burstWords = 2; + uint32_t burst[burstWords]; + int32_t rc; + + driverGroups[driverGroupConfig->groupNum] = *driverGroupConfig; + DEBUG(PRLog("Installing driver group\n")); + rc = CreateDriverUpdateGroupConfigBurst(burst, driverGroupConfig); + DEBUG(PRLog("Words: %x %x\n", burst[0], burst[1])); - return WriteData(burst, burstWords); + return WriteData(burst, burstWords); } PRResult PRDevice::DriverGetState(uint8_t driverNum, PRDriverState *driverState) { - *driverState = drivers[driverNum]; - return kPRSuccess; + *driverState = drivers[driverNum]; + return kPRSuccess; } PRResult PRDevice::DriverUpdateState(PRDriverState *driverState) { - const int burstWords = 3; - uint32_t burst[burstWords]; - int32_t rc; - - DEBUG(PRLog("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)); - return kPRFailure; - } - - drivers[driverState->driverNum] = *driverState; - - rc = CreateDriverUpdateBurst(burst, &drivers[driverState->driverNum]); + const int burstWords = 3; + uint32_t burst[burstWords]; + int32_t rc; + + DEBUG(PRLog("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)); + 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])); - - return WriteData(burst, burstWords); + + return WriteData(burst, burstWords); } PRResult PRDevice::DriverDisable(uint16_t driverNum) { - PRDriverState driver; - DriverGetState(driverNum, &driver); - driver.state = 0; - driver.timeslots = 0; - driver.waitForFirstTimeSlot = false; - driver.outputDriveTime = 0; - driver.patterOnTime = 0; - driver.patterOffTime = 0; - driver.patterEnable = false; - return DriverUpdateState(&driver); + PRDriverState driver; + DriverGetState(driverNum, &driver); + driver.state = 0; + driver.timeslots = 0; + driver.waitForFirstTimeSlot = false; + driver.outputDriveTime = 0; + driver.patterOnTime = 0; + driver.patterOffTime = 0; + driver.patterEnable = false; + return DriverUpdateState(&driver); } PRResult PRDevice::DriverPulse(uint16_t driverNum, int milliseconds) { - PRDriverState driver; - DriverGetState(driverNum, &driver); - driver.state = 1; - driver.timeslots = 0; - driver.waitForFirstTimeSlot = false; - driver.outputDriveTime = milliseconds; - driver.patterOnTime = 0; - driver.patterOffTime = 0; - driver.patterEnable = false; - return DriverUpdateState(&driver); + PRDriverState driver; + DriverGetState(driverNum, &driver); + driver.state = 1; + driver.timeslots = 0; + driver.waitForFirstTimeSlot = false; + driver.outputDriveTime = milliseconds; + driver.patterOnTime = 0; + driver.patterOffTime = 0; + driver.patterEnable = false; + return DriverUpdateState(&driver); } PRResult PRDevice::DriverSchedule(uint16_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool now) { - PRDriverState driver; - DriverGetState(driverNum, &driver); - driver.state = 1; - driver.timeslots = schedule; - driver.waitForFirstTimeSlot = !now; - driver.outputDriveTime = cycleSeconds; - driver.patterOnTime = 0; - driver.patterOffTime = 0; - driver.patterEnable = false; - return DriverUpdateState(&driver); + PRDriverState driver; + DriverGetState(driverNum, &driver); + driver.state = 1; + driver.timeslots = schedule; + driver.waitForFirstTimeSlot = !now; + driver.outputDriveTime = cycleSeconds; + driver.patterOnTime = 0; + driver.patterOffTime = 0; + driver.patterEnable = false; + return DriverUpdateState(&driver); } PRResult PRDevice::DriverPatter(uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime) { - PRDriverState driver; - DriverGetState(driverNum, &driver); - driver.state = originalOnTime != 0; - driver.timeslots = 0; - driver.waitForFirstTimeSlot = false; - driver.outputDriveTime = originalOnTime; - driver.patterOnTime = millisecondsOn; - driver.patterOffTime = millisecondsOff; - driver.patterEnable = true; - return DriverUpdateState(&driver); + PRDriverState driver; + DriverGetState(driverNum, &driver); + driver.state = originalOnTime != 0; + driver.timeslots = 0; + driver.waitForFirstTimeSlot = false; + driver.outputDriveTime = originalOnTime; + driver.patterOnTime = millisecondsOn; + driver.patterOffTime = millisecondsOff; + driver.patterEnable = true; + return DriverUpdateState(&driver); } PRResult PRDevice::SwitchesUpdateRules(PRSwitchRule *rules, int numRules) { - int32_t i,rc; - DEBUG(PRLog("SwitchesUpdateRules: numRules: %d\n", numRules)); - - // Iterate through the array of rules, install each in the P-ROC - for (i=0; i < numRules; i++) { - uint16_t switchNum = rules[i].switchNum; - switchRules[switchNum] = rules[i]; - PRSwitchRule *rule = &switchRules[switchNum]; - PRSwitchRule *nextRule = NULL; - - // See if this is the last item. If not, need to add a link to the current item - if (i != numRules - 1) { - nextRule = &rules[i+1]; - - // Link address is the switch number assigned to the next rule as that's where - // the next rule will be installed - rule->linkAddress = nextRule->switchNum; - rule->linkActive = true; - } - else { - rule->linkActive = false; - rule->linkAddress = 0; - } - - DEBUG(PRLog("Installing switch rule: switchNum: %d, eventType: %d\n link: %d, link address: %d\n", - rule->switchNum, rule->eventType, rule->linkActive, rule->linkAddress)); - - uint32_t rule_burst[4]; - rc = CreateSwitchesUpdateRulesBurst (rule_burst, rule); - - DEBUG(PRLog("words: %d:%d:%d:%d\n", rule_burst[0], rule_burst[1], rule_burst[2], rule_burst[3])); - - rc = WriteData(rule_burst, 4); - } - return rc; + int32_t i,rc; + DEBUG(PRLog("SwitchesUpdateRules: numRules: %d\n", numRules)); + + // Iterate through the array of rules, install each in the P-ROC + for (i=0; i < numRules; i++) { + uint16_t switchNum = rules[i].switchNum; + switchRules[switchNum] = rules[i]; + PRSwitchRule *rule = &switchRules[switchNum]; + PRSwitchRule *nextRule = NULL; + + // See if this is the last item. If not, need to add a link to the current item + if (i != numRules - 1) { + nextRule = &rules[i+1]; + + // Link address is the switch number assigned to the next rule as that's where + // the next rule will be installed + rule->linkAddress = nextRule->switchNum; + rule->linkActive = true; + } + else { + rule->linkActive = false; + rule->linkAddress = 0; + } + + DEBUG(PRLog("Installing switch rule: switchNum: %d, eventType: %d\n link: %d, link address: %d\n", + rule->switchNum, rule->eventType, rule->linkActive, rule->linkAddress)); + + uint32_t rule_burst[4]; + rc = CreateSwitchesUpdateRulesBurst (rule_burst, rule); + + DEBUG(PRLog("words: %d:%d:%d:%d\n", rule_burst[0], rule_burst[1], rule_burst[2], rule_burst[3])); + + rc = WriteData(rule_burst, 4); + } + return rc; } int32_t PRDevice::DMDUpdateGlobalConfig(PRDMDGlobalConfig *dmdGlobalConfig) { - uint32_t rc; - uint32_t burst[10]; - - CreateDMDUpdateGlobalConfigBurst(burst, dmdGlobalConfig); - - DEBUG(PRLog("DMD config packet: ")); - for (int i=0; i<10; i++) { - DEBUG(PRLog("%d ", burst[i])); - } - DEBUG(PRLog("\n")); - - rc = WriteData(burst, 9); - return rc; + uint32_t rc; + uint32_t burst[10]; + + CreateDMDUpdateGlobalConfigBurst(burst, dmdGlobalConfig); + + DEBUG(PRLog("DMD config packet: ")); + for (int i=0; i<10; i++) { + DEBUG(PRLog("%d ", burst[i])); + } + DEBUG(PRLog("\n")); + + rc = WriteData(burst, 9); + return rc; } PRResult PRDevice::DMDDraw(uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames) { - int32_t k; //i,x,y,j,k,m; - //uint8_t color; - uint16_t words_per_sub_frame = (columns*rows) / 32; - uint16_t words_per_frame = words_per_sub_frame * numSubFrames; - uint32_t dmd_command_buffer[1024]; - uint32_t * p_dmd_frame_buffer_words; - - p_dmd_frame_buffer_words = (uint32_t *)dots; - - dmd_command_buffer[0] = CreateBurstCommand(P_ROC_BUS_DMD_SELECT, P_ROC_DMD_DOT_TABLE_BASE_ADDR, words_per_frame); - for (k=0; kdev, manufacturer, 128, description, 128, NULL, 0)) < 0) { - DEBUG(PRLog(" 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)); - } - curdev = curdev->next; - } - - } - - // Don't need the device list anymore - ftdi_list_free (&devlist); - // Did previous logic leave ftdic clean? Probably - // Need to de-init and re-init before opening usb? Doubtful. - //ftdi_deinit(&ftdic); - //ftdi_init(&ftdic); - - - 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))); - return kPRFailure; - } - else - { - rc = kPRSuccess; - if (ftdic.type == TYPE_R) { - uint32_t chipid; - ftdi_read_chipid(&ftdic,&chipid); - DEBUG(PRLog("FTDI chip_id = 0x%x\n", chipid)); + int32_t i=0; + PRResult rc; + struct ftdi_device_list *devlist, *curdev; + char manufacturer[128], description[128]; + uint32_t temp_word; - // 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")); - 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")); - rc = FlushReadBuffer(); - temp_word = P_ROC_INIT_PATTERN_A; - rc = WriteData(&temp_word, 1); - temp_word = P_ROC_INIT_PATTERN_B; - rc = WriteData(&temp_word, 1); - rc = VerifyChipID(); - } - else - { - DEBUG(PRLog("Failed to verify chip ID.")); - rc = kPRFailure; - } - } - } - - if (rc == kPRSuccess) - ftdiInitialized = true; - - return rc; + ftdiInitialized = false; + + // Open the FTDI device + if (ftdi_init(&ftdic) != 0) + { + DEBUG(PRLog("Failed to initialize FTDI.\n")); + return kPRFailure; + } + + // Find all FTDI devices + // This is very basic and really only expects to see 1 device. It needs to be + // smarter. At the very least, it should check some register on the P-ROC versus + // an input parameter to ensure the software is set up for the same architecture as + // the P-ROC (Stern vs WPC). Otherwise, it's possible to drive the coils the wrong + // polarity and blow fuses or fry transistors and all other sorts of badness. + + // 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))); + ftdi_deinit(&ftdic); + return kPRFailure; + } + else { + DEBUG(PRLog("Number of FTDI devices found: %d\n", numDevices)); + + for (curdev = devlist; curdev != NULL; i++) { + DEBUG(PRLog("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))); + } + else { + DEBUG(PRLog(" Device #%d:\n", i)); + DEBUG(PRLog(" Manufacturer: %s\n", manufacturer)); + DEBUG(PRLog(" Description: %s\n", description)); + } + curdev = curdev->next; + } + + } + + // Don't need the device list anymore + ftdi_list_free (&devlist); + // Did previous logic leave ftdic clean? Probably + // Need to de-init and re-init before opening usb? Doubtful. + //ftdi_deinit(&ftdic); + //ftdi_init(&ftdic); + + + 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))); + return kPRFailure; + } + else + { + rc = kPRSuccess; + if (ftdic.type == TYPE_R) { + uint32_t chipid; + ftdi_read_chipid(&ftdic,&chipid); + DEBUG(PRLog("FTDI chip_id = 0x%x\n", chipid)); + + // 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")); + 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")); + rc = FlushReadBuffer(); + temp_word = P_ROC_INIT_PATTERN_A; + rc = WriteData(&temp_word, 1); + temp_word = P_ROC_INIT_PATTERN_B; + rc = WriteData(&temp_word, 1); + rc = VerifyChipID(); + } + else + { + DEBUG(PRLog("Failed to verify chip ID.")); + rc = kPRFailure; + } + } + } + + if (rc == kPRSuccess) + ftdiInitialized = true; + + return rc; } PRResult PRDevice::Close() { - // TODO: Add protection against closing a not-open ftdic. - if (ftdiInitialized) - { - ftdi_usb_close(&ftdic); - ftdi_deinit(&ftdic); - } - return kPRSuccess; + // TODO: Add protection against closing a not-open ftdic. + if (ftdiInitialized) + { + ftdi_usb_close(&ftdic); + ftdi_deinit(&ftdic); + } + return kPRSuccess; } PRResult PRDevice::VerifyChipID() { - PRResult rc; - const int bufferWords = 5; - uint32_t buffer[bufferWords]; - //uint32_t temp_word; - uint32_t max_count; - - //std::cout << "Requesting FPGA Chip ID: "; - rc = RequestData(P_ROC_MANAGER_SELECT, P_ROC_REG_CHIP_ID_ADDR, 4); - - max_count = 0; - //std::cout << "Waiting for read data "; - while (num_collected_bytes < (bufferWords*4) && max_count < 10) { - sleep(.01); - //std::cout << ". "; - rc = CollectReadData(); - max_count++; - } - //std::cout << "\n"; - - if (max_count != 10) { - int wordsRead = ReadData(buffer, bufferWords); - - 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])); - rc = kPRSuccess; - } - else { - DEBUG(PRLog("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")); - rc = kPRFailure; - } - return (rc); + PRResult rc; + const int bufferWords = 5; + uint32_t buffer[bufferWords]; + //uint32_t temp_word; + uint32_t max_count; + + //std::cout << "Requesting FPGA Chip ID: "; + rc = RequestData(P_ROC_MANAGER_SELECT, P_ROC_REG_CHIP_ID_ADDR, 4); + + max_count = 0; + //std::cout << "Waiting for read data "; + while (num_collected_bytes < (bufferWords*4) && max_count < 10) { + sleep(.01); + //std::cout << ". "; + rc = CollectReadData(); + max_count++; + } + //std::cout << "\n"; + + if (max_count != 10) { + int wordsRead = ReadData(buffer, bufferWords); + + 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])); + rc = kPRSuccess; + } + else { + DEBUG(PRLog("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")); + rc = kPRFailure; + } + return (rc); } PRResult PRDevice::RequestData(uint32_t module_select, uint32_t start_addr, int32_t num_words) { - uint32_t requestWord = CreateRegRequestWord(module_select, start_addr, num_words); - return WriteData(&requestWord, 1); + uint32_t requestWord = CreateRegRequestWord(module_select, start_addr, num_words); + return WriteData(&requestWord, 1); } PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords) { - int32_t j,k; -// int32_t item; - - if (numWords == 0) - return kPRSuccess; - - // The 32-bit words coming in are in the same byte order they need to be in the P-ROC. - // However, due to Intel endian-ness, simply casting the words to 4 bytes changes the - // byte order. So, the conversion to bytes is done here manually to preserve the byte - // order. Might want to add a parameter for endian-ness at some point to make it - // work on big endian architectures. - for (j = 0; j < numWords; j++) { - uint32_t temp_word = words[j]; - for (k = 3; k >= 0; k--) - { - wr_buffer[(j*4)+k] = (uint8_t)(temp_word & 0x000000ff); - temp_word = temp_word >> 8; - } -// for (k=0; k<4; k++) -// { -// item = wr_buffer[(j*4)+k]; -// } - } - - int bytesToWrite = numWords * 4; + int32_t j,k; +// int32_t item; + + if (numWords == 0) + return kPRSuccess; + + // The 32-bit words coming in are in the same byte order they need to be in the P-ROC. + // However, due to Intel endian-ness, simply casting the words to 4 bytes changes the + // byte order. So, the conversion to bytes is done here manually to preserve the byte + // order. Might want to add a parameter for endian-ness at some point to make it + // work on big endian architectures. + for (j = 0; j < numWords; j++) { + uint32_t temp_word = words[j]; + for (k = 3; k >= 0; k--) + { + wr_buffer[(j*4)+k] = (uint8_t)(temp_word & 0x000000ff); + temp_word = temp_word >> 8; + } +// for (k=0; k<4; k++) +// { +// item = wr_buffer[(j*4)+k]; +// } + } + + int bytesToWrite = numWords * 4; int bytesWritten = (int32_t)ftdi_write_data(&ftdic, wr_buffer, bytesToWrite); - - if (bytesWritten != bytesToWrite) - { - DEBUG(PRLog("Error in WriteData: wrote %d of %d bytes\n", bytesWritten, bytesToWrite)); - return kPRFailure; - } - else - { - return kPRSuccess; - } + + if (bytesWritten != bytesToWrite) + { + DEBUG(PRLog("Error in WriteData: wrote %d of %d bytes\n", bytesWritten, bytesToWrite)); + return kPRFailure; + } + else + { + return kPRSuccess; + } } int32_t PRDevice::ReadData(uint32_t *buffer, int32_t num_words) { - int32_t rc,i,j; - - // Just like in the write_data method, the bytes are ordered here manually to put - // them in the right order. They are pulled from the collected_bytes_fifo 1 at a time - // and stuffed into 32-bit words, high byte to low byte. - if ((num_words * 4) <= num_collected_bytes) { - for (j=0; j 0) - { - DEBUG(PRLog("Collected bytes: %d\n", rc)); - } - return (rc); + int32_t rc,i; + rc = ftdi_read_data(&ftdic, collect_buffer, FTDI_BUFFER_SIZE-num_collected_bytes); + for (i=0; i 0) + { + DEBUG(PRLog("Collected bytes: %d\n", rc)); + } + return (rc); } PRResult PRDevice::SortReturningData() { - uint32_t num_bytes, num_words, rc; - uint32_t rd_buffer[512]; - - num_bytes = CollectReadData(); - num_words = num_collected_bytes/4; - - while (num_words >= 2) { - rc = ReadData(rd_buffer, 1); - DEBUG(PRLog("New returning word: 0x%x\n", rd_buffer[0])); - - switch ( (rd_buffer[0] & P_ROC_COMMAND_MASK) >> P_ROC_COMMAND_SHIFT) - { - // Must be a bug in the P-ROC. Unrequested packets are returning looking - // like requested packets. Commenting out requested packets for now. - case P_ROC_REQUESTED_DATA: { - int bytesRead = ReadData(rd_buffer, - (rd_buffer[0] & P_ROC_HEADER_LENGTH_MASK) >> - P_ROC_HEADER_LENGTH_SHIFT); - for (int i = 0; i < bytesRead; i++) - requestedDataQueue.push(rd_buffer[i]); - break; - } - case P_ROC_UNREQUESTED_DATA: { - ReadData(rd_buffer,1); - DEBUG(PRLog("Pushing onto unreq Q 0x%x\n", rd_buffer[0])); - unrequestedDataQueue.push(rd_buffer[0]); - break; - } - } - num_words = num_collected_bytes/4; - } - return kPRSuccess; + uint32_t num_bytes, num_words, rc; + uint32_t rd_buffer[512]; + + num_bytes = CollectReadData(); + num_words = num_collected_bytes/4; + + while (num_words >= 2) { + rc = ReadData(rd_buffer, 1); + DEBUG(PRLog("New returning word: 0x%x\n", rd_buffer[0])); + + switch ( (rd_buffer[0] & P_ROC_COMMAND_MASK) >> P_ROC_COMMAND_SHIFT) + { + // Must be a bug in the P-ROC. Unrequested packets are returning looking + // like requested packets. Commenting out requested packets for now. + case P_ROC_REQUESTED_DATA: { + int bytesRead = ReadData(rd_buffer, + (rd_buffer[0] & P_ROC_HEADER_LENGTH_MASK) >> + P_ROC_HEADER_LENGTH_SHIFT); + for (int i = 0; i < bytesRead; i++) + requestedDataQueue.push(rd_buffer[i]); + break; + } + case P_ROC_UNREQUESTED_DATA: { + ReadData(rd_buffer,1); + DEBUG(PRLog("Pushing onto unreq Q 0x%x\n", rd_buffer[0])); + unrequestedDataQueue.push(rd_buffer[0]); + break; + } + } + num_words = num_collected_bytes/4; + } + return kPRSuccess; } diff --git a/src/PRDevice.h b/src/PRDevice.h index 07f8fbf..af4086a 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -1,7 +1,7 @@ -/* +/* * The MIT License * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -9,11 +9,11 @@ * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following - * conditions: - * + * conditions: + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -49,95 +49,95 @@ extern void PRLog(const char *format, ...); class PRDevice { public: - static PRDevice *Create(PRMachineType machineType); - ~PRDevice(); + static PRDevice *Create(PRMachineType machineType); + ~PRDevice(); protected: - PRDevice(PRMachineType machineType); + PRDevice(PRMachineType machineType); public: - // public libpinproc API: - int GetEvents(PREvent *events, int maxEvents); + // public libpinproc API: + int GetEvents(PREvent *events, int maxEvents); - PRResult DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalConfig); - PRResult DriverGetGroupConfig(uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig); - PRResult DriverUpdateGroupConfig(PRDriverGroupConfig *driverGroupConfig); - PRResult DriverGetState(uint8_t driverNum, PRDriverState *driverState); - PRResult DriverUpdateState(PRDriverState *driverState); - - PRResult DriverDisable(uint16_t driverNum); - PRResult DriverPulse(uint16_t driverNum, int milliseconds); - PRResult DriverSchedule(uint16_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool now); - PRResult DriverPatter(uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); + PRResult DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalConfig); + PRResult DriverGetGroupConfig(uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig); + PRResult DriverUpdateGroupConfig(PRDriverGroupConfig *driverGroupConfig); + PRResult DriverGetState(uint8_t driverNum, PRDriverState *driverState); + PRResult DriverUpdateState(PRDriverState *driverState); - PRResult SwitchesUpdateRules(PRSwitchRule *rules, int numRules); + PRResult DriverDisable(uint16_t driverNum); + PRResult DriverPulse(uint16_t driverNum, int milliseconds); + PRResult DriverSchedule(uint16_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool now); + PRResult DriverPatter(uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); + + PRResult SwitchesUpdateRules(PRSwitchRule *rules, int numRules); + + PRResult DMDUpdateGlobalConfig(PRDMDGlobalConfig *dmdGlobalConfig); + PRResult DMDDraw(uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames); - PRResult DMDUpdateGlobalConfig(PRDMDGlobalConfig *dmdGlobalConfig); - PRResult DMDDraw(uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames); - protected: - - // Device I/O - + + // Device I/O + PRResult Open(); PRResult Close(); - - PRResult VerifyChipID(); - - // Raw write and read methods - - /** Writes data to P-ROC. - * Returns #kPFailure if the number of words read does not match the number requested. - */ - PRResult WriteData(uint32_t * buffer, int32_t numWords); - - /** - * Reads data from the buffer that was previously collected by CollectReadData(). - * Returns the number of bytes read. - */ - int32_t ReadData(uint32_t *buffer, int32_t maxWords); - - // Collection of methods to get data returning from the P-ROC - /** - * Request a block of data from the P-ROC. - */ - PRResult RequestData(uint32_t module_select, uint32_t start_addr, int32_t num_words); - /** - * Actually reads the data off of the FTDI chip. - * This is called by SortReturningData() in order to get some data to process. - */ - int32_t CollectReadData(); - /** - * Processes data into unrequestedDataQueue and requestedDataQueue. - * Calls CollectReadData() to obtain the data and then uses ReadData() to read it out. - */ - PRResult SortReturningData(); - /** - * Empties out the read buffer. - * Calls CollectReadData() and then ReadData() until it's empty. - */ - PRResult FlushReadBuffer(); - - queue unrequestedDataQueue; /**< Queue of words received from the device that were not requested via RequestData(). Usually switch events. */ - queue requestedDataQueue; /**< Queue of words received from the device as the result of a call to RequestData(). */ - bool ftdiInitialized; + PRResult VerifyChipID(); + + // Raw write and read methods + + /** Writes data to P-ROC. + * Returns #kPFailure if the number of words read does not match the number requested. + */ + PRResult WriteData(uint32_t * buffer, int32_t numWords); + + /** + * Reads data from the buffer that was previously collected by CollectReadData(). + * Returns the number of bytes read. + */ + int32_t ReadData(uint32_t *buffer, int32_t maxWords); + + // Collection of methods to get data returning from the P-ROC + /** + * Request a block of data from the P-ROC. + */ + PRResult RequestData(uint32_t module_select, uint32_t start_addr, int32_t num_words); + /** + * Actually reads the data off of the FTDI chip. + * This is called by SortReturningData() in order to get some data to process. + */ + int32_t CollectReadData(); + /** + * Processes data into unrequestedDataQueue and requestedDataQueue. + * Calls CollectReadData() to obtain the data and then uses ReadData() to read it out. + */ + PRResult SortReturningData(); + /** + * Empties out the read buffer. + * Calls CollectReadData() and then ReadData() until it's empty. + */ + PRResult FlushReadBuffer(); + + queue unrequestedDataQueue; /**< Queue of words received from the device that were not requested via RequestData(). Usually switch events. */ + queue requestedDataQueue; /**< Queue of words received from the device as the result of a call to RequestData(). */ + + bool ftdiInitialized; ftdi_context ftdic; - - uint8_t collected_bytes_fifo[FTDI_BUFFER_SIZE]; + + uint8_t collected_bytes_fifo[FTDI_BUFFER_SIZE]; int32_t collected_bytes_rd_addr; int32_t collected_bytes_wr_addr; int32_t num_collected_bytes; - + uint8_t wr_buffer[16384]; uint8_t collect_buffer[FTDI_BUFFER_SIZE]; - - - // Local Device State - void Reset(); - PRMachineType machineType; - PRDriverGlobalConfig driverGlobalConfig; - PRDriverGroupConfig driverGroups[maxDriverGroups]; - PRDriverState drivers[maxDrivers]; - PRSwitchRule switchRules[maxSwitchRules]; - -}; \ No newline at end of file + + + // Local Device State + void Reset(); + PRMachineType machineType; + PRDriverGlobalConfig driverGlobalConfig; + PRDriverGroupConfig driverGroups[maxDriverGroups]; + PRDriverState drivers[maxDrivers]; + PRSwitchRule switchRules[maxSwitchRules]; + +}; diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index d3edcc4..829ff6b 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -1,7 +1,7 @@ -/* +/* * The MIT License * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -9,11 +9,11 @@ * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following - * conditions: - * + * conditions: + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -33,139 +33,139 @@ uint32_t CreateRegRequestWord( uint32_t select, uint32_t addr, uint32_t num_words ) { - return ( (P_ROC_READ << P_ROC_COMMAND_SHIFT) | - (num_words << P_ROC_HEADER_LENGTH_SHIFT) | - (select << P_ROC_MODULE_SELECT_SHIFT) | - (addr << P_ROC_ADDR_SHIFT) ); + return ( (P_ROC_READ << P_ROC_COMMAND_SHIFT) | + (num_words << P_ROC_HEADER_LENGTH_SHIFT) | + (select << P_ROC_MODULE_SELECT_SHIFT) | + (addr << P_ROC_ADDR_SHIFT) ); }; uint32_t CreateBurstCommand ( uint32_t select, uint32_t addr, uint32_t num_words ) { - return ( (P_ROC_WRITE << P_ROC_COMMAND_SHIFT) | - (num_words << P_ROC_HEADER_LENGTH_SHIFT) | - (select << P_ROC_MODULE_SELECT_SHIFT) | - (addr << P_ROC_ADDR_SHIFT) ); + return ( (P_ROC_WRITE << P_ROC_COMMAND_SHIFT) | + (num_words << P_ROC_HEADER_LENGTH_SHIFT) | + (select << P_ROC_MODULE_SELECT_SHIFT) | + (addr << P_ROC_ADDR_SHIFT) ); } int32_t CreateDriverUpdateGlobalConfigBurst ( uint32_t * burst, PRDriverGlobalConfig *driver_globals) { - uint32_t addr; - - addr = 0; - addr = (P_ROC_DRIVER_CTRL_REG_DECODE << P_ROC_DRIVER_CTRL_DECODE_SHIFT); - - burst[0] = CreateBurstCommand (P_ROC_BUS_DRIVER_CTRL_SELECT, addr, 1 ); - burst[1] = ( (driver_globals->enableOutputs << - P_ROC_DRIVER_GLOBAL_ENABLE_DIRECT_OUTPUTS_SHIFT) | - (driver_globals->globalPolarity << - P_ROC_DRIVER_GLOBAL_GLOBAL_POLARITY_SHIFT) | - (driver_globals->useClear << - P_ROC_DRIVER_GLOBAL_USE_CLEAR_SHIFT) | - (driver_globals->strobeStartSelect << - P_ROC_DRIVER_GLOBAL_STROBE_START_SELECT_SHIFT) | - (driver_globals->startStrobeTime << - P_ROC_DRIVER_GLOBAL_START_STROBE_TIME_SHIFT) | - (driver_globals->matrixRowEnableIndex1 << - P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_1_SHIFT) | - (driver_globals->matrixRowEnableIndex0 << - P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_0_SHIFT) | - (driver_globals->activeLowMatrixRows << - P_ROC_DRIVER_GLOBAL_ACTIVE_LOW_MATRIX_ROWS_SHIFT) | - (driver_globals->encodeEnables << - P_ROC_DRIVER_GLOBAL_ENCODE_ENABLES_SHIFT) | - (driver_globals->tickleWatchdog << - P_ROC_DRIVER_GLOBAL_TICKLE_WATCHDOG_SHIFT) ); - return kPRSuccess; + uint32_t addr; + + addr = 0; + addr = (P_ROC_DRIVER_CTRL_REG_DECODE << P_ROC_DRIVER_CTRL_DECODE_SHIFT); + + burst[0] = CreateBurstCommand (P_ROC_BUS_DRIVER_CTRL_SELECT, addr, 1 ); + burst[1] = ( (driver_globals->enableOutputs << + P_ROC_DRIVER_GLOBAL_ENABLE_DIRECT_OUTPUTS_SHIFT) | + (driver_globals->globalPolarity << + P_ROC_DRIVER_GLOBAL_GLOBAL_POLARITY_SHIFT) | + (driver_globals->useClear << + P_ROC_DRIVER_GLOBAL_USE_CLEAR_SHIFT) | + (driver_globals->strobeStartSelect << + P_ROC_DRIVER_GLOBAL_STROBE_START_SELECT_SHIFT) | + (driver_globals->startStrobeTime << + P_ROC_DRIVER_GLOBAL_START_STROBE_TIME_SHIFT) | + (driver_globals->matrixRowEnableIndex1 << + P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_1_SHIFT) | + (driver_globals->matrixRowEnableIndex0 << + P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_0_SHIFT) | + (driver_globals->activeLowMatrixRows << + P_ROC_DRIVER_GLOBAL_ACTIVE_LOW_MATRIX_ROWS_SHIFT) | + (driver_globals->encodeEnables << + P_ROC_DRIVER_GLOBAL_ENCODE_ENABLES_SHIFT) | + (driver_globals->tickleWatchdog << + P_ROC_DRIVER_GLOBAL_TICKLE_WATCHDOG_SHIFT) ); + return kPRSuccess; } int32_t CreateDriverUpdateGroupConfigBurst ( uint32_t * burst, PRDriverGroupConfig *driver_group) { - uint32_t addr; - - addr = 0; - addr = (P_ROC_DRIVER_CTRL_REG_DECODE << P_ROC_DRIVER_CTRL_DECODE_SHIFT) | - driver_group->groupNum; - - burst[0] = CreateBurstCommand (P_ROC_BUS_DRIVER_CTRL_SELECT, addr, 1 ); - burst[1] = ( (driver_group->slowTime << - P_ROC_DRIVER_GROUP_SLOW_TIME_SHIFT) | - (driver_group->disableStrobeAfter << - P_ROC_DRIVER_GROUP_DISABLE_STROBE_AFTER_SHIFT) | - (driver_group->enableIndex << - P_ROC_DRIVER_GROUP_ENABLE_INDEX_SHIFT) | - (driver_group->rowActivateIndex << - P_ROC_DRIVER_GROUP_ROW_ACTIVATE_INDEX_SHIFT) | - (driver_group->rowEnableSelect << - P_ROC_DRIVER_GROUP_ROW_ENABLE_SELECT_SHIFT) | - (driver_group->matrixed << - P_ROC_DRIVER_GROUP_MATRIXED_SHIFT) | - (driver_group->polarity << - P_ROC_DRIVER_GROUP_POLARITY_SHIFT) | - (driver_group->active << - P_ROC_DRIVER_GROUP_ACTIVE_SHIFT) ); - return kPRSuccess; + uint32_t addr; + + addr = 0; + addr = (P_ROC_DRIVER_CTRL_REG_DECODE << P_ROC_DRIVER_CTRL_DECODE_SHIFT) | + driver_group->groupNum; + + burst[0] = CreateBurstCommand (P_ROC_BUS_DRIVER_CTRL_SELECT, addr, 1 ); + burst[1] = ( (driver_group->slowTime << + P_ROC_DRIVER_GROUP_SLOW_TIME_SHIFT) | + (driver_group->disableStrobeAfter << + P_ROC_DRIVER_GROUP_DISABLE_STROBE_AFTER_SHIFT) | + (driver_group->enableIndex << + P_ROC_DRIVER_GROUP_ENABLE_INDEX_SHIFT) | + (driver_group->rowActivateIndex << + P_ROC_DRIVER_GROUP_ROW_ACTIVATE_INDEX_SHIFT) | + (driver_group->rowEnableSelect << + P_ROC_DRIVER_GROUP_ROW_ENABLE_SELECT_SHIFT) | + (driver_group->matrixed << + P_ROC_DRIVER_GROUP_MATRIXED_SHIFT) | + (driver_group->polarity << + P_ROC_DRIVER_GROUP_POLARITY_SHIFT) | + (driver_group->active << + P_ROC_DRIVER_GROUP_ACTIVE_SHIFT) ); + return kPRSuccess; } int32_t CreateDriverUpdateBurst ( uint32_t * burst, PRDriverState *driver) { - uint32_t addr; - - addr = 0; - addr = (P_ROC_DRIVER_CONFIG_TABLE_DECODE << P_ROC_DRIVER_CTRL_DECODE_SHIFT) | - (driver->driverNum << P_ROC_DRIVER_CONFIG_TABLE_DRIVER_NUM_SHIFT); - - burst[0] = CreateBurstCommand (P_ROC_BUS_DRIVER_CTRL_SELECT, addr, 2 ); - burst[1] = ( (driver->outputDriveTime << P_ROC_DRIVER_CONFIG_OUTPUT_DRIVE_TIME_SHIFT) | - (driver->polarity << P_ROC_DRIVER_CONFIG_POLARITY_SHIFT) | - (driver->state << P_ROC_DRIVER_CONFIG_STATE_SHIFT) | - (1 << P_ROC_DRIVER_CONFIG_UPDATE_SHIFT) | - (driver->waitForFirstTimeSlot << P_ROC_DRIVER_CONFIG_WAIT_4_1ST_SLOT_SHIFT) | - (driver->timeslots << P_ROC_DRIVER_CONFIG_TIMESLOT_SHIFT) ); - burst[2] = (driver->timeslots >> P_ROC_DRIVER_CONFIG_TIMESLOT_SHIFT) | - (driver->patterOnTime << P_ROC_DRIVER_CONFIG_PATTER_ON_TIME_SHIFT) | - (driver->patterOffTime << P_ROC_DRIVER_CONFIG_PATTER_OFF_TIME_SHIFT) | - (driver->patterEnable << P_ROC_DRIVER_CONFIG_PATTER_ENABLE_SHIFT); - return kPRSuccess; + uint32_t addr; + + addr = 0; + addr = (P_ROC_DRIVER_CONFIG_TABLE_DECODE << P_ROC_DRIVER_CTRL_DECODE_SHIFT) | + (driver->driverNum << P_ROC_DRIVER_CONFIG_TABLE_DRIVER_NUM_SHIFT); + + burst[0] = CreateBurstCommand (P_ROC_BUS_DRIVER_CTRL_SELECT, addr, 2 ); + burst[1] = ( (driver->outputDriveTime << P_ROC_DRIVER_CONFIG_OUTPUT_DRIVE_TIME_SHIFT) | + (driver->polarity << P_ROC_DRIVER_CONFIG_POLARITY_SHIFT) | + (driver->state << P_ROC_DRIVER_CONFIG_STATE_SHIFT) | + (1 << P_ROC_DRIVER_CONFIG_UPDATE_SHIFT) | + (driver->waitForFirstTimeSlot << P_ROC_DRIVER_CONFIG_WAIT_4_1ST_SLOT_SHIFT) | + (driver->timeslots << P_ROC_DRIVER_CONFIG_TIMESLOT_SHIFT) ); + burst[2] = (driver->timeslots >> P_ROC_DRIVER_CONFIG_TIMESLOT_SHIFT) | + (driver->patterOnTime << P_ROC_DRIVER_CONFIG_PATTER_ON_TIME_SHIFT) | + (driver->patterOffTime << P_ROC_DRIVER_CONFIG_PATTER_OFF_TIME_SHIFT) | + (driver->patterEnable << P_ROC_DRIVER_CONFIG_PATTER_ENABLE_SHIFT); + return kPRSuccess; } int32_t CreateSwitchesUpdateRulesBurst ( uint32_t * burst, PRSwitchRule *rule_record) { - uint32_t addr; - uint32_t driver_command[3]; - - CreateDriverUpdateBurst ( driver_command, &(rule_record->driver)); - - uint32_t debounce = (rule_record->eventType == kPREventTypeSwitchOpenDebounced) || (rule_record->eventType == kPREventTypeSwitchClosedDebounced) ? 1 : 0; - uint32_t state = (rule_record->eventType == kPREventTypeSwitchOpenDebounced) || (rule_record->eventType == kPREventTypeSwitchOpenNondebounced) ? 1 : 0; - - addr = ( (debounce << P_ROC_SWITCH_RULE_ADDR_DEBOUNCE_SHIFT) | - (state << P_ROC_SWITCH_RULE_ADDR_STATE_SHIFT) | - (rule_record->switchNum << P_ROC_SWITCH_RULE_ADDR_SWITCH_NUM_SHIFT) ); - - burst[0] = CreateBurstCommand (P_ROC_BUS_STATE_CHANGE_PROC_SELECT, addr, 3 ); - burst[1] = driver_command[1]; - burst[2] = driver_command[2]; - - burst[3] = (rule_record->changeOutput << P_ROC_SWITCH_RULE_CHANGE_OUTPUT_SHIFT) | - (rule_record->driver.driverNum << P_ROC_SWITCH_RULE_DRIVER_NUM_SHIFT) | - (rule_record->linkActive << P_ROC_SWITCH_RULE_LINK_ACTIVE_SHIFT) | - (rule_record->linkAddress << P_ROC_SWITCH_RULE_LINK_ADDRESS_SHIFT) | - (rule_record->notifyHost << P_ROC_SWITCH_RULE_NOTIFY_HOST_SHIFT); - return kPRSuccess; - + uint32_t addr; + uint32_t driver_command[3]; + + CreateDriverUpdateBurst ( driver_command, &(rule_record->driver)); + + uint32_t debounce = (rule_record->eventType == kPREventTypeSwitchOpenDebounced) || (rule_record->eventType == kPREventTypeSwitchClosedDebounced) ? 1 : 0; + uint32_t state = (rule_record->eventType == kPREventTypeSwitchOpenDebounced) || (rule_record->eventType == kPREventTypeSwitchOpenNondebounced) ? 1 : 0; + + addr = ( (debounce << P_ROC_SWITCH_RULE_ADDR_DEBOUNCE_SHIFT) | + (state << P_ROC_SWITCH_RULE_ADDR_STATE_SHIFT) | + (rule_record->switchNum << P_ROC_SWITCH_RULE_ADDR_SWITCH_NUM_SHIFT) ); + + burst[0] = CreateBurstCommand (P_ROC_BUS_STATE_CHANGE_PROC_SELECT, addr, 3 ); + burst[1] = driver_command[1]; + burst[2] = driver_command[2]; + + burst[3] = (rule_record->changeOutput << P_ROC_SWITCH_RULE_CHANGE_OUTPUT_SHIFT) | + (rule_record->driver.driverNum << P_ROC_SWITCH_RULE_DRIVER_NUM_SHIFT) | + (rule_record->linkActive << P_ROC_SWITCH_RULE_LINK_ACTIVE_SHIFT) | + (rule_record->linkAddress << P_ROC_SWITCH_RULE_LINK_ADDRESS_SHIFT) | + (rule_record->notifyHost << P_ROC_SWITCH_RULE_NOTIFY_HOST_SHIFT); + return kPRSuccess; + } -int32_t CreateDMDUpdateGlobalConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config) -{ - uint32_t addr; - uint32_t i; - - addr = 8; - burst[0] = CreateBurstCommand (P_ROC_BUS_DMD_SELECT, addr, 8 ); - - for (i=0; i<8; i++) { - burst[i+1] = 0; - burst[i+1] = (dmd_config->rclkLowCycles[i] << P_ROC_DMD_RCLK_LOW_CYCLES_SHIFT) | - (dmd_config->latchHighCycles[i] << P_ROC_DMD_LATCH_HIGH_CYCLES_SHIFT) | - (dmd_config->deHighCycles[i] << P_ROC_DMD_DE_HIGH_CYCLES_SHIFT) | - (dmd_config->dotclkHalfPeriod[i] << P_ROC_DMD_DOTCLK_HALF_PERIOD_SHIFT); - } - return kPRSuccess; +int32_t CreateDMDUpdateGlobalConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config) +{ + uint32_t addr; + uint32_t i; + + addr = 8; + burst[0] = CreateBurstCommand (P_ROC_BUS_DMD_SELECT, addr, 8 ); + + for (i=0; i<8; i++) { + burst[i+1] = 0; + burst[i+1] = (dmd_config->rclkLowCycles[i] << P_ROC_DMD_RCLK_LOW_CYCLES_SHIFT) | + (dmd_config->latchHighCycles[i] << P_ROC_DMD_LATCH_HIGH_CYCLES_SHIFT) | + (dmd_config->deHighCycles[i] << P_ROC_DMD_DE_HIGH_CYCLES_SHIFT) | + (dmd_config->dotclkHalfPeriod[i] << P_ROC_DMD_DOTCLK_HALF_PERIOD_SHIFT); + } + return kPRSuccess; } diff --git a/src/PRHardware.h b/src/PRHardware.h index e039ac7..875542b 100644 --- a/src/PRHardware.h +++ b/src/PRHardware.h @@ -1,7 +1,7 @@ -/* +/* * The MIT License * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -9,11 +9,11 @@ * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following - * conditions: - * + * conditions: + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 86ed25c..a89b82d 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -1,7 +1,7 @@ -/* +/* * The MIT License * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -9,11 +9,11 @@ * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following - * conditions: - * + * conditions: + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -37,20 +37,20 @@ PRLogCallback logCallback = NULL; void PRLog(const char *format, ...) { - const int maxLogLineLength = 1024; - char line[maxLogLineLength]; - va_list ap; - va_start(ap, format); - vsnprintf(line, maxLogLineLength, format, ap); - if (logCallback) - logCallback(line); - else - fprintf(stderr, line); + const int maxLogLineLength = 1024; + char line[maxLogLineLength]; + va_list ap; + va_start(ap, format); + vsnprintf(line, maxLogLineLength, format, ap); + if (logCallback) + logCallback(line); + else + fprintf(stderr, line); } void PRLogSetCallback(PRLogCallback callback) { - logCallback = callback; + logCallback = callback; } @@ -59,17 +59,17 @@ void PRLogSetCallback(PRLogCallback callback) /** 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. */ PR_EXPORT PRHandle PRCreate(PRMachineType machineType) { - PRDevice *device = PRDevice::Create(machineType); - if (device == NULL) - return kPRHandleInvalid; - else - return device; + PRDevice *device = PRDevice::Create(machineType); + if (device == NULL) + return kPRHandleInvalid; + else + return device; } /** Destroys an existing P-ROC device handle. */ PR_EXPORT void PRDelete(PRHandle handle) { - if (handle != kPRHandleInvalid) - delete (PRDevice*)handle; + if (handle != kPRHandleInvalid) + delete (PRDevice*)handle; } @@ -78,48 +78,48 @@ PR_EXPORT void PRDelete(PRHandle handle) /** Get all of the available events that have been received. */ PR_EXPORT int PRGetEvents(PRHandle handle, PREvent *eventsOut, int maxEvents) { - return handleAsDevice->GetEvents(eventsOut, maxEvents); + return handleAsDevice->GetEvents(eventsOut, maxEvents); } // Drivers PR_EXPORT PRResult PRDriverUpdateGlobalConfig(PRHandle handle, PRDriverGlobalConfig *driverGlobalConfig) { - return handleAsDevice->DriverUpdateGlobalConfig(driverGlobalConfig); + return handleAsDevice->DriverUpdateGlobalConfig(driverGlobalConfig); } PR_EXPORT PRResult PRDriverGetGroupConfig(PRHandle handle, uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig) { - return handleAsDevice->DriverGetGroupConfig(groupNum, driverGroupConfig); + return handleAsDevice->DriverGetGroupConfig(groupNum, driverGroupConfig); } PR_EXPORT PRResult PRDriverUpdateGroupConfig(PRHandle handle, PRDriverGroupConfig *driverGroupConfig) { - return handleAsDevice->DriverUpdateGroupConfig(driverGroupConfig); + return handleAsDevice->DriverUpdateGroupConfig(driverGroupConfig); } PR_EXPORT PRResult PRDriverGetState(PRHandle handle, uint8_t driverNum, PRDriverState *driverState) { - return handleAsDevice->DriverGetState(driverNum, driverState); + return handleAsDevice->DriverGetState(driverNum, driverState); } PR_EXPORT PRResult PRDriverUpdateState(PRHandle handle, PRDriverState *driverState) { - return handleAsDevice->DriverUpdateState(driverState); + return handleAsDevice->DriverUpdateState(driverState); } // Driver Helper functions: PR_EXPORT PRResult PRDriverDisable(PRHandle handle, uint16_t driverNum) { - return handleAsDevice->DriverDisable(driverNum); + return handleAsDevice->DriverDisable(driverNum); } PR_EXPORT PRResult PRDriverPulse(PRHandle handle, uint16_t driverNum, int milliseconds) { - return handleAsDevice->DriverPulse(driverNum, milliseconds); + return handleAsDevice->DriverPulse(driverNum, milliseconds); } PR_EXPORT PRResult PRDriverSchedule(PRHandle handle, uint16_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool_t now) { - return handleAsDevice->DriverSchedule(driverNum, schedule, cycleSeconds, now); + return handleAsDevice->DriverSchedule(driverNum, schedule, cycleSeconds, now); } PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime) { - return handleAsDevice->DriverPatter(driverNum, millisecondsOn, millisecondsOff, originalOnTime); + return handleAsDevice->DriverPatter(driverNum, millisecondsOn, millisecondsOff, originalOnTime); } @@ -128,15 +128,15 @@ PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t PR_EXPORT PRResult PRSwitchesUpdateRules(PRHandle handle, PRSwitchRule *rules, int numRules) { - return handleAsDevice->SwitchesUpdateRules(rules, numRules); + return handleAsDevice->SwitchesUpdateRules(rules, numRules); } PR_EXPORT int32_t PRDMDUpdateGlobalConfig(PRHandle handle, PRDMDGlobalConfig *dmdGlobalConfig) { - return handleAsDevice->DMDUpdateGlobalConfig(dmdGlobalConfig); + return handleAsDevice->DMDUpdateGlobalConfig(dmdGlobalConfig); } PR_EXPORT PRResult PRDMDDraw(PRHandle handle, uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames) { - return handleAsDevice->DMDDraw(dots, columns, rows, numSubFrames); + return handleAsDevice->DMDDraw(dots, columns, rows, numSubFrames); }