1
0
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:
gstellenberg
2009-05-31 11:25:09 -05:00
parent 301f3aa26b
commit 2fc0732908
9 changed files with 153 additions and 9 deletions

View File

@@ -100,3 +100,4 @@ void UpdateDots( unsigned char * dots, unsigned int dotOffset )
}
}
}

View File

@@ -84,6 +84,9 @@ void RunLoop(PRHandle proc)
unsigned char dots[4*((128*32)/8)];
unsigned int dotOffset = 0;
// Retrieve and store initial switch states.
LoadSwitchStates(proc);
while (runLoopRun)
{
PRDriverWatchdogTickle(proc);
@@ -107,6 +110,7 @@ void RunLoop(PRHandle proc)
struct timeval tv;
gettimeofday(&tv, NULL);
printf("%d.%03d switch % 3d: %s\n", tv.tv_sec-startTime, tv.tv_usec/1000, event->value, stateText);
UpdateSwitchState( event );
}
PRFlushWriteData(proc);
usleep(10*1000); // Sleep for 10ms so we aren't pegging the CPU.

View File

@@ -54,6 +54,8 @@ void ConfigureDrivers(PRHandle proc, PRMachineType machineType, YAML::Node& yaml
void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc);
void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc);
void UpdateSwitchState (PREvent * event);
void LoadSwitchStates (PRHandle proc);
void ConfigureDMD(PRHandle proc);
void UpdateDots(unsigned char * dots, unsigned int dotOffset);

View File

@@ -24,6 +24,12 @@
*/
#include "pinproctest.h"
typedef struct SwitchStatus {
PREventType state;
uint32_t lastEventTime;
} SwitchStatus;
static SwitchStatus switches[kPRSwitchPhysicalLast + 1];
void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc)
{
@@ -36,6 +42,13 @@ void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc)
switchConfig.pulsesPerBurst = 6;
switchConfig.pulseHalfPeriodTime = 13; // milliseconds
PRSwitchUpdateConfig(proc, &switchConfig);
// Go through the switches array and reset the current status of each switch
for (int i = 0; i <= kPRSwitchPhysicalLast; i++)
{
switches[i].state = kPREventTypeInvalid;
switches[i].lastEventTime = 0;
}
}
void ConfigureWPCFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, int holdCoilNum, int pulseTime)
@@ -107,3 +120,42 @@ void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc)
ConfigureBumperRule (proc, swNum, coilNum, kBumperPulseTime);
}
}
void UpdateSwitchState( PREvent * event )
{
switches[event->value].state = event->type;
switches[event->value].lastEventTime = event->time;
}
void LoadSwitchStates( PRHandle proc )
{
int i;
PREventType procSwitchStates[kPRSwitchPhysicalLast + 1];
// Get all of the switch states from the P-ROC.
if (PRSwitchGetStates( proc, procSwitchStates, kPRSwitchPhysicalLast + 1 ) == kPRFailure)
{
fprintf(stderr, "Error: Unable to retrieve switch states\n");
}
else
{
// Copy the returning states into the local switches array.
for (i = 0; i <= kPRSwitchPhysicalLast; i++)
{
switches[i].state = procSwitchStates[i];
}
fprintf(stderr, "\nCurrent Switch States: 0 : ");
for (i = 0; i < kPRSwitchPhysicalLast + 1; i++)
{
fprintf(stderr, "%d ", switches[i].state);
if ((i + 1) % 32 == 0)
{
printf("\n");
if (i != kPRSwitchPhysicalLast)
fprintf(stderr, "Current Switch States: %d : ", i);
}
}
fprintf(stderr, "\n");
}
}

View File

@@ -334,6 +334,9 @@ PR_EXPORT PRResult PRSwitchUpdateConfig(PRHandle handle, PRSwitchConfig *switchC
*/
PR_EXPORT PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers);
/** Returns a list of PREventTypes describing the states of the requested number of switches */
PR_EXPORT PRResult PRSwitchGetStates(PRHandle handle, PREventType * switchStates, uint16_t numSwitches);
/** @} */ // End of Switches & Events
// DMD

View File

@@ -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: {

View File

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

View File

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

View File

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