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

Fixed switch rule linking and completed DMD configuration

This commit is contained in:
gstellenberg
2009-05-22 21:46:35 -05:00
parent 77fe39aec5
commit a609cfdb42
3 changed files with 112 additions and 83 deletions

View File

@@ -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,32 +222,38 @@ 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;
// Process each driver who's state should change in response to the switch event.
if (numDrivers > 0)
{
while (numDrivers > 0)
{
newRule->changeOutput = true;
@@ -256,13 +262,13 @@ PRResult PRDevice::SwitchesUpdateRule(uint8_t switchNum, PREventType eventType,
if (numDrivers > 1)
{
newRule->linkActive = true;
newRule->linkAddress = freeSwitchRules.front();
freeSwitchRules.pop();
newRule->linkIndex = freeSwitchRuleIndexes.front();
freeSwitchRuleIndexes.pop();
CreateSwitchesUpdateRulesBurst(burst, newRule);
// Prepare for the next rule:
newRule = GetSwitchRuleByAddress(newRule->linkAddress);
newRule = GetSwitchRuleByIndex(newRule->linkIndex);
}
else
{
@@ -270,12 +276,13 @@ PRResult PRDevice::SwitchesUpdateRule(uint8_t switchNum, PREventType eventType,
CreateSwitchesUpdateRulesBurst(burst, newRule);
}
// Write the actual rule:
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 = GetSwitchRuleByAddress(firstRuleAddr);
newRule = GetSwitchRuleByIndex(firstRuleIndex);
newRule->changeOutput = false;
newRule->linkActive = false;
CreateSwitchesUpdateRulesBurst(burst, newRule);
@@ -289,34 +296,43 @@ PRResult PRDevice::SwitchesUpdateRule(uint8_t switchNum, PREventType eventType,
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;

View File

@@ -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) );
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;
}
int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType)
{
uint16_t number = CreateSwitchRuleIndex( switchNum, eventType );
uint32_t addr = number << P_ROC_SWITCH_RULE_NUM_TO_ADDR_SHIFT;
return addr;
}
void ParseSwitchAddress(uint32_t addr, uint8_t *switchNum, PREventType *eventType)
void ParseSwitchRuleIndex(uint16_t index, uint8_t *switchNum, PREventType *eventType)
{
*switchNum = (addr >> P_ROC_SWITCH_RULE_ADDR_SWITCH_NUM_SHIFT) & 0xff;
*switchNum = (index >> P_ROC_SWITCH_RULE_NUM_SWITCH_NUM_SHIFT) & 0xff;
bool open = ((addr >> P_ROC_SWITCH_RULE_ADDR_STATE_SHIFT) & 0x1) == 0x1;
bool debounce = ((addr >> P_ROC_SWITCH_RULE_ADDR_DEBOUNCE_SHIFT) & 0x1) == 0x1;
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);

View File

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