diff --git a/CMakeLists.txt b/CMakeLists.txt index 0853ac4..612de28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,14 @@ ### ### CMake settings ### -## Due to Mac OSX we need to keep compatibility with CMake 2.6 -# see http://www.cmake.org/Wiki/CMake_Policies -cmake_minimum_required(VERSION 2.6) -# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0012 -if(POLICY CMP0012) - cmake_policy(SET CMP0012 OLD) -endif() -# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0015 -if(POLICY CMP0015) - cmake_policy(SET CMP0015 OLD) -endif() +# Version 2.8.1 was released 2010-03-16 and is a reasonable minimum. +cmake_minimum_required(VERSION 2.8.1) +# allow relative paths in link_directories() +# see https://cmake.org/cmake/help/v3.18/policy/CMP0081.html +if(POLICY CMP0081) + cmake_policy(SET CMP0081 OLD) +endif() ### ### Project settings @@ -20,7 +16,7 @@ endif() project(PINPROC) set(PINPROC_VERSION_MAJOR "2") -set(PINPROC_VERSION_MINOR "0") +set(PINPROC_VERSION_MINOR "1") set(PINPROC_VERSION "${PINPROC_VERSION_MAJOR}.${PINPROC_VERSION_MINOR}") @@ -45,6 +41,7 @@ option(APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF) option(MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON) option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF) +option(CROSS_ROOT "Cross-compilation root path" OFF) ### ### Sources, headers, directories and libs @@ -69,11 +66,15 @@ if(VERBOSE) endif() # use -DEXTRA_INC=";" and -DEXTRA_LINK=";" +set(EXTRA_INC "" CACHE STRING "Extra include directories separated by ;") +set(EXTRA_LINK "" CACHE STRING "Extra link directories separated by ;") +if(CROSS_ROOT) +include_directories(${PINPROC_SOURCE_DIR}/include ${EXTRA_INC} ${CROSS_ROOT}/usr/local/include) +link_directories(${EXTRA_LINK} ${CROSS_ROOT}/usr/local/lib) +else() include_directories(${PINPROC_SOURCE_DIR}/include ${EXTRA_INC} /usr/local/include) link_directories(${EXTRA_LINK} /usr/local/lib) - -set(YAML_CPP_LIB "yaml-cpp") -set(YAML_CPP_LIB_DBG "${YAML_CPP_LIB}") +endif() ### @@ -100,7 +101,7 @@ if(WIN32) set(CMAKE_INSTALL_PREFIX "C:/") endif() else() - set(lib_ftdi_usb usb ftdi1) + set(lib_ftdi_usb usb-1.0 ftdi1) endif() # GCC specialities @@ -153,13 +154,7 @@ if(MSVC) # c) Correct suffixes for static libraries if(NOT BUILD_SHARED_LIBS) - ### General stuff set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}") - - ### Project stuff - # correct external library names - set(YAML_CPP_LIB "${CMAKE_STATIC_LIBRARY_PREFIX}${YAML_CPP_LIB}${LIB_RT_SUFFIX}") - set(YAML_CPP_LIB_DBG "${YAML_CPP_LIB}d") endif() endif() @@ -244,8 +239,6 @@ add_executable(pinproctest ) target_link_libraries(pinproctest pinproc - optimized ${YAML_CPP_LIB} - debug ${YAML_CPP_LIB_DBG} ) # Create a target for the firmware tool diff --git a/Makefile b/Makefile index abeb0c1..8e12f43 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,6 @@ LIBPINPROC_DYLIB = bin/libpinproc.dylib SRCS = src/pinproc.cpp src/PRDevice.cpp src/PRHardware.cpp OBJS := $(SRCS:.cpp=.o) INCLUDES = include/pinproc.h src/PRCommon.h src/PRDevice.h src/PRHardware.h -LIBS = usb ftdi .PHONY: libpinproc libpinproc: $(LIBPINPROC) $(LIBPINPROC_DYLIB) @@ -20,7 +19,7 @@ $(LIBPINPROC): $(OBJS) $(RANLIB) $@ $(LIBPINPROC_DYLIB): $(OBJS) - g++ -dynamiclib -o $@ /usr/local/lib/libftdi.dylib $(LDFLAGS) $(OBJS) + g++ -dynamiclib -o $@ `pkg-config --libs libftdi1` $(LDFLAGS) $(OBJS) .cpp.o: $(CC) $(LIBPINPROC_CFLAGS) $(CFLAGS) -o $@ $< diff --git a/README.markdown b/README.markdown index 252acc1..8e591b5 100644 --- a/README.markdown +++ b/README.markdown @@ -1,6 +1,6 @@ ## libpinproc -Library for Gerry Stellenberg's [P-ROC](http://pinballcontrollers.com/) (Pinball Remote Operations Controller). +Library for [Multimorphic, Inc.'s](https://www.multimorphic.com/) P-ROC and P3-ROC pinball controller boards. ### Compiling @@ -8,27 +8,13 @@ Library for Gerry Stellenberg's [P-ROC](http://pinballcontrollers.com/) (Pinball libpinproc requires: -- [libusb-0.1.12](http://libusb.wiki.sourceforge.net/): Install with the default /usr/local prefix. Version 0.1.12 has been tested on Mac and Linux. Mac users: If you want to use libpinproc under Cocoa or pygame, you may wish to try libusb 1.0. See below. +- [libusb](https://github.com/libusb/libusb): Install with the default /usr/local prefix. Current builds of libftdi and libpinproc use libusb-1.0. -- [libftdi-0.16](http://www.intra2net.com/en/developer/libftdi/): Install with the default /usr/local prefix. +- [libftdi](https://www.intra2net.com/en/developer/libftdi/): Install with the default /usr/local prefix. -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 main source directory, run the following commands to manually install it: +#### Building with CMake (Linux and macOS) - sudo cp lib/libyaml-cpp.a /usr/local/lib/ - sudo mkdir /usr/local/include/yaml-cpp - sudo cp include/*.h /usr/local/include/yaml-cpp/ - -##### libusb-1.0 and libusb-compat - -Version 1.0.2 does not work out of the box since libftdi is written against libusb-0.1. You can use the libusb-compat-0.1.2 project, however, which creates a library that provides the older libusb interface. Because Macs do not come with pkg-config, you may need to run configure for libusb-compat as follows: - - ./configure LIBUSB_1_0_CFLAGS=-I/usr/local/include/libusb-1.0 LIBUSB_1_0_LIBS="-L/usr/local/lib -lusb-1.0" - -Note that libusb-1.0 must have been built and installed prior to this step. This also assumes that you installed libusb-1.0 with the default /usr/local prefix. - -#### Building with CMake - -Download and install [CMake](http://www.cmake.org/cmake/resources/software.html). Then: +Download and install [CMake](https://cmake.org/download/). Then: cd libpinproc mkdir bin; cd bin @@ -37,33 +23,61 @@ Download and install [CMake](http://www.cmake.org/cmake/resources/software.html) The CMakeLists.txt file is presently designed to be run from a directory inside the libpinproc directory. This will build both libpinproc and pinproctest. Binaries will be placed in the directory that make was run from. We recommend 'bin', as it is the path expected by pypinproc. -Note: On some systems, it may be necessary to build libpinproc with the '-fPIC' option. To do this with cmake, instead of running 'cmake ..', run 'cmake .. -DCMAKE_CXX_FLAGS="-fPIC"'. Compiling without '-fPIC' may cause problems when building the python extensions on some 64-bit Linux machines. +Note: On some systems, it may be necessary to build libpinproc with the '-fPIC' option. To do this with cmake, instead of running 'cmake ..', run 'cmake .. -DCMAKE_CXX_FLAGS="-fPIC"'. Compiling without '-fPIC' may cause problems when building the Python extensions on some 64-bit Linux machines. + +Mac users may need to install [D2xxHelper](http://www.ftdichip.com/Drivers/D2XX.htm) to keep the Mac from claiming the P-ROC/P3-ROC and creating a `/dev/tty.usbserial` device for it. It may be necessary to install a second time, if you're asked to allowing the installation via the Security & Privacy System Preference. You will also need to reboot after installing D2xxHelper. Run a `ls /dev/tty.usbserial*` before and after connecting the P-ROC/P3-ROC. If you see a new entry, libpinproc will not be able to connect. #### Building in Windows with MinGW/CMake +(Note that these instructions are outdated with the advent of of MSYS2/MinGW64. Recent attempts at building with these instructions result in builds with dependencies on DLLs from MinGW64. For users with MSYS/MinGW32 installations they should still be valid.) + Download and unzip [ftd2xx for Windows zip file](http://www.ftdichip.com/Drivers/D2XX.htm). Plug in a powered-up P-ROC and point the driver install wizard to the unzipped driver. Note, this is a two-step process. It will ask you to install a driver twice (once for USB and again for the FTDI specific stuff). -Download and install [CMake](http://www.cmake.org/cmake/resources/software.html). +Download and install [CMake](https://cmake.org/download/). Download and install [MinGW](http://sourceforge.net/projects/mingw/files/). (Tested with MinGW 5.1.4) -Follow directions above for building yaml-cpp with the following exception: - add '-G "MinGW Makefiles"' to the cmake command line. +Follow directions above for Building with CMake with the following exception: +- Add `-G "MinGW Makefiles"` to the cmake command line. +- Use `-DEXTRA_INC=""` and `-DEXTRA_LINK=""` to add include/library paths for `ftd2xx.h` and `ftd2xx.sys`. +- Use mingw32-make instead of make. -To build libpinproc: +#### Building in Windows with CMake and Visual Studio 2019 -- add the paths for ftd2xx.h (from the unzipped driver package) and the yaml-cpp/include/*.h files to the "include_directories" line in libpinproc/CMakeLists.txt. +Follow directions above for Building with CMake with the following exception: +- Add `-A Win32` to the cmake command line. +- Use `-DEXTRA_INC=""` and `-DEXTRA_LINK=""` to add include/library paths for `ftd2xx.h` and `ftd2xx.sys`. +- Open PINPROC.sln in Visual Studio, switch to the Debug or Release configuration and perform ALL_BUILD. It will place the libary and sample programs in `build/Debug` and `build/Release`. -- either create the directory c:\usr\local\lib and copy libyaml-cpp*.a from the yaml-cpp build directory and ftd2xx.sys to it or add the location of those files to the "link_directories" line in libpinproc/CMakeLists.txt. +Example: + + cd libpinproc + mkdir bin; cd bin + cmake .. -A Win32 + # configure paths for ftd2xxx; use `cmake .. -L` to list configured options + cmake .. -D EXTRA_INC="../ftd2xx" + cmake .. -D EXTRA_LINK="../ftd2xx/i386" + # Can now open PINPROC.sln in Visual Studio and build Debug and Release targets. + +### Testing + +Once built, run the `pinproctest` program with the appropriate "machine type" passed in (e.g., "wpc"). Run `pinproctest` without any parameters for a list of valid types. -Follow instructions above for building libpinproc with cmake with the following exceptions: - add '-G "MinGW Makefiles' to the cmake command line, - use mingw32-make instead of make - ### License Copyright (c) 2009 Gerry Stellenberg, Adam Preble +Copyright (c) 2020 Multimorphic, Inc. + +Contributors: + - Adam Preble + - Gerry Stellenberg + - Jan Kantert + - Jimmy Lipham + - Koen Heltzel + - Roy Eltham + - Tom Collins + 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 diff --git a/examples/pinproctest/Makefile b/examples/pinproctest/Makefile index 97c9da0..18aa846 100644 --- a/examples/pinproctest/Makefile +++ b/examples/pinproctest/Makefile @@ -11,7 +11,7 @@ SRCS = pinproctest.cpp drivers.cpp dmd.cpp switches.cpp OBJS := $(SRCS:.cpp=.o) INCLUDES = ../../include/pinproc.h -LIBS = usb pinproc yaml-cpp +LIBS = usb pinproc ifneq ($(uname_s),Windows) # not Windows LIBS += ftdi endif diff --git a/examples/pinproctest/alphanumeric.cpp b/examples/pinproctest/alphanumeric.cpp index e91b5c7..9c4b58d 100644 --- a/examples/pinproctest/alphanumeric.cpp +++ b/examples/pinproctest/alphanumeric.cpp @@ -116,9 +116,9 @@ void display(PRHandle proc, char * string_1, char * string_2) segs_a = asciiSegments[char_a - 32]; segs_b = asciiSegments[char_b - 32]; - printf("\nASCII Chars and associated segment values: %d", i); - printf("\nchar_a: %x, segs_a: %x", char_a, segs_a); - printf("\nchar_b: %x, segs_b: %x", char_b, segs_b); + printf("ASCII Chars and associated segment values: %d\n", i); + printf("char_a: %x, segs_a: %x\n", char_a, segs_a); + printf("char_b: %x, segs_b: %x\n", char_b, segs_b); PRDriverAuxPrepareOutput(&(auxCommands[cmd_index++]), segs_a & 0xff, 0, STB_1, false, 0); PRDriverAuxPrepareOutput(&(auxCommands[cmd_index++]), (segs_a >> 8) & 0xff, 0, STB_2, false, 0); @@ -137,9 +137,11 @@ void display(PRHandle proc, char * string_1, char * string_2) PRDriverAuxPrepareJump(&auxCommands[cmd_index++],1); - printf("\nAux commands being sent:"); + printf("Aux commands being sent:\n"); for (i=0; i 0) printf("\nNum events: %x\n", numEvents); 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; + const char *stateText; + 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; + default: + stateText = "Unknown"; } #ifdef _MSC_VER struct _timeb tv; - _ftime(&tv); + _ftime_s(&tv); #else struct timeval tv; gettimeofday(&tv, NULL); @@ -248,17 +215,14 @@ void RunLoop(PRHandle proc) case kPREventTypeSwitchClosedDebounced: case kPREventTypeSwitchOpenNondebounced: case kPREventTypeSwitchClosedNondebounced: - { #ifdef _MSC_VER - printf("%d.%03d switch % 3d: %s\n", tv.time-startTime, tv.millitm, event->value, stateText); + printf("%d.%03d switch %3d: %s\n", (int)(tv.time-startTime), tv.millitm, event->value, stateText); #else - printf("%d.%03d switch % 3d: %s\n", (int)(tv.tv_sec-startTime), (int)tv.tv_usec/1000, event->value, stateText); + printf("%d.%03d switch %3d: %s\n", (int)(tv.tv_sec-startTime), (int)tv.tv_usec/1000, event->value, stateText); #endif UpdateSwitchState( event ); break; - } case kPREventTypeDMDFrameDisplayed: - { if (machineType == kPRMachineWPCAlphanumeric) { //UpdateAlphaDisplay(proc, dotOffset++); } @@ -267,37 +231,26 @@ void RunLoop(PRHandle proc) PRDMDDraw(proc,dots); } break; - } case kPREventTypeAccelerometerX: - { //readData[0] = event->value & 0x3FFF; readData[0] = event->value; break; - } case kPREventTypeAccelerometerY: - { //readData[1] = event->value & 0x3FFF; readData[1] = event->value; break; - } case kPREventTypeAccelerometerZ: - { //readData[2] = event->value & 0x3FFF; readData[2] = event->value; - printf("\nAccel: X: %x, Y: %x, Z: %x", readData[0], readData[1],readData[2]); + printf("Accel: X: %x, Y: %x, Z: %x\n", readData[0], readData[1],readData[2]); break; - } case kPREventTypeAccelerometerIRQ: - { //readData[2] = event->value & 0x3FFF; readData[3] = event->value; - printf("\nAccel IRQ: %x", readData[3]); + printf("Accel IRQ: %x\n", readData[3]); break; - } default: - { - printf("\nUnknown event: %x:%x", event->type, event->value); - } + printf("Unknown event: %x:%x\n", event->type, event->value); } } PRFlushWriteData(proc); @@ -316,70 +269,85 @@ void sigint(int) printf("Exiting...\n"); } +const struct { + PRMachineType type; + const char *name; +} machine_types[] = { + { kPRMachineCustom, "custom" }, + { kPRMachineWPCAlphanumeric, "wpcAlphanumeric" }, + { kPRMachineWPC, "wpc" }, + { kPRMachineWPC95, "wpc95" }, + { kPRMachineSternWhitestar, "sternWhitestar" }, + { kPRMachineSternSAM, "sternSAM" }, + { kPRMachinePDB, "pdb" }, +}; +#define MACHINE_TYPES (sizeof(machine_types) / sizeof(machine_types[0])) + int main(int argc, const char **argv) { int i; + // Set stdout unbuffered to eliminate need to fflush() + setbuf(stdout, NULL); + // Set a signal handler so that we can exit gracefully on Ctrl-C: signal(SIGINT, sigint); startTime = time(NULL); - if (argc < 2) - { - fprintf(stderr, "Usage: %s \n", argv[0]); + if (argc < 2) { + printf("Usage: %s \n\nWhere machine_type is one of:\n ", argv[0]); + for (i = 0; i < MACHINE_TYPES; i++) { + printf("%s %s", i ? "," : "", machine_types[i].name); + } 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; - if (LoadConfiguration(yamlDoc, yamlFilename) != kPRSuccess) - { - fprintf(stderr, "Failed to load configuration file %s\n", yamlFilename); - return 1; + for (i = 0; i < MACHINE_TYPES; i++) { + if (strcmp(argv[1], machine_types[i].name) == 0) { + machineType = machine_types[i].type; + break; + } } - std::string machineTypeString; - yamlDoc["PRGame"]["machineType"] >> machineTypeString; - if (machineTypeString == "wpc") - machineType = kPRMachineWPC; - else if (machineTypeString == "wpc95") - machineType = kPRMachineWPC95; - else if (machineTypeString == "wpcAlphanumeric") - machineType = kPRMachineWPCAlphanumeric; - else if(machineTypeString == "sternWhitestar") - machineType = kPRMachineSternWhitestar; - else if(machineTypeString == "sternSAM") - machineType = kPRMachineSternSAM; - else if(machineTypeString == "custom") - machineType = kPRMachineCustom; - else - { - fprintf(stderr, "Unknown machine type: %s\n", machineTypeString.c_str()); + if (machineType == kPRMachineInvalid) { + printf("Unknown machine type: %s\n", argv[1]); return 1; } // Finally instantiate the P-ROC device: PRHandle proc = PRCreate(machineType); - if (proc == kPRHandleInvalid) - { - fprintf(stderr, "Error during PRCreate: %s\n", PRGetLastErrorText()); + if (proc == kPRHandleInvalid) { + printf("Error during PRCreate: %s\n", PRGetLastErrorText()); return 1; } + PRReadData(proc, P_ROC_MANAGER_SELECT, P_ROC_REG_CHIP_ID_ADDR, 1, &board_id); + if (board_id == P_ROC_CHIP_ID) { + printf("Connected to P-ROC\n"); + } + else if (board_id == P3_ROC_CHIP_ID) { + printf("Connected to P3-ROC\n"); + } + else { + printf("Warning: unrecognized board ID 0x%08X\n", board_id); + } - PRLogSetLevel (kPRLogInfo); + PRLogSetLevel(kPRLogInfo); PRReset(proc, kPRResetFlagUpdateDevice); // Reset the device structs and write them into the device. // Even if WPCAlphanumeric, configure the DMD at least to get frame events for // timing purposes. ConfigureDMD(proc); - if (machineType == kPRMachineCustom) ConfigureDrivers(proc); - ConfigureSwitches(proc, yamlDoc); // Notify host for all debounced switch events. - ConfigureSwitchRules(proc, yamlDoc); // Flippers, slingshots + if (machineType == kPRMachineCustom) { + ConfigureDrivers(proc); + } + ConfigureSwitches(proc); // Notify host for all debounced switch events. - if (machineType == kPRMachineWPCAlphanumeric) UpdateAlphaDisplay(proc, 0); + if (machineType == kPRMachineWPCAlphanumeric) { + UpdateAlphaDisplay(proc, 0); + } // Pulse a coil for testing purposes. PRDriverPulse(proc, 47, 30); @@ -421,7 +389,6 @@ int main(int argc, const char **argv) */ PRFlushWriteData(proc); - printf("Running. Hit Ctrl-C to exit.\n"); RunLoop(proc); diff --git a/examples/pinproctest/pinproctest.h b/examples/pinproctest/pinproctest.h index 9a8f4f9..1557168 100644 --- a/examples/pinproctest/pinproctest.h +++ b/examples/pinproctest/pinproctest.h @@ -44,7 +44,6 @@ #include #include "pinproc.h" // Include libpinproc's header. #include -#include #ifdef _MSC_VER #include @@ -72,8 +71,7 @@ void ConfigureDrivers(PRHandle proc); -void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc); -void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc); +void ConfigureSwitches(PRHandle proc); void UpdateSwitchState (PREvent * event); void LoadSwitchStates (PRHandle proc); diff --git a/examples/pinproctest/switches.cpp b/examples/pinproctest/switches.cpp index 5b19132..641e560 100644 --- a/examples/pinproctest/switches.cpp +++ b/examples/pinproctest/switches.cpp @@ -33,7 +33,7 @@ typedef struct SwitchStatus { static SwitchStatus switches[kPRSwitchPhysicalLast + 1]; -void ConfigureSwitches(PRHandle proc, YAML::Node& yamlDoc) +void ConfigureSwitches(PRHandle proc) { // Configure switch controller registers (if the defaults aren't acceptable) PRSwitchConfig switchConfig; @@ -137,45 +137,6 @@ void ConfigureBumperRule (PRHandle proc, int swNum, int coilNum, int pulseTime) PRSwitchUpdateRule(proc, swNum, kPREventTypeSwitchClosedDebounced, &sw, NULL, 0, false); } -void ConfigureSwitchRules(PRHandle proc, YAML::Node& yamlDoc) -{ - // WPC Flippers - std::string numStr; - 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; - if (machineType == kPRMachineWPC) - { - yamlDoc[kSwitchesSection][flipperName][kNumberField] >> numStr; swNum = PRDecode(machineType, numStr.c_str()); - yamlDoc[kCoilsSection][flipperName + "Main"][kNumberField] >> numStr; coilMain = PRDecode(machineType, numStr.c_str()); - yamlDoc[kCoilsSection][flipperName + "Hold"][kNumberField] >> numStr; coilHold = PRDecode(machineType, numStr.c_str()); - ConfigureWPCFlipperSwitchRule (proc, swNum, coilMain, coilHold, kFlipperPulseTime); - } - else if (machineType == kPRMachineSternWhitestar || machineType == kPRMachineSternSAM) - { - printf("hi\n"); - yamlDoc[kSwitchesSection][flipperName][kNumberField] >> numStr; swNum = PRDecode(machineType, numStr.c_str()); - yamlDoc[kCoilsSection][flipperName + "Main"][kNumberField] >> numStr; coilMain = PRDecode(machineType, numStr.c_str()); - ConfigureSternFlipperSwitchRule (proc, swNum, coilMain, kFlipperPulseTime, kFlipperPatterOnTime, kFlipperPatterOffTime); - } - } - - 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][kNumberField] >> numStr; swNum = PRDecode(machineType, numStr.c_str()); - yamlDoc[kCoilsSection][bumperName][kNumberField] >> numStr; coilNum = PRDecode(machineType, numStr.c_str()); - ConfigureBumperRule (proc, swNum, coilNum, kBumperPulseTime); - } -} - void UpdateSwitchState( PREvent * event ) { switches[event->value].state = event->type; @@ -190,7 +151,7 @@ void LoadSwitchStates( PRHandle proc ) // 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"); + printf("Error: Unable to retrieve switch states\n"); } else { @@ -201,17 +162,15 @@ void LoadSwitchStates( PRHandle proc ) } int zero = 0; - fprintf(stderr, "\nCurrent Switch States: %3d : ", zero); for (i = 0; i < kPRSwitchPhysicalLast + 1; i++) { - fprintf(stderr, "%d ", switches[i].state); - if ((i + 1) % 32 == 0) - { + if (i % 32 == 0) { printf("\n"); if (i != kPRSwitchPhysicalLast) - fprintf(stderr, "Current Switch States: %3d : ", i+1); + printf("Current Switch States: %3d: ", i); } + printf("%d", switches[i].state); } - fprintf(stderr, "\n"); + printf("\n"); } } diff --git a/include/pinproc.h b/include/pinproc.h index 521334f..ccc2fe8 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -84,6 +84,261 @@ typedef int32_t PRResult; /**< See: #kPRSuccess and #kPRFailure. */ typedef void * PRHandle; /**< Opaque type used to reference an individual P-ROC device. Created with PRCreate() and destroyed with PRDelete(). This value is used as the first parameter to all P-ROC API function calls. */ #define kPRHandleInvalid (0) /**< Value returned by PRCreate() on failure. Indicates an invalid #PRHandle. */ +#define P_ROC_INIT_PATTERN_A 0x801F1122 +#define P_ROC_INIT_PATTERN_B 0x345678AB +#define P_ROC_CHIP_ID 0xfeedbeef +#define P3_ROC_CHIP_ID 0xf33db33f + +#define P_ROC_VER_REV_FIXED_SWITCH_STATE_READS 0x10013 // 1.19 + +#define P_ROC_AUTO_STERN_DETECT_SHIFT 8 +#define P_ROC_AUTO_STERN_DETECT_MASK 0x00000100 +#define P_ROC_AUTO_STERN_DETECT_VALUE 0x1 +#define P_ROC_MANUAL_STERN_DETECT_SHIFT 0 +#define P_ROC_MANUAL_STERN_DETECT_MASK 0x00000001 +#define P_ROC_MANUAL_STERN_DETECT_VALUE 0x00000000 +#define P_ROC_BOARD_VERSION_SHIFT 7 +#define P_ROC_BOARD_VERSION_MASK 0x00000080 + +#define P_ROC_ADDR_MASK 0x000FFFFF +#define P_ROC_HEADER_LENGTH_MASK 0x7FF00000 +#define P_ROC_COMMAND_MASK 0x80000000 + +#define P_ROC_ADDR_SHIFT 0 +#define P_ROC_HEADER_LENGTH_SHIFT 20 +#define P_ROC_COMMAND_SHIFT 31 + +#define P_ROC_READ 0 +#define P_ROC_WRITE 1 +#define P_ROC_REQUESTED_DATA 0 +#define P_ROC_UNREQUESTED_DATA 1 + +#define P_ROC_REG_ADDR_MASK 0x0000FFFF +#define P_ROC_MODULE_SELECT_MASK 0x000F0000 + +#define P_ROC_REG_ADDR_SHIFT 0 +#define P_ROC_MODULE_SELECT_SHIFT 16 + +#define P_ROC_MANAGER_SELECT 0 +#define P_ROC_BUS_JTAG_SELECT 1 +#define P_ROC_BUS_SWITCH_CTRL_SELECT 2 +#define P_ROC_BUS_DRIVER_CTRL_SELECT 3 +#define P_ROC_BUS_STATE_CHANGE_PROC_SELECT 4 +#define P_ROC_BUS_DMD_SELECT 5 +#define P_ROC_BUS_UNASSOCIATED_SELECT 15 + +#define P3_ROC_MANAGER_SELECT 0 +#define P3_ROC_BUS_SPI_SELECT 1 +#define P3_ROC_BUS_SWITCH_CTRL_SELECT 2 +#define P3_ROC_BUS_DRIVER_CTRL_SELECT 3 +#define P3_ROC_BUS_STATE_CHANGE_PROC_SELECT 4 +#define P3_ROC_BUS_AUX_CTRL_SELECT 5 +#define P3_ROC_BUS_ACCELEROMETER_SELECT 6 +#define P3_ROC_BUS_I2C_SELECT 7 +#define P3_ROC_BUS_UNASSOCIATED_SELECT 15 + +#define P_ROC_REG_CHIP_ID_ADDR 0 +#define P_ROC_REG_VERSION_ADDR 1 +#define P_ROC_REG_WATCHDOG_ADDR 2 +#define P_ROC_REG_DIPSWITCH_ADDR 3 + +#define P_ROC_MANAGER_WATCHDOG_EXPIRED_SHIFT 30 +#define P_ROC_MANAGER_WATCHDOG_ENABLE_SHIFT 14 +#define P_ROC_MANAGER_WATCHDOG_RESET_TIME_SHIFT 0 +#define P_ROC_MANAGER_REUSE_DMD_DATA_FOR_AUX_SHIFT 10 +#define P_ROC_MANAGER_INVERT_DIPSWITCH_1_SHIFT 9 + +#define P3_ROC_SPI_OPCODE_SHIFT 24 + +#define P3_ROC_SPI_OPCODE_WR_ENABLE 0 +#define P3_ROC_SPI_OPCODE_WR_DISABLE 1 +#define P3_ROC_SPI_OPCODE_RD_ID 2 +#define P3_ROC_SPI_OPCODE_RD_STATUS 3 +#define P3_ROC_SPI_OPCODE_WR_STATUS 4 +#define P3_ROC_SPI_OPCODE_RD_DATA 5 +#define P3_ROC_SPI_OPCODE_FRD_DATA 6 +#define P3_ROC_SPI_OPCODE_PP 7 +#define P3_ROC_SPI_OPCODE_SECTOR_ERASE 8 +#define P3_ROC_SPI_OPCODE_BULK_ERASE 9 +#define P3_ROC_SPI_OPCODE_DEEP_POWERDN 10 +#define P3_ROC_SPI_OPCODE_RELEASE 11 + +#define P_ROC_JTAG_SHIFT_EXIT_SHIFT 16 +#define P_ROC_JTAG_SHIFT_NUM_BITS_SHIFT 0 + +#define P_ROC_JTAG_CMD_CHANGE_STATE 0 +#define P_ROC_JTAG_CMD_SHIFT 1 +#define P_ROC_JTAG_CMD_TRANSITION 2 +#define P_ROC_JTAG_CMD_SET_PORTS 3 + +#define P_ROC_JTAG_CMD_START_SHIFT 31 +#define P_ROC_JTAG_CMD_OE_SHIFT 30 +#define P_ROC_JTAG_CMD_CMD_SHIFT 24 + +#define P_ROC_JTAG_TRANSITION_TCK_MASK_SHIFT 6 +#define P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT 5 +#define P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT 4 +#define P_ROC_JTAG_TRANSITION_TCK_SHIFT 2 +#define P_ROC_JTAG_TRANSITION_TDO_SHIFT 1 +#define P_ROC_JTAG_TRANSITION_TMS_SHIFT 0 + +#define P_ROC_JTAG_STATUS_DONE_SHIFT 31 +#define P_ROC_JTAG_STATUS_TDI_SHIFT 16 + +#define P_ROC_JTAG_COMMAND_REG_BASE_ADDR 0x0 +#define P_ROC_JTAG_STATUS_REG_BASE_ADDR 0x1 +#define P_ROC_JTAG_TDO_MEMORY_BASE_ADDR 0x400 +#define P_ROC_JTAG_TDI_MEMORY_BASE_ADDR 0x800 + +#define P_ROC_SWITCH_CTRL_STATE_BASE_ADDR 4 +#define P_ROC_SWITCH_CTRL_OLD_DEBOUNCE_BASE_ADDR 11 +#define P_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR 12 +#define P3_ROC_SWITCH_CTRL_STATE_BASE_ADDR 16 +#define P3_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR 32 + +#define P_ROC_EVENT_TYPE_SWITCH 0 +#define P_ROC_EVENT_TYPE_DMD 1 +#define P_ROC_EVENT_TYPE_BURST_SWITCH 2 +#define P_ROC_EVENT_TYPE_ACCELEROMETER 3 + +#define P_ROC_V1_EVENT_TYPE_MASK 0xC00 +#define P_ROC_V1_EVENT_TYPE_SHIFT 10 +#define P_ROC_V2_EVENT_TYPE_MASK 0xC000 +#define P_ROC_V2_EVENT_TYPE_SHIFT 14 + +#define P_ROC_V1_EVENT_SWITCH_NUM_MASK 0xFF +#define P_ROC_V2_EVENT_SWITCH_NUM_MASK 0x7FF +#define P_ROC_V1_EVENT_SWITCH_STATE_MASK 0x100 +#define P_ROC_V2_EVENT_SWITCH_STATE_MASK 0x1000 +#define P_ROC_V1_EVENT_SWITCH_STATE_SHIFT 8 +#define P_ROC_V2_EVENT_SWITCH_STATE_SHIFT 12 +#define P_ROC_V1_EVENT_SWITCH_DEBOUNCED_MASK 0x200 +#define P_ROC_V2_EVENT_SWITCH_DEBOUNCED_MASK 0x2000 +#define P_ROC_V1_EVENT_SWITCH_DEBOUNCED_SHIFT 9 +#define P_ROC_V2_EVENT_SWITCH_DEBOUNCED_SHIFT 13 +#define P_ROC_V1_EVENT_SWITCH_TIMESTAMP_MASK 0xFFFFF000 +#define P_ROC_V1_EVENT_SWITCH_TIMESTAMP_SHIFT 12 +#define P_ROC_V2_EVENT_SWITCH_TIMESTAMP_MASK 0xFFFF0000 +#define P_ROC_V2_EVENT_SWITCH_TIMESTAMP_SHIFT 16 +#define P_ROC_V2_EVENT_ACCEL_TIMESTAMP_MASK 0xFFFC0000 +#define P_ROC_V2_EVENT_ACCEL_TIMESTAMP_SHIFT 18 + + +#define P_ROC_DRIVER_CTRL_DECODE_SHIFT 10 +#define P_ROC_DRIVER_CTRL_REG_DECODE 0 +#define P_ROC_DRIVER_CONFIG_TABLE_DECODE 1 +#define P_ROC_DRIVER_AUX_MEM_DECODE 2 +#define P_ROC_DRIVER_CATCHALL_DECODE 3 + +#define P_ROC_DRIVER_GLOBAL_ENABLE_DIRECT_OUTPUTS_SHIFT 31 +#define P_ROC_DRIVER_GLOBAL_GLOBAL_POLARITY_SHIFT 30 +#define P_ROC_DRIVER_GLOBAL_USE_CLEAR_SHIFT 28 +#define P_ROC_DRIVER_GLOBAL_STROBE_START_SELECT_SHIFT 27 +#define P_ROC_DRIVER_GLOBAL_START_STROBE_TIME_SHIFT 20 +#define P_ROC_DRIVER_GLOBAL_START_STROBE_TIME_MASK 0x07F00000 +#define P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_1_SHIFT 16 +#define P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_1_MASK 0x000F0000 +#define P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_0_SHIFT 12 +#define P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_0_MASK 0x0000F000 +#define P_ROC_DRIVER_GLOBAL_ACTIVE_LOW_MATRIX_ROWS_SHIFT 11 +#define P_ROC_DRIVER_GLOBAL_ENCODE_ENABLES_SHIFT 10 +#define P_ROC_DRIVER_GLOBAL_TICKLE_WATCHDOG_SHIFT 9 + +#define P_ROC_DRIVER_GROUP_SLOW_TIME_SHIFT 12 +#define P_ROC_DRIVER_GROUP_DISABLE_STROBE_AFTER_SHIFT 11 +#define P_ROC_DRIVER_GROUP_ENABLE_INDEX_SHIFT 7 +#define P_ROC_DRIVER_GROUP_ROW_ACTIVATE_INDEX_SHIFT 4 +#define P_ROC_DRIVER_GROUP_ROW_ENABLE_SELECT_SHIFT 3 +#define P_ROC_DRIVER_GROUP_MATRIXED_SHIFT 2 +#define P_ROC_DRIVER_GROUP_POLARITY_SHIFT 1 +#define P_ROC_DRIVER_GROUP_ACTIVE_SHIFT 0 + +#define P_ROC_DRIVER_CONFIG_OUTPUT_DRIVE_TIME_SHIFT 0 +#define P_ROC_DRIVER_CONFIG_POLARITY_SHIFT 8 +#define P_ROC_DRIVER_CONFIG_STATE_SHIFT 9 +#define P_ROC_DRIVER_CONFIG_UPDATE_SHIFT 10 +#define P_ROC_DRIVER_CONFIG_WAIT_4_1ST_SLOT_SHIFT 11 +#define P_ROC_DRIVER_CONFIG_TIMESLOT_SHIFT 16 +#define P_ROC_DRIVER_CONFIG_PATTER_ON_TIME_SHIFT 16 +#define P_ROC_DRIVER_CONFIG_PATTER_OFF_TIME_SHIFT 23 +#define P_ROC_DRIVER_CONFIG_PATTER_ENABLE_SHIFT 30 +#define P_ROC_DRIVER_CONFIG_FUTURE_ENABLE_SHIFT 31 + +#define P_ROC_DRIVER_CONFIG_TABLE_DRIVER_NUM_SHIFT 1 + +#define P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT 31 +#define P_ROC_DRIVER_AUX_OUTPUT_DELAY_SHIFT 20 +#define P_ROC_DRIVER_AUX_OUTPUT_DELAY_MASK 0x7ff +#define P_ROC_DRIVER_AUX_MUX_ENABLES_SHIFT 19 +#define P_ROC_DRIVER_AUX_COMMAND_SHIFT 16 +#define P_ROC_DRIVER_AUX_COMMAND_MASK 0x3 +#define P_ROC_DRIVER_AUX_ENABLES_SHIFT 12 +#define P_ROC_DRIVER_AUX_ENABLES_MASK 0xF +#define P_ROC_DRIVER_AUX_EXTRA_DATA_SHIFT 8 +#define P_ROC_DRIVER_AUX_EXTRA_DATA_MASK 0xF +#define P_ROC_DRIVER_AUX_DATA_SHIFT 0 +#define P_ROC_DRIVER_AUX_DATA_MASK 0xFF +#define P_ROC_DRIVER_AUX_DELAY_TIME_SHIFT 0 +#define P_ROC_DRIVER_AUX_DELAY_TIME_MASK 0x3FFF +#define P_ROC_DRIVER_AUX_JUMP_ADDR_SHIFT 0 +#define P_ROC_DRIVER_AUX_JUMP_ADDR_MASK 0xFF + +#define P_ROC_DRIVER_AUX_CMD_OUTPUT 2 +#define P_ROC_DRIVER_AUX_CMD_DELAY 1 +#define P_ROC_DRIVER_AUX_CMD_JUMP 0 + +#define P_ROC_SWITCH_CONFIG_CLEAR_SHIFT 31 +#define P_ROC_SWITCH_CONFIG_USE_COLUMN_9 30 +#define P_ROC_SWITCH_CONFIG_USE_COLUMN_8 29 +#define P_ROC_SWITCH_CONFIG_MS_PER_DM_SCAN_LOOP_SHIFT 24 +#define P_ROC_SWITCH_CONFIG_PULSES_BEFORE_CHECKING_RX_SHIFT 18 +#define P_ROC_SWITCH_CONFIG_INACTIVE_PULSES_AFTER_BURST_SHIFT 12 +#define P_ROC_SWITCH_CONFIG_PULSES_PER_BURST_SHIFT 6 +#define P_ROC_SWITCH_CONFIG_MS_PER_PULSE_HALF_PERIOD_SHIFT 0 + +#define P_ROC_SWITCH_RULE_DRIVE_OUTPUTS_NOW 13 +#define P_ROC_SWITCH_RULE_NUM_DEBOUNCE_SHIFT 9 +#define P_ROC_SWITCH_RULE_NUM_STATE_SHIFT 8 +#define P_ROC_SWITCH_RULE_NUM_SWITCH_NUM_SHIFT 0 +#define P_ROC_SWITCH_RULE_NUM_TO_ADDR_SHIFT 2 + +#define P_ROC_SWITCH_RULE_RELOAD_ACTIVE_SHIFT 31 +#define P_ROC_SWITCH_RULE_NOTIFY_HOST_SHIFT 23 +#define P_ROC_SWITCH_RULE_LINK_ACTIVE_SHIFT 10 +#define P_ROC_SWITCH_RULE_LINK_ADDRESS_SHIFT 11 +#define P_ROC_SWITCH_RULE_CHANGE_OUTPUT_SHIFT 9 +#define P_ROC_SWITCH_RULE_DRIVER_NUM_SHIFT 0 + +#define P_ROC_STATE_CHANGE_CONFIG_ADDR 0x1000 + +#define P_ROC_DMD_NUM_COLUMNS_SHIFT 0 +#define P_ROC_DMD_NUM_ROWS_SHIFT 8 +#define P_ROC_DMD_NUM_SUB_FRAMES_SHIFT 16 +#define P_ROC_DMD_NUM_FRAME_BUFFERS_SHIFT 24 +#define P_ROC_DMD_AUTO_INC_WR_POINTER_SHIFT 29 +#define P_ROC_DMD_ENABLE_FRAME_EVENTS_SHIFT 30 +#define P_ROC_DMD_ENABLE_SHIFT 31 + +#define P_ROC_DMD_DOTCLK_HALF_PERIOD_SHIFT 0 +#define P_ROC_DMD_DE_HIGH_CYCLES_SHIFT 6 +#define P_ROC_DMD_LATCH_HIGH_CYCLES_SHIFT 16 +#define P_ROC_DMD_RCLK_LOW_CYCLES_SHIFT 24 + +#define P_ROC_DMD_DOT_TABLE_BASE_ADDR 0x1000 + +#define P_ROC_DRIVER_PDB_ADDR 0xC00 +#define P_ROC_DRIVER_PDB_COMMAND_SHIFT 24 +#define P_ROC_DRIVER_PDB_BOARD_ADDR_SHIFT 16 +#define P_ROC_DRIVER_PDB_REGISTER_SHIFT 8 +#define P_ROC_DRIVER_PDB_DATA_SHIFT 0 +#define P_ROC_DRIVER_PDB_READ_COMMAND 0x00 +#define P_ROC_DRIVER_PDB_WRITE_COMMAND 0x01 +#define P_ROC_DRIVER_PDB_CLEAR_ALL_COMMAND 0x07 +#define P_ROC_DRIVER_PDB_BROADCAST_ADDR 0x3F + +#define p_ROC_DRIVER_PDB_REGISTER_BANK_A 0 +#define p_ROC_DRIVER_PDB_REGISTER_BANK_B 1 + typedef enum PRLogLevel { kPRLogVerbose, kPRLogInfo, @@ -96,7 +351,7 @@ PINPROC_API void PRLogSetCallback(PRLogCallback callback); /**< Replaces the def PINPROC_API void PRLogSetLevel(PRLogLevel level); -PINPROC_API const char *PRGetLastErrorText(); +PINPROC_API const char *PRGetLastErrorText(void); /** * @defgroup device Device Creation & Deletion @@ -111,7 +366,7 @@ typedef enum PRMachineType { kPRMachineWPC95 = 4, kPRMachineSternWhitestar = 5, kPRMachineSternSAM = 6, - kPRMachinePDB = 7, + kPRMachinePDB = 7, // PinballControllers.com Driver Boards } PRMachineType; // PRHandle Creation and Deletion @@ -138,6 +393,9 @@ PINPROC_API PRResult PRFlushWriteData(PRHandle handle); /** Write data out to the P-ROC immediately (does not require a call to PRFlushWriteData). */ PINPROC_API PRResult PRWriteData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer); +/** Write data buffered to P-ROC (does require a call to PRFlushWriteData). */ +PINPROC_API PRResult PRWriteDataUnbuffered(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer); + /** Read data from the P-ROC. */ PINPROC_API PRResult PRReadData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer); diff --git a/libpinproc.xcodeproj/project.pbxproj b/libpinproc.xcodeproj/project.pbxproj index 1da2af3..8ef288f 100644 --- a/libpinproc.xcodeproj/project.pbxproj +++ b/libpinproc.xcodeproj/project.pbxproj @@ -369,7 +369,6 @@ INSTALL_PATH = /usr/local/bin; OTHER_LDFLAGS = ( "-Lbin", - "-lyaml-cpp", "-lftdi", ); PREBINDING = NO; @@ -388,7 +387,6 @@ HEADER_SEARCH_PATHS = /usr/local/include; INSTALL_PATH = /usr/local/bin; OTHER_LDFLAGS = ( - "-lyaml-cpp", "-lftdi", ); PREBINDING = NO; diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index f3444ed..3cab9cb 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -71,15 +71,15 @@ PRDevice* PRDevice::Create(PRMachineType machineType) if (machineType != kPRMachineCustom && machineType != kPRMachinePDB && // Don't accept if requested type is WPC/WPC95 but read machine is not. - ( (((machineType == kPRMachineWPC) || + ( (((machineType == kPRMachineWPC) || (machineType == kPRMachineWPC95) || - (machineType == kPRMachineWPCAlphanumeric)) && - (readMachineType != kPRMachineWPC && + (machineType == kPRMachineWPCAlphanumeric)) && + (readMachineType != kPRMachineWPC && readMachineType != kPRMachineWPC95 && readMachineType != kPRMachineWPCAlphanumeric)) || // Also don't accept if the requested is not WPC/WPC95 but the P-ROC is. - (machineType != kPRMachineWPC && - machineType != kPRMachineWPC95 && + (machineType != kPRMachineWPC && + machineType != kPRMachineWPC95 && machineType != kPRMachineWPCAlphanumeric && readMachineType == kPRMachineWPC) ) ) { @@ -95,7 +95,7 @@ PRDevice* PRDevice::Create(PRMachineType machineType) PRResult PRDevice::Reset(uint32_t resetFlags) { int i; - + // Initialize buffer pointers collected_bytes_rd_addr = 0; collected_bytes_wr_addr = 0; @@ -106,12 +106,12 @@ PRResult PRDevice::Reset(uint32_t resetFlags) while (!requestedDataQueue.empty()) requestedDataQueue.pop(); num_collected_bytes = 0; numPreparedWriteWords = 0; - + if (machineType != kPRMachineCustom && machineType != kPRMachinePDB) DriverLoadMachineTypeDefaults(machineType, resetFlags); // Disable dmd events if updating the device. #if 0 - if (resetFlags & kPRResetFlagUpdateDevice) + if (resetFlags & kPRResetFlagUpdateDevice) { PRDMDConfig *dmdConfig = &(this->dmdConfig); dmdConfig->enableFrameEvents = false; @@ -121,9 +121,9 @@ PRResult PRDevice::Reset(uint32_t resetFlags) // Make sure the free list is empty. while (!freeSwitchRuleIndexes.empty()) freeSwitchRuleIndexes.pop(); - + memset(switchRules, 0x00, sizeof(PRSwitchRuleInternal) * maxSwitchRules); - + for (i = 0; i < kPRSwitchRulesCount; i++) { PRSwitchRuleInternal *switchRule = &switchRules[i]; @@ -137,15 +137,15 @@ PRResult PRDevice::Reset(uint32_t resetFlags) // However, some of the switches are always optos and don't need to be debounced. // So the debounced rule resources for those switches are available for linked rules. if (switchRule->switchNum >= kPRSwitchNeverDebounceFirst && - (switchRule->eventType == kPREventTypeSwitchClosedDebounced || - switchRule->eventType == kPREventTypeSwitchOpenDebounced)) + (switchRule->eventType == kPREventTypeSwitchClosedDebounced || + switchRule->eventType == kPREventTypeSwitchOpenDebounced)) freeSwitchRuleIndexes.push(ruleIndex); } - + // Create empty switch rule for clearing the rules in the device. - PRSwitchRule emptySwitchRule; + PRSwitchRule emptySwitchRule; memset(&emptySwitchRule, 0x00, sizeof(PRSwitchRule)); - + for (i = 0; i < kPRSwitchCount; i++) { // Send blank rule for each event type to Device if necessary @@ -166,7 +166,7 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) if (SortReturningData() != kPRSuccess) { PRSetLastErrorText("GetEvents ERROR: Error in CollectReadData"); - return -1; + return -1; } // The unrequestedDataQueue only has unrequested switch event data. Pop @@ -177,7 +177,7 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) uint32_t event_data = unrequestedDataQueue.front(); unrequestedDataQueue.pop(); - int type; + int type; bool open, debounced; if (version >= 2) { @@ -196,7 +196,7 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) } - //fprintf(stderr, "\nLibpinproc: event type: %d", type); + //fprintf(stderr, "Libpinproc: event type: %d\n", type); switch (type) { case P_ROC_EVENT_TYPE_SWITCH: @@ -205,7 +205,7 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) events[i].type = debounced ? kPREventTypeSwitchOpenDebounced : kPREventTypeSwitchOpenNondebounced; else events[i].type = debounced ? kPREventTypeSwitchClosedDebounced : kPREventTypeSwitchClosedNondebounced; - break; + break; } case P_ROC_EVENT_TYPE_DMD: @@ -216,10 +216,10 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) case P_ROC_EVENT_TYPE_BURST_SWITCH: { - //fprintf(stderr, "\nBurst event"); + //fprintf(stderr, "Burst event\n"); if (open) events[i].type = kPREventTypeBurstSwitchOpen; else events[i].type = kPREventTypeBurstSwitchClosed; - break; + break; } case P_ROC_EVENT_TYPE_ACCELEROMETER: @@ -255,8 +255,8 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) } default: events[i].type = kPREventTypeInvalid; - - } + + } } return i; } @@ -265,10 +265,9 @@ PRResult PRDevice::ManagerUpdateConfig(PRManagerConfig *managerConfig) { const int burstWords = 2; uint32_t burst[burstWords]; - int32_t rc; DEBUG(PRLog(kPRLogInfo, "Setting Manager Config Register\n")); this->managerConfig = *managerConfig; - rc = CreateManagerUpdateConfigBurst(burst, managerConfig); + CreateManagerUpdateConfigBurst(burst, managerConfig); return PrepareWriteData(burst, burstWords); } @@ -276,15 +275,14 @@ PRResult PRDevice::DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalCo { const int burstWords = 4; uint32_t burst[burstWords]; - int32_t rc; DEBUG(PRLog(kPRLogInfo, "Installing driver globals\n")); this->driverGlobalConfig = *driverGlobalConfig; - rc = CreateDriverUpdateGlobalConfigBurst(burst, driverGlobalConfig); - rc = CreateWatchdogConfigBurst(burst+2, driverGlobalConfig->watchdogExpired, - driverGlobalConfig->watchdogEnable, - driverGlobalConfig->watchdogResetTime); + CreateDriverUpdateGlobalConfigBurst(burst, driverGlobalConfig); + CreateWatchdogConfigBurst(burst+2, driverGlobalConfig->watchdogExpired, + driverGlobalConfig->watchdogEnable, + driverGlobalConfig->watchdogResetTime); DEBUG(PRLog(kPRLogVerbose, "Driver Global words: %x %x\n", burst[0], burst[1])); DEBUG(PRLog(kPRLogVerbose, "Watchdog words: %x %x\n", burst[2], burst[3])); @@ -301,11 +299,10 @@ PRResult PRDevice::DriverUpdateGroupConfig(PRDriverGroupConfig *driverGroupConfi { const int burstWords = 2; uint32_t burst[burstWords]; - int32_t rc; driverGroups[driverGroupConfig->groupNum] = *driverGroupConfig; DEBUG(PRLog(kPRLogInfo, "Installing driver group\n")); - rc = CreateDriverUpdateGroupConfigBurst(burst, driverGroupConfig); + CreateDriverUpdateGroupConfigBurst(burst, driverGroupConfig); DEBUG(PRLog(kPRLogVerbose, "Words: %x %x\n", burst[0], burst[1])); return PrepareWriteData(burst, burstWords); @@ -321,10 +318,9 @@ PRResult PRDevice::DriverUpdateState(PRDriverState *driverState) { const int burstWords = 3; uint32_t burst[burstWords]; - int32_t rc; // Don't allow Constant Pulse (non-schedule with time = 0) for known high current drivers. - // Note, the driver numbers depend on the driver group settings from DriverLoadMachineTypeDefaults. + // Note, the driver numbers depend on the driver group settings from DriverLoadMachineTypeDefaults. // TODO: Create some constants that are used both here and in DriverLoadMachineTypeDefaults. DEBUG(PRLog(kPRLogInfo, "Updating driver #%d\n", driverState->driverNum)); @@ -337,7 +333,7 @@ PRResult PRDevice::DriverUpdateState(PRDriverState *driverState) drivers[driverState->driverNum] = *driverState; - rc = CreateDriverUpdateBurst(burst, &drivers[driverState->driverNum]); + CreateDriverUpdateBurst(burst, &drivers[driverState->driverNum]); DEBUG(PRLog(kPRLogVerbose, "Words: %x %x %x\n", burst[0], burst[1], burst[2])); return PrepareWriteData(burst, burstWords); @@ -347,10 +343,10 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint { int i; PRResult res = kPRSuccess; - + //const int WPCDriverLoopTime = 4; // milliseconds //const int SternDriverLoopTime = 2; // milliseconds - + const int mappedWPCDriverGroupEnableIndex[] = {0, 0, 0, 0, 0, 2, 4, 3, 1, 5, 7, 7, 7, 7, 7, 7, 7, 7, 8, 0, 0, 0, 0, 0, 0, 0}; const int mappedSternDriverGroupEnableIndex[] = {0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9}; const bool mappedWPCDriverGroupPolarity[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; @@ -361,9 +357,9 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint const int mappedSternDriverGroupSlowTime[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400}; const int mappedWPCDriverGroupActivateIndex[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0}; const int mappedSternDriverGroupActivateIndex[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; - + const int watchdogResetTime = 1000; // milliseconds - + int mappedDriverGroupEnableIndex[kPRDriverGroupsMax]; bool mappedDriverGroupPolarity[kPRDriverGroupsMax]; int mappedDriverGroupSlowTime[kPRDriverGroupsMax]; @@ -380,51 +376,51 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint int rowEnableSelect; int lastCoilDriverGroup; - - switch (machineType) + + switch (machineType) { - case kPRMachineWPC: - case kPRMachineWPC95: - case kPRMachineWPCAlphanumeric: + case kPRMachineWPC: + case kPRMachineWPC95: + case kPRMachineWPCAlphanumeric: { - memcpy(mappedDriverGroupEnableIndex,mappedWPCDriverGroupEnableIndex, - sizeof(mappedDriverGroupEnableIndex)); - memcpy(mappedDriverGroupPolarity,mappedWPCDriverGroupPolarity, - sizeof(mappedDriverGroupPolarity)); + memcpy(mappedDriverGroupEnableIndex,mappedWPCDriverGroupEnableIndex, + sizeof(mappedDriverGroupEnableIndex)); + memcpy(mappedDriverGroupPolarity,mappedWPCDriverGroupPolarity, + sizeof(mappedDriverGroupPolarity)); rowEnableIndex1 = 6; // Unused in WPC rowEnableIndex0 = 6; tickleSternWatchdog = false; globalPolarity = false; activeLowMatrixRows = true; driverLoopTime = 4; // milliseconds - memcpy(mappedDriverGroupSlowTime,mappedWPCDriverGroupSlowTime, - sizeof(mappedDriverGroupSlowTime)); - memcpy(mappedDriverGroupActivateIndex,mappedWPCDriverGroupActivateIndex, - sizeof(mappedDriverGroupActivateIndex)); + memcpy(mappedDriverGroupSlowTime,mappedWPCDriverGroupSlowTime, + sizeof(mappedDriverGroupSlowTime)); + memcpy(mappedDriverGroupActivateIndex,mappedWPCDriverGroupActivateIndex, + sizeof(mappedDriverGroupActivateIndex)); numMatrixGroups = 8; encodeEnables = false; rowEnableSelect = 0; lastCoilDriverGroup = lastWPCCoilDriverGroup; break; } - - case kPRMachineSternWhitestar: - case kPRMachineSternSAM: + + case kPRMachineSternWhitestar: + case kPRMachineSternSAM: { - memcpy(mappedDriverGroupEnableIndex,mappedSternDriverGroupEnableIndex, - sizeof(mappedDriverGroupEnableIndex)); - memcpy(mappedDriverGroupPolarity,mappedSternDriverGroupPolarity, - sizeof(mappedDriverGroupPolarity)); + memcpy(mappedDriverGroupEnableIndex,mappedSternDriverGroupEnableIndex, + sizeof(mappedDriverGroupEnableIndex)); + memcpy(mappedDriverGroupPolarity,mappedSternDriverGroupPolarity, + sizeof(mappedDriverGroupPolarity)); rowEnableIndex1 = 6; // Unused in Stern rowEnableIndex0 = 10; tickleSternWatchdog = true; globalPolarity = true; activeLowMatrixRows = false; driverLoopTime = 1; // milliseconds - memcpy(mappedDriverGroupSlowTime,mappedSternDriverGroupSlowTime, - sizeof(mappedDriverGroupSlowTime)); - memcpy(mappedDriverGroupActivateIndex,mappedSternDriverGroupActivateIndex, - sizeof(mappedDriverGroupActivateIndex)); + memcpy(mappedDriverGroupSlowTime,mappedSternDriverGroupSlowTime, + sizeof(mappedDriverGroupSlowTime)); + memcpy(mappedDriverGroupActivateIndex,mappedSternDriverGroupActivateIndex, + sizeof(mappedDriverGroupActivateIndex)); numMatrixGroups = 16; encodeEnables = true; rowEnableSelect = 0; @@ -439,7 +435,7 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint return kPRSuccess; } - + memset(&driverGlobalConfig, 0x00, sizeof(PRDriverGlobalConfig)); for (i = 0; i < kPRDriverCount; i++) { @@ -447,8 +443,9 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint memset(driver, 0x00, sizeof(PRDriverState)); driver->driverNum = i; driver->polarity = mappedDriverGroupPolarity[i/8]; - DEBUG(PRLog(kPRLogInfo,"\nDriver Polarity for Driver: %d is %x.", i,driver->polarity)); - if (resetFlags & kPRResetFlagUpdateDevice) + DEBUG(PRLog(kPRLogInfo, "Driver Polarity for Driver: %d is %x.\n", + i, driver->polarity)); + if (resetFlags & kPRResetFlagUpdateDevice) res = DriverUpdateState(driver); } for (i = 0; i < kPRDriverGroupsMax; i++) @@ -458,11 +455,11 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint group->groupNum = i; group->polarity = mappedDriverGroupPolarity[i]; } - - + + // Configure the groups. Each group corresponds to 8 consecutive drivers, starting // with driver #32. The following 6 groups are configured for coils/flashlamps. - + PRDriverGroupConfig group; for (i = 4; i <= lastCoilDriverGroup; i++) { @@ -475,16 +472,17 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint group.polarity = mappedDriverGroupPolarity[i]; group.active = 1; group.disableStrobeAfter = false; - + if (resetFlags & kPRResetFlagUpdateDevice) { res = DriverUpdateGroupConfig(&group); - DEBUG(PRLog(kPRLogInfo,"\nDriver Polarity for Group: %d is %x.", i,group.polarity)); + DEBUG(PRLog(kPRLogInfo, "Driver Polarity for Group: %d is %x.\n", + i, group.polarity)); } else driverGroups[i] = group; } - + // The following 8 groups are configured for the feature lamp matrix. for (i = 10; i < 10 + numMatrixGroups; i++) { DriverGetGroupConfig(i, &group); @@ -496,10 +494,11 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint group.polarity = mappedDriverGroupPolarity[i]; group.active = 1; group.disableStrobeAfter = mappedDriverGroupSlowTime[i] != 0; - + if (resetFlags & kPRResetFlagUpdateDevice) { res = DriverUpdateGroupConfig(&group); - DEBUG(PRLog(kPRLogInfo,"\nDriver Polarity for Group: %d is %x.", i,group.polarity)); + DEBUG(PRLog(kPRLogInfo,"Driver Polarity for Group: %d is %x.\n", + i, group.polarity)); } else driverGroups[i] = group; @@ -517,10 +516,11 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint group.polarity = mappedDriverGroupPolarity[i]; group.active = 1; group.disableStrobeAfter = false; - + if (resetFlags & kPRResetFlagUpdateDevice) { res = DriverUpdateGroupConfig(&group); - DEBUG(PRLog(kPRLogInfo,"\nDriver Polarity for Group: %d is %x.\n", i,group.polarity)); + DEBUG(PRLog(kPRLogInfo, "Driver Polarity for Group: %d is %x.\n", + i, group.polarity)); } else driverGroups[i] = group; @@ -540,16 +540,16 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint globals.watchdogExpired = false; globals.watchdogEnable = true; globals.watchdogResetTime = watchdogResetTime; - + // 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: if (resetFlags & kPRResetFlagUpdateDevice) res = DriverUpdateGlobalConfig(&globals); else driverGlobalConfig = globals; - + // Now enable the outputs to protect against the polarity being driven incorrectly: globals.enableOutputs = true; if (resetFlags & kPRResetFlagUpdateDevice) @@ -559,7 +559,7 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint // If WPCAlphanumeric, select Aux functionality for the dual-purpose Aux/DMD // pins. - + managerConfig.reuse_dmd_data_for_aux = (machineType == kPRMachineWPCAlphanumeric); managerConfig.invert_dipswitch_1 = false; ManagerUpdateConfig(&managerConfig); @@ -598,12 +598,11 @@ PRResult PRDevice::DriverWatchdogTickle() { const int burstWords = 2; uint32_t burst[burstWords]; - int32_t rc; - - rc = CreateWatchdogConfigBurst(burst, driverGlobalConfig.watchdogExpired, - driverGlobalConfig.watchdogEnable, - driverGlobalConfig.watchdogResetTime); - + + CreateWatchdogConfigBurst(burst, driverGlobalConfig.watchdogExpired, + driverGlobalConfig.watchdogEnable, + driverGlobalConfig.watchdogResetTime); + return PrepareWriteData(burst, burstWords); } @@ -635,8 +634,8 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR // Updates a single rule with the associated linked driver state changes. const int burstSize = 4; uint32_t burst[burstSize]; - - // If more the base rule will link to others, ensure free indexes exists for + + // If more the base rule will link to others, ensure free indexes exists for // the links. if (numDrivers > 0 && freeSwitchRuleIndexes.size() < (uint32_t)(numDrivers-1)) // -1 because the first switch rule holds the first driver. { @@ -646,46 +645,46 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR PRResult res = kPRSuccess; uint32_t newRuleIndex = CreateSwitchRuleIndex(switchNum, eventType); - + // Because we're redefining the rule chain, we need to remove all previously existing links and return the indexes to the free list. PRSwitchRuleInternal *oldRule = GetSwitchRuleByIndex(newRuleIndex); - + uint16_t oldLinkIndex; while (oldRule->linkActive) { // Save old link index so it can freed after the linked rule is retrieved. - oldLinkIndex = oldRule->linkIndex; + oldLinkIndex = oldRule->linkIndex; oldRule = GetSwitchRuleByIndex(oldRule->linkIndex); freeSwitchRuleIndexes.push(oldLinkIndex); - + if (freeSwitchRuleIndexes.size() > 128) // Detect a corrupted link-related values before it eats up all of the memory. { PRSetLastErrorText("Too many free switch rule indicies!"); return kPRFailure; } } - + // Create a pointer for new rules. PRSwitchRuleInternal *newRule; - + // Process each driver who's state should change in response to the switch event. - if (numDrivers > 0) + if (numDrivers > 0) { uint32_t ruleIndex, savedRuleIndex; // Need to program the main rule last just in case drive_outputs_now is true. // Otherwise, the hardware could try to access the linked rules before they're // programmed. So, program the rules in reverse order. - + // Move to last driver - linkedDrivers += (numDrivers - 1); + linkedDrivers += (numDrivers - 1); int totalNumDrivers = numDrivers; - + while (numDrivers > 0) { if (numDrivers > 1) { - ruleIndex = freeSwitchRuleIndexes.front(); + ruleIndex = freeSwitchRuleIndexes.front(); freeSwitchRuleIndexes.pop(); newRule = GetSwitchRuleByIndex(ruleIndex); newRule->driver = linkedDrivers[0]; @@ -741,7 +740,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR DEBUG(PRLog(kPRLogError, "Failed to disable.\n")); return res; } - + linkedDrivers--; numDrivers--; } @@ -762,20 +761,19 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR // Write the rule: res = PrepareWriteData(burst, burstSize); } - + 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 + // 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++) @@ -783,44 +781,46 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit if (chip_id == P_ROC_CHIP_ID) { - rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, - P_ROC_SWITCH_CTRL_STATE_BASE_ADDR + i, 1); + RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, + P_ROC_SWITCH_CTRL_STATE_BASE_ADDR + i, 1); if (combinedVersionRevision < P_ROC_VER_REV_FIXED_SWITCH_STATE_READS) { - rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, - P_ROC_SWITCH_CTRL_OLD_DEBOUNCE_BASE_ADDR + i, 1); + RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, + P_ROC_SWITCH_CTRL_OLD_DEBOUNCE_BASE_ADDR + i, 1); } else { - rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, - P_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR + i, 1); + RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, + P_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR + i, 1); } } - else // chip == P3_ROC_CHIP_ID) + else // chip == P3_ROC_CHIP_ID) { - rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, - P3_ROC_SWITCH_CTRL_STATE_BASE_ADDR + i, 1); + RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, + P3_ROC_SWITCH_CTRL_STATE_BASE_ADDR + i, 1); - rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, - P3_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR + i, 1); + RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, + P3_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR + i, 1); } } - // Expect 4 words for each 32 switches. The state and debounce words, + // Expect 4 words for each 32 switches. The state and debounce words, // and the address words for both. - uint16_t numWords = 4 * (numSwitches / 32); - + 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) + while (requestedDataQueue.size() < numWords && i++ < 10) { PRSleep (10); // 10 milliseconds should be plenty of time. if (SortReturningData() != kPRSuccess) + { return kPRFailure; + } } // Make sure all of the requested words are available before processing them. - // Too many words is just as bad as not enough words. + // Too many words is just as bad as not enough words. // If too many come back, can they be trusted? if (requestedDataQueue.size() == numWords) { @@ -829,10 +829,10 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit { requestedDataQueue.pop(); // Ignore address word. TODO: Verify this address word. stateWord = requestedDataQueue.front(); // This is the switch state word. - requestedDataQueue.pop(); + requestedDataQueue.pop(); requestedDataQueue.pop(); // Ignore address word. TODO: Verify this address word. debounceWord = requestedDataQueue.front(); // This is the debounce word. - requestedDataQueue.pop(); + requestedDataQueue.pop(); // Loop through each bit of the words, combining them into an eventType for (j = 0; j < 32; j++) @@ -851,7 +851,11 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit } return kPRSuccess; } - else return kPRFailure; + else + { + PRSetLastErrorText("Switch response length does not match."); + return kPRFailure; + } } int32_t PRDevice::DMDUpdateConfig(PRDMDConfig *dmdConfig) @@ -889,44 +893,6 @@ PRResult PRDevice::DMDDraw(uint8_t * dots) } return PrepareWriteData(dmd_command_buffer, words_per_frame+1); - - // The following code prints out the init lines for the 4 Xilinx BlockRAMs - // in the FPGA. It's used to make an image for the P-ROC to display on power-up. -#if 0 - // This is the original version... needs to be deleted. - for (i=0; i<4; i++) { - std::cout << "For memory: "<< i << "\n"; - // Need 4 lines to get 1 frame (4*256*4 = 4096) - // The rest will be all 0. - for (y=0; y<4; y++) { - std::cout << "defparam blockram.INIT_00 = 256'b"; - for (j=31; j>=0; j--) { - for (x=7; x>=0; x--) { - std::cout << ((dmd_frame_buffer[(y*32)+j] >> ((i*8)+x)) & 1); - } - } - std::cout << ";\n"; - } - std::cout << "\n\n\n"; - } -#endif -#if 0 - for (i=0; i<4; i++) { - std::cout << "For memory: "<< i << "\n"; - // Need 4 lines to get 1 frame (4*256*4 = 4096) - // The rest will be all 0. - for (y=0; y<4; y++) { - std::cout << "defparam blockram.INIT_00 = 256'b"; - for (j=8; j>=0; j--) { - for (x=31; x>=0; x--) { - std::cout << ((dmd_frame_buffer[(y*32)+j] >> ((i*8)+x)) & 1); - } - } - std::cout << ";\n"; - } - std::cout << "\n\n\n"; - } -#endif } PRResult PRDevice::PRJTAGDriveOutputs(PRJTAGOutputs * jtagOutputs, bool_t toggleClk) @@ -993,8 +959,8 @@ PRResult PRDevice::Open() // Attempt to turn off events. This is necessary if P-ROC wasn't shut down // properly previously. If the P-ROC isn't initialized, this request will - // be ignored. - + // be ignored. + PRDMDConfig dmdConfig; dmdConfig.numRows = 32; // Doesn't matter. dmdConfig.numColumns = 128; // Doesn't matter @@ -1016,7 +982,7 @@ PRResult PRDevice::Open() switchConfig.pulseHalfPeriodTime = 13; // milliseconds SwitchUpdateConfig(&switchConfig); - // Flush read data to ensure VerifyChipID starts with clean buffer. + // Flush read data to ensure VerifyChipID starts with clean buffer. // It's possible the P-ROC has a lot of data stored up in internal buffers. So if // the verify still fails, do a bunch of flushes. res = FlushReadBuffer(); @@ -1074,7 +1040,7 @@ PRResult PRDevice::VerifyChipID() max_count = 0; // Wait for data to return. Give it 10 loops before giving up. - while (requestedDataQueue.size() < 5 && max_count++ < max_count_limit) + while (requestedDataQueue.size() < 5 && max_count++ < max_count_limit) { PRSleep (10); // 10 milliseconds should be plenty of time. if (SortReturningData() != kPRSuccess) @@ -1088,11 +1054,12 @@ PRResult PRDevice::VerifyChipID() buffer[i] = requestedDataQueue.front(); requestedDataQueue.pop(); // Ignore address word. TODO: Verify the address. } - if (buffer[1] != P_ROC_CHIP_ID && buffer[1] != P3_ROC_CHIP_ID) + if (buffer[1] != P_ROC_CHIP_ID && buffer[1] != P3_ROC_CHIP_ID) { DEBUG(PRLog(kPRLogError, "Error in VerifyID(): Dumping buffer\n")); - for (i = 0; i < bufferWords; i++) + for (i = 0; i < bufferWords; i++) DEBUG(PRLog(kPRLogError, "buffer[%d]: 0x%x\n", i, buffer[i])); + PRSetLastErrorText("Chip ID does not match."); rc = kPRFailure; } else rc = kPRSuccess; @@ -1110,14 +1077,16 @@ PRResult PRDevice::VerifyChipID() else readMachineType = kPRMachineWPC; // Choose WPC or WPC95, doesn't matter. } else { - DEBUG(PRLog(kPRLogError, "Error reading Chip IP and Version. Read %d words instead of 5. The first 2 were: 0x%x and 0x%x.\n", requestedDataQueue.size(), buffer[0], buffer[1])); + DEBUG(PRLog(kPRLogError, "Error reading Chip IP and Version. Read %d words instead of 5. The first 2 were: 0x%x and 0x%x.\n", requestedDataQueue.size(), buffer[0], buffer[1])); + PRSetLastErrorText("Error reading Chip IP and Version. Read %d words instead of 5. The first 2 were: 0x%x and 0x%x.", requestedDataQueue.size(), buffer[0], buffer[1]); rc = kPRFailure; } } - else + else { // Return failure without logging; calling function must log. DEBUG(PRLog(kPRLogError, "Verify Chip ID took too long to receive data\n")); + PRSetLastErrorText("Verify Chip ID took too long to receive data"); rc = kPRFailure; } return (rc); @@ -1132,7 +1101,7 @@ PRResult PRDevice::RequestData(uint32_t module_select, uint32_t start_addr, int3 PRResult PRDevice::PrepareWriteData(uint32_t * words, int32_t numWords) { if (numWords > maxWriteWords) - { + { PRSetLastErrorText("%d words Exceeds write capabilities. Restrict write requests to %d words.", numWords, maxWriteWords); return kPRFailure; } @@ -1179,10 +1148,6 @@ PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords) wr_buffer[(j*4)+k] = (uint8_t)(temp_word & 0x000000ff); temp_word = temp_word >> 8; } -// for (k=0; k<4; k++) -// { -// item = wr_buffer[(j*4)+k]; -// } } int bytesToWrite = numWords * 4; @@ -1199,6 +1164,19 @@ PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords) } } +PRResult PRDevice::WriteDataRawUnbuffered(uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) +{ + PRResult res; + uint32_t * buffer; + + buffer = (uint32_t *)malloc((numWriteWords * 4) + 4); + buffer[0] = CreateBurstCommand(moduleSelect, startingAddr, numWriteWords); + memcpy(buffer+1, writeBuffer, numWriteWords * 4); + res = PrepareWriteData(buffer, numWriteWords + 1); + free (buffer); + return res; +} + PRResult PRDevice::WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) { PRResult res; @@ -1214,17 +1192,16 @@ PRResult PRDevice::WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, in PRResult PRDevice::ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer) { - uint32_t rc; - uint32_t i; + int32_t i; // Send out the request. - rc = RequestData(moduleSelect, startingAddr, numReadWords); + RequestData(moduleSelect, startingAddr, numReadWords); 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. // Expect numReadWords + 1 word with the address. - while (requestedDataQueue.size() < (uint32_t)((numReadWords + 1)) && i++ < 10) + while (requestedDataQueue.size() < (uint32_t)((numReadWords + 1)) && i++ < 10) { PRSleep (10); // 10 milliseconds should be plenty of time. if (SortReturningData() != kPRSuccess) @@ -1232,19 +1209,23 @@ PRResult PRDevice::ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int } // Make sure all of the requested words are available before processing them. - // Too many words is just as bad as not enough words. + // Too many words is just as bad as not enough words. // If too many come back, can they be trusted? if (requestedDataQueue.size() == (uint32_t)(numReadWords + 1)) { requestedDataQueue.pop(); // Ignore address word. TODO: Verify the address. for (i = 0; i < numReadWords; i++) { - readBuffer[i] = requestedDataQueue.front(); - requestedDataQueue.pop(); + readBuffer[i] = requestedDataQueue.front(); + requestedDataQueue.pop(); } return kPRSuccess; } - else return kPRFailure; + else + { + PRSetLastErrorText("Response length did not match."); + return kPRFailure; + } } @@ -1273,6 +1254,7 @@ int32_t PRDevice::ReadData(uint32_t *buffer, int32_t num_words) rc = num_words; } else { + PRSetLastErrorText("Read length did not match."); rc = 0; } DEBUG(PRLog(kPRLogVerbose, "Read num bytes: %d\n", rc)); @@ -1281,12 +1263,11 @@ int32_t PRDevice::ReadData(uint32_t *buffer, int32_t num_words) PRResult PRDevice::FlushReadBuffer() { - int32_t numBytes,rc=0,k; + int32_t numBytes,rc=0; //uint32_t rd_buffer[3]; numBytes = CollectReadData(); - k = 0; DEBUG(PRLog(kPRLogError, "Flushing Read Buffer: %d bytes trashed\n", numBytes)); - + //while (k < numBytes) { // rc = ReadData(rd_buffer, 1); // k++; @@ -1320,7 +1301,7 @@ int32_t PRDevice::CollectReadData() PRResult PRDevice::SortReturningData() { - int32_t num_bytes, num_words, rc; + int32_t num_bytes, num_words; uint32_t rd_buffer[FTDI_BUFFER_SIZE/4]; num_bytes = CollectReadData(); @@ -1332,7 +1313,7 @@ PRResult PRDevice::SortReturningData() num_words = num_collected_bytes/4; while (num_words >= 2) { - rc = ReadData(rd_buffer, 1); + ReadData(rd_buffer, 1); DEBUG(PRLog(kPRLogVerbose, "New returning word: 0x%x\n", rd_buffer[0])); switch ( (rd_buffer[0] & P_ROC_COMMAND_MASK) >> P_ROC_COMMAND_SHIFT) @@ -1368,7 +1349,7 @@ int PRDevice::CalcCombinedVerRevision() return 0; } -int PRDevice::GetVersionInfo(uint16_t *verPtr, uint16_t *revPtr, uint16_t *combinedPtr) +int PRDevice::GetVersionInfo(uint16_t *verPtr, uint16_t *revPtr, uint32_t *combinedPtr) { *verPtr = version; *revPtr = revision; diff --git a/src/PRDevice.h b/src/PRDevice.h index 69a25f5..c77ebac 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -60,6 +60,7 @@ class PRDevice PRResult FlushWriteData(); PRResult WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * buffer); + PRResult WriteDataRawUnbuffered(uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * buffer); PRResult ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer); PRResult ManagerUpdateConfig(PRManagerConfig *managerConfig); @@ -94,7 +95,7 @@ class PRDevice PRResult PRLEDRGBFade(PRLEDRGB * pLED, uint32_t fadeColor, uint16_t fadeRate); PRResult PRLEDRGBFadeColor(PRLEDRGB * pLED, uint32_t fadeColor); - int GetVersionInfo(uint16_t *verPtr, uint16_t *revPtr, uint16_t *combinedPtr); + int GetVersionInfo(uint16_t *verPtr, uint16_t *revPtr, uint32_t *combinedPtr); protected: @@ -108,7 +109,7 @@ class PRDevice // Raw write and read methods // - + /** Schedules data to be written to the P-ROC. */ PRResult PrepareWriteData(uint32_t * buffer, int32_t numWords); @@ -174,7 +175,7 @@ class PRDevice PRDriverGroupConfig driverGroups[maxDriverGroups]; PRDriverState drivers[maxDrivers]; PRDMDConfig dmdConfig; - + PRSwitchConfig switchConfig; PRSwitchRuleInternal switchRules[maxSwitchRules]; queue freeSwitchRuleIndexes; /**< Indexes of available switch rules. */ diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index 5aa2b90..deb1480 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -33,9 +33,9 @@ #include "PRCommon.h" bool_t IsStern (uint32_t hardware_data) { -// if ( ((hardware_data & P_ROC_BOARD_VERSION_MASK) >> P_ROC_BOARD_VERSION_SHIFT) == 0x1) +// if ( ((hardware_data & P_ROC_BOARD_VERSION_MASK) >> P_ROC_BOARD_VERSION_SHIFT) == 0x1) // return ( ((hardware_data & P_ROC_AUTO_STERN_DETECT_MASK) >> P_ROC_AUTO_STERN_DETECT_SHIFT) == P_ROC_AUTO_STERN_DETECT_VALUE); -// else +// else return ( ((hardware_data & P_ROC_MANUAL_STERN_DETECT_MASK) >> P_ROC_MANUAL_STERN_DETECT_SHIFT) == P_ROC_MANUAL_STERN_DETECT_VALUE); } @@ -59,11 +59,11 @@ int32_t CreateManagerUpdateConfigBurst ( uint32_t * burst, PRManagerConfig *mana addr = P_ROC_REG_DIPSWITCH_ADDR; burst[0] = CreateBurstCommand (P_ROC_MANAGER_SELECT, addr, 1 ); - burst[1] = ( (manager_config->reuse_dmd_data_for_aux << + burst[1] = ( (manager_config->reuse_dmd_data_for_aux << P_ROC_MANAGER_REUSE_DMD_DATA_FOR_AUX_SHIFT) | - (manager_config->invert_dipswitch_1 << + (manager_config->invert_dipswitch_1 << P_ROC_MANAGER_INVERT_DIPSWITCH_1_SHIFT) ); - + return kPRSuccess; } @@ -181,7 +181,7 @@ uint32_t CreateDriverAuxCommand ( PRDriverAuxCommand command) { } break; default : { - return (false << P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT); + return (false << P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT); } } } @@ -189,13 +189,13 @@ uint32_t CreateDriverAuxCommand ( PRDriverAuxCommand command) { int32_t CreateWatchdogConfigBurst ( uint32_t * burst, bool_t watchdogExpired, bool_t watchdogEnable, uint16_t watchdogResetTime) { uint32_t addr; - + addr = P_ROC_REG_WATCHDOG_ADDR; burst[0] = CreateBurstCommand (P_ROC_MANAGER_SELECT, addr, 1 ); burst[1] = ( (watchdogExpired << P_ROC_MANAGER_WATCHDOG_EXPIRED_SHIFT) | (watchdogEnable << P_ROC_MANAGER_WATCHDOG_ENABLE_SHIFT) | (watchdogResetTime << P_ROC_MANAGER_WATCHDOG_RESET_TIME_SHIFT) ); - + return kPRSuccess; } @@ -206,39 +206,39 @@ int32_t CreateSwitchUpdateConfigBurst ( uint32_t * burst, PRSwitchConfig *switch addr = 0; burst[0] = CreateBurstCommand (P_ROC_BUS_SWITCH_CTRL_SELECT, addr, 1 ); burst[1] = (switchConfig->clear << P_ROC_SWITCH_CONFIG_CLEAR_SHIFT) | - (switchConfig->directMatrixScanLoopTime << + (switchConfig->directMatrixScanLoopTime << P_ROC_SWITCH_CONFIG_MS_PER_DM_SCAN_LOOP_SHIFT) | - (switchConfig->pulsesBeforeCheckingRX << + (switchConfig->pulsesBeforeCheckingRX << P_ROC_SWITCH_CONFIG_PULSES_BEFORE_CHECKING_RX_SHIFT) | - (switchConfig->inactivePulsesAfterBurst << + (switchConfig->inactivePulsesAfterBurst << P_ROC_SWITCH_CONFIG_INACTIVE_PULSES_AFTER_BURST_SHIFT) | - (switchConfig->pulsesPerBurst << + (switchConfig->pulsesPerBurst << P_ROC_SWITCH_CONFIG_PULSES_PER_BURST_SHIFT) | - (switchConfig->pulseHalfPeriodTime << + (switchConfig->pulseHalfPeriodTime << P_ROC_SWITCH_CONFIG_MS_PER_PULSE_HALF_PERIOD_SHIFT) | - (switchConfig->use_column_8 << + (switchConfig->use_column_8 << P_ROC_SWITCH_CONFIG_USE_COLUMN_8) | - (switchConfig->use_column_9 << + (switchConfig->use_column_9 << P_ROC_SWITCH_CONFIG_USE_COLUMN_9); - burst[2] = CreateBurstCommand (P_ROC_BUS_STATE_CHANGE_PROC_SELECT, + burst[2] = CreateBurstCommand (P_ROC_BUS_STATE_CHANGE_PROC_SELECT, P_ROC_STATE_CHANGE_CONFIG_ADDR, 1 ); burst[3] = switchConfig->hostEventsEnable; return kPRSuccess; } -int16_t CreateSwitchRuleIndex(uint8_t switchNum, PREventType eventType) +int16_t CreateSwitchRuleIndex(uint8_t switchNum, PREventType eventType) { uint32_t debounce = (eventType == kPREventTypeSwitchOpenDebounced) || (eventType == kPREventTypeSwitchClosedDebounced) ? 1 : 0; uint32_t state = (eventType == kPREventTypeSwitchOpenDebounced) || (eventType == kPREventTypeSwitchOpenNondebounced) ? 1 : 0; - + uint32_t index = ((debounce << P_ROC_SWITCH_RULE_NUM_DEBOUNCE_SHIFT) | (state << P_ROC_SWITCH_RULE_NUM_STATE_SHIFT) | (switchNum << P_ROC_SWITCH_RULE_NUM_SWITCH_NUM_SHIFT) ); return index; } -int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType, bool_t drive_outputs_now) +int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType, bool_t drive_outputs_now) { uint16_t number = CreateSwitchRuleIndex( switchNum, eventType ); uint32_t addr = (number << P_ROC_SWITCH_RULE_NUM_TO_ADDR_SHIFT) | @@ -291,7 +291,7 @@ int32_t CreateDMDUpdateConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config) (dmd_config->numFrameBuffers << P_ROC_DMD_NUM_FRAME_BUFFERS_SHIFT) | (dmd_config->numSubFrames << P_ROC_DMD_NUM_SUB_FRAMES_SHIFT) | (dmd_config->numRows << P_ROC_DMD_NUM_ROWS_SHIFT) | - (dmd_config->numColumns << P_ROC_DMD_NUM_COLUMNS_SHIFT); + (dmd_config->numColumns << P_ROC_DMD_NUM_COLUMNS_SHIFT); addr = 8; burst[2] = CreateBurstCommand (P_ROC_BUS_DMD_SELECT, addr, 4 ); @@ -311,12 +311,12 @@ int32_t CreateJTAGForceOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutpu burst[1] = 1 << P_ROC_JTAG_CMD_START_SHIFT | 1 << P_ROC_JTAG_CMD_OE_SHIFT | P_ROC_JTAG_CMD_SET_PORTS << P_ROC_JTAG_CMD_CMD_SHIFT | - jtagOutputs->tckMask << P_ROC_JTAG_TRANSITION_TCK_MASK_SHIFT | - jtagOutputs->tdoMask << P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT | - jtagOutputs->tmsMask << P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT | - jtagOutputs->tck << P_ROC_JTAG_TRANSITION_TCK_SHIFT | - jtagOutputs->tdo << P_ROC_JTAG_TRANSITION_TCK_SHIFT | - jtagOutputs->tms << P_ROC_JTAG_TRANSITION_TCK_SHIFT; + jtagOutputs->tckMask << P_ROC_JTAG_TRANSITION_TCK_MASK_SHIFT | + jtagOutputs->tdoMask << P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT | + jtagOutputs->tmsMask << P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT | + jtagOutputs->tck << P_ROC_JTAG_TRANSITION_TCK_SHIFT | + jtagOutputs->tdo << P_ROC_JTAG_TRANSITION_TCK_SHIFT | + jtagOutputs->tms << P_ROC_JTAG_TRANSITION_TCK_SHIFT; return kPRSuccess; } @@ -326,10 +326,10 @@ int32_t CreateJTAGLatchOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutpu burst[1] = 1 << P_ROC_JTAG_CMD_START_SHIFT | 1 << P_ROC_JTAG_CMD_OE_SHIFT | P_ROC_JTAG_CMD_TRANSITION << P_ROC_JTAG_CMD_CMD_SHIFT | - jtagOutputs->tdoMask << P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT | - jtagOutputs->tmsMask << P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT | - jtagOutputs->tdo << P_ROC_JTAG_TRANSITION_TCK_SHIFT | - jtagOutputs->tms << P_ROC_JTAG_TRANSITION_TMS_SHIFT; + jtagOutputs->tdoMask << P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT | + jtagOutputs->tmsMask << P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT | + jtagOutputs->tdo << P_ROC_JTAG_TRANSITION_TCK_SHIFT | + jtagOutputs->tms << P_ROC_JTAG_TRANSITION_TMS_SHIFT; return kPRSuccess; } @@ -340,7 +340,7 @@ int32_t CreateJTAGShiftTDODataBurst ( uint32_t * burst, uint16_t numBits, bool_t 1 << P_ROC_JTAG_CMD_OE_SHIFT | P_ROC_JTAG_CMD_SHIFT << P_ROC_JTAG_CMD_CMD_SHIFT | dataBlockComplete << P_ROC_JTAG_SHIFT_EXIT_SHIFT | - numBits << P_ROC_JTAG_SHIFT_NUM_BITS_SHIFT; + numBits << P_ROC_JTAG_SHIFT_NUM_BITS_SHIFT; return kPRSuccess; } @@ -385,18 +385,19 @@ PRResult PRHardwareOpen() ftHandles[i] = NULL; } pcBufLD[MAX_DEVICES] = NULL; - + ftStatus = FT_ListDevices(pcBufLD, &iNumDevs, FT_LIST_ALL | FT_OPEN_BY_SERIAL_NUMBER); - + if(ftStatus != FT_OK) { + PRSetLastErrorText("FT_ListDevices(%d)\n", ftStatus); DEBUG(PRLog(kPRLogInfo,"Error: FT_ListDevices(%d)\n", ftStatus)); return kPRFailure; } - + for(j = 0; j < BUF_SIZE; j++) { cBufWrite[j] = j; } - + for(i = 0; ( (i 0) + if (iDevicesOpen > 0) { FT_ResetDevice(ftHandle); DEBUG(PRLog(kPRLogInfo,"FTDI Device Opened\n")); return kPRSuccess; } - else return kPRFailure; + else + { + PRSetLastErrorText("No FTDI device found."); + return kPRFailure; + } } - + void PRHardwareClose() { int i; @@ -447,14 +453,14 @@ void PRHardwareClose() int PRHardwareRead(uint8_t *buffer, int maxBytes) { - FT_STATUS ftStatus; + FT_STATUS ftStatus; DWORD bytesToRead; DWORD bytesRead; int i; ftStatus = FT_GetQueueStatus(ftHandle,&bytesToRead); if (ftStatus != FT_OK) return 0; - + if ((DWORD)maxBytes < bytesToRead) bytesToRead = maxBytes; ftStatus = FT_Read(ftHandle, buffer, bytesToRead, &bytesRead); if (ftStatus == FT_OK) { @@ -469,13 +475,13 @@ int PRHardwareRead(uint8_t *buffer, int maxBytes) int PRHardwareWrite(uint8_t *buffer, int bytes) { - FT_STATUS ftStatus=0; + FT_STATUS ftStatus=0; DWORD bytesWritten=0; int i; DEBUG(PRLog(kPRLogVerbose,"Writing %d bytes:\n",bytes)); ftStatus = FT_Write(ftHandle, buffer, (DWORD)bytes, &bytesWritten); - if (ftStatus == FT_OK) + if (ftStatus == FT_OK) { DEBUG(PRLog(kPRLogVerbose,"Wrote %d bytes:\n",bytesWritten)); if (bytesWritten != DWORD(bytes)) DEBUG(PRLog(kPRLogVerbose,"Wrote %d bytes, should have written %d bytes",bytesWritten,bytes)); @@ -503,23 +509,23 @@ PRResult PRHardwareOpen() PRResult rc; struct ftdi_device_list *devlist, *curdev; char manufacturer[128], description[128]; - + ftdiInitialized = false; - + // Open the FTDI device if (ftdi_init(&ftdic) != 0) { PRSetLastErrorText("Failed to initialize FTDI."); return kPRFailure; } - + // Find all FTDI devices // This is very basic and really only expects to see 1 device. It needs to be // smarter. At the very least, it should check some register on the P-ROC versus // an input parameter to ensure the software is set up for the same architecture as // the P-ROC (Stern vs WPC). Otherwise, it's possible to drive the coils the wrong // polarity and blow fuses or fry transistors and all other sorts of badness. - + // We first enumerate all of the devices: int numDevices = ftdi_usb_find_all(&ftdic, &devlist, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID); if (numDevices <=0) numDevices = ftdi_usb_find_all(&ftdic, &devlist, FTDI_VENDOR_ID, FTDI_FT240X_PRODUCT_ID); @@ -530,7 +536,7 @@ PRResult PRHardwareOpen() } else { DEBUG(PRLog(kPRLogInfo, "Number of FTDI devices found: %d\n", numDevices)); - + for (curdev = devlist; curdev != NULL; i++) { DEBUG(PRLog(kPRLogInfo, "Checking device %d\n", i)); if ((rc = (int32_t)ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, NULL, 0)) < 0) { @@ -543,12 +549,12 @@ PRResult PRHardwareOpen() } curdev = curdev->next; } - + } - + // Don't need the device list anymore ftdi_list_free (&devlist); - + if (((rc = (int32_t)ftdi_usb_open(&ftdic, FTDI_VENDOR_ID, FTDI_FT245RL_PRODUCT_ID)) < 0) && ((rc = (int32_t)ftdi_usb_open(&ftdic, FTDI_VENDOR_ID, FTDI_FT240X_PRODUCT_ID)) < 0)) { PRSetLastErrorText("Unable to open ftdi device: %d: %s", rc, ftdi_get_error_string(&ftdic)); diff --git a/src/PRHardware.h b/src/PRHardware.h index 809f890..9d14ed9 100644 --- a/src/PRHardware.h +++ b/src/PRHardware.h @@ -45,260 +45,7 @@ const int32_t FTDI_FT240X_PRODUCT_ID = 0x6015; //const int32_t FTDI_BUFFER_SIZE = 2048; const int32_t FTDI_BUFFER_SIZE = 8192; -const uint32_t P_ROC_INIT_PATTERN_A = 0x801F1122; -const uint32_t P_ROC_INIT_PATTERN_B = 0x345678AB; -const uint32_t P_ROC_CHIP_ID = 0xfeedbeef; -const uint32_t P3_ROC_CHIP_ID = 0xf33db33f; -const uint32_t P_ROC_VER_REV_FIXED_SWITCH_STATE_READS = 0x10013; // 1.19 - -const uint32_t P_ROC_AUTO_STERN_DETECT_SHIFT = 8; -const uint32_t P_ROC_AUTO_STERN_DETECT_MASK = 0x00000100; -const uint32_t P_ROC_AUTO_STERN_DETECT_VALUE = 0x1; -const uint32_t P_ROC_MANUAL_STERN_DETECT_SHIFT = 0; -const uint32_t P_ROC_MANUAL_STERN_DETECT_MASK = 0x00000001; -const uint32_t P_ROC_MANUAL_STERN_DETECT_VALUE = 0x00000000; -const uint32_t P_ROC_BOARD_VERSION_SHIFT = 7; -const uint32_t P_ROC_BOARD_VERSION_MASK = 0x00000080; - -const uint32_t P_ROC_ADDR_MASK = 0x000FFFFF; -const uint32_t P_ROC_HEADER_LENGTH_MASK = 0x7FF00000; -const uint32_t P_ROC_COMMAND_MASK = 0x80000000; - -const uint32_t P_ROC_ADDR_SHIFT = 0; -const uint32_t P_ROC_HEADER_LENGTH_SHIFT = 20; -const uint32_t P_ROC_COMMAND_SHIFT = 31; - -const uint32_t P_ROC_READ = 0; -const uint32_t P_ROC_WRITE = 1; -const uint32_t P_ROC_REQUESTED_DATA = 0; -const uint32_t P_ROC_UNREQUESTED_DATA = 1; - -const uint32_t P_ROC_REG_ADDR_MASK = 0x0000FFFF; -const uint32_t P_ROC_MODULE_SELECT_MASK = 0x000F0000; - -const uint32_t P_ROC_REG_ADDR_SHIFT = 0; -const uint32_t P_ROC_MODULE_SELECT_SHIFT = 16; - -const uint32_t P_ROC_MANAGER_SELECT = 0; -const uint32_t P_ROC_BUS_JTAG_SELECT = 1; -const uint32_t P_ROC_BUS_SWITCH_CTRL_SELECT = 2; -const uint32_t P_ROC_BUS_DRIVER_CTRL_SELECT = 3; -const uint32_t P_ROC_BUS_STATE_CHANGE_PROC_SELECT = 4; -const uint32_t P_ROC_BUS_DMD_SELECT = 5; -const uint32_t P_ROC_BUS_UNASSOCIATED_SELECT = 15; - -const uint32_t P3_ROC_MANAGER_SELECT = 0; -const uint32_t P3_ROC_BUS_SPI_SELECT = 1; -const uint32_t P3_ROC_BUS_SWITCH_CTRL_SELECT = 2; -const uint32_t P3_ROC_BUS_DRIVER_CTRL_SELECT = 3; -const uint32_t P3_ROC_BUS_STATE_CHANGE_PROC_SELECT = 4; -const uint32_t P3_ROC_BUS_AUX_CTRL_SELECT = 5; -const uint32_t P3_ROC_BUS_ACCELEROMETER_SELECT = 6; -const uint32_t P3_ROC_BUS_I2C_SELECT = 7; -const uint32_t P3_ROC_BUS_UNASSOCIATED_SELECT = 15; - -const uint32_t P_ROC_REG_CHIP_ID_ADDR = 0; -const uint32_t P_ROC_REG_VERSION_ADDR = 1; -const uint32_t P_ROC_REG_WATCHDOG_ADDR = 2; -const uint32_t P_ROC_REG_DIPSWITCH_ADDR = 3; - -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_MANAGER_REUSE_DMD_DATA_FOR_AUX_SHIFT = 10; -const uint32_t P_ROC_MANAGER_INVERT_DIPSWITCH_1_SHIFT = 9; - -const uint32_t P3_ROC_SPI_OPCODE_SHIFT = 24; - -const uint32_t P3_ROC_SPI_OPCODE_WR_ENABLE = 0; -const uint32_t P3_ROC_SPI_OPCODE_WR_DISABLE = 1; -const uint32_t P3_ROC_SPI_OPCODE_RD_ID = 2; -const uint32_t P3_ROC_SPI_OPCODE_RD_STATUS = 3; -const uint32_t P3_ROC_SPI_OPCODE_WR_STATUS = 4; -const uint32_t P3_ROC_SPI_OPCODE_RD_DATA = 5; -const uint32_t P3_ROC_SPI_OPCODE_FRD_DATA = 6; -const uint32_t P3_ROC_SPI_OPCODE_PP = 7; -const uint32_t P3_ROC_SPI_OPCODE_SECTOR_ERASE = 8; -const uint32_t P3_ROC_SPI_OPCODE_BULK_ERASE = 9; -const uint32_t P3_ROC_SPI_OPCODE_DEEP_POWERDN = 10; -const uint32_t P3_ROC_SPI_OPCODE_RELEASE = 11; - -const uint32_t P_ROC_JTAG_SHIFT_EXIT_SHIFT = 16; -const uint32_t P_ROC_JTAG_SHIFT_NUM_BITS_SHIFT = 0; - -const uint32_t P_ROC_JTAG_CMD_CHANGE_STATE = 0; -const uint32_t P_ROC_JTAG_CMD_SHIFT = 1; -const uint32_t P_ROC_JTAG_CMD_TRANSITION = 2; -const uint32_t P_ROC_JTAG_CMD_SET_PORTS = 3; - -const uint32_t P_ROC_JTAG_CMD_START_SHIFT = 31; -const uint32_t P_ROC_JTAG_CMD_OE_SHIFT = 30; -const uint32_t P_ROC_JTAG_CMD_CMD_SHIFT = 24; - -const uint32_t P_ROC_JTAG_TRANSITION_TCK_MASK_SHIFT = 6; -const uint32_t P_ROC_JTAG_TRANSITION_TDO_MASK_SHIFT = 5; -const uint32_t P_ROC_JTAG_TRANSITION_TMS_MASK_SHIFT = 4; -const uint32_t P_ROC_JTAG_TRANSITION_TCK_SHIFT = 2; -const uint32_t P_ROC_JTAG_TRANSITION_TDO_SHIFT = 1; -const uint32_t P_ROC_JTAG_TRANSITION_TMS_SHIFT = 0; - -const uint32_t P_ROC_JTAG_STATUS_DONE_SHIFT = 31; -const uint32_t P_ROC_JTAG_STATUS_TDI_SHIFT = 16; - -const uint32_t P_ROC_JTAG_COMMAND_REG_BASE_ADDR = 0x0; -const uint32_t P_ROC_JTAG_STATUS_REG_BASE_ADDR = 0x1; -const uint32_t P_ROC_JTAG_TDO_MEMORY_BASE_ADDR = 0x400; -const uint32_t P_ROC_JTAG_TDI_MEMORY_BASE_ADDR = 0x800; - -const uint32_t P_ROC_SWITCH_CTRL_STATE_BASE_ADDR = 4; -const uint32_t P_ROC_SWITCH_CTRL_OLD_DEBOUNCE_BASE_ADDR = 11; -const uint32_t P_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR = 12; -const uint32_t P3_ROC_SWITCH_CTRL_STATE_BASE_ADDR = 16; -const uint32_t P3_ROC_SWITCH_CTRL_DEBOUNCE_BASE_ADDR = 32; - -const uint32_t P_ROC_EVENT_TYPE_SWITCH = 0; -const uint32_t P_ROC_EVENT_TYPE_DMD = 1; -const uint32_t P_ROC_EVENT_TYPE_BURST_SWITCH = 2; -const uint32_t P_ROC_EVENT_TYPE_ACCELEROMETER = 3; - -const uint32_t P_ROC_V1_EVENT_TYPE_MASK = 0xC00; -const uint32_t P_ROC_V1_EVENT_TYPE_SHIFT = 10; -const uint32_t P_ROC_V2_EVENT_TYPE_MASK = 0xC000; -const uint32_t P_ROC_V2_EVENT_TYPE_SHIFT = 14; - -const uint32_t P_ROC_V1_EVENT_SWITCH_NUM_MASK = 0xFF; -const uint32_t P_ROC_V2_EVENT_SWITCH_NUM_MASK = 0x7FF; -const uint32_t P_ROC_V1_EVENT_SWITCH_STATE_MASK = 0x100; -const uint32_t P_ROC_V2_EVENT_SWITCH_STATE_MASK = 0x1000; -const uint32_t P_ROC_V1_EVENT_SWITCH_STATE_SHIFT = 8; -const uint32_t P_ROC_V2_EVENT_SWITCH_STATE_SHIFT = 12; -const uint32_t P_ROC_V1_EVENT_SWITCH_DEBOUNCED_MASK = 0x200; -const uint32_t P_ROC_V2_EVENT_SWITCH_DEBOUNCED_MASK = 0x2000; -const uint32_t P_ROC_V1_EVENT_SWITCH_DEBOUNCED_SHIFT = 9; -const uint32_t P_ROC_V2_EVENT_SWITCH_DEBOUNCED_SHIFT = 13; -const uint32_t P_ROC_V1_EVENT_SWITCH_TIMESTAMP_MASK = 0xFFFFF000; -const uint32_t P_ROC_V1_EVENT_SWITCH_TIMESTAMP_SHIFT = 12; -const uint32_t P_ROC_V2_EVENT_SWITCH_TIMESTAMP_MASK = 0xFFFF0000; -const uint32_t P_ROC_V2_EVENT_SWITCH_TIMESTAMP_SHIFT = 16; -const uint32_t P_ROC_V2_EVENT_ACCEL_TIMESTAMP_MASK = 0xFFFC0000; -const uint32_t P_ROC_V2_EVENT_ACCEL_TIMESTAMP_SHIFT = 18; - - -const uint32_t P_ROC_DRIVER_CTRL_DECODE_SHIFT = 10; -const uint32_t P_ROC_DRIVER_CTRL_REG_DECODE = 0; -const uint32_t P_ROC_DRIVER_CONFIG_TABLE_DECODE = 1; -const uint32_t P_ROC_DRIVER_AUX_MEM_DECODE = 2; -const uint32_t P_ROC_DRIVER_CATCHALL_DECODE = 3; - -const uint32_t P_ROC_DRIVER_GLOBAL_ENABLE_DIRECT_OUTPUTS_SHIFT = 31; -const uint32_t P_ROC_DRIVER_GLOBAL_GLOBAL_POLARITY_SHIFT = 30; -const uint32_t P_ROC_DRIVER_GLOBAL_USE_CLEAR_SHIFT = 28; -const uint32_t P_ROC_DRIVER_GLOBAL_STROBE_START_SELECT_SHIFT = 27; -const uint32_t P_ROC_DRIVER_GLOBAL_START_STROBE_TIME_SHIFT = 20; -const uint32_t P_ROC_DRIVER_GLOBAL_START_STROBE_TIME_MASK = 0x07F00000; -const uint32_t P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_1_SHIFT = 16; -const uint32_t P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_1_MASK = 0x000F0000; -const uint32_t P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_0_SHIFT = 12; -const uint32_t P_ROC_DRIVER_GLOBAL_MATRIX_ROW_ENABLE_INDEX_0_MASK = 0x0000F000; -const uint32_t P_ROC_DRIVER_GLOBAL_ACTIVE_LOW_MATRIX_ROWS_SHIFT = 11; -const uint32_t P_ROC_DRIVER_GLOBAL_ENCODE_ENABLES_SHIFT = 10; -const uint32_t P_ROC_DRIVER_GLOBAL_TICKLE_WATCHDOG_SHIFT = 9; - -const uint32_t P_ROC_DRIVER_GROUP_SLOW_TIME_SHIFT = 12; -const uint32_t P_ROC_DRIVER_GROUP_DISABLE_STROBE_AFTER_SHIFT = 11; -const uint32_t P_ROC_DRIVER_GROUP_ENABLE_INDEX_SHIFT = 7; -const uint32_t P_ROC_DRIVER_GROUP_ROW_ACTIVATE_INDEX_SHIFT = 4; -const uint32_t P_ROC_DRIVER_GROUP_ROW_ENABLE_SELECT_SHIFT = 3; -const uint32_t P_ROC_DRIVER_GROUP_MATRIXED_SHIFT = 2; -const uint32_t P_ROC_DRIVER_GROUP_POLARITY_SHIFT = 1; -const uint32_t P_ROC_DRIVER_GROUP_ACTIVE_SHIFT = 0; - -const uint32_t P_ROC_DRIVER_CONFIG_OUTPUT_DRIVE_TIME_SHIFT = 0; -const uint32_t P_ROC_DRIVER_CONFIG_POLARITY_SHIFT = 8; -const uint32_t P_ROC_DRIVER_CONFIG_STATE_SHIFT = 9; -const uint32_t P_ROC_DRIVER_CONFIG_UPDATE_SHIFT = 10; -const uint32_t P_ROC_DRIVER_CONFIG_WAIT_4_1ST_SLOT_SHIFT = 11; -const uint32_t P_ROC_DRIVER_CONFIG_TIMESLOT_SHIFT = 16; -const uint32_t P_ROC_DRIVER_CONFIG_PATTER_ON_TIME_SHIFT = 16; -const uint32_t P_ROC_DRIVER_CONFIG_PATTER_OFF_TIME_SHIFT = 23; -const uint32_t P_ROC_DRIVER_CONFIG_PATTER_ENABLE_SHIFT = 30; -const uint32_t P_ROC_DRIVER_CONFIG_FUTURE_ENABLE_SHIFT = 31; - -const uint32_t P_ROC_DRIVER_CONFIG_TABLE_DRIVER_NUM_SHIFT = 1; - -const uint32_t P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT = 31; -const uint32_t P_ROC_DRIVER_AUX_OUTPUT_DELAY_SHIFT = 20; -const uint32_t P_ROC_DRIVER_AUX_OUTPUT_DELAY_MASK = 0x7ff; -const uint32_t P_ROC_DRIVER_AUX_MUX_ENABLES_SHIFT = 19; -const uint32_t P_ROC_DRIVER_AUX_COMMAND_SHIFT = 16; -const uint32_t P_ROC_DRIVER_AUX_COMMAND_MASK = 0x3; -const uint32_t P_ROC_DRIVER_AUX_ENABLES_SHIFT = 12; -const uint32_t P_ROC_DRIVER_AUX_ENABLES_MASK = 0xF; -const uint32_t P_ROC_DRIVER_AUX_EXTRA_DATA_SHIFT = 8; -const uint32_t P_ROC_DRIVER_AUX_EXTRA_DATA_MASK = 0xF; -const uint32_t P_ROC_DRIVER_AUX_DATA_SHIFT = 0; -const uint32_t P_ROC_DRIVER_AUX_DATA_MASK = 0xFF; -const uint32_t P_ROC_DRIVER_AUX_DELAY_TIME_SHIFT = 0; -const uint32_t P_ROC_DRIVER_AUX_DELAY_TIME_MASK = 0x3FFF; -const uint32_t P_ROC_DRIVER_AUX_JUMP_ADDR_SHIFT = 0; -const uint32_t P_ROC_DRIVER_AUX_JUMP_ADDR_MASK = 0xFF; - -const uint32_t P_ROC_DRIVER_AUX_CMD_OUTPUT = 2; -const uint32_t P_ROC_DRIVER_AUX_CMD_DELAY = 1; -const uint32_t P_ROC_DRIVER_AUX_CMD_JUMP = 0; - -const uint32_t P_ROC_SWITCH_CONFIG_CLEAR_SHIFT = 31; -const uint32_t P_ROC_SWITCH_CONFIG_USE_COLUMN_9 = 30; -const uint32_t P_ROC_SWITCH_CONFIG_USE_COLUMN_8 = 29; -const uint32_t P_ROC_SWITCH_CONFIG_MS_PER_DM_SCAN_LOOP_SHIFT = 24; -const uint32_t P_ROC_SWITCH_CONFIG_PULSES_BEFORE_CHECKING_RX_SHIFT = 18; -const uint32_t P_ROC_SWITCH_CONFIG_INACTIVE_PULSES_AFTER_BURST_SHIFT = 12; -const uint32_t P_ROC_SWITCH_CONFIG_PULSES_PER_BURST_SHIFT = 6; -const uint32_t P_ROC_SWITCH_CONFIG_MS_PER_PULSE_HALF_PERIOD_SHIFT = 0; - -const uint32_t P_ROC_SWITCH_RULE_DRIVE_OUTPUTS_NOW = 13; -const uint32_t P_ROC_SWITCH_RULE_NUM_DEBOUNCE_SHIFT = 9; -const uint32_t P_ROC_SWITCH_RULE_NUM_STATE_SHIFT = 8; -const uint32_t P_ROC_SWITCH_RULE_NUM_SWITCH_NUM_SHIFT = 0; -const uint32_t P_ROC_SWITCH_RULE_NUM_TO_ADDR_SHIFT = 2; - -const uint32_t P_ROC_SWITCH_RULE_RELOAD_ACTIVE_SHIFT = 31; -const uint32_t P_ROC_SWITCH_RULE_NOTIFY_HOST_SHIFT = 23; -const uint32_t P_ROC_SWITCH_RULE_LINK_ACTIVE_SHIFT = 10; -const uint32_t P_ROC_SWITCH_RULE_LINK_ADDRESS_SHIFT = 11; -const uint32_t P_ROC_SWITCH_RULE_CHANGE_OUTPUT_SHIFT = 9; -const uint32_t P_ROC_SWITCH_RULE_DRIVER_NUM_SHIFT = 0; - -const uint32_t P_ROC_STATE_CHANGE_CONFIG_ADDR = 0x1000; - -const uint32_t P_ROC_DMD_NUM_COLUMNS_SHIFT = 0; -const uint32_t P_ROC_DMD_NUM_ROWS_SHIFT = 8; -const uint32_t P_ROC_DMD_NUM_SUB_FRAMES_SHIFT = 16; -const uint32_t P_ROC_DMD_NUM_FRAME_BUFFERS_SHIFT = 24; -const uint32_t P_ROC_DMD_AUTO_INC_WR_POINTER_SHIFT = 29; -const uint32_t P_ROC_DMD_ENABLE_FRAME_EVENTS_SHIFT = 30; -const uint32_t P_ROC_DMD_ENABLE_SHIFT = 31; - -const uint32_t P_ROC_DMD_DOTCLK_HALF_PERIOD_SHIFT = 0; -const uint32_t P_ROC_DMD_DE_HIGH_CYCLES_SHIFT = 6; -const uint32_t P_ROC_DMD_LATCH_HIGH_CYCLES_SHIFT = 16; -const uint32_t P_ROC_DMD_RCLK_LOW_CYCLES_SHIFT = 24; - -const uint32_t P_ROC_DMD_DOT_TABLE_BASE_ADDR = 0x1000; - -const uint32_t P_ROC_DRIVER_PDB_ADDR = 0xC00; -const uint32_t P_ROC_DRIVER_PDB_COMMAND_SHIFT = 24; -const uint32_t P_ROC_DRIVER_PDB_BOARD_ADDR_SHIFT = 16; -const uint32_t P_ROC_DRIVER_PDB_REGISTER_SHIFT = 8; -const uint32_t P_ROC_DRIVER_PDB_DATA_SHIFT = 0; -const uint32_t P_ROC_DRIVER_PDB_READ_COMMAND = 0x00; -const uint32_t P_ROC_DRIVER_PDB_WRITE_COMMAND = 0x01; -const uint32_t P_ROC_DRIVER_PDB_CLEAR_ALL_COMMAND = 0x07; -const uint32_t P_ROC_DRIVER_PDB_BROADCAST_ADDR = 0x3F; - -const uint32_t p_ROC_DRIVER_PDB_REGISTER_BANK_A = 0; -const uint32_t p_ROC_DRIVER_PDB_REGISTER_BANK_B = 1; typedef enum PRLEDRegisterType { kPRLEDRegisterTypeLEDIndex = 0, diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 3e01757..3d682ac 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -51,7 +51,7 @@ void PRLog(PRLogLevel level, const char *format, ...) { if (level < logLevel) return; - + char line[MAX_TEXT]; va_list ap; va_start(ap, format); @@ -82,7 +82,7 @@ void PRSetLastErrorText(const char *format, ...) PRLog(kPRLogError, "%s\n", lastErrorText); } -const char *PRGetLastErrorText() +const char *PRGetLastErrorText(void) { return lastErrorText; } @@ -119,12 +119,18 @@ PRResult PRFlushWriteData(PRHandle handle) return handleAsDevice->FlushWriteData(); } -/** Write data out to the P-ROC immediately (does not require a call to PRFlushWriteData */ +/** Write data out to the P-ROC immediately (does not require a call to PRFlushWriteData). */ PRResult PRWriteData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) { return handleAsDevice->WriteDataRaw(moduleSelect, startingAddr, numWriteWords, writeBuffer); } +/** Write data buffered to P-ROC (does require a call to PRFlushWriteData). */ +PRResult PRWriteDataUnbuffered(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) +{ + return handleAsDevice->WriteDataRawUnbuffered(moduleSelect, startingAddr, numWriteWords, writeBuffer); +} + /** Read data from the P-ROC. */ PRResult PRReadData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer) { @@ -358,8 +364,8 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) else if ( strlen(str) == 4) x = (str[2]-'0') * 10 + (str[3]-'0'); else return atoi(str); - - if ((machineType == kPRMachineWPC) || + + if ((machineType == kPRMachineWPC) || (machineType == kPRMachineWPC95) || (machineType == kPRMachineWPCAlphanumeric)) { @@ -381,7 +387,7 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) case 'm': return 32; default: - return 33; + return 33; } default: switch (str[3]) @@ -390,7 +396,7 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) case 'm': return 34; default: - return 35; + return 35; } } default: @@ -404,7 +410,7 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) case 'm': return 36; default: - return 37; + return 37; } default: switch (str[3]) @@ -413,7 +419,7 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) case 'm': return 38; default: - return 39; + return 39; } } } @@ -432,7 +438,7 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) if (machineType == kPRMachineWPC95) //return x + 7; return x + 31; - else + else return x + 107; // WPC 37-44 use 8-driver board (mapped to drivers 144-151) } else return x + 108; @@ -473,7 +479,7 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) { case 'D': case 'd': - if (strlen(str) == 3) + if (strlen(str) == 3) return (str[2]-'0') + 7; else return x + 7; default: @@ -502,7 +508,7 @@ uint16_t PRDecode(PRMachineType machineType, const char *str) { case 'D': case 'd': - if (strlen(str) == 3) + if (strlen(str) == 3) return (str[2]-'0') + 7; else return x + 7; default: diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index 0bff8a2..3322c50 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -32,12 +32,18 @@ #endif /* DEBUG_MODE */ #include "pinprocfw.h" -#include "../../src/PRHardware.h" #include "lenval.h" #ifndef _MSC_VER #include #endif +#if defined(__WIN32__) || defined(_WIN32) +#include +#define PRSleep(milliseconds) Sleep(milliseconds) +#else +#define PRSleep(milliseconds) usleep(milliseconds*1000) +#endif + #include "pinproc.h" // Include libpinproc's header. PRMachineType machineType = kPRMachineCustom; // Should work with all machines. @@ -514,7 +520,7 @@ void setPort(short p,short val) // Toggle TCK. -void pulseClock() +void pulseClock(void) { setPort(TCK,0); /* set the TCK port to low */ setPort(TCK,1); /* set the TCK port to high */ @@ -527,12 +533,10 @@ void readByte(unsigned char *data) fprintf(stderr, "\n\nUpdating P-ROC. This may take a couple of minutes.\n"); fprintf(stderr, "WARNING: DO NOT POWER CYCLE UNTIL COMPLETE!\n"); printf("\nErasing PROM... "); - fflush(stdout); } if (numBytesCurrent == 5000) { printf("complete.\nProgramming:\n0%% "); - fflush(stdout); } // read in a byte of data from the xsvf file *data = (unsigned char)fgetc( in ); @@ -540,16 +544,14 @@ void readByte(unsigned char *data) long int bytesPer200th = numBytesTotal / 200; numBytesCurrent++; if (numBytesCurrent % bytesPerTenth == 0) { - printf("\n%ld0%% ",numBytesCurrent/bytesPerTenth); - fflush(stdout); + printf("\n%d0%% ",(int) (numBytesCurrent/bytesPerTenth)); } else if (numBytesCurrent % bytesPer200th == 0) { printf("."); - fflush(stdout); } } -unsigned char readTDOBit() +unsigned char readTDOBit(void) { PRJTAGStatus jtagStatus; @@ -1853,7 +1855,7 @@ void xsvfCleanup( SXsvfInfo* pXsvfInfo ) * Parameters: none. * Returns: int - Legacy result values: 1 == success; 0 == failed. *****************************************************************************/ -int xsvfExecute() +int xsvfExecute(void) { SXsvfInfo xsvfInfo; @@ -1874,7 +1876,7 @@ int xsvfExecute() } else { - XSVFDBG_PRINTF( 0, "SUCCESS - Operation completed successfully. Cycle P-ROC power to activate any changes.\n" ); + XSVFDBG_PRINTF( 0, "SUCCESS - Operation completed successfully.\nCycle P-ROC power to activate any changes.\n" ); } xsvfCleanup( &xsvfInfo ); @@ -1882,7 +1884,7 @@ int xsvfExecute() return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) ); } -int openPROC() +int openPROC(void) { // Instantiate the P-ROC device: XSVFDBG_PRINTF( 1, "Opening P-ROC.\n"); @@ -1898,35 +1900,27 @@ int openPROC() void printUsage(char * name) { - fprintf(stderr, "\n%s: Version 1.1", name ); - fprintf(stderr, "\nUSAGE: %s \n", name ); + fprintf(stderr, "%s: Version 1.1\n", name ); + fprintf(stderr, "USAGE: %s \n", name ); fprintf(stderr, " filename = the .xsvf or .p-roc file to execute.\n" ); } -int getNumFileBytes() { - unsigned char data; - int i=0; - while (!feof(in)) - { - data = (unsigned char)fgetc( in ); - i++; - } - return i; -} - // Move file pointer to beginning of XSVF data. -void preparePROCFile() { +void preparePROCFile(void) { int temp, num_header_words; int i; + rewind(in); fscanf(in, "%x\n", &temp); num_header_words = (int)(0x012345678 - temp); - for (i=0; i> 7 | - (board_rev & 0x40) >> 5 | - (board_rev & 0x20) >> 3 | - (board_rev & 0x10) >> 1; + int board_rev = 0; + if (board_id == P3_ROC_CHIP_ID) { + board_rev = (readdata[3] & 0x800) >> 11 | + (readdata[3] & 0x400) >> 10 | + (readdata[3] & 0x200) >> 9 | + (readdata[3] & 0x100) >> 8; + fprintf(stderr, "Connected to P3-ROC (board rev %d).\n", board_rev); + } + else if (board_id == P_ROC_CHIP_ID) { + board_rev = (readdata[3] & 0x80) >> 7 | + (readdata[3] & 0x40) >> 6 | + (readdata[3] & 0x20) >> 5 | + (readdata[3] & 0x10) >> 4; + fprintf(stderr, "Connected to P-ROC (board rev %d).\n", board_rev); + } + else { + fprintf(stderr, "Connected to unrecognized hardware (0x%08X).\n", + board_id); + return 0; + } + fprintf(stderr, "Current FPGA version: %u.%u\n", + readdata[1] >> 16, readdata[1] & 0xffff); if (proc_file_version != 0) { - fprintf(stderr, "\nERROR: Unsupported .p-roc file version: %x. Check for an updated version of this tool.\n\n", proc_file_version); + fprintf(stderr, "ERROR: Unsupported .p-roc file version: 0x%x. Check for an updated version of this tool.\n\n", + proc_file_version); return 0; } // Check for valid board ID and rev - if (board_id != file_board_id) { - fprintf(stderr, "\nERROR: board type mismatch."); - if (board_id == P_ROC_CHIP_ID && file_board_id == P3_ROC_CHIP_ID) - fprintf(stderr, "\nCannot program a P3-ROC image onto a P-ROC\n\n"); - else if (board_id == P3_ROC_CHIP_ID && file_board_id == P_ROC_CHIP_ID) - fprintf(stderr, "\nCannot program a P-ROC image onto a P3-ROC\n\n"); - else fprintf(stderr, "\nImage (0x%08X) and board (0x%08X) are incompatible\n\n", file_board_id, board_id); + if (board_id == file_board_id) { + fprintf(stderr, "Board ID verified\n"); + } + else { + if (board_id == P_ROC_CHIP_ID && file_board_id == P3_ROC_CHIP_ID) { + fprintf(stderr, "ERROR: Cannot program a P3-ROC image onto a P-ROC\n\n"); + } + else if (board_id == P3_ROC_CHIP_ID && file_board_id == P_ROC_CHIP_ID) { + fprintf(stderr, "ERROR: Cannot program a P-ROC image onto a P3-ROC\n\n"); + } + else { + fprintf(stderr, "ERROR: Image (0x%08X) and board (0x%08X) are incompatible\n\n", + file_board_id, board_id); + } return 0; } - else fprintf(stderr, "\nBoard ID verified"); + if (board_rev > max_board_rev || board_rev < min_board_rev) { - fprintf(stderr, "\nERROR: This image is not compatible with the P-ROC board (rev: %x)", board_id); + fprintf(stderr, "ERROR: Board rev %d not between %d and %d\n", + board_rev, min_board_rev, max_board_rev); return 0; } - else fprintf(stderr, "\nBoard rev verified"); checksum = 0; i = 0; - while (!feof(in)) - { + while (!feof(in)) { data = (unsigned char)fgetc( in ); checksum += data; i++; @@ -2218,7 +2213,7 @@ int checkPROCFile() { if ((i != file_i) || (checksum != file_checksum) || (header_checksum != new_header_checksum)) { - fprintf(stderr, "\nFPGA data verification failure!\n\n"); + fprintf(stderr, "FPGA data verification failure!\n\n"); return 0; } @@ -2247,11 +2242,11 @@ int main( int argc, char** argv ) int i; int iErrorCode; - // Set a signal handler so that we can exit gracefully on Ctrl-C: - //signal(SIGINT, sigint); + // Set stdout unbuffered to eliminate need to fflush() + setbuf(stdout, NULL); iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); - pzXsvfFileName = 0; + pzXsvfFileName = NULL; //printf( "XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION ); @@ -2279,58 +2274,61 @@ int main( int argc, char** argv ) // Check for .p-roc file if (strstr(pzXsvfFileName, ".p-roc")) { - fprintf(stderr, "\nP-ROC file format detected\n."); + fprintf(stderr, "P-ROC file format detected.\n"); in = fopen( pzXsvfFileName, "rb" ); if ( !in ) { - fprintf(stderr, "ERROR: Cannot open file %s\n.", pzXsvfFileName ); + fprintf(stderr, "ERROR: Cannot open file '%s'.\n", pzXsvfFileName ); iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_UNKNOWN ); } else { - if (openPROC()) { - fprintf(stderr, "\nVerifying file contents and board compatibility..."); - switch (checkPROCFile()) - { - case P_ROC_CHIP_ID: - rewind(in); + fprintf(stderr, "Verifying file contents and board compatibility...\n"); + switch (checkPROCFile()) { + case P_ROC_CHIP_ID: preparePROCFile(); processFile(); break; - case P3_ROC_CHIP_ID: - rewind(in); - preparePROCFile(); - processP3ROCFile(); - break; - default: - break; - } + case P3_ROC_CHIP_ID: + preparePROCFile(); + processP3ROCFile(); + break; + default: + fprintf(stderr, "Failed to parse file.\n"); + break; + } } } } - // Check for .p-roc file + // Check for .xsvf file else if (strstr(pzXsvfFileName, ".xsvf")) { - fprintf(stderr, "\nXSVF file format detected.\n"); + fprintf(stderr, "XSVF file format detected.\n"); in = fopen( pzXsvfFileName, "rb" ); if ( !in ) { - fprintf(stderr, "ERROR: Cannot open file %s\n.", pzXsvfFileName ); + fprintf(stderr, "ERROR: Cannot open file '%s'.\n", pzXsvfFileName ); iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_UNKNOWN ); } else { - numBytesTotal = getNumFileBytes(); - rewind(in); - if (openPROC()) { + fseek(in, 0, SEEK_END); + numBytesTotal = ftell(in); + rewind(in); processFile(); } } } else { - fprintf(stderr, "\nERROR: Unsupported file format.\n"); + fprintf(stderr, "ERROR: Unsupported file format.\n"); printUsage(argv[0]); } } + if (proc != kPRHandleInvalid) { + // Destroy the P-ROC device handle created by openPROC() + PRDelete(proc); + proc = kPRHandleInvalid; + } + return( iErrorCode ); } #endif /* XSVF_MAIN */