diff --git a/CMakeLists.txt b/CMakeLists.txt index 69639dd..e619546 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,18 @@ cmake_minimum_required(VERSION 2.6) -#set( CMAKE_OSX_ARCHITECTURES ppc;i386 ) #Comment out if not universal binary +#set( CMAKE_OSX_ARCHITECTURES ppc;i386 ) # Uncomment for universal binary #set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../bin) #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../bin) #set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../bin) -include_directories(/usr/local/include ./include) +include_directories(/usr/local/include $ENV{EXTRA_INC}) -link_directories(/usr/local/lib) +link_directories(/usr/local/lib $ENV{EXTRA_LINK}) set(FILES src/pinproc.cpp src/PRDevice.cpp src/PRHardware.cpp) add_library(pinproc ${FILES}) add_executable(pinproctest examples/pinproctest/pinproctest.cpp) -target_link_libraries(pinproctest pinproc usb ftdi) +target_link_libraries(pinproctest pinproc usb ftdi yaml-cpp) diff --git a/Makefile b/Makefile deleted file mode 100644 index a1f8b48..0000000 --- a/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# File: Makefile (for library) -# -CC=g++ -LIB=libpinproc.a -LIBDEST=./bin/ - -LIBSRC=src/pinproc.cpp src/PRDevice.cpp src/PRHardware.cpp - -LIBOBJ=$(LIBSRC:.cpp=.o) - -CXXFLAGS= - -$(LIB): $(LIBOBJ) - @echo lib Makefile - archiving $(LIB) - $(AR) r $(LIBDEST)$(LIB) $(LIBOBJ) - -.cpp.o: - @echo lib Makefile - compiling $< - $(CC) $(CXXFLAGS) -c $< -o $@ - -clean: - rm -f $(LIBOBJ) $(LIBDEST)$(LIB) diff --git a/README.markdown b/README.markdown index e92e344..a9bb1b0 100644 --- a/README.markdown +++ b/README.markdown @@ -11,14 +11,16 @@ libpinproc requires: - [libusb-0.1.12](http://libusb.wiki.sourceforge.net/): Install with the default /usr/local prefix. - [libftdi-0.16](http://www.intra2net.com/en/developer/libftdi/): Install with the default /usr/local prefix. -Once required but not right now: +The pinproctest example requires [yaml-cpp](http://code.google.com/p/yaml-cpp/). Follow the build instructions, creating the build subdirectory. After building, from the build directory, run the following commands to manually install it: -- [yaml-cpp](http://code.google.com/p/yaml-cpp/): Should be checked out in the directory two levels below libpinproc in the full source tree (at the same level as ./P-ROC) in a directory named yaml-cpp. Follow the build instructions, creating the build subdirectory. The Makefiles and other project files expect to find libyaml-cpp.a in the yaml-cpp/build/bin directory. - -We are presently experimenting with different build mechanisms. As such there are three ways to build libpinproc at this time: CMake, GNU Make, and the Xcode project (for Mac). As the preferred method is presently CMake, here's how. Before you get started, you will need CMake if you don't already have it. + sudo cp bin/libyaml-cpp.a /usr/local/lib/ + sudo mkdir /usr/local/include/yaml-cpp + sudo cp ../include/*.h /usr/local/include/yaml-cpp/ #### Building with CMake +Download and install [CMake](http://www.cmake.org/cmake/resources/software.html). Then: + cd libpinproc mkdir build; cd build cmake .. diff --git a/examples/pinproctest/Example.yaml b/examples/pinproctest/Example.yaml deleted file mode 100644 index f99a700..0000000 --- a/examples/pinproctest/Example.yaml +++ /dev/null @@ -1,7 +0,0 @@ -PRGameName: My Great Pin -PRDrivers: - 1: driver one - 2: driver two -PRSwitches: - 1: switch one - 2: switch two diff --git a/examples/pinproctest/JD.yaml b/examples/pinproctest/JD.yaml new file mode 100644 index 0000000..4c978bf --- /dev/null +++ b/examples/pinproctest/JD.yaml @@ -0,0 +1,29 @@ +# P-ROC Game Description file for Judge Dredd +PRGame: + machineType: wpc +PRFlippers: + - flipperLwR + - flipperLwL + - flipperUpR + - flipperUpL +PRBumpers: + - slingL + - slingR +PRSwitches: + flipperLwR: 1 + flipperLwL: 3 + flipperUpR: 5 + flipperUpL: 7 + slingL: 96 + slingR: 97 +PRCoils: + flipperLwRMain: 32 + flipperLwRHold: 33 + flipperLwLMain: 34 + flipperLwLHold: 35 + flipperUpRMain: 36 + flipperUpRHold: 37 + flipperUpLMain: 38 + flipperUpLHold: 39 + slingL: 70 + slingR: 71 \ No newline at end of file diff --git a/examples/pinproctest/Makefile b/examples/pinproctest/Makefile deleted file mode 100644 index 8b5ddf4..0000000 --- a/examples/pinproctest/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# File: Makefile for application -# -PINPROC_PATH=../.. - -CC=g++ -LDFLAGS=-L$(PINPROC_PATH)/bin -L/usr/local/lib -LIBS=-lpinproc -lusb -lftdi - -SRC=pinproctest.cpp - -CXXFLAGS=-I$(PINPROC_PATH)/include - -OBJS=$(SRC:.cpp=.o) - -EXE=pinproctest - -all: $(EXE) - -# FIXME: This makes the exe require libpinproc but not in a very graceful way. -$(EXE): $(OBJS) $(PINPROC_PATH)/bin/libpinproc.a - @echo application Makefile - linking $< - $(CC) $^ $(LDFLAGS) $(LIBS) -o $@ - -.cpp.o: - @echo application Makefile - compiling $< - $(CC) $(CXXFLAGS) -c $< -o $@ - -clean: - rm -f $(OBJS) $(EXE) diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index e70fbc9..4582a73 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -32,29 +32,14 @@ #include #include #include -#include "pinproc.h" // Include libpinproc's header. +#include "../../include/pinproc.h" // Include libpinproc's header. +#include +#include - -#define kFlipperLwRightSw (1) -#define kFlipperLwLeftSw (3) -#define kFlipperUpRightSw (5) -#define kFlipperUpLeftSw (7) - -#define kFlipperLwRightMain (32) -#define kFlipperLwLeftMain (34) -#define kFlipperUpRightMain (36) -#define kFlipperUpLeftMain (38) - -#define kFlipperLwRightHold (33) -#define kFlipperLwLeftHold (35) -#define kFlipperUpRightHold (37) -#define kFlipperUpLeftHold (39) - -#define kSlingLeftSw (96) -#define kSlingRightSw (97) - -#define kSlingLeftCoil (70) -#define kSlingRightCoil (71) +#define kFlippersSection "PRFlippers" +#define kBumpersSection "PRBumpers" +#define kCoilsSection "PRCoils" +#define kSwitchesSection "PRSwitches" #define kFlipperPulseTime (34) // 34 ms #define kBumperPulseTime (25) // 25 ms @@ -69,7 +54,42 @@ void TestLogger(const char *text) fprintf(stderr, "TEST: %s", text); } -void ConfigureDrivers(PRHandle proc) +PRResult LoadConfiguration(YAML::Node& yamlDoc, const char *yamlFilePath) +{ + try + { + std::ifstream fin(yamlFilePath); + if (fin.is_open() == false) + { + fprintf(stderr, "YAML file not found: %s\n", yamlFilePath); + return kPRFailure; + } + YAML::Parser parser(fin); + + while(parser) + { + parser.GetNextDocument(yamlDoc); + } + } + catch (YAML::ParserException& ex) + { + fprintf(stderr, "YAML parse error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str()); + return kPRFailure; + } + catch (YAML::RepresentationException& ex) + { + fprintf(stderr, "YAML representation error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str()); + return kPRFailure; + } + catch (...) + { + fprintf(stderr, "Unexpected exception while parsing YAML config.\n"); + return kPRFailure; + } + return kPRSuccess; +} + +void ConfigureDrivers(PRHandle proc, YAML::Node& yamlDoc) { int i; @@ -131,7 +151,7 @@ void ConfigureDrivers(PRHandle proc) } } -void ConfigureSwitches(PRHandle proc) +void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc) { int i; @@ -191,17 +211,32 @@ void ConfigureBumperRule (PRHandle proc, int swNum, int coilNum, int pulseTime) PRSwitchUpdateRule(proc,swNum, kPREventTypeSwitchClosedNondebounced, &sw, drivers, numDriverRules); } -void ConfigureSwitchRules(PRHandle proc) +void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc) { // WPC Flippers - ConfigureWPCFlipperSwitchRule (proc, kFlipperLwRightSw, kFlipperLwRightMain, kFlipperLwRightHold, kFlipperPulseTime); // Lower Right WPC Flipper - ConfigureWPCFlipperSwitchRule (proc, kFlipperLwLeftSw, kFlipperLwLeftMain, kFlipperLwLeftHold, kFlipperPulseTime); // Lower Left WPC Flipper - ConfigureWPCFlipperSwitchRule (proc, kFlipperUpRightSw, kFlipperUpRightMain, kFlipperUpRightHold, kFlipperPulseTime); // Upper Right WPC Flipper - ConfigureWPCFlipperSwitchRule (proc, kFlipperUpLeftSw, kFlipperUpLeftMain, kFlipperUpLeftHold, kFlipperPulseTime); // Upper Left WPC Flipper + const YAML::Node& flippers = yamlDoc[kFlippersSection]; + for (YAML::Iterator flippersIt = flippers.begin(); flippersIt != flippers.end(); ++flippersIt) + { + int swNum, coilMain, coilHold; + std::string flipperName; + *flippersIt >> flipperName; + yamlDoc[kSwitchesSection][flipperName] >> swNum; + yamlDoc[kCoilsSection][flipperName + "Main"] >> coilMain; + yamlDoc[kCoilsSection][flipperName + "Hold"] >> coilHold; + ConfigureWPCFlipperSwitchRule (proc, swNum, coilMain, coilHold, kFlipperPulseTime); + } - // WPC Slingshots - ConfigureBumperRule (proc, kSlingRightSw, kSlingRightCoil, kBumperPulseTime); // WPC Right Slingshot - ConfigureBumperRule (proc, kSlingLeftSw, kSlingLeftCoil, kBumperPulseTime); // WPC Left Slingshot + const YAML::Node& bumpers = yamlDoc[kBumpersSection]; + for (YAML::Iterator bumpersIt = bumpers.begin(); bumpersIt != bumpers.end(); ++bumpersIt) + { + int swNum, coilNum; + // WPC Slingshots + std::string bumperName; + *bumpersIt >> bumperName; + yamlDoc[kSwitchesSection][bumperName] >> swNum; + yamlDoc[kCoilsSection][bumperName] >> coilNum; + ConfigureBumperRule (proc, swNum, coilNum, kBumperPulseTime); + } } void ConfigureDMD(PRHandle proc) @@ -325,26 +360,49 @@ void sigint(int) printf("Exiting...\n"); } -int main(const char **argv, int argc) +int main(int argc, const char **argv) { // Set a signal handler so that we can exit gracefully on Ctrl-C: signal(SIGINT, sigint); + if (argc < 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + const char *yamlFilename = argv[1]; + // Assign a custom logging callback to demonstrate capturing log information from P-ROC: PRLogSetCallback(TestLogger); + + YAML::Node yamlDoc; + LoadConfiguration(yamlDoc, yamlFilename); + PRMachineType machineType = kPRMachineInvalid; + std::string machineTypeString; + yamlDoc["PRGame"]["machineType"] >> machineTypeString; + if (machineTypeString == "wpc") + machineType = kPRMachineWPC; + else if(machineTypeString == "stern") + machineType = kPRMachineStern; + else + { + fprintf(stderr, "Unknown machine type: %s\n", machineTypeString.c_str()); + return 1; + } + // Finally instantiate the P-ROC device: - PRHandle proc = PRCreate(kPRMachineWPC); + PRHandle proc = PRCreate(machineType); if (proc == kPRHandleInvalid) return 1; - + ConfigureDMD(proc); - ConfigureSwitches(proc); // Notify host for all debounced switch events. - ConfigureSwitchRules(proc); // Flippers, slingshots + ConfigureSwitches(proc, yamlDoc); // Notify host for all debounced switch events. + ConfigureSwitchRules(proc, yamlDoc); // Flippers, slingshots // Make Drivers the last thing to configure so watchdog doesn't expire // before the RunLoop begins. - ConfigureDrivers(proc); + ConfigureDrivers(proc, yamlDoc); printf("Running. Hit Ctrl-C to exit.\n"); diff --git a/libpinproc.xcodeproj/project.pbxproj b/libpinproc.xcodeproj/project.pbxproj index 4febfb7..e23674d 100644 --- a/libpinproc.xcodeproj/project.pbxproj +++ b/libpinproc.xcodeproj/project.pbxproj @@ -225,10 +225,7 @@ GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; - HEADER_SEARCH_PATHS = ( - /usr/local/include, - "../../yaml-cpp/include", - ); + HEADER_SEARCH_PATHS = /usr/local/include; INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = pinproc; }; @@ -240,10 +237,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_MODEL_TUNING = G5; - HEADER_SEARCH_PATHS = ( - /usr/local/include, - "../../yaml-cpp/include", - ); + HEADER_SEARCH_PATHS = /usr/local/include; INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = pinproc; }; @@ -284,8 +278,12 @@ GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = /usr/local/include; INSTALL_PATH = /usr/local/bin; - OTHER_LDFLAGS = "-lftdi"; + OTHER_LDFLAGS = ( + "-lyaml-cpp", + "-lftdi", + ); PREBINDING = NO; PRODUCT_NAME = pinproctest; }; @@ -299,8 +297,12 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; + HEADER_SEARCH_PATHS = /usr/local/include; INSTALL_PATH = /usr/local/bin; - OTHER_LDFLAGS = "-lftdi"; + OTHER_LDFLAGS = ( + "-lyaml-cpp", + "-lftdi", + ); PREBINDING = NO; PRODUCT_NAME = pinproctest; ZERO_LINK = NO; diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index 9d255bc..fd32748 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -31,7 +31,6 @@ #include "PRHardware.h" #include "PRCommon.h" -#include "pinproc.h" uint32_t CreateRegRequestWord( uint32_t select, uint32_t addr, uint32_t num_words ) {