From a609cfdb42d1f74a840df52dc7cfd557aca08770 Mon Sep 17 00:00:00 2001 From: gstellenberg Date: Fri, 22 May 2009 21:46:35 -0500 Subject: [PATCH] Fixed switch rule linking and completed DMD configuration --- src/PRDevice.cpp | 142 +++++++++++++++++++++++++-------------------- src/PRHardware.cpp | 45 +++++++++----- src/pinproc.cpp | 8 +-- 3 files changed, 112 insertions(+), 83 deletions(-) diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index db14858..4ca579f 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -85,11 +85,11 @@ void PRDevice::Reset() { PRSwitchRuleInternal *switchRule = &switchRules[i]; memset(switchRule, 0x00, sizeof(PRSwitchRule)); - uint32_t addr = (i << P_ROC_SWITCH_RULE_ADDR_SWITCH_NUM_SHIFT); - ParseSwitchAddress(addr, &switchRule->switchNum, &switchRule->eventType); + uint16_t ruleIndex = i; + ParseSwitchRuleIndex(ruleIndex, &switchRule->switchNum, &switchRule->eventType); switchRule->driver.polarity = defaultPolarity; if (switchRule->switchNum >= kPRSwitchVirtualFirst && switchRule->switchNum <= kPRSwitchVirtualLast) - freeSwitchRules.push(addr); + freeSwitchRuleIndexes.push(ruleIndex); } unrequestedDataQueue.empty(); @@ -206,9 +206,9 @@ PRResult PRDevice::DriverWatchdogTickle() -PRSwitchRuleInternal *PRDevice::GetSwitchRuleByAddress(uint32_t addr) +PRSwitchRuleInternal *PRDevice::GetSwitchRuleByIndex(uint16_t index) { - return &switchRules[addr>>P_ROC_SWITCH_RULE_ADDR_SWITCH_NUM_SHIFT]; + return &switchRules[index]; } PRResult PRDevice::SwitchesUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers) @@ -222,101 +222,117 @@ PRResult PRDevice::SwitchesUpdateRule(uint8_t switchNum, PREventType eventType, DEBUG(PRLog("Switch rule out of range 0-%d\n", kPRSwitchPhysicalLast)); return kPRFailure; } - if (freeSwitchRules.size() < numDrivers-1) // -1 because the first switch rule holds the first driver. + + // If more the base rule will link to others, ensure free indexes exists for + // 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 rules: %d available, need %d\n", freeSwitchRules.size(), numDrivers)); + DEBUG(PRLog("Not enough free switch rule indexes: %d available, need %d\n", freeSwitchRuleIndexes.size(), numDrivers)); return kPRFailure; } - + PRResult res = kPRSuccess; - uint32_t newRuleAddr = CreateSwitchRuleAddr(switchNum, eventType); + uint32_t newRuleIndex = CreateSwitchRuleIndex(switchNum, eventType); - // First we need to check the linked rule to see if the indicated switchNum has any rules that need to be freed: - PRSwitchRuleInternal *oldRule = GetSwitchRuleByAddress(newRuleAddr); + // Because we're redefining the rule chain, we need to remove all previously existing links and return the indexes to the free list. + PRSwitchRuleInternal *oldRule = GetSwitchRuleByIndex(newRuleIndex); while (oldRule->linkActive) { - oldRule = GetSwitchRuleByAddress(oldRule->linkAddress); - freeSwitchRules.push(oldRule->linkAddress); + oldRule = GetSwitchRuleByIndex(oldRule->linkIndex); + freeSwitchRuleIndexes.push(oldRule->linkIndex); } // Now let's setup the first actual rule: - uint32_t firstRuleAddr = newRuleAddr; - PRSwitchRuleInternal *newRule = GetSwitchRuleByAddress(newRuleAddr); + 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", newRuleAddr, 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)); newRule->notifyHost = rule->notifyHost; newRule->changeOutput = false; newRule->linkActive = false; - while (numDrivers > 0) + // Process each driver who's state should change in response to the switch event. + if (numDrivers > 0) { - newRule->changeOutput = true; - newRule->driver = linkedDrivers[0]; - - if (numDrivers > 1) + while (numDrivers > 0) { - newRule->linkActive = true; - newRule->linkAddress = freeSwitchRules.front(); - freeSwitchRules.pop(); + newRule->changeOutput = true; + newRule->driver = linkedDrivers[0]; - CreateSwitchesUpdateRulesBurst(burst, newRule); - - // Prepare for the next rule: - newRule = GetSwitchRuleByAddress(newRule->linkAddress); - } - else - { - newRule->linkActive = false; - CreateSwitchesUpdateRulesBurst(burst, newRule); - } - - // Write the actual rule: - res = WriteData(burst, burstSize); - if (res != kPRSuccess) - { - DEBUG(PRLog("Error while writing switch update, attempting to revert switch rule to a safe state...")); - newRule = GetSwitchRuleByAddress(firstRuleAddr); - newRule->changeOutput = false; - newRule->linkActive = false; - CreateSwitchesUpdateRulesBurst(burst, newRule); - if (WriteData(burst, burstSize) == kPRSuccess) - DEBUG(PRLog("Disabled successfully.\n")); + if (numDrivers > 1) + { + newRule->linkActive = true; + newRule->linkIndex = freeSwitchRuleIndexes.front(); + freeSwitchRuleIndexes.pop(); + + CreateSwitchesUpdateRulesBurst(burst, newRule); + + // Prepare for the next rule: + newRule = GetSwitchRuleByIndex(newRule->linkIndex); + } else - DEBUG(PRLog("Failed to disable.\n")); - return res; + { + newRule->linkActive = false; + CreateSwitchesUpdateRulesBurst(burst, newRule); + } + + DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3])); + // Write the rule: + res = WriteData(burst, burstSize); + if (res != kPRSuccess) + { + DEBUG(PRLog("Error while writing switch update, attempting to revert switch rule to a safe state...")); + newRule = GetSwitchRuleByIndex(firstRuleIndex); + newRule->changeOutput = false; + newRule->linkActive = false; + CreateSwitchesUpdateRulesBurst(burst, newRule); + if (WriteData(burst, burstSize) == kPRSuccess) + DEBUG(PRLog("Disabled successfully.\n")); + else + DEBUG(PRLog("Failed to disable.\n")); + return res; + } + + linkedDrivers++; + numDrivers--; } - - linkedDrivers++; - numDrivers--; + } + else + { + CreateSwitchesUpdateRulesBurst(burst, newRule); + DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3])); + + // Write the rule: + res = WriteData(burst, burstSize); } return res; } -int32_t PRDevice::DMDUpdateGlobalConfig(PRDMDGlobalConfig *dmdGlobalConfig) +int32_t PRDevice::DMDUpdateConfig(PRDMDConfig *dmdConfig) { uint32_t rc; - uint32_t burst[10]; + const int burstWords = 7; + uint32_t burst[burstWords]; - CreateDMDUpdateGlobalConfigBurst(burst, dmdGlobalConfig); + this->dmdConfig = *dmdConfig; + CreateDMDUpdateConfigBurst(burst, dmdConfig); - DEBUG(PRLog("DMD config packet: ")); - for (int i=0; i<10; i++) { - DEBUG(PRLog("%d ", burst[i])); - } - DEBUG(PRLog("\n")); + DEBUG(PRLog("Configuring DMD")); + DEBUG(PRLog("Words: %x %x %x %x %x %x %x\n",burst[0],burst[1],burst[2],burst[3], + burst[4],burst[5],burst[6])); - rc = WriteData(burst, 9); + rc = WriteData(burst, burstWords); return rc; } -PRResult PRDevice::DMDDraw(uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames) +PRResult PRDevice::DMDDraw(uint8_t * dots) { 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; + uint16_t words_per_sub_frame = (dmdConfig.numColumns*dmdConfig.numRows) / 32; + uint16_t words_per_frame = words_per_sub_frame * dmdConfig.numSubFrames; uint32_t dmd_command_buffer[1024]; uint32_t * p_dmd_frame_buffer_words; diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index a9a276e..ca46741 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -139,23 +139,30 @@ int32_t CreateWatchdogConfigBurst ( uint32_t * burst, bool_t watchdogExpired, return kPRSuccess; } -int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType) +int16_t CreateSwitchRuleIndex(uint8_t switchNum, PREventType eventType) { uint32_t debounce = (eventType == kPREventTypeSwitchOpenDebounced) || (eventType == kPREventTypeSwitchClosedDebounced) ? 1 : 0; uint32_t state = (eventType == kPREventTypeSwitchOpenDebounced) || (eventType == kPREventTypeSwitchOpenNondebounced) ? 1 : 0; - uint32_t addr = ((debounce << P_ROC_SWITCH_RULE_ADDR_DEBOUNCE_SHIFT) | - (state << P_ROC_SWITCH_RULE_ADDR_STATE_SHIFT) | - (switchNum << P_ROC_SWITCH_RULE_ADDR_SWITCH_NUM_SHIFT) ); - return addr; + uint32_t index = ((debounce << P_ROC_SWITCH_RULE_NUM_DEBOUNCE_SHIFT) | + (state << P_ROC_SWITCH_RULE_NUM_STATE_SHIFT) | + (switchNum << P_ROC_SWITCH_RULE_NUM_SWITCH_NUM_SHIFT) ); + return index; } -void ParseSwitchAddress(uint32_t addr, uint8_t *switchNum, PREventType *eventType) +int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType) { - *switchNum = (addr >> P_ROC_SWITCH_RULE_ADDR_SWITCH_NUM_SHIFT) & 0xff; + uint16_t number = CreateSwitchRuleIndex( switchNum, eventType ); + uint32_t addr = number << P_ROC_SWITCH_RULE_NUM_TO_ADDR_SHIFT; + return addr; +} - bool open = ((addr >> P_ROC_SWITCH_RULE_ADDR_STATE_SHIFT) & 0x1) == 0x1; - bool debounce = ((addr >> P_ROC_SWITCH_RULE_ADDR_DEBOUNCE_SHIFT) & 0x1) == 0x1; +void ParseSwitchRuleIndex(uint16_t index, uint8_t *switchNum, PREventType *eventType) +{ + *switchNum = (index >> P_ROC_SWITCH_RULE_NUM_SWITCH_NUM_SHIFT) & 0xff; + + bool open = ((index >> P_ROC_SWITCH_RULE_NUM_STATE_SHIFT) & 0x1) == 0x1; + bool debounce = ((index >> P_ROC_SWITCH_RULE_NUM_DEBOUNCE_SHIFT) & 0x1) == 0x1; if (open) *eventType = debounce ? kPREventTypeSwitchOpenDebounced : kPREventTypeSwitchOpenNondebounced; else @@ -175,23 +182,29 @@ int32_t CreateSwitchesUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal 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->linkIndex << 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) +int32_t CreateDMDUpdateConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config) { uint32_t addr; uint32_t i; - addr = 8; - burst[0] = CreateBurstCommand (P_ROC_BUS_DMD_SELECT, addr, 8 ); + addr = 0; + burst[0] = CreateBurstCommand (P_ROC_BUS_DMD_SELECT, addr, 1 ); + burst[1] = (1 << P_ROC_DMD_ENABLE_SHIFT) | + (dmd_config->numSubFrames << P_ROC_DMD_NUM_SUB_FRAMES_SHIFT) | + (dmd_config->numRows << P_ROC_DMD_NUM_ROWS_SHIFT) | + (dmd_config->numColumns << P_ROC_DMD_NUM_COLUMNS_SHIFT); - for (i=0; i<8; i++) { - burst[i+1] = 0; - burst[i+1] = (dmd_config->rclkLowCycles[i] << P_ROC_DMD_RCLK_LOW_CYCLES_SHIFT) | + addr = 8; + burst[2] = CreateBurstCommand (P_ROC_BUS_DMD_SELECT, addr, 4 ); + + for (i=0; i<4; i++) { + burst[i+3] = (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); diff --git a/src/pinproc.cpp b/src/pinproc.cpp index e223f6f..ea6ce52 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -187,12 +187,12 @@ PR_EXPORT PRResult PRSwitchesUpdateRule(PRHandle handle, uint8_t switchNum, PREv return handleAsDevice->SwitchesUpdateRule(switchNum, eventType, rule, linkedDrivers, numDrivers); } -PR_EXPORT int32_t PRDMDUpdateGlobalConfig(PRHandle handle, PRDMDGlobalConfig *dmdGlobalConfig) +PR_EXPORT int32_t PRDMDUpdateConfig(PRHandle handle, PRDMDConfig *dmdConfig) { - return handleAsDevice->DMDUpdateGlobalConfig(dmdGlobalConfig); + return handleAsDevice->DMDUpdateConfig(dmdConfig); } -PR_EXPORT PRResult PRDMDDraw(PRHandle handle, uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames) +PR_EXPORT PRResult PRDMDDraw(PRHandle handle, uint8_t * dots) { - return handleAsDevice->DMDDraw(dots, columns, rows, numSubFrames); + return handleAsDevice->DMDDraw(dots); }