mirror of
https://github.com/preble/libpinproc
synced 2026-02-24 18:25:23 +01:00
Merge branch 'master' of ssh://gerrys-quad/home/gerrys/work/pinball/P-ROC/P-ROC
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
#include "../../include/pinproc.h" // Include libpinproc's header.
|
#include "../../include/pinproc.h" // Include libpinproc's header.
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#define kFlippersSection "PRFlippers"
|
#define kFlippersSection "PRFlippers"
|
||||||
#define kBumpersSection "PRBumpers"
|
#define kBumpersSection "PRBumpers"
|
||||||
@@ -188,8 +189,6 @@ void ConfigureDrivers(PRHandle proc, PRMachineType machineType, YAML::Node& yaml
|
|||||||
|
|
||||||
void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc)
|
void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
// Configure switch controller registers (if the defaults aren't acceptable)
|
// Configure switch controller registers (if the defaults aren't acceptable)
|
||||||
PRSwitchConfig switchConfig;
|
PRSwitchConfig switchConfig;
|
||||||
switchConfig.clear = false;
|
switchConfig.clear = false;
|
||||||
@@ -199,15 +198,6 @@ void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc)
|
|||||||
switchConfig.pulsesPerBurst = 6;
|
switchConfig.pulsesPerBurst = 6;
|
||||||
switchConfig.pulseHalfPeriodTime = 13; // milliseconds
|
switchConfig.pulseHalfPeriodTime = 13; // milliseconds
|
||||||
PRSwitchUpdateConfig(proc, &switchConfig);
|
PRSwitchUpdateConfig(proc, &switchConfig);
|
||||||
|
|
||||||
// Configures rules to notify the host for every debounced switch event.
|
|
||||||
for (i = 0; i <= kPRSwitchPhysicalLast; i++)
|
|
||||||
{
|
|
||||||
PRSwitchRule sw;
|
|
||||||
sw.notifyHost = true;
|
|
||||||
PRSwitchUpdateRule(proc, i, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0);
|
|
||||||
PRSwitchUpdateRule(proc, i, kPREventTypeSwitchOpenDebounced, &sw, NULL, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWPCFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, int holdCoilNum, int pulseTime)
|
void ConfigureWPCFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, int holdCoilNum, int pulseTime)
|
||||||
@@ -223,6 +213,8 @@ void ConfigureWPCFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, i
|
|||||||
PRDriverStatePulse(&drivers[1],0); // Turn on indefintely (set pulse for 0ms)
|
PRDriverStatePulse(&drivers[1],0); // Turn on indefintely (set pulse for 0ms)
|
||||||
sw.notifyHost = false;
|
sw.notifyHost = false;
|
||||||
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules);
|
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules);
|
||||||
|
sw.notifyHost = true;
|
||||||
|
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, drivers, numDriverRules);
|
||||||
|
|
||||||
// Flipper off rules
|
// Flipper off rules
|
||||||
PRDriverGetState(proc, mainCoilNum, &drivers[0]);
|
PRDriverGetState(proc, mainCoilNum, &drivers[0]);
|
||||||
@@ -231,6 +223,8 @@ void ConfigureWPCFlipperSwitchRule (PRHandle proc, int swNum, int mainCoilNum, i
|
|||||||
PRDriverStateDisable(&drivers[1]); // Disable hold coil
|
PRDriverStateDisable(&drivers[1]); // Disable hold coil
|
||||||
sw.notifyHost = false;
|
sw.notifyHost = false;
|
||||||
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenNondebounced, &sw, drivers, numDriverRules);
|
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenNondebounced, &sw, drivers, numDriverRules);
|
||||||
|
sw.notifyHost = true;
|
||||||
|
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchOpenDebounced, &sw, drivers, numDriverRules);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureBumperRule (PRHandle proc, int swNum, int coilNum, int pulseTime)
|
void ConfigureBumperRule (PRHandle proc, int swNum, int coilNum, int pulseTime)
|
||||||
@@ -244,6 +238,8 @@ void ConfigureBumperRule (PRHandle proc, int swNum, int coilNum, int pulseTime)
|
|||||||
PRDriverStatePulse(&drivers[0],pulseTime); // Pulse coil for 34ms.
|
PRDriverStatePulse(&drivers[0],pulseTime); // Pulse coil for 34ms.
|
||||||
sw.notifyHost = false;
|
sw.notifyHost = false;
|
||||||
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules);
|
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules);
|
||||||
|
sw.notifyHost = true;
|
||||||
|
PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, drivers, numDriverRules);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc)
|
void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc)
|
||||||
@@ -306,7 +302,7 @@ void ConfigureDMD(PRHandle proc)
|
|||||||
// starting with dim dots at the top.
|
// starting with dim dots at the top.
|
||||||
void UpdateDots( unsigned char * dots, unsigned int dotOffset )
|
void UpdateDots( unsigned char * dots, unsigned int dotOffset )
|
||||||
{
|
{
|
||||||
int i,j,k,color,mappedColor,loopCtr,byte_shifter;
|
int row,col,subFrame,color,mappedColor,loopCtr,byte_shifter;
|
||||||
const int rate_reduction_divisor = 1;
|
const int rate_reduction_divisor = 1;
|
||||||
|
|
||||||
loopCtr = dotOffset/rate_reduction_divisor;
|
loopCtr = dotOffset/rate_reduction_divisor;
|
||||||
@@ -323,33 +319,34 @@ void UpdateDots( unsigned char * dots, unsigned int dotOffset )
|
|||||||
memset(dots,0,((kDMDColumns*kDMDRows)/8)*kDMDSubFrames);
|
memset(dots,0,((kDMDColumns*kDMDRows)/8)*kDMDSubFrames);
|
||||||
|
|
||||||
// Loop through all of the rows
|
// Loop through all of the rows
|
||||||
for (i = kDMDRows - 1; i >= 0; i--)
|
for (row = kDMDRows - 1; row >= 0; row--)
|
||||||
{
|
{
|
||||||
// Map the color index to the DMD's physical color map
|
// Map the color index to the DMD's physical color map
|
||||||
int mappedColors[] = {0, 2, 8, 10, 1, 3, 9, 11, 4, 6, 12, 14, 5, 7, 13, 15};
|
int mappedColors[] = {0, 2, 8, 10, 1, 3, 9, 11, 4, 6, 12, 14, 5, 7, 13, 15};
|
||||||
mappedColor = mappedColors[color];
|
mappedColor = mappedColors[color];
|
||||||
|
|
||||||
// Loop through each of 16 bytes in a row
|
// Loop through each of 16 bytes in a row
|
||||||
for (j = 0; j < kDMDColumns / 8; j++)
|
for (col = 0; col < kDMDColumns / 8; col++)
|
||||||
{
|
{
|
||||||
// Loop through each subframe
|
// Loop through each subframe
|
||||||
for (k = 0; k < kDMDSubFrames; k++)
|
for (subFrame = 0; subFrame < kDMDSubFrames; subFrame++)
|
||||||
{
|
{
|
||||||
// Turn on the byte in each sub-frame that's enabled
|
// Turn on the byte in each sub-frame that's enabled
|
||||||
// active for the color code.
|
// active for the color code.
|
||||||
if ((mappedColor >> k) & 1 == 1)
|
if ((mappedColor >> subFrame) & 1 == 1)
|
||||||
dots[k*(kDMDColumns*kDMDRows/8)+((i%kDMDRows)*(kDMDColumns / 8))+j] = byte_shifter;
|
dots[subFrame*(kDMDColumns*kDMDRows/8)+((row%kDMDRows)*(kDMDColumns / 8))+col] = byte_shifter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Determine where to change the color in order to progress from row 0 = color 0
|
// Determine where to change the color in order to progress from row 0 = color 0
|
||||||
// to the last row being the last color.
|
// to the last row being the last color.
|
||||||
if (i % (int)((kDMDRows/pow(2,kDMDSubFrames))) == 0) color--;
|
if (row % (int)((kDMDRows/pow(2,kDMDSubFrames))) == 0) color--;
|
||||||
if (byte_shifter == 1) byte_shifter = 0x80;
|
if (byte_shifter == 1) byte_shifter = 0x80;
|
||||||
else byte_shifter = byte_shifter >> 1;
|
else byte_shifter = byte_shifter >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t startTime;
|
||||||
bool runLoopRun = true;
|
bool runLoopRun = true;
|
||||||
|
|
||||||
void RunLoop(PRHandle proc)
|
void RunLoop(PRHandle proc)
|
||||||
@@ -382,7 +379,9 @@ void RunLoop(PRHandle proc)
|
|||||||
case kPREventTypeSwitchOpenNondebounced: stateText = "open(ndb)"; break;
|
case kPREventTypeSwitchOpenNondebounced: stateText = "open(ndb)"; break;
|
||||||
case kPREventTypeSwitchClosedNondebounced: stateText = "closed(ndb)"; break;
|
case kPREventTypeSwitchClosedNondebounced: stateText = "closed(ndb)"; break;
|
||||||
}
|
}
|
||||||
printf("switch % 3d: %s\n", event->value, stateText);
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
printf("%d.%03d switch % 3d: %s\n", tv.tv_sec-startTime, tv.tv_usec/1000, event->value, stateText);
|
||||||
}
|
}
|
||||||
usleep(10*1000); // Sleep for 10ms so we aren't pegging the CPU.
|
usleep(10*1000); // Sleep for 10ms so we aren't pegging the CPU.
|
||||||
}
|
}
|
||||||
@@ -399,6 +398,7 @@ int main(int argc, const char **argv)
|
|||||||
{
|
{
|
||||||
// Set a signal handler so that we can exit gracefully on Ctrl-C:
|
// Set a signal handler so that we can exit gracefully on Ctrl-C:
|
||||||
signal(SIGINT, sigint);
|
signal(SIGINT, sigint);
|
||||||
|
startTime = time(NULL);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
@@ -431,6 +431,8 @@ int main(int argc, const char **argv)
|
|||||||
if (proc == kPRHandleInvalid)
|
if (proc == kPRHandleInvalid)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
PRReset(proc, kPRResetFlagUpdateDevice); // Reset the device structs and write them into the device.
|
||||||
|
|
||||||
ConfigureDMD(proc);
|
ConfigureDMD(proc);
|
||||||
ConfigureSwitches(proc, yamlDoc); // Notify host for all debounced switch events.
|
ConfigureSwitches(proc, yamlDoc); // Notify host for all debounced switch events.
|
||||||
ConfigureSwitchRules(proc, yamlDoc); // Flippers, slingshots
|
ConfigureSwitchRules(proc, yamlDoc); // Flippers, slingshots
|
||||||
|
|||||||
@@ -247,7 +247,8 @@ PR_EXPORT int PRGetEvents(PRHandle handle, PREvent *eventsOut, int maxEvents);
|
|||||||
#define kPRSwitchPhysicalLast (223) /**< Switch number of the last physical switch. */
|
#define kPRSwitchPhysicalLast (223) /**< Switch number of the last physical switch. */
|
||||||
#define kPRSwitchVirtualFirst (224) /**< Switch number of the first virtual switch. */
|
#define kPRSwitchVirtualFirst (224) /**< Switch number of the first virtual switch. */
|
||||||
#define kPRSwitchVirtualLast (255) /**< Switch number of the last virtual switch. */
|
#define kPRSwitchVirtualLast (255) /**< Switch number of the last virtual switch. */
|
||||||
#define kPRSwitchRulesCount ((kPRSwitchVirtualLast + 1) << 2) /**< Total number of available switch rules. */
|
#define kPRSwitchCount (256)
|
||||||
|
#define kPRSwitchRulesCount (kPRSwitchCount << 2) /**< Total number of available switch rules. */
|
||||||
|
|
||||||
typedef struct PRSwitchConfig {
|
typedef struct PRSwitchConfig {
|
||||||
bool_t clear; // Drive the clear output
|
bool_t clear; // Drive the clear output
|
||||||
|
|||||||
@@ -82,23 +82,13 @@ PRResult PRDevice::Reset(uint32_t resetFlags)
|
|||||||
group->polarity = defaultPolarity;
|
group->polarity = defaultPolarity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create empty switch rule for clearing the rules in the device.
|
freeSwitchRuleIndexes.empty();
|
||||||
PRSwitchRule emptySwitchRule;
|
|
||||||
memset(&emptySwitchRule, 0x00, sizeof(PRSwitchRule));
|
|
||||||
|
|
||||||
for (i = 0; i < kPRSwitchRulesCount; i++)
|
for (i = 0; i < kPRSwitchRulesCount; i++)
|
||||||
{
|
{
|
||||||
PRSwitchRuleInternal *switchRule = &switchRules[i];
|
PRSwitchRuleInternal *switchRule = &switchRules[i];
|
||||||
memset(switchRule, 0x00, sizeof(PRSwitchRule));
|
memset(switchRule, 0x00, sizeof(PRSwitchRule));
|
||||||
|
|
||||||
// Send blank rule for each event type to Device if necessary
|
|
||||||
if ((resetFlags & kPRResetFlagUpdateDevice) && i <= kPRSwitchPhysicalLast) {
|
|
||||||
SwitchUpdateRule(i, kPREventTypeSwitchOpenDebounced, &emptySwitchRule, NULL, 0);
|
|
||||||
SwitchUpdateRule(i, kPREventTypeSwitchClosedDebounced, &emptySwitchRule, NULL, 0);
|
|
||||||
SwitchUpdateRule(i, kPREventTypeSwitchOpenNondebounced, &emptySwitchRule, NULL, 0);
|
|
||||||
SwitchUpdateRule(i, kPREventTypeSwitchClosedNondebounced, &emptySwitchRule, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t ruleIndex = i;
|
uint16_t ruleIndex = i;
|
||||||
ParseSwitchRuleIndex(ruleIndex, &switchRule->switchNum, &switchRule->eventType);
|
ParseSwitchRuleIndex(ruleIndex, &switchRule->switchNum, &switchRule->eventType);
|
||||||
switchRule->driver.polarity = defaultPolarity;
|
switchRule->driver.polarity = defaultPolarity;
|
||||||
@@ -106,6 +96,22 @@ PRResult PRDevice::Reset(uint32_t resetFlags)
|
|||||||
freeSwitchRuleIndexes.push(ruleIndex);
|
freeSwitchRuleIndexes.push(ruleIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create empty switch rule for clearing the rules in the device.
|
||||||
|
PRSwitchRule emptySwitchRule;
|
||||||
|
memset(&emptySwitchRule, 0x00, sizeof(PRSwitchRule));
|
||||||
|
|
||||||
|
for (i = 0; i < kPRSwitchCount; i++)
|
||||||
|
{
|
||||||
|
// Send blank rule for each event type to Device if necessary
|
||||||
|
if ((resetFlags & kPRResetFlagUpdateDevice) && i <= kPRSwitchPhysicalLast)
|
||||||
|
{
|
||||||
|
SwitchUpdateRule(i, kPREventTypeSwitchOpenDebounced, &emptySwitchRule, NULL, 0);
|
||||||
|
SwitchUpdateRule(i, kPREventTypeSwitchClosedDebounced, &emptySwitchRule, NULL, 0);
|
||||||
|
SwitchUpdateRule(i, kPREventTypeSwitchOpenNondebounced, &emptySwitchRule, NULL, 0);
|
||||||
|
SwitchUpdateRule(i, kPREventTypeSwitchClosedNondebounced, &emptySwitchRule, NULL, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unrequestedDataQueue.empty();
|
unrequestedDataQueue.empty();
|
||||||
requestedDataQueue.empty();
|
requestedDataQueue.empty();
|
||||||
num_collected_bytes = 0;
|
num_collected_bytes = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user