1
0
mirror of https://github.com/preble/libpinproc synced 2026-02-24 18:25:23 +01:00
Files
libpinproc/examples/pinproctest/pinproctest.cpp
2009-05-19 21:21:20 -04:00

189 lines
5.6 KiB
C++

/*
* The MIT License
* Copyright (c) 2009 Gerry Stellenberg, Adam Preble
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* pinproctest.cpp
* libpinproc
*/
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include "pinproc.h" // Include libpinproc's header.
/** Demonstration of the custom logging callback. */
void TestLogger(const char *text)
{
fprintf(stderr, "TEST: %s", text);
}
void ConfigureDrivers(PRHandle proc)
{
int i;
PRDriverGlobalConfig globals;
globals.enableOutputs = false;
globals.globalPolarity = false;
globals.useClear = false;
globals.strobeStartSelect = false;
globals.startStrobeTime = 4; // milliseconds per output loop
globals.matrixRowEnableIndex1 = 12;
globals.matrixRowEnableIndex0 = 6;
globals.activeLowMatrixRows = true;
globals.tickleWatchdog = false;
globals.encodeEnables = false;
// We want to start up safely, so we'll update the global driver config twice.
// When we toggle enableOutputs like this P-ROC will reset the polarity:
// Enable now without the outputs enabled:
PRDriverUpdateGlobalConfig(proc, &globals);
// Now enable the outputs: (TODO: Why?)
globals.enableOutputs = true;
PRDriverUpdateGlobalConfig(proc, &globals);
// Configure the groups:
PRDriverGroupConfig group;
for (i = 0; i < 6; i++)
{
PRDriverGetGroupConfig(proc, i + 4, &group);
group.slowTime = 0;
group.enableIndex = i;
group.rowActivateIndex = i;
group.rowEnableSelect = 0;
group.matrixed = false;
group.polarity = false;
group.active = 1;
group.disableStrobeAfter = false;
PRDriverUpdateGroupConfig(proc, &group);
}
for (i = 6; i < 14; i++) {
PRDriverGetGroupConfig(proc, i + 4, &group);
group.slowTime = 400;
group.enableIndex = 7;
group.rowActivateIndex = i - 6;
group.rowEnableSelect = 0;
group.matrixed = 1;
group.polarity = 0;
group.active = 1;
group.disableStrobeAfter = 1;
PRDriverUpdateGroupConfig(proc, &group);
}
}
void ConfigureSwitches(PRHandle proc)
{
int i;
// Create a basic driver for all of the switches to default to:
PRDriverState defaultDriver;
memset(&defaultDriver, 0x0, sizeof(defaultDriver)); // Set all fields to 0.
for (i = 0; i <= kPRSwitchPhysicalLast; i++)
{
PRSwitchRule sw;
sw.switchNum = i;
sw.notifyHost = true;
sw.changeOutput = false;
sw.linkActive = false;
sw.linkAddress = 0;
sw.eventType = kPREventTypeSwitchClosedDebounced;
sw.driver = defaultDriver;
PRSwitchesUpdateRules(proc, &sw, 1);
sw.eventType = kPREventTypeSwitchOpenDebounced;
PRSwitchesUpdateRules(proc, &sw, 1);
}
}
bool runLoopRun = true;
void RunLoop(PRHandle proc)
{
const int maxEvents = 16;
PREvent events[maxEvents];
while (runLoopRun)
{
int numEvents = PRGetEvents(proc, events, maxEvents);
for (int i = 0; i < numEvents; i++)
{
PREvent *event = &events[i];
const char *stateText = "Unknown";
switch (event->type)
{
case kPREventTypeSwitchOpenDebounced: stateText = "open"; break;
case kPREventTypeSwitchClosedDebounced: stateText = "closed"; break;
case kPREventTypeSwitchOpenNondebounced: stateText = "open(ndb)"; break;
case kPREventTypeSwitchClosedNondebounced: stateText = "closed(ndb)"; break;
}
printf("switch % 3d: %s\n", event->value, stateText);
}
usleep(10*1000); // Sleep for 10ms so we aren't pegging the CPU.
}
}
void sigint(int)
{
runLoopRun = false;
signal(SIGINT, SIG_DFL); // Re-install the default signal handler.
printf("Exiting...\n");
}
int main(const char **argv, int argc)
{
// Set a signal handler so that we can exit gracefully on Ctrl-C:
signal(SIGINT, sigint);
// Assign a custom logging callback to demonstrate capturing log information from P-ROC:
PRLogSetCallback(TestLogger);
// Finally instantiate the P-ROC device:
PRHandle proc = PRCreate(kPRMachineWPC);
if (proc == kPRHandleInvalid)
return 1;
printf("Configuring P-ROC...\n");
ConfigureDrivers(proc);
ConfigureSwitches(proc);
printf("Running. Hit Ctrl-C to exit.\n");
// Pulse a coil to test:
// PRDriverDisable(proc, 80);
// PRDriverPulse(proc, 53, 100);
RunLoop(proc);
// Destroy the P-ROC device handle:
PRDelete(proc);
proc = kPRHandleInvalid;
return 0;
}