mirror of
https://github.com/preble/libpinproc
synced 2026-02-24 18:25:23 +01:00
Implemented PRSwitchGetStates to retrieve the current state of each switch
This commit is contained in:
@@ -82,7 +82,8 @@ PRResult PRDevice::Reset(uint32_t resetFlags)
|
||||
group->polarity = defaultPolarity;
|
||||
}
|
||||
|
||||
freeSwitchRuleIndexes.empty();
|
||||
// Make sure the free list is empty.
|
||||
while (!freeSwitchRuleIndexes.empty()) freeSwitchRuleIndexes.pop();
|
||||
|
||||
for (i = 0; i < kPRSwitchRulesCount; i++)
|
||||
{
|
||||
@@ -112,8 +113,9 @@ PRResult PRDevice::Reset(uint32_t resetFlags)
|
||||
}
|
||||
}
|
||||
|
||||
unrequestedDataQueue.empty();
|
||||
requestedDataQueue.empty();
|
||||
// Make sure the data queues are empty.
|
||||
while (!unrequestedDataQueue.empty()) unrequestedDataQueue.pop();
|
||||
while (!requestedDataQueue.empty()) requestedDataQueue.pop();
|
||||
num_collected_bytes = 0;
|
||||
numPreparedWriteWords = 0;
|
||||
|
||||
@@ -346,6 +348,74 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR
|
||||
return res;
|
||||
}
|
||||
|
||||
PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwitches )
|
||||
{
|
||||
uint32_t rc;
|
||||
uint32_t stateWord, debounceWord;
|
||||
uint8_t i, j;
|
||||
PREventType eventType;
|
||||
|
||||
// Request one state word and one debounce word at a time. Could make more efficient
|
||||
// use of the USB bus by requesting a burst of state words and then a burst of debounce
|
||||
// words, but doing one word at a time makes it easier to process each switch when the
|
||||
// data returns. Also, this function shouldn't be called during timing sensitive
|
||||
// situations; so the inefficiencies are acceptable.
|
||||
for (i = 0; i < numSwitches / 32; i++)
|
||||
{
|
||||
rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT,
|
||||
P_ROC_SWITCH_CTRL_STATE_BASE_ADDR + i, 1);
|
||||
rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT,
|
||||
P_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR + i, 1);
|
||||
}
|
||||
|
||||
// Expect 4 words for each 32 switches. The state and debounce words,
|
||||
// and the address words for both.
|
||||
uint16_t numWords = 4 * (numSwitches / 32);
|
||||
|
||||
i = 0; // Reset i so it can be used to prevent an infinite loop below
|
||||
|
||||
// Wait for data to return. Give it 10 loops before giving up.
|
||||
while (requestedDataQueue.size() < numWords && i++ < 10)
|
||||
{
|
||||
sleep (.01); // 10 milliseconds should be plenty of time.
|
||||
SortReturningData();
|
||||
}
|
||||
|
||||
// Make sure all of the requested words are available before processing them.
|
||||
// Too many words is just as bad as not enough words.
|
||||
// If too many come back, can they be trusted?
|
||||
if (requestedDataQueue.size() == numWords)
|
||||
{
|
||||
// Process the returning words.
|
||||
for (i = 0; i < numSwitches / 32; i++)
|
||||
{
|
||||
requestedDataQueue.pop(); // Ignore address word. TODO: Verify this address word.
|
||||
stateWord = requestedDataQueue.front(); // This is the switch state word.
|
||||
requestedDataQueue.pop();
|
||||
requestedDataQueue.pop(); // Ignore address word. TODO: Verify this address word.
|
||||
debounceWord = requestedDataQueue.front(); // This is the debounce word.
|
||||
requestedDataQueue.pop();
|
||||
|
||||
// Loop through each bit of the words, combining them into an eventType
|
||||
for (j = 0; j < 32; j++)
|
||||
{
|
||||
// Only process the number of switches requested via numSwitches
|
||||
if ((i * 32) + j < numSwitches)
|
||||
{
|
||||
if (stateWord >> j & 1)
|
||||
if (debounceWord >> j & 1) eventType = kPREventTypeSwitchOpenDebounced;
|
||||
else eventType = kPREventTypeSwitchOpenNondebounced;
|
||||
else if (debounceWord >> j & 1) eventType = kPREventTypeSwitchClosedDebounced;
|
||||
else eventType = kPREventTypeSwitchClosedNondebounced;
|
||||
switchStates[(i * 32) + j] = eventType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return kPRSuccess;
|
||||
}
|
||||
else return kPRFailure;
|
||||
}
|
||||
|
||||
int32_t PRDevice::DMDUpdateConfig(PRDMDConfig *dmdConfig)
|
||||
{
|
||||
uint32_t rc;
|
||||
@@ -645,14 +715,17 @@ PRResult PRDevice::SortReturningData()
|
||||
|
||||
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,
|
||||
// Push the address word so it can be used to identify the subsequent data.
|
||||
requestedDataQueue.push(rd_buffer[0]);
|
||||
int wordsRead = ReadData(rd_buffer,
|
||||
(rd_buffer[0] & P_ROC_HEADER_LENGTH_MASK) >>
|
||||
P_ROC_HEADER_LENGTH_SHIFT);
|
||||
for (int i = 0; i < bytesRead; i++)
|
||||
for (int i = 0; i < wordsRead; i++)
|
||||
{
|
||||
DEBUG(PRLog(kPRLogVerbose, "Pushing onto unreq Q 0x%x\n", rd_buffer[i]));
|
||||
requestedDataQueue.push(rd_buffer[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case P_ROC_UNREQUESTED_DATA: {
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
|
||||
PRResult SwitchUpdateConfig(PRSwitchConfig *switchConfig);
|
||||
PRResult SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers);
|
||||
PRResult SwitchGetStates(PREventType * switchStates, uint16_t numSwitches);
|
||||
|
||||
PRResult DriverWatchdogTickle();
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ const uint32_t P_ROC_MANAGER_WATCHDOG_EXPIRED_SHIFT = 30;
|
||||
const uint32_t P_ROC_MANAGER_WATCHDOG_ENABLE_SHIFT = 14;
|
||||
const uint32_t P_ROC_MANAGER_WATCHDOG_RESET_TIME_SHIFT = 0;
|
||||
|
||||
const uint32_t P_ROC_SWITCH_CTRL_STATE_BASE_ADDR = 4;
|
||||
const uint32_t P_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR = 11;
|
||||
|
||||
const uint32_t P_ROC_EVENT_SWITCH_NUM_MASK = 0xFF;
|
||||
const uint32_t P_ROC_EVENT_SWITCH_STATE_MASK = 0x100;
|
||||
const uint32_t P_ROC_EVENT_SWITCH_STATE_SHIFT = 8;
|
||||
|
||||
@@ -212,6 +212,11 @@ PR_EXPORT PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREven
|
||||
return handleAsDevice->SwitchUpdateRule(switchNum, eventType, rule, linkedDrivers, numDrivers);
|
||||
}
|
||||
|
||||
PR_EXPORT PRResult PRSwitchGetStates(PRHandle handle, PREventType * switchStates, uint16_t numSwitches)
|
||||
{
|
||||
return handleAsDevice->SwitchGetStates(switchStates, numSwitches);
|
||||
}
|
||||
|
||||
PR_EXPORT int32_t PRDMDUpdateConfig(PRHandle handle, PRDMDConfig *dmdConfig)
|
||||
{
|
||||
return handleAsDevice->DMDUpdateConfig(dmdConfig);
|
||||
|
||||
Reference in New Issue
Block a user