From c53227c90e02c71d0b1892fe9bcf95a1772315b1 Mon Sep 17 00:00:00 2001 From: Gerry Stellenberg Date: Thu, 17 Feb 2011 21:40:06 -0600 Subject: [PATCH] Added progress status to pinprocfw. Also added the drive_outputs_now parameter to PRSwitchUpdateRule() and associated methods. When true and FPGA version is 1.17 (non-debug) or higher), the P-ROC will check the switch state to see if the drivers should be processed immediately. --- examples/pinproctest/switches.cpp | 24 +++---- include/pinproc.h | 2 +- src/PRDevice.cpp | 100 ++++++++++++++++++++---------- src/PRDevice.h | 2 +- src/PRHardware.cpp | 9 +-- src/PRHardware.h | 5 +- src/pinproc.cpp | 4 +- utils/pinprocfw/pinprocfw.cpp | 25 +++++++- 8 files changed, 114 insertions(+), 57 deletions(-) diff --git a/examples/pinproctest/switches.cpp b/examples/pinproctest/switches.cpp index 569cd0a..3c49690 100644 --- a/examples/pinproctest/switches.cpp +++ b/examples/pinproctest/switches.cpp @@ -57,8 +57,8 @@ void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc) PRSwitchRule sw; sw.notifyHost = true; sw.reloadActive = false; - PRSwitchUpdateRule(proc, i, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0); - PRSwitchUpdateRule(proc, i, kPREventTypeSwitchOpenDebounced, &sw, NULL, 0); + PRSwitchUpdateRule(proc, i, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0, false); + PRSwitchUpdateRule(proc, i, kPREventTypeSwitchOpenDebounced, &sw, NULL, 0, false); } } @@ -75,10 +75,10 @@ void ConfigureWPCFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, i PRDriverStatePulse(&drivers[1],0); // Turn on indefintely (set pulse for 0ms) sw.notifyHost = false; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules, true); sw.notifyHost = true; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0, false); // Flipper off rules PRDriverGetState(proc, mainCoilNum, &drivers[0]); @@ -87,10 +87,10 @@ void ConfigureWPCFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, i PRDriverStateDisable(&drivers[1]); // Disable hold coil sw.notifyHost = false; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenNondebounced, &sw, drivers, numDriverRules); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenNondebounced, &sw, drivers, numDriverRules, true); sw.notifyHost = true; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenDebounced, &sw, NULL, 0); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenDebounced, &sw, NULL, 0, false); } void ConfigureSternFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, int pulseTime, int patterOnTime, int patterOffTime) @@ -105,20 +105,20 @@ void ConfigureSternFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, PRDriverStatePatter(&drivers[0],patterOnTime,patterOffTime,pulseTime); // Pulse coil for 34ms. sw.notifyHost = false; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules, true); sw.notifyHost = true; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0, false); // Flipper off rules PRDriverGetState(proc, mainCoilNum, &drivers[0]); PRDriverStateDisable(&drivers[0]); // Disable main coil sw.notifyHost = false; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenNondebounced, &sw, drivers, numDriverRules); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenNondebounced, &sw, drivers, numDriverRules, true); sw.notifyHost = true; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenDebounced, &sw, NULL, 0); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenDebounced, &sw, NULL, 0, false); } void ConfigureBumperRule (PRHandle proc, int swNum, int coilNum, int pulseTime) @@ -131,10 +131,10 @@ void ConfigureBumperRule (PRHandle proc, int swNum, int coilNum, int pulseTime) PRDriverStatePulse(&drivers[0],pulseTime); // Pulse coil for 34ms. sw.reloadActive = true; sw.notifyHost = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules, true); sw.notifyHost = true; sw.reloadActive = false; - PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0); + PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0, false); } void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc) diff --git a/include/pinproc.h b/include/pinproc.h index df9f18f..105ae11 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -461,7 +461,7 @@ PINPROC_API PRResult PRSwitchUpdateConfig(PRHandle handle, PRSwitchConfig *switc * @param linkedDrivers An array of #PRDriverState structures describing the driver state changes to be made when this switch rule is triggered. May be NULL if numDrivers is 0. * @param numDrivers Number of elements in the linkedDrivers array. May be zero or more. */ -PINPROC_API PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers); +PINPROC_API PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers, bool_t drive_outputs_now); /** Returns a list of PREventTypes describing the states of the requested number of switches */ PINPROC_API PRResult PRSwitchGetStates(PRHandle handle, PREventType * switchStates, uint16_t numSwitches); diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 015a587..7d72115 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -149,10 +149,10 @@ PRResult PRDevice::Reset(uint32_t resetFlags) // Send blank rule for each event type to Device if necessary if ((resetFlags & kPRResetFlagUpdateDevice) && i <= kPRSwitchPhysicalLast) { - SwitchUpdateRule(i, kPREventTypeSwitchOpenDebounced, &emptySwitchRule, NULL, 0); - SwitchUpdateRule(i, kPREventTypeSwitchClosedDebounced, &emptySwitchRule, NULL, 0); - SwitchUpdateRule(i, kPREventTypeSwitchOpenNondebounced, &emptySwitchRule, NULL, 0); - SwitchUpdateRule(i, kPREventTypeSwitchClosedNondebounced, &emptySwitchRule, NULL, 0); + SwitchUpdateRule(i, kPREventTypeSwitchOpenDebounced, &emptySwitchRule, NULL, 0, false); + SwitchUpdateRule(i, kPREventTypeSwitchClosedDebounced, &emptySwitchRule, NULL, 0, false); + SwitchUpdateRule(i, kPREventTypeSwitchOpenNondebounced, &emptySwitchRule, NULL, 0, false); + SwitchUpdateRule(i, kPREventTypeSwitchClosedNondebounced, &emptySwitchRule, NULL, 0, false); } } @@ -580,7 +580,7 @@ PRResult PRDevice::SwitchUpdateConfig(PRSwitchConfig *switchConfig) return rc; } -PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers) +PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers, bool_t drive_outputs_now ) { // Updates a single rule with the associated linked driver state changes. const int burstSize = 4; @@ -621,52 +621,76 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR } } - // Now let's setup the first actual rule: - uint16_t firstRuleIndex = newRuleIndex; - PRSwitchRuleInternal *newRule = GetSwitchRuleByIndex(newRuleIndex); - if (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->reloadActive = rule->reloadActive; - newRule->changeOutput = false; - newRule->linkActive = false; + // Create a pointer for new rules. + PRSwitchRuleInternal *newRule; // Process each driver who's state should change in response to the switch event. if (numDrivers > 0) { + uint32_t ruleIndex, savedRuleIndex; + + // Need to program the main rule last just in case drive_outputs_now is true. + // Otherwise, the hardware could try to access the linked rules before they're + // programmed. So, program the rules in reverse order. + + // Move to last driver + linkedDrivers += (numDrivers - 1); + int totalNumDrivers = numDrivers; + while (numDrivers > 0) { - newRule->changeOutput = true; - newRule->driver = linkedDrivers[0]; - if (numDrivers > 1) { - newRule->linkActive = true; - newRule->linkIndex = freeSwitchRuleIndexes.front(); + ruleIndex = freeSwitchRuleIndexes.front(); freeSwitchRuleIndexes.pop(); - - CreateSwitchUpdateRulesBurst(burst, newRule); - - // Prepare for the next rule: - newRule = GetSwitchRuleByIndex(newRule->linkIndex); + newRule = GetSwitchRuleByIndex(ruleIndex); + newRule->driver = linkedDrivers[0]; + newRule->changeOutput = true; + + if (totalNumDrivers == numDrivers) newRule->linkActive = false; + else + { + newRule->linkActive = true; + newRule->linkIndex = savedRuleIndex; + } + + savedRuleIndex = ruleIndex; + // Set the 3rd param (drive_outputs_now) to false to keep the hardware + // from evaluating the state of the rule index and possibly activating the + // driver. The evaluation will happen later when the primary rule is + // written. + CreateSwitchUpdateRulesBurst(burst, newRule, false); } else { - newRule->linkActive = false; - CreateSwitchUpdateRulesBurst(burst, newRule); + // This is the primary rule. + newRule = GetSwitchRuleByIndex(newRuleIndex); + if (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->reloadActive = rule->reloadActive; + newRule->changeOutput = true; + if (totalNumDrivers > 1) + { + newRule->linkActive = true; + newRule->linkIndex = savedRuleIndex; + newRule->driver = linkedDrivers[0]; + } + else newRule->linkActive = false; + CreateSwitchUpdateRulesBurst(burst, newRule, drive_outputs_now); } - + 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(kPRLogError, "Error while writing switch update, attempting to revert switch rule to a safe state...")); - newRule = GetSwitchRuleByIndex(firstRuleIndex); + newRule = GetSwitchRuleByIndex(newRuleIndex); newRule->changeOutput = false; newRule->linkActive = false; - CreateSwitchUpdateRulesBurst(burst, newRule); + CreateSwitchUpdateRulesBurst(burst, newRule, false); if (PrepareWriteData(burst, burstSize) == kPRSuccess) DEBUG(PRLog(kPRLogError, "Disabled successfully.\n")); else @@ -674,13 +698,21 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR return res; } - linkedDrivers++; + linkedDrivers--; numDrivers--; } } - else - { - CreateSwitchUpdateRulesBurst(burst, newRule); + else { + newRule = GetSwitchRuleByIndex(newRuleIndex); + if (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->reloadActive = rule->reloadActive; + newRule->changeOutput = false; + newRule->linkActive = false; + + CreateSwitchUpdateRulesBurst(burst, newRule, false); DEBUG(PRLog(kPRLogVerbose, "Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3])); // Write the rule: diff --git a/src/PRDevice.h b/src/PRDevice.h index 2582d1c..251a8c1 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -74,7 +74,7 @@ public: PRResult DriverWatchdogTickle(); PRResult SwitchUpdateConfig(PRSwitchConfig *switchConfig); - PRResult SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers); + PRResult SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers, bool_t drive_outputs_now); PRResult SwitchGetStates(PREventType * switchStates, uint16_t numSwitches); PRResult DMDUpdateConfig(PRDMDConfig *dmdConfig); diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index e93fdc5..3860175 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -237,10 +237,11 @@ int16_t CreateSwitchRuleIndex(uint8_t switchNum, PREventType eventType) return index; } -int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType) +int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType, bool_t drive_outputs_now) { uint16_t number = CreateSwitchRuleIndex( switchNum, eventType ); - uint32_t addr = number << P_ROC_SWITCH_RULE_NUM_TO_ADDR_SHIFT; + uint32_t addr = (number << P_ROC_SWITCH_RULE_NUM_TO_ADDR_SHIFT) | + (drive_outputs_now << P_ROC_SWITCH_RULE_DRIVE_OUTPUTS_NOW); return addr; } @@ -256,8 +257,8 @@ void ParseSwitchRuleIndex(uint16_t index, uint8_t *switchNum, PREventType *event *eventType = debounce ? kPREventTypeSwitchClosedDebounced : kPREventTypeSwitchClosedNondebounced; } -int32_t CreateSwitchUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal *rule_record) { - uint32_t addr = CreateSwitchRuleAddr(rule_record->switchNum, rule_record->eventType); +int32_t CreateSwitchUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal *rule_record, bool_t drive_outputs_now) { + uint32_t addr = CreateSwitchRuleAddr(rule_record->switchNum, rule_record->eventType, drive_outputs_now); uint32_t driver_command[3]; CreateDriverUpdateBurst ( driver_command, &(rule_record->driver)); diff --git a/src/PRHardware.h b/src/PRHardware.h index b733dbd..b6dd182 100644 --- a/src/PRHardware.h +++ b/src/PRHardware.h @@ -206,6 +206,7 @@ const uint32_t P_ROC_SWITCH_CONFIG_INACTIVE_PULSES_AFTER_BURST_SHIFT = 12; const uint32_t P_ROC_SWITCH_CONFIG_PULSES_PER_BURST_SHIFT = 6; const uint32_t P_ROC_SWITCH_CONFIG_MS_PER_PULSE_HALF_PERIOD_SHIFT = 0; +const uint32_t P_ROC_SWITCH_RULE_DRIVE_OUTPUTS_NOW = 13; const uint32_t P_ROC_SWITCH_RULE_NUM_DEBOUNCE_SHIFT = 9; const uint32_t P_ROC_SWITCH_RULE_NUM_STATE_SHIFT = 8; const uint32_t P_ROC_SWITCH_RULE_NUM_SWITCH_NUM_SHIFT = 0; @@ -262,11 +263,11 @@ int32_t CreateWatchdogConfigBurst ( uint32_t * burst, bool_t watchdogExpired, int32_t CreateDMDUpdateConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config); int32_t CreateSwitchUpdateConfigBurst ( uint32_t * burst, PRSwitchConfig *switchConfig); -int32_t CreateSwitchUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal *rule_record); +int32_t CreateSwitchUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal *rule_record, bool_t drive_outputs_now); void ParseSwitchRuleIndex(uint16_t index, uint8_t *switchNum, PREventType *eventType); int16_t CreateSwitchRuleIndex(uint8_t switchNum, PREventType eventType); -int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType); +int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType, bool_t drive_outputs_now); int32_t CreateJTAGLatchOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutputs); int32_t CreateJTAGForceOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutputs); diff --git a/src/pinproc.cpp b/src/pinproc.cpp index fef071e..dc092ad 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -497,9 +497,9 @@ PRResult PRSwitchUpdateConfig(PRHandle handle, PRSwitchConfig *switchConfig) return handleAsDevice->SwitchUpdateConfig(switchConfig); } -PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers) +PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers, bool_t drive_outputs_now) { - return handleAsDevice->SwitchUpdateRule(switchNum, eventType, rule, linkedDrivers, numDrivers); + return handleAsDevice->SwitchUpdateRule(switchNum, eventType, rule, linkedDrivers, numDrivers, drive_outputs_now); } PRResult PRSwitchGetStates(PRHandle handle, PREventType * switchStates, uint16_t numSwitches) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index a159d3d..9d36fa1 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -367,9 +367,11 @@ TXsvfDoCmdFuncPtr xsvf_pfDoCmd[] = #endif /* DEBUG_MODE */ #ifdef DEBUG_MODE - FILE* in; /* Legacy DEBUG_MODE file pointer */ int xsvf_iDebugLevel; #endif /* DEBUG_MODE */ +FILE* in; +long int numBytesTotal; +long int numBytesCurrent; PRHandle proc; static int g_iTCK = 0; /* For xapp058_example .exe */ static int g_iTMS = 0; /* For xapp058_example .exe */ @@ -520,8 +522,23 @@ void pulseClock() void readByte(unsigned char *data) { + if (numBytesCurrent == 0) { + printf("\nProgress:\n0%% "); + fflush(stdout); + } // read in a byte of data from the xsvf file *data = (unsigned char)fgetc( in ); + long int bytesPerTenth = numBytesTotal / 10; + long int bytesPer200th = numBytesTotal / 200; + numBytesCurrent++; + if (numBytesCurrent % bytesPerTenth == 0) { + printf("\n%ld0%% ",numBytesCurrent/bytesPerTenth); + fflush(stdout); + } + else if (numBytesCurrent % bytesPer200th == 0) { + printf("."); + fflush(stdout); + } } unsigned char readTDOBit() @@ -1927,6 +1944,12 @@ int main( int argc, char** argv ) } else { + + fseek(in, 0L, SEEK_END); + numBytesTotal = ftell(in); + fseek(in, 0L, SEEK_SET); + numBytesCurrent = 0; + // Instantiate the P-ROC device: XSVFDBG_PRINTF( 1, "Opening P-ROC.\n"); proc = PRCreate(machineType);