From d681054a1d9ffada4228523ecb45da8487c28f8a Mon Sep 17 00:00:00 2001 From: Jan Kantert Date: Wed, 10 Feb 2016 18:15:15 +0100 Subject: [PATCH 01/38] dont compile examples --- CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0853ac4..d858b58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,18 +235,18 @@ if(PINPROC_BUILD_TOOLS) # Create a target for the test tool #TODO: use add_subdirectory() and separate CMakeLists.txt (like yaml-cpp) # see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_subdirectory -add_executable(pinproctest - examples/pinproctest/pinproctest.cpp - examples/pinproctest/drivers.cpp - examples/pinproctest/dmd.cpp - examples/pinproctest/switches.cpp - examples/pinproctest/alphanumeric.cpp -) -target_link_libraries(pinproctest - pinproc - optimized ${YAML_CPP_LIB} - debug ${YAML_CPP_LIB_DBG} -) +#add_executable(pinproctest +# examples/pinproctest/pinproctest.cpp +# examples/pinproctest/drivers.cpp +# examples/pinproctest/dmd.cpp +# examples/pinproctest/switches.cpp +# examples/pinproctest/alphanumeric.cpp +#) +#target_link_libraries(pinproctest +# pinproc +# optimized ${YAML_CPP_LIB} +# debug ${YAML_CPP_LIB_DBG} +#) # Create a target for the firmware tool #TODO: use add_subdirectory() and separate CMakeLists.txt (like yaml-cpp) From a87e5fb9b9de3ab9233b2243ec84eed2440eb6a1 Mon Sep 17 00:00:00 2001 From: Jan Kantert Date: Wed, 10 Feb 2016 18:15:26 +0100 Subject: [PATCH 02/38] use pkg-config --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 $@ $< From 69bd547f0efe4c2c289feb5c3a730789fe1a880c Mon Sep 17 00:00:00 2001 From: Jan Kantert Date: Wed, 10 Feb 2016 22:20:25 +0100 Subject: [PATCH 03/38] add debian control files --- debian/changelog | 5 + debian/compat | 1 + debian/control | 21 + debian/copyright | 13 + debian/docs | 0 debian/files | 2 + debian/libpinproc-dev.debhelper.log | 24 + debian/libpinproc-dev.dirs | 2 + debian/libpinproc-dev.install | 3 + debian/libpinproc-dev.substvars | 1 + debian/libpinproc-dev/DEBIAN/control | 12 + debian/libpinproc-dev/DEBIAN/md5sums | 4 + .../usr/include/p-roc/pinproc.h | 598 ++++++++++++++++++ debian/libpinproc-dev/usr/lib/libpinproc.so | 1 + .../usr/lib/pkgconfig/pinproc.pc | 11 + .../doc/libpinproc-dev/changelog.Debian.gz | Bin 0 -> 140 bytes .../usr/share/doc/libpinproc-dev/copyright | 13 + debian/libpinproc.debhelper.log | 24 + debian/libpinproc.install | 1 + debian/libpinproc.postinst.debhelper | 5 + debian/libpinproc.postrm.debhelper | 5 + debian/libpinproc.substvars | 2 + debian/libpinproc/DEBIAN/control | 11 + debian/libpinproc/DEBIAN/md5sums | 3 + debian/libpinproc/DEBIAN/postinst | 7 + debian/libpinproc/DEBIAN/postrm | 7 + debian/libpinproc/DEBIAN/shlibs | 1 + debian/libpinproc/usr/lib/libpinproc.so.2.0 | Bin 0 -> 51360 bytes .../share/doc/libpinproc/changelog.Debian.gz | Bin 0 -> 140 bytes .../usr/share/doc/libpinproc/copyright | 13 + debian/libpinproc1.dirs | 1 + debian/rules | 27 + debian/source/format | 1 + 33 files changed, 819 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/docs create mode 100644 debian/files create mode 100644 debian/libpinproc-dev.debhelper.log create mode 100644 debian/libpinproc-dev.dirs create mode 100644 debian/libpinproc-dev.install create mode 100644 debian/libpinproc-dev.substvars create mode 100644 debian/libpinproc-dev/DEBIAN/control create mode 100644 debian/libpinproc-dev/DEBIAN/md5sums create mode 100644 debian/libpinproc-dev/usr/include/p-roc/pinproc.h create mode 120000 debian/libpinproc-dev/usr/lib/libpinproc.so create mode 100644 debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc create mode 100644 debian/libpinproc-dev/usr/share/doc/libpinproc-dev/changelog.Debian.gz create mode 100644 debian/libpinproc-dev/usr/share/doc/libpinproc-dev/copyright create mode 100644 debian/libpinproc.debhelper.log create mode 100644 debian/libpinproc.install create mode 100644 debian/libpinproc.postinst.debhelper create mode 100644 debian/libpinproc.postrm.debhelper create mode 100644 debian/libpinproc.substvars create mode 100644 debian/libpinproc/DEBIAN/control create mode 100644 debian/libpinproc/DEBIAN/md5sums create mode 100755 debian/libpinproc/DEBIAN/postinst create mode 100755 debian/libpinproc/DEBIAN/postrm create mode 100644 debian/libpinproc/DEBIAN/shlibs create mode 100644 debian/libpinproc/usr/lib/libpinproc.so.2.0 create mode 100644 debian/libpinproc/usr/share/doc/libpinproc/changelog.Debian.gz create mode 100644 debian/libpinproc/usr/share/doc/libpinproc/copyright create mode 100644 debian/libpinproc1.dirs create mode 100755 debian/rules create mode 100644 debian/source/format diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..2db71e6 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +libpinproc (0.1.0-1) trusty; urgency=low + + * Initial release + + -- Jan Kantert Wed, 10 Feb 2016 20:21:33 +0100 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..5217999 --- /dev/null +++ b/debian/control @@ -0,0 +1,21 @@ +Source: libpinproc +Priority: optional +Maintainer: Jan Kantert +Build-Depends: debhelper (>= 8.0.0) +Standards-Version: 3.9.4 +Section: libs +Homepage: https://github.com/jabdoa2/libpinproc + +Package: libpinproc-dev +Section: libdevel +Architecture: any +Depends: libpinproc (= ${binary:Version}) +Description: Devel header for libpinproc + Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic + +Package: libpinproc +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: libpinproc + Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..91432fa --- /dev/null +++ b/debian/copyright @@ -0,0 +1,13 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: libpinproc +Source: README.markdown + +Files: * +Copyright: 2009 Gerry Stellenberg + 2009 Adam Preble +License: AS IS + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e69de29 diff --git a/debian/files b/debian/files new file mode 100644 index 0000000..1782cbb --- /dev/null +++ b/debian/files @@ -0,0 +1,2 @@ +libpinproc-dev_0.1.0-1_amd64.deb libdevel optional +libpinproc_0.1.0-1_amd64.deb libs optional diff --git a/debian/libpinproc-dev.debhelper.log b/debian/libpinproc-dev.debhelper.log new file mode 100644 index 0000000..3dd8e80 --- /dev/null +++ b/debian/libpinproc-dev.debhelper.log @@ -0,0 +1,24 @@ +dh_auto_configure +dh_auto_build +dh_auto_test +dh_prep +dh_installdirs +override_dh_auto_install dh_auto_install +dh_auto_install +dh_install +dh_installdocs +dh_installchangelogs +dh_perl +dh_link +dh_compress +dh_fixperms +dh_strip +dh_makeshlibs +override_dh_shlibdeps dh_shlibdeps +dh_shlibdeps +dh_installdeb +dh_gencontrol +dh_md5sums +dh_builddeb +dh_builddeb +dh_builddeb diff --git a/debian/libpinproc-dev.dirs b/debian/libpinproc-dev.dirs new file mode 100644 index 0000000..4418816 --- /dev/null +++ b/debian/libpinproc-dev.dirs @@ -0,0 +1,2 @@ +usr/lib +usr/include diff --git a/debian/libpinproc-dev.install b/debian/libpinproc-dev.install new file mode 100644 index 0000000..c4e0b93 --- /dev/null +++ b/debian/libpinproc-dev.install @@ -0,0 +1,3 @@ +usr/include/* +usr/lib/pkgconfig/* +usr/lib/lib*.so diff --git a/debian/libpinproc-dev.substvars b/debian/libpinproc-dev.substvars new file mode 100644 index 0000000..abd3ebe --- /dev/null +++ b/debian/libpinproc-dev.substvars @@ -0,0 +1 @@ +misc:Depends= diff --git a/debian/libpinproc-dev/DEBIAN/control b/debian/libpinproc-dev/DEBIAN/control new file mode 100644 index 0000000..f427b95 --- /dev/null +++ b/debian/libpinproc-dev/DEBIAN/control @@ -0,0 +1,12 @@ +Package: libpinproc-dev +Source: libpinproc +Version: 0.1.0-1 +Architecture: amd64 +Maintainer: Jan Kantert +Installed-Size: 68 +Depends: libpinproc (= 0.1.0-1) +Section: libdevel +Priority: optional +Homepage: https://github.com/jabdoa2/libpinproc +Description: Devel header for libpinproc + Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic diff --git a/debian/libpinproc-dev/DEBIAN/md5sums b/debian/libpinproc-dev/DEBIAN/md5sums new file mode 100644 index 0000000..1135cfb --- /dev/null +++ b/debian/libpinproc-dev/DEBIAN/md5sums @@ -0,0 +1,4 @@ +675f72525b8aa87966c0b35e27cbf2d0 usr/include/p-roc/pinproc.h +d291de7e93c0d47be0f40e87c7dd93e8 usr/lib/pkgconfig/pinproc.pc +74322abf217a8f4e1d6f50d89a8a009c usr/share/doc/libpinproc-dev/changelog.Debian.gz +9b8881ce99456b7e1d090ab95820ff1f usr/share/doc/libpinproc-dev/copyright diff --git a/debian/libpinproc-dev/usr/include/p-roc/pinproc.h b/debian/libpinproc-dev/usr/include/p-roc/pinproc.h new file mode 100644 index 0000000..521334f --- /dev/null +++ b/debian/libpinproc-dev/usr/include/p-roc/pinproc.h @@ -0,0 +1,598 @@ +/* + * The MIT License + * Copyright (c) 2009 Gerry Stellenberg, Adam Preble + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/** @file pinproc.h + * @brief libpinproc, P-ROC Layer 1 API (Preliminary) + * + */ +#ifndef PINPROC_PINPROC_H +#define PINPROC_PINPROC_H +#if !defined(__GNUC__) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +/* + * 3rd party "stdint.h" replacement available for Visual C++ before version 2010. + * http://en.wikipedia.org/wiki/Stdint.h#External_links + * -> http://msinttypes.googlecode.com/svn/trunk/stdint.h + * Place inside the major include dir (e.g. %ProgramFiles%\Microsoft Visual Studio\VC98\INCLUDE) + */ +#include + +/** @cond */ +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the pinproc_EXPORTS +// symbol defined on the command line. This symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// PINPROC_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#undef PINPROC_API + +#ifdef PINPROC_DLL // Using or Building PinPROC DLL (definition defined manually) + #ifdef pinproc_EXPORTS // Building PinPROC DLL (definition created by CMake or defined manually) + #define PINPROC_API __declspec(dllexport) + #else + #define PINPROC_API __declspec(dllimport) + #endif +#endif +// fallback for non-DLL usage and builds +#ifndef PINPROC_API + #define PINPROC_API +#endif + +#if defined(__cplusplus) + #define PINPROC_EXTERN_C_BEGIN extern "C" { + #define PINPROC_EXTERN_C_END } +#else + #define PINPROC_EXTERN_C_BEGIN + #define PINPROC_EXTERN_C_END +#endif + +PINPROC_EXTERN_C_BEGIN +/** @endcond */ + +// Types + +typedef int32_t bool_t; // FIXME: This needs better platform independence. + +typedef int32_t PRResult; /**< See: #kPRSuccess and #kPRFailure. */ +#define kPRSuccess (1) /**< Success value for #PRResult. */ +#define kPRFailure (0) /**< Failure value for #PRResult. */ + +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. */ + +typedef enum PRLogLevel { + kPRLogVerbose, + kPRLogInfo, + kPRLogWarning, + kPRLogError +} PRLogLevel; + +typedef void (*PRLogCallback)(PRLogLevel level, const char *text); /**< Function pointer type for a custom logging callback. See: PRLogSetCallback(). */ +PINPROC_API void PRLogSetCallback(PRLogCallback callback); /**< Replaces the default logging handler with the given callback function. */ + +PINPROC_API void PRLogSetLevel(PRLogLevel level); + +PINPROC_API const char *PRGetLastErrorText(); + +/** + * @defgroup device Device Creation & Deletion + * @{ + */ + +typedef enum PRMachineType { + kPRMachineInvalid = 0, + kPRMachineCustom = 1, + kPRMachineWPCAlphanumeric = 2, + kPRMachineWPC = 3, + kPRMachineWPC95 = 4, + kPRMachineSternWhitestar = 5, + kPRMachineSternSAM = 6, + kPRMachinePDB = 7, +} PRMachineType; + +// PRHandle Creation and Deletion + +PINPROC_API PRHandle PRCreate(PRMachineType machineType); /**< Create a new P-ROC device handle. Only one handle per device may be created. This handle must be destroyed with PRDelete() when it is no longer needed. Returns #kPRHandleInvalid if an error occurred. */ +PINPROC_API void PRDelete(PRHandle handle); /**< Destroys an existing P-ROC device handle. */ + +#define kPRResetFlagDefault (0) /**< Only resets state in memory and does not write changes to the device. */ +#define kPRResetFlagUpdateDevice (1) /**< Instructs PRReset() to update the device once it has reset the configuration to its defaults. */ + +/** + * @brief Resets internally maintained driver and switch rule structures. + * @param resetFlags Specify #kPRResetFlagDefault to only reset the configuration in host memory. #kPRResetFlagUpdateDevice will write the default configuration to the device, effectively disabling all drivers and switch rules. + */ +PINPROC_API PRResult PRReset(PRHandle handle, uint32_t resetFlags); + +/** @} */ // End of Device Creation & Deletion + +// I/O + +/** Flush all pending write data out to the P-ROC. */ +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); + +/** Read data from the P-ROC. */ +PINPROC_API PRResult PRReadData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer); + +// Manager +/** @defgroup Manager + * @{ + */ + +typedef struct PRManagerConfig { + bool_t reuse_dmd_data_for_aux; + bool_t invert_dipswitch_1; +} PRManagerConfig; + +/** Update Manager configuration */ +PINPROC_API PRResult PRManagerUpdateConfig(PRHandle handle, PRManagerConfig *managerConfig); + +// Drivers +/** @defgroup drivers Driver Manipulation + * @{ + */ + +#define kPRDriverGroupsMax (26) /**< Number of available driver groups. */ +#define kPRDriverCount (256) /**< Total number of drivers */ + +#define kPRDriverAuxCmdOutput (2) +#define kPRDriverAuxCmdDelay (1) +#define kPRDriverAuxCmdJump (0) + +typedef struct PRDriverGlobalConfig { + bool_t enableOutputs; // Formerly enable_direct_outputs + bool_t globalPolarity; + bool_t useClear; + bool_t strobeStartSelect; + uint8_t startStrobeTime; + uint8_t matrixRowEnableIndex1; + uint8_t matrixRowEnableIndex0; + bool_t activeLowMatrixRows; + bool_t encodeEnables; + bool_t tickleSternWatchdog; + bool_t watchdogExpired; + bool_t watchdogEnable; + uint16_t watchdogResetTime; +} PRDriverGlobalConfig; + +typedef struct PRDriverGroupConfig { + uint8_t groupNum; + uint16_t slowTime; + uint8_t enableIndex; + uint8_t rowActivateIndex; + uint8_t rowEnableSelect; + bool_t matrixed; + bool_t polarity; + bool_t active; + bool_t disableStrobeAfter; +} PRDriverGroupConfig; + +typedef struct PRDriverState { + uint16_t driverNum; + uint8_t outputDriveTime; + bool_t polarity; + bool_t state; + bool_t waitForFirstTimeSlot; + uint32_t timeslots; + uint8_t patterOnTime; + uint8_t patterOffTime; + bool_t patterEnable; + bool_t futureEnable; +} PRDriverState; + +typedef struct PRDriverAuxCommand { + bool_t active; + bool_t muxEnables; + uint8_t command; + uint8_t enables; + uint8_t extraData; + uint8_t data; + uint16_t delayTime; + uint8_t jumpAddr; +} PRDriverAuxCommand; + +/** Update registers for the global driver configuration. */ +PINPROC_API PRResult PRDriverUpdateGlobalConfig(PRHandle handle, PRDriverGlobalConfig *driverGlobalConfig); + +PINPROC_API PRResult PRDriverGetGroupConfig(PRHandle handle, uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig); +/** Update registers for the given driver group configuration. */ +PINPROC_API PRResult PRDriverUpdateGroupConfig(PRHandle handle, PRDriverGroupConfig *driverGroupConfig); + +PINPROC_API PRResult PRDriverGetState(PRHandle handle, uint8_t driverNum, PRDriverState *driverState); +/** + * @brief Sets the state of the given driver (lamp or coil). + */ +PINPROC_API PRResult PRDriverUpdateState(PRHandle handle, PRDriverState *driverState); +/** + * @brief Loads the driver defaults for the given machine type. + * + * PRReset() calls this function internally; this function is useful for basing custom driver settings off of the defaults for a particular machine. + * @note This function does not update the P-ROC hardware, only the internal data structures. Use PRDriverGetGlobalConfig() and PRDriverGetGroupConfig() to retrieve the settings. + */ +PINPROC_API PRResult PRDriverLoadMachineTypeDefaults(PRHandle handle, PRMachineType machineType); + +// Driver Group Helper functions: + +/** + * Disables (turns off) the given driver group. + * This function is provided for convenience. See PRDriverGroupDisable() for a full description. + */ +PINPROC_API PRResult PRDriverGroupDisable(PRHandle handle, uint8_t groupNum); +// Driver Helper functions: + +/** + * Disables (turns off) the given driver. + * This function is provided for convenience. See PRDriverStateDisable() for a full description. + */ +PINPROC_API PRResult PRDriverDisable(PRHandle handle, uint8_t driverNum); +/** + * Pulses the given driver for a number of milliseconds. + * This function is provided for convenience. See PRDriverStatePulse() for a full description. + */ +PINPROC_API PRResult PRDriverPulse(PRHandle handle, uint8_t driverNum, uint8_t milliseconds); +/** + * Pulses the given driver for a number of milliseconds when the hardware reaches a specific timestamp. + * This function is provided for convenience. See PRDriverStatePulse() for a full description. + */ +PINPROC_API PRResult PRDriverFuturePulse(PRHandle handle, uint8_t driverNum, uint8_t milliseconds, uint32_t futureTime); +/** + * Assigns a repeating schedule to the given driver. + * This function is provided for convenience. See PRDriverStateSchedule() for a full description. + */ +PINPROC_API PRResult PRDriverSchedule(PRHandle handle, uint8_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool_t now); +/** + * Assigns a pitter-patter schedule (repeating on/off) to the given driver. + * This function is provided for convenience. See PRDriverStatePatter() for a full description. + */ +PINPROC_API PRResult PRDriverPatter(PRHandle handle, uint8_t driverNum, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t originalOnTime, bool_t now); +/** + * Assigns a pitter-patter schedule (repeating on/off) to the given driver on for the given duration. + * This function is provided for convenience. See PRDriverStatePulsedPatter() for a full description. + */ +PINPROC_API PRResult PRDriverPulsedPatter(PRHandle handle, uint8_t driverNum, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t originalOnTime, bool_t now); +/** + * Prepares an Aux Command to drive the Aux bus. + * This function is provided for convenience. + */ +PINPROC_API void PRDriverAuxPrepareOutput(PRDriverAuxCommand *auxCommand, uint8_t data, uint8_t extraData, uint8_t enables, bool_t muxEnables, uint16_t delayTime); +/** + * Prepares an Aux Command to delay the Aux logic. + * This function is provided for convenience. + */ +PINPROC_API void PRDriverAuxPrepareDelay(PRDriverAuxCommand *auxCommand, uint16_t delayTime); +/** + * Prepares an Aux Command to have the Aux memory pointer jump to a new address. + * This function is provided for convenience. + */ +PINPROC_API void PRDriverAuxPrepareJump(PRDriverAuxCommand *auxCommand, uint8_t jumpAddr); +/** + * Prepares a disabled Aux Command. + * This function is provided for convenience. + */ +PINPROC_API void PRDriverAuxPrepareDisable(PRDriverAuxCommand *auxCommand); + +/** Tickle the watchdog timer. */ +PINPROC_API PRResult PRDriverWatchdogTickle(PRHandle handle); + +/** + * Changes the given #PRDriverGroupConfig to reflect a disabled group. + * @note The driver group config structure must be applied using PRDriverUpdateGroupConfig() to have any effect. + */ +PINPROC_API void PRDriverGroupStateDisable(PRDriverGroupConfig *driverGroup); +/** + * Changes the given #PRDriverState to reflect a disabled state. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. + */ +PINPROC_API void PRDriverStateDisable(PRDriverState *driverState); +/** + * Changes the given #PRDriverState to reflect a pulse state. + * @param milliseconds Number of milliseconds to pulse the driver for. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. + */ +PINPROC_API void PRDriverStatePulse(PRDriverState *driverState, uint8_t milliseconds); +/** + * Changes the given #PRDriverState to reflect a future scheduled pulse state. + * @param milliseconds Number of milliseconds to pulse the driver for. + * @param futureTime Value indicating at which HW timestamp the pulse should occur. Currently only the low 10-bits are used. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. + */ +PINPROC_API void PRDriverStateFuturePulse(PRDriverState *driverState, uint8_t milliseconds, uint32_t futureTime); +/** + * Changes the given #PRDriverState to reflect a scheduled state. + * Assigns a repeating schedule to the given driver. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. + */ +PINPROC_API void PRDriverStateSchedule(PRDriverState *driverState, uint32_t schedule, uint8_t cycleSeconds, bool_t now); +/** + * @brief Changes the given #PRDriverState to reflect a pitter-patter schedule state. + * Assigns a pitter-patter schedule (repeating on/off) to the given driver. + * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. + * + * Use originalOnTime to pulse the driver for a number of milliseconds before the pitter-patter schedule begins. + */ +PINPROC_API void PRDriverStatePatter(PRDriverState *driverState, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t originalOnTime, bool_t now); + +/** + * @brief Changes the given #PRDriverState to reflect a pitter-patter schedule state. + * Just like the regular Patter above, but PulsePatter only drives the patter + * scheduled for the given number of milliseconds before disabling the driver. + */ +PINPROC_API void PRDriverStatePulsedPatter(PRDriverState *driverState, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t patterTime, bool_t now); + +/** + * Write Aux Port commands into the Aux Port command memory. + */ + +PINPROC_API PRResult PRDriverAuxSendCommands(PRHandle handle, PRDriverAuxCommand * commands, uint8_t numCommands, uint8_t startingAddr); + +/** + * @brief Converts a coil, lamp, switch, or GI string into a P-ROC driver number. + * The following formats are accepted: Cxx (coil), Lxx (lamp), Sxx (matrix switch), SFx (flipper grounded switch), or SDx (dedicated grounded switch). + * If the string does not match this format it will be converted into an integer using atoi(). + */ +PINPROC_API uint16_t PRDecode(PRMachineType machineType, const char *str); + +/** @} */ // End of Drivers + +// Switches + +/** @defgroup switches Switches and Events + * @{ + */ + +// Events +// Closed == 0, Open == 1 +typedef enum PREventType { + kPREventTypeInvalid = 0, + kPREventTypeSwitchClosedDebounced = 1, /**< The switch has gone from open to closed and the signal has been debounced. */ + kPREventTypeSwitchOpenDebounced = 2, /**< The switch has gone from closed to open and the signal has been debounced. */ + kPREventTypeSwitchClosedNondebounced = 3, /**< The switch has gone from open to closed and the signal has not been debounced. */ + kPREventTypeSwitchOpenNondebounced = 4, /**< The switch has gone from closed to open and the signal has not been debounced. */ + kPREventTypeDMDFrameDisplayed = 5, /**< A DMD frame has been displayed. */ + kPREventTypeBurstSwitchOpen = 6, /**< A burst switch has gone from closed to open. */ + kPREventTypeBurstSwitchClosed = 7, /**< A burst switch has gone from open to closed. */ + kPREventTypeAccelerometerX = 8, /**< New value from the accelerometer - X plane. */ + kPREventTypeAccelerometerY = 9, /**< New value from the accelerometer - Y plane. */ + kPREventTypeAccelerometerZ = 10, /**< New value from the accelerometer - Z plane. */ + kPREventTypeAccelerometerIRQ = 11, /**< New interrupt from the accelerometer */ + kPREventTypetLast = kPREventTypeSwitchOpenNondebounced +} PREventType; + +typedef struct PREvent { + PREventType type; /**< The type of event that has occurred. Usually a switch event at this point. */ + uint32_t value; /**< For switch events, the switch number that has changed. For DMD events, the frame buffer that was just displayed. */ + uint32_t time; /**< Time (in milliseconds) that this event occurred. */ +} PREvent; + +/** Get all of the available events that have been received. + * \return Number of events returned; -1 if an error occurred. + */ +PINPROC_API int PRGetEvents(PRHandle handle, PREvent *eventsOut, int maxEvents); + + +#define kPRSwitchPhysicalFirst (0) /**< Switch number of the first physical switch. */ +#define kPRSwitchPhysicalLast (255) /**< Switch number of the last physical switch. */ +#define kPRSwitchNeverDebounceFirst (192) /**< Switch number of the first switch that doesn't need to debounced. */ +#define kPRSwitchNeverDebounceLast (255) /**< Switch number of the last switch that doesn't need to be debounce. */ +#define kPRSwitchCount (256) +#define kPRSwitchRulesCount (kPRSwitchCount << 2) /**< Total number of available switch rules. */ + +typedef struct PRSwitchConfig { + bool_t clear; // Drive the clear output + bool_t hostEventsEnable; // Drive the clear output + bool_t use_column_9; // Use switch matrix column 9 + bool_t use_column_8; // Use switch matrix column 8 + uint8_t directMatrixScanLoopTime; // milliseconds + uint8_t pulsesBeforeCheckingRX; + uint8_t inactivePulsesAfterBurst; + uint8_t pulsesPerBurst; + uint8_t pulseHalfPeriodTime; // milliseconds +} PRSwitchConfig; + +typedef struct PRSwitchRule { + bool_t reloadActive; /**< If true, any associated driver changes resulting from this rule will only happen at most once every 256ms. */ + bool_t notifyHost; /**< If true this switch change event will provided to the user via PRGetEvents(). */ +} PRSwitchRule; + +/** Update the switch controller configurion registers */ +PINPROC_API PRResult PRSwitchUpdateConfig(PRHandle handle, PRSwitchConfig *switchConfig); + +/** + * @brief Configures the handling of switch rules within P-ROC. + * + * P-ROC's switch rule system allows the user to decide which switch events are returned to software, + * as well as optionally linking one or more driver state changes to rules to create immediate feedback (such as in pop bumpers). + * + * For instance, P-ROC can provide debounced switch events for a flipper button so software can apply lange change behavior. + * This is accomplished by configuring the P-ROC with a switch rule for the flipper button and then receiving the events via the PRGetEvents() call. + * The same switch can also be configured with a non-debounced rule to fire a flipper coil. + * Multiple driver changes can be tied to a single switch state transition to create more complicated effects: a slingshot + * switch that fires the slingshot coil, a flash lamp, and a score event. + * + * P-ROC holds four different switch rules for each switch: closed to open and open to closed, each with a debounced and non-debounced versions: + * - #kPREventTypeSwitchOpenDebounced + * - #kPREventTypeSwitchClosedDebounced + * - #kPREventTypeSwitchOpenNondebounced + * - #kPREventTypeSwitchClosedNondebounced + * + * @section Examples + * + * Configuring a basic switch rule to simply notify software via PRGetEvents() without affecting any coil/lamp drivers: + * @code + * PRSwitchRule rule; + * rule.notifyHost = true; + * PRSwitchUpdateRule(handle, switchNum, kPREventTypeSwitchOpenDebounced, &rule, NULL, 0); + * @endcode + * + * Configuring a pop bumper switch to pulse the coil and a flash lamp for 50ms each: + * @code + * // Configure a switch rule to fire the coil and flash lamp: + * PRSwitchRule rule; + * rule.notifyHost = false; + * PRDriverState drivers[2]; + * PRDriverGetState(handle, drvCoilPopBumper1, &drivers[0]); + * PRDriverGetState(handle, drvFlashLamp1, &drivers[1]); + * PRDriverStatePulse(&drivers[0], 50); + * PRDriverStatePulse(&drivers[1], 50); + * PRSwitchUpdateRule(handle, swPopBumper1, kPREventTypeSwitchClosedNondebounced, + * &rule, drivers, 2); + * // Now configure a switch rule to process scoring in software: + * rule.notifyHost = true; + * PRSwitchUpdateRule(handle, swPopBumper1, kPREventTypeSwitchClosedDebounced, + * &rule, NULL, 0); + * @endcode + * + * @param handle The P-ROC device handle. + * @param switchNum The index of the switch this configuration affects. + * @param eventType The switch rule for the specified switchNum to be configured. + * @param rule A pointer to the #PRSwitchRule structure describing how this state change should be handled. May not be NULL. + * @param linkedDrivers An array of #PRDriverState structures describing the driver state changes to be made when this switch rule is triggered. May be NULL if numDrivers is 0. + * @param numDrivers Number of elements in the linkedDrivers array. May be zero or more. + */ +PINPROC_API PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers, bool_t drive_outputs_now); + +/** Returns a list of PREventTypes describing the states of the requested number of switches */ +PINPROC_API PRResult PRSwitchGetStates(PRHandle handle, PREventType * switchStates, uint16_t numSwitches); + +/** @} */ // End of Switches & Events + +// DMD + +/** + * @defgroup dmd DMD Control + * @{ + */ +typedef struct PRDMDConfig { + uint8_t numRows; + uint16_t numColumns; + uint8_t numSubFrames; + uint8_t numFrameBuffers; + bool_t autoIncBufferWrPtr; + bool_t enableFrameEvents; + bool_t enable; + uint8_t rclkLowCycles[8]; + uint8_t latchHighCycles[8]; + uint16_t deHighCycles[8]; + uint8_t dotclkHalfPeriod[8]; +} PRDMDConfig; + +/** Sets the configuration registers for the DMD driver. */ +PINPROC_API int32_t PRDMDUpdateConfig(PRHandle handle, PRDMDConfig *dmdConfig); +/** Updates the DMD frame buffer with the given data. */ +PINPROC_API PRResult PRDMDDraw(PRHandle handle, uint8_t * dots); + +/** @} */ // End of DMD + + +// JTAG + +/** + * @defgroup jtag JTAG interface control + * @{ + */ + +typedef struct PRJTAGStatus { + bool_t commandComplete; + bool_t tdi; +} PRJTAGStatus; + +typedef struct PRJTAGOutputs { + bool_t tckMask; + bool_t tmsMask; + bool_t tdoMask; + bool_t tck; + bool_t tms; + bool_t tdo; +} PRJTAGOutputs; + +/** Force JTAG outputs (TCK, TDO, TMS) to specific values. Optionally toggle the clock when driving only TDO and/or TMS.*/ +PINPROC_API PRResult PRJTAGDriveOutputs(PRHandle handle, PRJTAGOutputs * jtagOutputs, bool_t toggleClk); +/** Store data to be shifted out on TDO */ +PINPROC_API PRResult PRJTAGWriteTDOMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdoData); +/** Shift stored TDO data onto the TDO pin, toggling TCK on every bit. */ +PINPROC_API PRResult PRJTAGShiftTDOData(PRHandle handle, uint16_t numBits, bool_t dataBlockComplete); +/** Get the contents of the TDI memory. */ +PINPROC_API PRResult PRJTAGReadTDIMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdiData); +/** Read the JTAG status register for the command complete bit and JTAG pin states. */ +PINPROC_API PRResult PRJTAGGetStatus(PRHandle handle, PRJTAGStatus * status); + +/** @} */ // End of JTAG + +// PD-LED + +/** + * @defgroup pdled PD-LED Control + * @{ + */ + + +typedef struct PRLED { + uint8_t boardAddr; + uint8_t LEDIndex; +} PRLED; + +typedef struct PRLEDRGB { + PRLED* pRedLED; + PRLED* pGreenLED; + PRLED* pBlueLED; +} PRLEDRGB; + +/** Sets the color of a given PRLED. */ +PINPROC_API PRResult PRLEDColor(PRHandle handle, PRLED * pLED, uint8_t color); +/** Sets the fade color on a given PRLED. */ +PINPROC_API PRResult PRLEDFadeColor(PRHandle handle, PRLED * pLED, uint8_t fadeColor); +/** Sets the fade color and rate on a given PRLED. Note: The rate will apply to any future PRLEDFadeColor or PRLEDRGBFadeColor calls on the same PD-LED board. */ +PINPROC_API PRResult PRLEDFade(PRHandle handle, PRLED * pLED, uint8_t fadeColor, uint16_t fadeRate); + +/** Sets the fade rate on a given board. Note: The rate will apply to any future PRLEDFadeColor or PRLEDRGBFadeColor calls on the same PD-LED board. */ +PINPROC_API PRResult PRLEDFadeRate(PRHandle handle, uint8_t boardAddr, uint16_t fadeRate); + +/** Sets the color of a given PRLEDRGB. */ +PINPROC_API PRResult PRLEDRGBColor(PRHandle handle, PRLEDRGB * pLED, uint32_t color); +/** Sets the fade color and rate on a given PRLEDRGB. Note: The rate will apply to any future PRLEDFadeColor or PRLEDRGBFadeColor calls on any of the referenced PD-LED boards. */ +PINPROC_API PRResult PRLEDRGBFade(PRHandle handle, PRLEDRGB * pLED, uint32_t fadeColor, uint16_t fadeRate); +/** Sets the fade color on a given PRLEDRGB. */ +PINPROC_API PRResult PRLEDRGBFadeColor(PRHandle handle, PRLEDRGB * pLED, uint32_t fadeColor); + + +/** @} */ // End of PD-LED + + +/** @cond */ +PINPROC_EXTERN_C_END +/** @endcond */ + +/** + * @mainpage libpinproc API Documentation + * + * This is the documentation for libpinproc, the P-ROC Layer 1 API. + */ + +#endif /* PINPROC_PINPROC_H */ diff --git a/debian/libpinproc-dev/usr/lib/libpinproc.so b/debian/libpinproc-dev/usr/lib/libpinproc.so new file mode 120000 index 0000000..7fcf201 --- /dev/null +++ b/debian/libpinproc-dev/usr/lib/libpinproc.so @@ -0,0 +1 @@ +libpinproc.so.2.0 \ No newline at end of file diff --git a/debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc b/debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc new file mode 100644 index 0000000..6c2eb66 --- /dev/null +++ b/debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=/usr +libdir=${prefix}/lib +includedir=${prefix}/include/p-roc + +Name: Pinproc +Description: P-ROC interface library +Version: 2.0 +Requires: +Libs: -L${libdir} -lpinproc +Cflags: -I${includedir} diff --git a/debian/libpinproc-dev/usr/share/doc/libpinproc-dev/changelog.Debian.gz b/debian/libpinproc-dev/usr/share/doc/libpinproc-dev/changelog.Debian.gz new file mode 100644 index 0000000000000000000000000000000000000000..412a8d039ca52dfc65b36b163d5aa6189c50d42c GIT binary patch literal 140 zcmV;70CWEziwFP!0000210~2g4#F@H1<*dH_$8aIaUxNKMN~+@0jQlYLP-+!C6{L8l$Y+_ALNA@<**09Lq2(BLC7NA?3_USn|ef}0oR utk}Q2m`{41-v6+|dIawL*uW9a+@K`4ovBM#R~6Reh>9OEM<2e20002}f= 2.14), libgcc1 (>= 1:4.1.1), libstdc++6 (>= 4.1.1) +misc:Depends= diff --git a/debian/libpinproc/DEBIAN/control b/debian/libpinproc/DEBIAN/control new file mode 100644 index 0000000..df8ee8d --- /dev/null +++ b/debian/libpinproc/DEBIAN/control @@ -0,0 +1,11 @@ +Package: libpinproc +Version: 0.1.0-1 +Architecture: amd64 +Maintainer: Jan Kantert +Installed-Size: 80 +Depends: libc6 (>= 2.14), libgcc1 (>= 1:4.1.1), libstdc++6 (>= 4.1.1) +Section: libs +Priority: optional +Homepage: https://github.com/jabdoa2/libpinproc +Description: libpinproc + Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic diff --git a/debian/libpinproc/DEBIAN/md5sums b/debian/libpinproc/DEBIAN/md5sums new file mode 100644 index 0000000..06e4041 --- /dev/null +++ b/debian/libpinproc/DEBIAN/md5sums @@ -0,0 +1,3 @@ +8c3c18eda463e90bb2faffb8c2d1315b usr/lib/libpinproc.so.2.0 +74322abf217a8f4e1d6f50d89a8a009c usr/share/doc/libpinproc/changelog.Debian.gz +9b8881ce99456b7e1d090ab95820ff1f usr/share/doc/libpinproc/copyright diff --git a/debian/libpinproc/DEBIAN/postinst b/debian/libpinproc/DEBIAN/postinst new file mode 100755 index 0000000..379f1fa --- /dev/null +++ b/debian/libpinproc/DEBIAN/postinst @@ -0,0 +1,7 @@ +#!/bin/sh +set -e +# Automatically added by dh_makeshlibs +if [ "$1" = "configure" ]; then + ldconfig +fi +# End automatically added section diff --git a/debian/libpinproc/DEBIAN/postrm b/debian/libpinproc/DEBIAN/postrm new file mode 100755 index 0000000..3e73d38 --- /dev/null +++ b/debian/libpinproc/DEBIAN/postrm @@ -0,0 +1,7 @@ +#!/bin/sh +set -e +# Automatically added by dh_makeshlibs +if [ "$1" = "remove" ]; then + ldconfig +fi +# End automatically added section diff --git a/debian/libpinproc/DEBIAN/shlibs b/debian/libpinproc/DEBIAN/shlibs new file mode 100644 index 0000000..1f60a0f --- /dev/null +++ b/debian/libpinproc/DEBIAN/shlibs @@ -0,0 +1 @@ +libpinproc 2.0 libpinproc diff --git a/debian/libpinproc/usr/lib/libpinproc.so.2.0 b/debian/libpinproc/usr/lib/libpinproc.so.2.0 new file mode 100644 index 0000000000000000000000000000000000000000..af7d8fbc3d44fb6a523cc37cc4364de5609f467f GIT binary patch literal 51360 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 PA9F_+{38x}d>r}%4I9?O literal 0 HcmV?d00001 diff --git a/debian/libpinproc/usr/share/doc/libpinproc/changelog.Debian.gz b/debian/libpinproc/usr/share/doc/libpinproc/changelog.Debian.gz new file mode 100644 index 0000000000000000000000000000000000000000..412a8d039ca52dfc65b36b163d5aa6189c50d42c GIT binary patch literal 140 zcmV;70CWEziwFP!0000210~2g4#F@H1<*dH_$8aIaUxNKMN~+@0jQlYLP-+!C6{L8l$Y+_ALNA@<**09Lq2(BLC7NA?3_USn|ef}0oR utk}Q2m`{41-v6+|dIawL*uW9a+@K`4ovBM#R~6Reh>9OEM<2e20002}f Date: Wed, 29 May 2019 14:06:19 -0700 Subject: [PATCH 04/38] changes for latest yaml-cpp and CPP 11 --- CMakeLists.txt | 3 ++- examples/pinproctest/pinproctest.cpp | 9 ++------- examples/pinproctest/switches.cpp | 24 +++++++++++------------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0853ac4..54213b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,12 +13,13 @@ if(POLICY CMP0015) cmake_policy(SET CMP0015 OLD) endif() - ### ### Project settings ### project(PINPROC) +set (CMAKE_CXX_STANDARD 11) + set(PINPROC_VERSION_MAJOR "2") set(PINPROC_VERSION_MINOR "0") set(PINPROC_VERSION "${PINPROC_VERSION_MAJOR}.${PINPROC_VERSION_MINOR}") diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 1729a57..7800930 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -46,12 +46,8 @@ PRResult LoadConfiguration(YAML::Node& yamlDoc, const char *yamlFilePath) fprintf(stderr, "YAML file not found: %s\n", yamlFilePath); return kPRFailure; } - YAML::Parser parser(fin); - while(parser) - { - parser.GetNextDocument(yamlDoc); - } + yamlDoc = YAML::Load(fin); } // catch (YAML::ParserException& ex) // { @@ -341,8 +337,7 @@ int main(int argc, const char **argv) return 1; } - std::string machineTypeString; - yamlDoc["PRGame"]["machineType"] >> machineTypeString; + std::string machineTypeString = yamlDoc["PRGame"]["machineType"].as(); if (machineTypeString == "wpc") machineType = kPRMachineWPC; else if (machineTypeString == "wpc95") diff --git a/examples/pinproctest/switches.cpp b/examples/pinproctest/switches.cpp index 5b19132..491def6 100644 --- a/examples/pinproctest/switches.cpp +++ b/examples/pinproctest/switches.cpp @@ -142,36 +142,34 @@ 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) + for (YAML::const_iterator flippersIt = flippers.begin(); flippersIt != flippers.end(); ++flippersIt) { int swNum, coilMain, coilHold; - std::string flipperName; - *flippersIt >> flipperName; + std::string flipperName = flippersIt->as(); 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()); + numStr = yamlDoc[kSwitchesSection][flipperName][kNumberField].as(); swNum = PRDecode(machineType, numStr.c_str()); + numStr = yamlDoc[kCoilsSection][flipperName + "Main"][kNumberField].as(); coilMain = PRDecode(machineType, numStr.c_str()); + numStr = yamlDoc[kCoilsSection][flipperName + "Hold"][kNumberField].as(); 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()); + numStr = yamlDoc[kSwitchesSection][flipperName][kNumberField].as(); swNum = PRDecode(machineType, numStr.c_str()); + numStr = yamlDoc[kCoilsSection][flipperName + "Main"][kNumberField].as(); 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) + for (YAML::const_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()); + std::string bumperName = bumpersIt->as(); + numStr = yamlDoc[kSwitchesSection][bumperName][kNumberField].as(); swNum = PRDecode(machineType, numStr.c_str()); + numStr = yamlDoc[kCoilsSection][bumperName][kNumberField].as(); coilNum = PRDecode(machineType, numStr.c_str()); ConfigureBumperRule (proc, swNum, coilNum, kBumperPulseTime); } } From 5bb2146d3e655515c08e41d184f2a6bcce4667d4 Mon Sep 17 00:00:00 2001 From: Jan Kantert Date: Wed, 8 Jan 2020 20:52:51 +0100 Subject: [PATCH 05/38] do not flush after every write data call --- src/PRDevice.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index f3444ed..8a39505 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -1179,10 +1179,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; @@ -1207,7 +1203,7 @@ PRResult PRDevice::WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, in buffer = (uint32_t *)malloc((numWriteWords * 4) + 4); buffer[0] = CreateBurstCommand(moduleSelect, startingAddr, numWriteWords); memcpy(buffer+1, writeBuffer, numWriteWords * 4); - res = WriteData(buffer, numWriteWords + 1); + res = PrepareWriteData(buffer, numWriteWords + 1); free (buffer); return res; } From 031109f5ecabca594ee934423d4183b82b147f27 Mon Sep 17 00:00:00 2001 From: Jan Kantert Date: Sat, 22 Feb 2020 13:07:29 +0100 Subject: [PATCH 06/38] add new PRWriteDataUnbuffered to libpinproc --- include/pinproc.h | 3 + src/PRDevice.cpp | 227 ++++++++++++++++++++++++---------------------- src/PRDevice.h | 5 +- src/pinproc.cpp | 28 +++--- 4 files changed, 143 insertions(+), 120 deletions(-) diff --git a/include/pinproc.h b/include/pinproc.h index 521334f..60c02e7 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -138,6 +138,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/src/PRDevice.cpp b/src/PRDevice.cpp index 8a39505..5487f66 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 @@ -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) { @@ -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: @@ -219,7 +219,7 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) //fprintf(stderr, "\nBurst event"); 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; } @@ -324,7 +324,7 @@ PRResult PRDevice::DriverUpdateState(PRDriverState *driverState) 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)); @@ -347,10 +347,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 +361,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 +380,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 +439,7 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint return kPRSuccess; } - + memset(&driverGlobalConfig, 0x00, sizeof(PRDriverGlobalConfig)); for (i = 0; i < kPRDriverCount; i++) { @@ -448,7 +448,7 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint driver->driverNum = i; driver->polarity = mappedDriverGroupPolarity[i/8]; DEBUG(PRLog(kPRLogInfo,"\nDriver Polarity for Driver: %d is %x.", i,driver->polarity)); - if (resetFlags & kPRResetFlagUpdateDevice) + if (resetFlags & kPRResetFlagUpdateDevice) res = DriverUpdateState(driver); } for (i = 0; i < kPRDriverGroupsMax; i++) @@ -458,11 +458,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,7 +475,7 @@ 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)); @@ -484,7 +484,7 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint 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,7 +496,7 @@ 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)); @@ -517,7 +517,7 @@ 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)); @@ -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); @@ -599,11 +599,11 @@ PRResult PRDevice::DriverWatchdogTickle() const int burstWords = 2; uint32_t burst[burstWords]; int32_t rc; - + rc = CreateWatchdogConfigBurst(burst, driverGlobalConfig.watchdogExpired, driverGlobalConfig.watchdogEnable, driverGlobalConfig.watchdogResetTime); - + return PrepareWriteData(burst, burstWords); } @@ -635,8 +635,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 +646,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 +741,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR DEBUG(PRLog(kPRLogError, "Failed to disable.\n")); return res; } - + linkedDrivers--; numDrivers--; } @@ -762,7 +762,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR // Write the rule: res = PrepareWriteData(burst, burstSize); } - + return res; } @@ -775,7 +775,7 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit // 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,36 +783,36 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit if (chip_id == P_ROC_CHIP_ID) { - rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, + rc = 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, + rc = 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, + rc = 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, + rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, P3_ROC_SWITCH_CTRL_STATE_BASE_ADDR + i, 1); - rc = RequestData(P_ROC_BUS_SWITCH_CTRL_SELECT, + rc = 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) @@ -820,7 +820,7 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit } // 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++) @@ -993,8 +993,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 +1016,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 +1074,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,10 +1088,10 @@ 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])); rc = kPRFailure; } @@ -1114,7 +1114,7 @@ PRResult PRDevice::VerifyChipID() 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")); @@ -1132,7 +1132,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; } @@ -1195,7 +1195,7 @@ PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords) } } -PRResult PRDevice::WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) +PRResult PRDevice::WriteDataRawUnbuffered(uint32_t moduleSelect, uint32_t startingAddr, int32_t numWriteWords, uint32_t * writeBuffer) { PRResult res; uint32_t * buffer; @@ -1208,6 +1208,19 @@ PRResult PRDevice::WriteDataRaw(uint32_t moduleSelect, uint32_t startingAddr, in return res; } +PRResult PRDevice::WriteDataRaw(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 = WriteData(buffer, numWriteWords + 1); + free (buffer); + return res; +} + PRResult PRDevice::ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer) { uint32_t rc; @@ -1220,7 +1233,7 @@ PRResult PRDevice::ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int // 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) @@ -1228,15 +1241,15 @@ 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; } @@ -1282,7 +1295,7 @@ PRResult PRDevice::FlushReadBuffer() numBytes = CollectReadData(); k = 0; DEBUG(PRLog(kPRLogError, "Flushing Read Buffer: %d bytes trashed\n", numBytes)); - + //while (k < numBytes) { // rc = ReadData(rd_buffer, 1); // k++; diff --git a/src/PRDevice.h b/src/PRDevice.h index 69a25f5..ca1e869 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); @@ -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/pinproc.cpp b/src/pinproc.cpp index 3e01757..c59313c 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); @@ -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: From ba938e24250fb8e8876300ee01ed80aff745cead Mon Sep 17 00:00:00 2001 From: Jan Kantert Date: Tue, 12 May 2020 21:11:03 +0200 Subject: [PATCH 07/38] add more error strings --- src/PRDevice.cpp | 22 +++++++-- src/PRHardware.cpp | 112 ++++++++++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 57 deletions(-) diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 5487f66..13ae396 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -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 @@ -816,7 +816,9 @@ PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwit { 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. @@ -851,7 +853,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) @@ -1093,6 +1099,7 @@ PRResult PRDevice::VerifyChipID() DEBUG(PRLog(kPRLogError, "Error in VerifyID(): Dumping buffer\n")); 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,7 +1117,8 @@ 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; } } @@ -1118,6 +1126,7 @@ PRResult PRDevice::VerifyChipID() { // 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); @@ -1253,7 +1262,11 @@ PRResult PRDevice::ReadDataRaw(uint32_t moduleSelect, uint32_t startingAddr, int } return kPRSuccess; } - else return kPRFailure; + else + { + PRSetLastErrorText("Response length did not match."); + return kPRFailure; + } } @@ -1282,6 +1295,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)); 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)); From 75bdb61b02d00b020cd8196f4e561d14535edefb Mon Sep 17 00:00:00 2001 From: Jan Kantert Date: Tue, 12 May 2020 21:16:23 +0200 Subject: [PATCH 08/38] fix compiler warnings --- src/PRDevice.cpp | 58 +++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 13ae396..d6d43fe 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -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,7 +318,6 @@ 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. @@ -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); @@ -598,11 +594,10 @@ 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); } @@ -768,7 +763,6 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR PRResult PRDevice::SwitchGetStates( PREventType * switchStates, uint16_t numSwitches ) { - uint32_t rc; uint32_t stateWord, debounceWord; uint8_t i, j; PREventType eventType; @@ -783,25 +777,25 @@ 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) { - 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); } } @@ -1232,11 +1226,10 @@ 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 @@ -1304,10 +1297,9 @@ 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) { @@ -1343,7 +1335,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(); @@ -1355,7 +1347,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) From 3e2aecdb6435624734647fa85220b8a2cb0c2df4 Mon Sep 17 00:00:00 2001 From: Jimmy Lipham Date: Sat, 16 May 2020 14:55:20 -0500 Subject: [PATCH 09/38] Adding cross-compilation support --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d858b58..b0ac065 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,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,8 +70,13 @@ if(VERBOSE) endif() # use -DEXTRA_INC=";" and -DEXTRA_LINK=";" +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) +endif() set(YAML_CPP_LIB "yaml-cpp") set(YAML_CPP_LIB_DBG "${YAML_CPP_LIB}") From 31e7b0b784defb67457597ff8dbb66e7b509bdac Mon Sep 17 00:00:00 2001 From: p3 Date: Fri, 22 May 2020 12:54:19 -0500 Subject: [PATCH 10/38] Parsing of board ID for P3-ROC and P-ROC are now different. Both read from address 3, but P3-ROC is bits 11:8, and P-ROC is bits 7:4. --- utils/pinprocfw/pinprocfw.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index 0bff8a2..794a65d 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -2176,10 +2176,20 @@ int checkPROCFile() { PRReadData(proc, 0, 0, 4, readdata); board_id = readdata[0]; board_rev = readdata[3]; - board_rev = (board_rev & 0x80) >> 7 | - (board_rev & 0x40) >> 5 | - (board_rev & 0x20) >> 3 | - (board_rev & 0x10) >> 1; + if (board_id == P3_ROC_CHIP_ID) { + board_rev = (board_rev & 0x800) >> 11 | + (board_rev & 0x400) >> 10 | + (board_rev & 0x200) >> 9 | + (board_rev & 0x100) >> 8; + fprintf(stderr, "\nReading P3-ROC board_rev: %d", board_rev); + } + else { + board_rev = (board_rev & 0x80) >> 7 | + (board_rev & 0x40) >> 6 | + (board_rev & 0x20) >> 5 | + (board_rev & 0x10) >> 4; + fprintf(stderr, "\nReading P-ROC board_rev: %d", board_rev); + } 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); @@ -2197,6 +2207,14 @@ int checkPROCFile() { return 0; } else fprintf(stderr, "\nBoard ID verified"); + + if (board_rev > max_board_rev) { + fprintf(stderr, "\nERROR: board_rev %d > max_board_rev %d", board_rev, max_board_rev); + } + if (board_rev < min_board_rev) { + fprintf(stderr, "\nERROR: board_rev < min_board_rev"); + } + 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); return 0; From b99197953ac961fde7017dfd688d85f4ce1ae8c3 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Tue, 23 Jun 2020 22:33:19 -0700 Subject: [PATCH 11/38] build: allow for setting EXTRA_INC and EXTRA_LINK Can now actually set these with the -D command line option. --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54213b8..6f37870 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,8 @@ 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 ;") include_directories(${PINPROC_SOURCE_DIR}/include ${EXTRA_INC} /usr/local/include) link_directories(${EXTRA_LINK} /usr/local/lib) From fed1d7e39850e1612f2d4f1ebdd6d5019849b23b Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Tue, 23 Jun 2020 22:34:13 -0700 Subject: [PATCH 12/38] pinprocfw: add missing return to verifyP3ROCImage() --- utils/pinprocfw/pinprocfw.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index 0bff8a2..a06ae8f 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -2051,6 +2051,8 @@ int verifyP3ROCImage() } XSVFDBG_PRINTF( 0, "\n\nSUCCESS - Operation completed successfully. Cycle P3-ROC power to activate any changes.\n" ); + + return 1; } void writeP3ROCImage() From f44cacd54e050b06272cae26b00d7c6de551e372 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Tue, 23 Jun 2020 22:35:22 -0700 Subject: [PATCH 13/38] pinprocfw: use correct checkPROCFile() return type Quiets a compiler warning, and matches the `file_board_id` declaration. --- utils/pinprocfw/pinprocfw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index a06ae8f..c062f40 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -2142,7 +2142,7 @@ int processFile() return iErrorCode; } -int checkPROCFile() { +uint32_t checkPROCFile() { uint32_t checksum=0, file_checksum, file_board_id, header_checksum; unsigned char data; int i=0,file_i=0; From 60c6859c35c16f4986b90494b0e1e373d20adbb1 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Tue, 23 Jun 2020 22:36:20 -0700 Subject: [PATCH 14/38] build: allow relative paths in LINK_DIRECTORIES --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f37870..75b7ac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,11 @@ if(POLICY CMP0015) cmake_policy(SET CMP0015 OLD) endif() +# allow relative paths in LINK_DIRECTORIES +if(POLICY CMP0081) + cmake_policy(SET CMP0081 OLD) +endif() + ### ### Project settings ### From 213c69dfc1ec588a8811cad03f79a4bf189cf6b5 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Tue, 23 Jun 2020 22:41:05 -0700 Subject: [PATCH 15/38] build: make non-MSVC executables statically linked When building in MSYS2/MinGW64, I was missing multiple DLLs necessary to run the EXE files from a command prompt. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75b7ac9..b949ae3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,6 +169,9 @@ if(MSVC) set(YAML_CPP_LIB "${CMAKE_STATIC_LIBRARY_PREFIX}${YAML_CPP_LIB}${LIB_RT_SUFFIX}") set(YAML_CPP_LIB_DBG "${YAML_CPP_LIB}d") endif() +else() + # make sure executable files are standalone + SET(CMAKE_EXE_LINKER_FLAGS "-static") endif() From 26600a3eafe4c3a59afcde556cee93b49d3fece8 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Tue, 23 Jun 2020 22:56:19 -0700 Subject: [PATCH 16/38] doc: yaml-cpp now hosted on GitHub --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 252acc1..ff796b8 100644 --- a/README.markdown +++ b/README.markdown @@ -12,7 +12,7 @@ libpinproc requires: - [libftdi-0.16](http://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: +The pinproctest example requires [yaml-cpp](https://github.com/jbeder/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: sudo cp lib/libyaml-cpp.a /usr/local/lib/ sudo mkdir /usr/local/include/yaml-cpp From acd55d6d69a64b0ac4e59fc24b11da0a55621b74 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Wed, 24 Jun 2020 10:00:00 -0700 Subject: [PATCH 17/38] pinprocfw: call PRDelete() even if file doesn't parse Previously we'd fail to call PRDelete(), which may have been causing some of my problems with attempting to re-connect to the P-ROC. I assume PRDelete() closes out the connection in some way. --- utils/pinprocfw/pinprocfw.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index c062f40..a29d863 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -2136,9 +2136,6 @@ int processFile() endClock = clock(); fclose( in ); - // Destroy the P-ROC device handle: - PRDelete(proc); - proc = kPRHandleInvalid; return iErrorCode; } @@ -2306,7 +2303,10 @@ int main( int argc, char** argv ) break; default: break; - } + } + // Destroy the P-ROC device handle created by openPROC() + PRDelete(proc); + proc = kPRHandleInvalid; } } } From a14aaef0b2de2edc6f5bf7d4e10ddcf99a03c879 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Wed, 24 Jun 2020 10:01:00 -0700 Subject: [PATCH 18/38] pinprocfw: always print an error if file parsing fails --- utils/pinprocfw/pinprocfw.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index a29d863..039ebda 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -2302,6 +2302,7 @@ int main( int argc, char** argv ) processP3ROCFile(); break; default: + fprintf(stderr, "Failed to parse file.\n"); break; } // Destroy the P-ROC device handle created by openPROC() From 804eebf180c41eb671bc3fdf500194acba6b1e94 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Wed, 24 Jun 2020 18:21:34 -0700 Subject: [PATCH 19/38] Revert "dont compile examples" This reverts commit d681054a1d9ffada4228523ecb45da8487c28f8a. --- CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09fcc54..81661fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -252,18 +252,18 @@ if(PINPROC_BUILD_TOOLS) # Create a target for the test tool #TODO: use add_subdirectory() and separate CMakeLists.txt (like yaml-cpp) # see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_subdirectory -#add_executable(pinproctest -# examples/pinproctest/pinproctest.cpp -# examples/pinproctest/drivers.cpp -# examples/pinproctest/dmd.cpp -# examples/pinproctest/switches.cpp -# examples/pinproctest/alphanumeric.cpp -#) -#target_link_libraries(pinproctest -# pinproc -# optimized ${YAML_CPP_LIB} -# debug ${YAML_CPP_LIB_DBG} -#) +add_executable(pinproctest + examples/pinproctest/pinproctest.cpp + examples/pinproctest/drivers.cpp + examples/pinproctest/dmd.cpp + examples/pinproctest/switches.cpp + examples/pinproctest/alphanumeric.cpp +) +target_link_libraries(pinproctest + pinproc + optimized ${YAML_CPP_LIB} + debug ${YAML_CPP_LIB_DBG} +) # Create a target for the firmware tool #TODO: use add_subdirectory() and separate CMakeLists.txt (like yaml-cpp) From b3191b3ad121f7c289bd497cc6e4741e2b7bacf7 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Wed, 24 Jun 2020 18:22:00 -0700 Subject: [PATCH 20/38] Revert "add debian control files" This reverts commit 69bd547f0efe4c2c289feb5c3a730789fe1a880c. --- debian/changelog | 5 - debian/compat | 1 - debian/control | 21 - debian/copyright | 13 - debian/docs | 0 debian/files | 2 - debian/libpinproc-dev.debhelper.log | 24 - debian/libpinproc-dev.dirs | 2 - debian/libpinproc-dev.install | 3 - debian/libpinproc-dev.substvars | 1 - debian/libpinproc-dev/DEBIAN/control | 12 - debian/libpinproc-dev/DEBIAN/md5sums | 4 - .../usr/include/p-roc/pinproc.h | 598 ------------------ debian/libpinproc-dev/usr/lib/libpinproc.so | 1 - .../usr/lib/pkgconfig/pinproc.pc | 11 - .../doc/libpinproc-dev/changelog.Debian.gz | Bin 140 -> 0 bytes .../usr/share/doc/libpinproc-dev/copyright | 13 - debian/libpinproc.debhelper.log | 24 - debian/libpinproc.install | 1 - debian/libpinproc.postinst.debhelper | 5 - debian/libpinproc.postrm.debhelper | 5 - debian/libpinproc.substvars | 2 - debian/libpinproc/DEBIAN/control | 11 - debian/libpinproc/DEBIAN/md5sums | 3 - debian/libpinproc/DEBIAN/postinst | 7 - debian/libpinproc/DEBIAN/postrm | 7 - debian/libpinproc/DEBIAN/shlibs | 1 - debian/libpinproc/usr/lib/libpinproc.so.2.0 | Bin 51360 -> 0 bytes .../share/doc/libpinproc/changelog.Debian.gz | Bin 140 -> 0 bytes .../usr/share/doc/libpinproc/copyright | 13 - debian/libpinproc1.dirs | 1 - debian/rules | 27 - debian/source/format | 1 - 33 files changed, 819 deletions(-) delete mode 100644 debian/changelog delete mode 100644 debian/compat delete mode 100644 debian/control delete mode 100644 debian/copyright delete mode 100644 debian/docs delete mode 100644 debian/files delete mode 100644 debian/libpinproc-dev.debhelper.log delete mode 100644 debian/libpinproc-dev.dirs delete mode 100644 debian/libpinproc-dev.install delete mode 100644 debian/libpinproc-dev.substvars delete mode 100644 debian/libpinproc-dev/DEBIAN/control delete mode 100644 debian/libpinproc-dev/DEBIAN/md5sums delete mode 100644 debian/libpinproc-dev/usr/include/p-roc/pinproc.h delete mode 120000 debian/libpinproc-dev/usr/lib/libpinproc.so delete mode 100644 debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc delete mode 100644 debian/libpinproc-dev/usr/share/doc/libpinproc-dev/changelog.Debian.gz delete mode 100644 debian/libpinproc-dev/usr/share/doc/libpinproc-dev/copyright delete mode 100644 debian/libpinproc.debhelper.log delete mode 100644 debian/libpinproc.install delete mode 100644 debian/libpinproc.postinst.debhelper delete mode 100644 debian/libpinproc.postrm.debhelper delete mode 100644 debian/libpinproc.substvars delete mode 100644 debian/libpinproc/DEBIAN/control delete mode 100644 debian/libpinproc/DEBIAN/md5sums delete mode 100755 debian/libpinproc/DEBIAN/postinst delete mode 100755 debian/libpinproc/DEBIAN/postrm delete mode 100644 debian/libpinproc/DEBIAN/shlibs delete mode 100644 debian/libpinproc/usr/lib/libpinproc.so.2.0 delete mode 100644 debian/libpinproc/usr/share/doc/libpinproc/changelog.Debian.gz delete mode 100644 debian/libpinproc/usr/share/doc/libpinproc/copyright delete mode 100644 debian/libpinproc1.dirs delete mode 100755 debian/rules delete mode 100644 debian/source/format diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 2db71e6..0000000 --- a/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -libpinproc (0.1.0-1) trusty; urgency=low - - * Initial release - - -- Jan Kantert Wed, 10 Feb 2016 20:21:33 +0100 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec63514..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control deleted file mode 100644 index 5217999..0000000 --- a/debian/control +++ /dev/null @@ -1,21 +0,0 @@ -Source: libpinproc -Priority: optional -Maintainer: Jan Kantert -Build-Depends: debhelper (>= 8.0.0) -Standards-Version: 3.9.4 -Section: libs -Homepage: https://github.com/jabdoa2/libpinproc - -Package: libpinproc-dev -Section: libdevel -Architecture: any -Depends: libpinproc (= ${binary:Version}) -Description: Devel header for libpinproc - Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic - -Package: libpinproc -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: libpinproc - Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 91432fa..0000000 --- a/debian/copyright +++ /dev/null @@ -1,13 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: libpinproc -Source: README.markdown - -Files: * -Copyright: 2009 Gerry Stellenberg - 2009 Adam Preble -License: AS IS - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - . - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/debian/docs b/debian/docs deleted file mode 100644 index e69de29..0000000 diff --git a/debian/files b/debian/files deleted file mode 100644 index 1782cbb..0000000 --- a/debian/files +++ /dev/null @@ -1,2 +0,0 @@ -libpinproc-dev_0.1.0-1_amd64.deb libdevel optional -libpinproc_0.1.0-1_amd64.deb libs optional diff --git a/debian/libpinproc-dev.debhelper.log b/debian/libpinproc-dev.debhelper.log deleted file mode 100644 index 3dd8e80..0000000 --- a/debian/libpinproc-dev.debhelper.log +++ /dev/null @@ -1,24 +0,0 @@ -dh_auto_configure -dh_auto_build -dh_auto_test -dh_prep -dh_installdirs -override_dh_auto_install dh_auto_install -dh_auto_install -dh_install -dh_installdocs -dh_installchangelogs -dh_perl -dh_link -dh_compress -dh_fixperms -dh_strip -dh_makeshlibs -override_dh_shlibdeps dh_shlibdeps -dh_shlibdeps -dh_installdeb -dh_gencontrol -dh_md5sums -dh_builddeb -dh_builddeb -dh_builddeb diff --git a/debian/libpinproc-dev.dirs b/debian/libpinproc-dev.dirs deleted file mode 100644 index 4418816..0000000 --- a/debian/libpinproc-dev.dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/lib -usr/include diff --git a/debian/libpinproc-dev.install b/debian/libpinproc-dev.install deleted file mode 100644 index c4e0b93..0000000 --- a/debian/libpinproc-dev.install +++ /dev/null @@ -1,3 +0,0 @@ -usr/include/* -usr/lib/pkgconfig/* -usr/lib/lib*.so diff --git a/debian/libpinproc-dev.substvars b/debian/libpinproc-dev.substvars deleted file mode 100644 index abd3ebe..0000000 --- a/debian/libpinproc-dev.substvars +++ /dev/null @@ -1 +0,0 @@ -misc:Depends= diff --git a/debian/libpinproc-dev/DEBIAN/control b/debian/libpinproc-dev/DEBIAN/control deleted file mode 100644 index f427b95..0000000 --- a/debian/libpinproc-dev/DEBIAN/control +++ /dev/null @@ -1,12 +0,0 @@ -Package: libpinproc-dev -Source: libpinproc -Version: 0.1.0-1 -Architecture: amd64 -Maintainer: Jan Kantert -Installed-Size: 68 -Depends: libpinproc (= 0.1.0-1) -Section: libdevel -Priority: optional -Homepage: https://github.com/jabdoa2/libpinproc -Description: Devel header for libpinproc - Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic diff --git a/debian/libpinproc-dev/DEBIAN/md5sums b/debian/libpinproc-dev/DEBIAN/md5sums deleted file mode 100644 index 1135cfb..0000000 --- a/debian/libpinproc-dev/DEBIAN/md5sums +++ /dev/null @@ -1,4 +0,0 @@ -675f72525b8aa87966c0b35e27cbf2d0 usr/include/p-roc/pinproc.h -d291de7e93c0d47be0f40e87c7dd93e8 usr/lib/pkgconfig/pinproc.pc -74322abf217a8f4e1d6f50d89a8a009c usr/share/doc/libpinproc-dev/changelog.Debian.gz -9b8881ce99456b7e1d090ab95820ff1f usr/share/doc/libpinproc-dev/copyright diff --git a/debian/libpinproc-dev/usr/include/p-roc/pinproc.h b/debian/libpinproc-dev/usr/include/p-roc/pinproc.h deleted file mode 100644 index 521334f..0000000 --- a/debian/libpinproc-dev/usr/include/p-roc/pinproc.h +++ /dev/null @@ -1,598 +0,0 @@ -/* - * The MIT License - * Copyright (c) 2009 Gerry Stellenberg, Adam Preble - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -/** @file pinproc.h - * @brief libpinproc, P-ROC Layer 1 API (Preliminary) - * - */ -#ifndef PINPROC_PINPROC_H -#define PINPROC_PINPROC_H -#if !defined(__GNUC__) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4) // GCC supports "pragma once" correctly since 3.4 -#pragma once -#endif - -/* - * 3rd party "stdint.h" replacement available for Visual C++ before version 2010. - * http://en.wikipedia.org/wiki/Stdint.h#External_links - * -> http://msinttypes.googlecode.com/svn/trunk/stdint.h - * Place inside the major include dir (e.g. %ProgramFiles%\Microsoft Visual Studio\VC98\INCLUDE) - */ -#include - -/** @cond */ -// The following ifdef block is the standard way of creating macros which make exporting -// from a DLL simpler. All files within this DLL are compiled with the pinproc_EXPORTS -// symbol defined on the command line. This symbol should not be defined on any project -// that uses this DLL. This way any other project whose source files include this file see -// PINPROC_API functions as being imported from a DLL, whereas this DLL sees symbols -// defined with this macro as being exported. -#undef PINPROC_API - -#ifdef PINPROC_DLL // Using or Building PinPROC DLL (definition defined manually) - #ifdef pinproc_EXPORTS // Building PinPROC DLL (definition created by CMake or defined manually) - #define PINPROC_API __declspec(dllexport) - #else - #define PINPROC_API __declspec(dllimport) - #endif -#endif -// fallback for non-DLL usage and builds -#ifndef PINPROC_API - #define PINPROC_API -#endif - -#if defined(__cplusplus) - #define PINPROC_EXTERN_C_BEGIN extern "C" { - #define PINPROC_EXTERN_C_END } -#else - #define PINPROC_EXTERN_C_BEGIN - #define PINPROC_EXTERN_C_END -#endif - -PINPROC_EXTERN_C_BEGIN -/** @endcond */ - -// Types - -typedef int32_t bool_t; // FIXME: This needs better platform independence. - -typedef int32_t PRResult; /**< See: #kPRSuccess and #kPRFailure. */ -#define kPRSuccess (1) /**< Success value for #PRResult. */ -#define kPRFailure (0) /**< Failure value for #PRResult. */ - -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. */ - -typedef enum PRLogLevel { - kPRLogVerbose, - kPRLogInfo, - kPRLogWarning, - kPRLogError -} PRLogLevel; - -typedef void (*PRLogCallback)(PRLogLevel level, const char *text); /**< Function pointer type for a custom logging callback. See: PRLogSetCallback(). */ -PINPROC_API void PRLogSetCallback(PRLogCallback callback); /**< Replaces the default logging handler with the given callback function. */ - -PINPROC_API void PRLogSetLevel(PRLogLevel level); - -PINPROC_API const char *PRGetLastErrorText(); - -/** - * @defgroup device Device Creation & Deletion - * @{ - */ - -typedef enum PRMachineType { - kPRMachineInvalid = 0, - kPRMachineCustom = 1, - kPRMachineWPCAlphanumeric = 2, - kPRMachineWPC = 3, - kPRMachineWPC95 = 4, - kPRMachineSternWhitestar = 5, - kPRMachineSternSAM = 6, - kPRMachinePDB = 7, -} PRMachineType; - -// PRHandle Creation and Deletion - -PINPROC_API PRHandle PRCreate(PRMachineType machineType); /**< Create a new P-ROC device handle. Only one handle per device may be created. This handle must be destroyed with PRDelete() when it is no longer needed. Returns #kPRHandleInvalid if an error occurred. */ -PINPROC_API void PRDelete(PRHandle handle); /**< Destroys an existing P-ROC device handle. */ - -#define kPRResetFlagDefault (0) /**< Only resets state in memory and does not write changes to the device. */ -#define kPRResetFlagUpdateDevice (1) /**< Instructs PRReset() to update the device once it has reset the configuration to its defaults. */ - -/** - * @brief Resets internally maintained driver and switch rule structures. - * @param resetFlags Specify #kPRResetFlagDefault to only reset the configuration in host memory. #kPRResetFlagUpdateDevice will write the default configuration to the device, effectively disabling all drivers and switch rules. - */ -PINPROC_API PRResult PRReset(PRHandle handle, uint32_t resetFlags); - -/** @} */ // End of Device Creation & Deletion - -// I/O - -/** Flush all pending write data out to the P-ROC. */ -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); - -/** Read data from the P-ROC. */ -PINPROC_API PRResult PRReadData(PRHandle handle, uint32_t moduleSelect, uint32_t startingAddr, int32_t numReadWords, uint32_t * readBuffer); - -// Manager -/** @defgroup Manager - * @{ - */ - -typedef struct PRManagerConfig { - bool_t reuse_dmd_data_for_aux; - bool_t invert_dipswitch_1; -} PRManagerConfig; - -/** Update Manager configuration */ -PINPROC_API PRResult PRManagerUpdateConfig(PRHandle handle, PRManagerConfig *managerConfig); - -// Drivers -/** @defgroup drivers Driver Manipulation - * @{ - */ - -#define kPRDriverGroupsMax (26) /**< Number of available driver groups. */ -#define kPRDriverCount (256) /**< Total number of drivers */ - -#define kPRDriverAuxCmdOutput (2) -#define kPRDriverAuxCmdDelay (1) -#define kPRDriverAuxCmdJump (0) - -typedef struct PRDriverGlobalConfig { - bool_t enableOutputs; // Formerly enable_direct_outputs - bool_t globalPolarity; - bool_t useClear; - bool_t strobeStartSelect; - uint8_t startStrobeTime; - uint8_t matrixRowEnableIndex1; - uint8_t matrixRowEnableIndex0; - bool_t activeLowMatrixRows; - bool_t encodeEnables; - bool_t tickleSternWatchdog; - bool_t watchdogExpired; - bool_t watchdogEnable; - uint16_t watchdogResetTime; -} PRDriverGlobalConfig; - -typedef struct PRDriverGroupConfig { - uint8_t groupNum; - uint16_t slowTime; - uint8_t enableIndex; - uint8_t rowActivateIndex; - uint8_t rowEnableSelect; - bool_t matrixed; - bool_t polarity; - bool_t active; - bool_t disableStrobeAfter; -} PRDriverGroupConfig; - -typedef struct PRDriverState { - uint16_t driverNum; - uint8_t outputDriveTime; - bool_t polarity; - bool_t state; - bool_t waitForFirstTimeSlot; - uint32_t timeslots; - uint8_t patterOnTime; - uint8_t patterOffTime; - bool_t patterEnable; - bool_t futureEnable; -} PRDriverState; - -typedef struct PRDriverAuxCommand { - bool_t active; - bool_t muxEnables; - uint8_t command; - uint8_t enables; - uint8_t extraData; - uint8_t data; - uint16_t delayTime; - uint8_t jumpAddr; -} PRDriverAuxCommand; - -/** Update registers for the global driver configuration. */ -PINPROC_API PRResult PRDriverUpdateGlobalConfig(PRHandle handle, PRDriverGlobalConfig *driverGlobalConfig); - -PINPROC_API PRResult PRDriverGetGroupConfig(PRHandle handle, uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig); -/** Update registers for the given driver group configuration. */ -PINPROC_API PRResult PRDriverUpdateGroupConfig(PRHandle handle, PRDriverGroupConfig *driverGroupConfig); - -PINPROC_API PRResult PRDriverGetState(PRHandle handle, uint8_t driverNum, PRDriverState *driverState); -/** - * @brief Sets the state of the given driver (lamp or coil). - */ -PINPROC_API PRResult PRDriverUpdateState(PRHandle handle, PRDriverState *driverState); -/** - * @brief Loads the driver defaults for the given machine type. - * - * PRReset() calls this function internally; this function is useful for basing custom driver settings off of the defaults for a particular machine. - * @note This function does not update the P-ROC hardware, only the internal data structures. Use PRDriverGetGlobalConfig() and PRDriverGetGroupConfig() to retrieve the settings. - */ -PINPROC_API PRResult PRDriverLoadMachineTypeDefaults(PRHandle handle, PRMachineType machineType); - -// Driver Group Helper functions: - -/** - * Disables (turns off) the given driver group. - * This function is provided for convenience. See PRDriverGroupDisable() for a full description. - */ -PINPROC_API PRResult PRDriverGroupDisable(PRHandle handle, uint8_t groupNum); -// Driver Helper functions: - -/** - * Disables (turns off) the given driver. - * This function is provided for convenience. See PRDriverStateDisable() for a full description. - */ -PINPROC_API PRResult PRDriverDisable(PRHandle handle, uint8_t driverNum); -/** - * Pulses the given driver for a number of milliseconds. - * This function is provided for convenience. See PRDriverStatePulse() for a full description. - */ -PINPROC_API PRResult PRDriverPulse(PRHandle handle, uint8_t driverNum, uint8_t milliseconds); -/** - * Pulses the given driver for a number of milliseconds when the hardware reaches a specific timestamp. - * This function is provided for convenience. See PRDriverStatePulse() for a full description. - */ -PINPROC_API PRResult PRDriverFuturePulse(PRHandle handle, uint8_t driverNum, uint8_t milliseconds, uint32_t futureTime); -/** - * Assigns a repeating schedule to the given driver. - * This function is provided for convenience. See PRDriverStateSchedule() for a full description. - */ -PINPROC_API PRResult PRDriverSchedule(PRHandle handle, uint8_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool_t now); -/** - * Assigns a pitter-patter schedule (repeating on/off) to the given driver. - * This function is provided for convenience. See PRDriverStatePatter() for a full description. - */ -PINPROC_API PRResult PRDriverPatter(PRHandle handle, uint8_t driverNum, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t originalOnTime, bool_t now); -/** - * Assigns a pitter-patter schedule (repeating on/off) to the given driver on for the given duration. - * This function is provided for convenience. See PRDriverStatePulsedPatter() for a full description. - */ -PINPROC_API PRResult PRDriverPulsedPatter(PRHandle handle, uint8_t driverNum, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t originalOnTime, bool_t now); -/** - * Prepares an Aux Command to drive the Aux bus. - * This function is provided for convenience. - */ -PINPROC_API void PRDriverAuxPrepareOutput(PRDriverAuxCommand *auxCommand, uint8_t data, uint8_t extraData, uint8_t enables, bool_t muxEnables, uint16_t delayTime); -/** - * Prepares an Aux Command to delay the Aux logic. - * This function is provided for convenience. - */ -PINPROC_API void PRDriverAuxPrepareDelay(PRDriverAuxCommand *auxCommand, uint16_t delayTime); -/** - * Prepares an Aux Command to have the Aux memory pointer jump to a new address. - * This function is provided for convenience. - */ -PINPROC_API void PRDriverAuxPrepareJump(PRDriverAuxCommand *auxCommand, uint8_t jumpAddr); -/** - * Prepares a disabled Aux Command. - * This function is provided for convenience. - */ -PINPROC_API void PRDriverAuxPrepareDisable(PRDriverAuxCommand *auxCommand); - -/** Tickle the watchdog timer. */ -PINPROC_API PRResult PRDriverWatchdogTickle(PRHandle handle); - -/** - * Changes the given #PRDriverGroupConfig to reflect a disabled group. - * @note The driver group config structure must be applied using PRDriverUpdateGroupConfig() to have any effect. - */ -PINPROC_API void PRDriverGroupStateDisable(PRDriverGroupConfig *driverGroup); -/** - * Changes the given #PRDriverState to reflect a disabled state. - * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. - */ -PINPROC_API void PRDriverStateDisable(PRDriverState *driverState); -/** - * Changes the given #PRDriverState to reflect a pulse state. - * @param milliseconds Number of milliseconds to pulse the driver for. - * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. - */ -PINPROC_API void PRDriverStatePulse(PRDriverState *driverState, uint8_t milliseconds); -/** - * Changes the given #PRDriverState to reflect a future scheduled pulse state. - * @param milliseconds Number of milliseconds to pulse the driver for. - * @param futureTime Value indicating at which HW timestamp the pulse should occur. Currently only the low 10-bits are used. - * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. - */ -PINPROC_API void PRDriverStateFuturePulse(PRDriverState *driverState, uint8_t milliseconds, uint32_t futureTime); -/** - * Changes the given #PRDriverState to reflect a scheduled state. - * Assigns a repeating schedule to the given driver. - * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. - */ -PINPROC_API void PRDriverStateSchedule(PRDriverState *driverState, uint32_t schedule, uint8_t cycleSeconds, bool_t now); -/** - * @brief Changes the given #PRDriverState to reflect a pitter-patter schedule state. - * Assigns a pitter-patter schedule (repeating on/off) to the given driver. - * @note The driver state structure must be applied using PRDriverUpdateState() or linked to a switch rule using PRSwitchUpdateRule() to have any effect. - * - * Use originalOnTime to pulse the driver for a number of milliseconds before the pitter-patter schedule begins. - */ -PINPROC_API void PRDriverStatePatter(PRDriverState *driverState, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t originalOnTime, bool_t now); - -/** - * @brief Changes the given #PRDriverState to reflect a pitter-patter schedule state. - * Just like the regular Patter above, but PulsePatter only drives the patter - * scheduled for the given number of milliseconds before disabling the driver. - */ -PINPROC_API void PRDriverStatePulsedPatter(PRDriverState *driverState, uint8_t millisecondsOn, uint8_t millisecondsOff, uint8_t patterTime, bool_t now); - -/** - * Write Aux Port commands into the Aux Port command memory. - */ - -PINPROC_API PRResult PRDriverAuxSendCommands(PRHandle handle, PRDriverAuxCommand * commands, uint8_t numCommands, uint8_t startingAddr); - -/** - * @brief Converts a coil, lamp, switch, or GI string into a P-ROC driver number. - * The following formats are accepted: Cxx (coil), Lxx (lamp), Sxx (matrix switch), SFx (flipper grounded switch), or SDx (dedicated grounded switch). - * If the string does not match this format it will be converted into an integer using atoi(). - */ -PINPROC_API uint16_t PRDecode(PRMachineType machineType, const char *str); - -/** @} */ // End of Drivers - -// Switches - -/** @defgroup switches Switches and Events - * @{ - */ - -// Events -// Closed == 0, Open == 1 -typedef enum PREventType { - kPREventTypeInvalid = 0, - kPREventTypeSwitchClosedDebounced = 1, /**< The switch has gone from open to closed and the signal has been debounced. */ - kPREventTypeSwitchOpenDebounced = 2, /**< The switch has gone from closed to open and the signal has been debounced. */ - kPREventTypeSwitchClosedNondebounced = 3, /**< The switch has gone from open to closed and the signal has not been debounced. */ - kPREventTypeSwitchOpenNondebounced = 4, /**< The switch has gone from closed to open and the signal has not been debounced. */ - kPREventTypeDMDFrameDisplayed = 5, /**< A DMD frame has been displayed. */ - kPREventTypeBurstSwitchOpen = 6, /**< A burst switch has gone from closed to open. */ - kPREventTypeBurstSwitchClosed = 7, /**< A burst switch has gone from open to closed. */ - kPREventTypeAccelerometerX = 8, /**< New value from the accelerometer - X plane. */ - kPREventTypeAccelerometerY = 9, /**< New value from the accelerometer - Y plane. */ - kPREventTypeAccelerometerZ = 10, /**< New value from the accelerometer - Z plane. */ - kPREventTypeAccelerometerIRQ = 11, /**< New interrupt from the accelerometer */ - kPREventTypetLast = kPREventTypeSwitchOpenNondebounced -} PREventType; - -typedef struct PREvent { - PREventType type; /**< The type of event that has occurred. Usually a switch event at this point. */ - uint32_t value; /**< For switch events, the switch number that has changed. For DMD events, the frame buffer that was just displayed. */ - uint32_t time; /**< Time (in milliseconds) that this event occurred. */ -} PREvent; - -/** Get all of the available events that have been received. - * \return Number of events returned; -1 if an error occurred. - */ -PINPROC_API int PRGetEvents(PRHandle handle, PREvent *eventsOut, int maxEvents); - - -#define kPRSwitchPhysicalFirst (0) /**< Switch number of the first physical switch. */ -#define kPRSwitchPhysicalLast (255) /**< Switch number of the last physical switch. */ -#define kPRSwitchNeverDebounceFirst (192) /**< Switch number of the first switch that doesn't need to debounced. */ -#define kPRSwitchNeverDebounceLast (255) /**< Switch number of the last switch that doesn't need to be debounce. */ -#define kPRSwitchCount (256) -#define kPRSwitchRulesCount (kPRSwitchCount << 2) /**< Total number of available switch rules. */ - -typedef struct PRSwitchConfig { - bool_t clear; // Drive the clear output - bool_t hostEventsEnable; // Drive the clear output - bool_t use_column_9; // Use switch matrix column 9 - bool_t use_column_8; // Use switch matrix column 8 - uint8_t directMatrixScanLoopTime; // milliseconds - uint8_t pulsesBeforeCheckingRX; - uint8_t inactivePulsesAfterBurst; - uint8_t pulsesPerBurst; - uint8_t pulseHalfPeriodTime; // milliseconds -} PRSwitchConfig; - -typedef struct PRSwitchRule { - bool_t reloadActive; /**< If true, any associated driver changes resulting from this rule will only happen at most once every 256ms. */ - bool_t notifyHost; /**< If true this switch change event will provided to the user via PRGetEvents(). */ -} PRSwitchRule; - -/** Update the switch controller configurion registers */ -PINPROC_API PRResult PRSwitchUpdateConfig(PRHandle handle, PRSwitchConfig *switchConfig); - -/** - * @brief Configures the handling of switch rules within P-ROC. - * - * P-ROC's switch rule system allows the user to decide which switch events are returned to software, - * as well as optionally linking one or more driver state changes to rules to create immediate feedback (such as in pop bumpers). - * - * For instance, P-ROC can provide debounced switch events for a flipper button so software can apply lange change behavior. - * This is accomplished by configuring the P-ROC with a switch rule for the flipper button and then receiving the events via the PRGetEvents() call. - * The same switch can also be configured with a non-debounced rule to fire a flipper coil. - * Multiple driver changes can be tied to a single switch state transition to create more complicated effects: a slingshot - * switch that fires the slingshot coil, a flash lamp, and a score event. - * - * P-ROC holds four different switch rules for each switch: closed to open and open to closed, each with a debounced and non-debounced versions: - * - #kPREventTypeSwitchOpenDebounced - * - #kPREventTypeSwitchClosedDebounced - * - #kPREventTypeSwitchOpenNondebounced - * - #kPREventTypeSwitchClosedNondebounced - * - * @section Examples - * - * Configuring a basic switch rule to simply notify software via PRGetEvents() without affecting any coil/lamp drivers: - * @code - * PRSwitchRule rule; - * rule.notifyHost = true; - * PRSwitchUpdateRule(handle, switchNum, kPREventTypeSwitchOpenDebounced, &rule, NULL, 0); - * @endcode - * - * Configuring a pop bumper switch to pulse the coil and a flash lamp for 50ms each: - * @code - * // Configure a switch rule to fire the coil and flash lamp: - * PRSwitchRule rule; - * rule.notifyHost = false; - * PRDriverState drivers[2]; - * PRDriverGetState(handle, drvCoilPopBumper1, &drivers[0]); - * PRDriverGetState(handle, drvFlashLamp1, &drivers[1]); - * PRDriverStatePulse(&drivers[0], 50); - * PRDriverStatePulse(&drivers[1], 50); - * PRSwitchUpdateRule(handle, swPopBumper1, kPREventTypeSwitchClosedNondebounced, - * &rule, drivers, 2); - * // Now configure a switch rule to process scoring in software: - * rule.notifyHost = true; - * PRSwitchUpdateRule(handle, swPopBumper1, kPREventTypeSwitchClosedDebounced, - * &rule, NULL, 0); - * @endcode - * - * @param handle The P-ROC device handle. - * @param switchNum The index of the switch this configuration affects. - * @param eventType The switch rule for the specified switchNum to be configured. - * @param rule A pointer to the #PRSwitchRule structure describing how this state change should be handled. May not be NULL. - * @param linkedDrivers An array of #PRDriverState structures describing the driver state changes to be made when this switch rule is triggered. May be NULL if numDrivers is 0. - * @param numDrivers Number of elements in the linkedDrivers array. May be zero or more. - */ -PINPROC_API PRResult PRSwitchUpdateRule(PRHandle handle, uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers, bool_t drive_outputs_now); - -/** Returns a list of PREventTypes describing the states of the requested number of switches */ -PINPROC_API PRResult PRSwitchGetStates(PRHandle handle, PREventType * switchStates, uint16_t numSwitches); - -/** @} */ // End of Switches & Events - -// DMD - -/** - * @defgroup dmd DMD Control - * @{ - */ -typedef struct PRDMDConfig { - uint8_t numRows; - uint16_t numColumns; - uint8_t numSubFrames; - uint8_t numFrameBuffers; - bool_t autoIncBufferWrPtr; - bool_t enableFrameEvents; - bool_t enable; - uint8_t rclkLowCycles[8]; - uint8_t latchHighCycles[8]; - uint16_t deHighCycles[8]; - uint8_t dotclkHalfPeriod[8]; -} PRDMDConfig; - -/** Sets the configuration registers for the DMD driver. */ -PINPROC_API int32_t PRDMDUpdateConfig(PRHandle handle, PRDMDConfig *dmdConfig); -/** Updates the DMD frame buffer with the given data. */ -PINPROC_API PRResult PRDMDDraw(PRHandle handle, uint8_t * dots); - -/** @} */ // End of DMD - - -// JTAG - -/** - * @defgroup jtag JTAG interface control - * @{ - */ - -typedef struct PRJTAGStatus { - bool_t commandComplete; - bool_t tdi; -} PRJTAGStatus; - -typedef struct PRJTAGOutputs { - bool_t tckMask; - bool_t tmsMask; - bool_t tdoMask; - bool_t tck; - bool_t tms; - bool_t tdo; -} PRJTAGOutputs; - -/** Force JTAG outputs (TCK, TDO, TMS) to specific values. Optionally toggle the clock when driving only TDO and/or TMS.*/ -PINPROC_API PRResult PRJTAGDriveOutputs(PRHandle handle, PRJTAGOutputs * jtagOutputs, bool_t toggleClk); -/** Store data to be shifted out on TDO */ -PINPROC_API PRResult PRJTAGWriteTDOMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdoData); -/** Shift stored TDO data onto the TDO pin, toggling TCK on every bit. */ -PINPROC_API PRResult PRJTAGShiftTDOData(PRHandle handle, uint16_t numBits, bool_t dataBlockComplete); -/** Get the contents of the TDI memory. */ -PINPROC_API PRResult PRJTAGReadTDIMemory(PRHandle handle, uint16_t tableOffset, uint16_t numWords, uint32_t * tdiData); -/** Read the JTAG status register for the command complete bit and JTAG pin states. */ -PINPROC_API PRResult PRJTAGGetStatus(PRHandle handle, PRJTAGStatus * status); - -/** @} */ // End of JTAG - -// PD-LED - -/** - * @defgroup pdled PD-LED Control - * @{ - */ - - -typedef struct PRLED { - uint8_t boardAddr; - uint8_t LEDIndex; -} PRLED; - -typedef struct PRLEDRGB { - PRLED* pRedLED; - PRLED* pGreenLED; - PRLED* pBlueLED; -} PRLEDRGB; - -/** Sets the color of a given PRLED. */ -PINPROC_API PRResult PRLEDColor(PRHandle handle, PRLED * pLED, uint8_t color); -/** Sets the fade color on a given PRLED. */ -PINPROC_API PRResult PRLEDFadeColor(PRHandle handle, PRLED * pLED, uint8_t fadeColor); -/** Sets the fade color and rate on a given PRLED. Note: The rate will apply to any future PRLEDFadeColor or PRLEDRGBFadeColor calls on the same PD-LED board. */ -PINPROC_API PRResult PRLEDFade(PRHandle handle, PRLED * pLED, uint8_t fadeColor, uint16_t fadeRate); - -/** Sets the fade rate on a given board. Note: The rate will apply to any future PRLEDFadeColor or PRLEDRGBFadeColor calls on the same PD-LED board. */ -PINPROC_API PRResult PRLEDFadeRate(PRHandle handle, uint8_t boardAddr, uint16_t fadeRate); - -/** Sets the color of a given PRLEDRGB. */ -PINPROC_API PRResult PRLEDRGBColor(PRHandle handle, PRLEDRGB * pLED, uint32_t color); -/** Sets the fade color and rate on a given PRLEDRGB. Note: The rate will apply to any future PRLEDFadeColor or PRLEDRGBFadeColor calls on any of the referenced PD-LED boards. */ -PINPROC_API PRResult PRLEDRGBFade(PRHandle handle, PRLEDRGB * pLED, uint32_t fadeColor, uint16_t fadeRate); -/** Sets the fade color on a given PRLEDRGB. */ -PINPROC_API PRResult PRLEDRGBFadeColor(PRHandle handle, PRLEDRGB * pLED, uint32_t fadeColor); - - -/** @} */ // End of PD-LED - - -/** @cond */ -PINPROC_EXTERN_C_END -/** @endcond */ - -/** - * @mainpage libpinproc API Documentation - * - * This is the documentation for libpinproc, the P-ROC Layer 1 API. - */ - -#endif /* PINPROC_PINPROC_H */ diff --git a/debian/libpinproc-dev/usr/lib/libpinproc.so b/debian/libpinproc-dev/usr/lib/libpinproc.so deleted file mode 120000 index 7fcf201..0000000 --- a/debian/libpinproc-dev/usr/lib/libpinproc.so +++ /dev/null @@ -1 +0,0 @@ -libpinproc.so.2.0 \ No newline at end of file diff --git a/debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc b/debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc deleted file mode 100644 index 6c2eb66..0000000 --- a/debian/libpinproc-dev/usr/lib/pkgconfig/pinproc.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr -exec_prefix=/usr -libdir=${prefix}/lib -includedir=${prefix}/include/p-roc - -Name: Pinproc -Description: P-ROC interface library -Version: 2.0 -Requires: -Libs: -L${libdir} -lpinproc -Cflags: -I${includedir} diff --git a/debian/libpinproc-dev/usr/share/doc/libpinproc-dev/changelog.Debian.gz b/debian/libpinproc-dev/usr/share/doc/libpinproc-dev/changelog.Debian.gz deleted file mode 100644 index 412a8d039ca52dfc65b36b163d5aa6189c50d42c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmV;70CWEziwFP!0000210~2g4#F@H1<*dH_$8aIaUxNKMN~+@0jQlYLP-+!C6{L8l$Y+_ALNA@<**09Lq2(BLC7NA?3_USn|ef}0oR utk}Q2m`{41-v6+|dIawL*uW9a+@K`4ovBM#R~6Reh>9OEM<2e20002}f= 2.14), libgcc1 (>= 1:4.1.1), libstdc++6 (>= 4.1.1) -misc:Depends= diff --git a/debian/libpinproc/DEBIAN/control b/debian/libpinproc/DEBIAN/control deleted file mode 100644 index df8ee8d..0000000 --- a/debian/libpinproc/DEBIAN/control +++ /dev/null @@ -1,11 +0,0 @@ -Package: libpinproc -Version: 0.1.0-1 -Architecture: amd64 -Maintainer: Jan Kantert -Installed-Size: 80 -Depends: libc6 (>= 2.14), libgcc1 (>= 1:4.1.1), libstdc++6 (>= 4.1.1) -Section: libs -Priority: optional -Homepage: https://github.com/jabdoa2/libpinproc -Description: libpinproc - Lib to speak to the P-Roc and P3-Roc hardware from Multimorphic diff --git a/debian/libpinproc/DEBIAN/md5sums b/debian/libpinproc/DEBIAN/md5sums deleted file mode 100644 index 06e4041..0000000 --- a/debian/libpinproc/DEBIAN/md5sums +++ /dev/null @@ -1,3 +0,0 @@ -8c3c18eda463e90bb2faffb8c2d1315b usr/lib/libpinproc.so.2.0 -74322abf217a8f4e1d6f50d89a8a009c usr/share/doc/libpinproc/changelog.Debian.gz -9b8881ce99456b7e1d090ab95820ff1f usr/share/doc/libpinproc/copyright diff --git a/debian/libpinproc/DEBIAN/postinst b/debian/libpinproc/DEBIAN/postinst deleted file mode 100755 index 379f1fa..0000000 --- a/debian/libpinproc/DEBIAN/postinst +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -set -e -# Automatically added by dh_makeshlibs -if [ "$1" = "configure" ]; then - ldconfig -fi -# End automatically added section diff --git a/debian/libpinproc/DEBIAN/postrm b/debian/libpinproc/DEBIAN/postrm deleted file mode 100755 index 3e73d38..0000000 --- a/debian/libpinproc/DEBIAN/postrm +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -set -e -# Automatically added by dh_makeshlibs -if [ "$1" = "remove" ]; then - ldconfig -fi -# End automatically added section diff --git a/debian/libpinproc/DEBIAN/shlibs b/debian/libpinproc/DEBIAN/shlibs deleted file mode 100644 index 1f60a0f..0000000 --- a/debian/libpinproc/DEBIAN/shlibs +++ /dev/null @@ -1 +0,0 @@ -libpinproc 2.0 libpinproc diff --git a/debian/libpinproc/usr/lib/libpinproc.so.2.0 b/debian/libpinproc/usr/lib/libpinproc.so.2.0 deleted file mode 100644 index af7d8fbc3d44fb6a523cc37cc4364de5609f467f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51360 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 PA9F_+{38x}d>r}%4I9?O diff --git a/debian/libpinproc/usr/share/doc/libpinproc/changelog.Debian.gz b/debian/libpinproc/usr/share/doc/libpinproc/changelog.Debian.gz deleted file mode 100644 index 412a8d039ca52dfc65b36b163d5aa6189c50d42c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmV;70CWEziwFP!0000210~2g4#F@H1<*dH_$8aIaUxNKMN~+@0jQlYLP-+!C6{L8l$Y+_ALNA@<**09Lq2(BLC7NA?3_USn|ef}0oR utk}Q2m`{41-v6+|dIawL*uW9a+@K`4ovBM#R~6Reh>9OEM<2e20002}f Date: Thu, 25 Jun 2020 23:19:56 -0700 Subject: [PATCH 21/38] yaml: remove yaml-cpp dependency `pinproctest` now takes machineType as it's command-line parameter. --- CMakeLists.txt | 13 ----- README.markdown | 32 +++++++---- examples/pinproctest/Makefile | 2 +- examples/pinproctest/pinproctest.cpp | 85 +++++++++------------------- examples/pinproctest/pinproctest.h | 4 +- examples/pinproctest/switches.cpp | 39 +------------ libpinproc.xcodeproj/project.pbxproj | 2 - 7 files changed, 50 insertions(+), 127 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81661fe..ed39e89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,9 +86,6 @@ include_directories(${PINPROC_SOURCE_DIR}/include ${EXTRA_INC} /usr/local/includ link_directories(${EXTRA_LINK} /usr/local/lib) endif() -set(YAML_CPP_LIB "yaml-cpp") -set(YAML_CPP_LIB_DBG "${YAML_CPP_LIB}") - ### ### General compilation settings @@ -169,15 +166,7 @@ if(MSVC) 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() -else() - # make sure executable files are standalone - SET(CMAKE_EXE_LINKER_FLAGS "-static") endif() @@ -261,8 +250,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/README.markdown b/README.markdown index ff796b8..425c44d 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 @@ -12,12 +12,6 @@ libpinproc requires: - [libftdi-0.16](http://www.intra2net.com/en/developer/libftdi/): Install with the default /usr/local prefix. -The pinproctest example requires [yaml-cpp](https://github.com/jbeder/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: - - 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: @@ -37,7 +31,7 @@ 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. #### Building in Windows with MinGW/CMake @@ -52,17 +46,31 @@ Follow directions above for building yaml-cpp with the following exception: To build libpinproc: -- 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. - -- 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. +- Use -DEXTRA_INC=";" and -DEXTRA_LINK=";" to add include/library paths for `ftd2xx.h` and `ftd2xx.sys`. 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 - + +#### Building in Windows with Visual Studio 2019 + +Assumes you are already running an MSYS2/MinGW64 system. + +Make sure you have cmake installed for i686 (MinGW32) or x86_64 (MinGW64): `pacman -S cmake mingw-w64-i686-cmake mingw-w64-x86_64-cmake` + + cd libpinproc + mkdir build; cd build + cmake .. -A Win32 + # configure paths for td2xxx; use `cmake .. -L` to list configured options + cmake .. -D EXTRA_INC="../ftd2xx" + cmake .. -D EXTRA_LINK="../../ftd2xx/i386" + +Then 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`. + ### License Copyright (c) 2009 Gerry Stellenberg, Adam Preble +Copyright (c) 2020 Multimorphic, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 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/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 7800930..10d2075 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -36,37 +36,6 @@ void TestLogger(PRLogLevel level, const char *text) fprintf(stderr, "TEST: %s", text); } -PRResult LoadConfiguration(YAML::Node& yamlDoc, const char *yamlFilePath) -{ - try - { - std::ifstream fin(yamlFilePath); - if (fin.is_open() == false) - { - fprintf(stderr, "YAML file not found: %s\n", yamlFilePath); - return kPRFailure; - } - - yamlDoc = YAML::Load(fin); - } -// catch (YAML::ParserException& ex) -// { -// fprintf(stderr, "YAML parse error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str()); - // return kPRFailure; -// } -// catch (YAML::RepresentationException& ex) -// { -// fprintf(stderr, "YAML representation error at line=%d col=%d: %s\n", ex.line, ex.column, ex.msg.c_str()); -// return kPRFailure; -// } - catch (...) - { - fprintf(stderr, "Unexpected exception while parsing YAML config.\n"); - return kPRFailure; - } - return kPRSuccess; -} - void ConfigureAccelerometerMotion(PRHandle proc) { uint32_t readData[5]; @@ -312,6 +281,20 @@ 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; @@ -320,39 +303,26 @@ int main(int argc, const char **argv) 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 (_strcmpi(argv[1], machine_types[i].name) == 0) { + machineType = machine_types[i].type; + break; + } } - std::string machineTypeString = yamlDoc["PRGame"]["machineType"].as(); - 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; } @@ -371,8 +341,7 @@ int main(int argc, const char **argv) // timing purposes. ConfigureDMD(proc); if (machineType == kPRMachineCustom) ConfigureDrivers(proc); - ConfigureSwitches(proc, yamlDoc); // Notify host for all debounced switch events. - ConfigureSwitchRules(proc, yamlDoc); // Flippers, slingshots + ConfigureSwitches(proc); // Notify host for all debounced switch events. if (machineType == kPRMachineWPCAlphanumeric) UpdateAlphaDisplay(proc, 0); 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 491def6..75a99d5 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,43 +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::const_iterator flippersIt = flippers.begin(); flippersIt != flippers.end(); ++flippersIt) - { - int swNum, coilMain, coilHold; - std::string flipperName = flippersIt->as(); - if (machineType == kPRMachineWPC) - { - numStr = yamlDoc[kSwitchesSection][flipperName][kNumberField].as(); swNum = PRDecode(machineType, numStr.c_str()); - numStr = yamlDoc[kCoilsSection][flipperName + "Main"][kNumberField].as(); coilMain = PRDecode(machineType, numStr.c_str()); - numStr = yamlDoc[kCoilsSection][flipperName + "Hold"][kNumberField].as(); coilHold = PRDecode(machineType, numStr.c_str()); - ConfigureWPCFlipperSwitchRule (proc, swNum, coilMain, coilHold, kFlipperPulseTime); - } - else if (machineType == kPRMachineSternWhitestar || machineType == kPRMachineSternSAM) - { - printf("hi\n"); - numStr = yamlDoc[kSwitchesSection][flipperName][kNumberField].as(); swNum = PRDecode(machineType, numStr.c_str()); - numStr = yamlDoc[kCoilsSection][flipperName + "Main"][kNumberField].as(); coilMain = PRDecode(machineType, numStr.c_str()); - ConfigureSternFlipperSwitchRule (proc, swNum, coilMain, kFlipperPulseTime, kFlipperPatterOnTime, kFlipperPatterOffTime); - } - } - - const YAML::Node& bumpers = yamlDoc[kBumpersSection]; - for (YAML::const_iterator bumpersIt = bumpers.begin(); bumpersIt != bumpers.end(); ++bumpersIt) - { - int swNum, coilNum; - // WPC Slingshots - std::string bumperName = bumpersIt->as(); - numStr = yamlDoc[kSwitchesSection][bumperName][kNumberField].as(); swNum = PRDecode(machineType, numStr.c_str()); - numStr = yamlDoc[kCoilsSection][bumperName][kNumberField].as(); coilNum = PRDecode(machineType, numStr.c_str()); - ConfigureBumperRule (proc, swNum, coilNum, kBumperPulseTime); - } -} - void UpdateSwitchState( PREvent * event ) { switches[event->value].state = event->type; 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; From cc92bc1235861eda9fec769050e457e97f25884f Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Thu, 25 Jun 2020 23:21:36 -0700 Subject: [PATCH 22/38] pinproctest: fix kPRDriverGroupsMax overflow Compiler warnings showed we were overflowing arrays sized for kPRDriverGroupsMax. --- examples/pinproctest/drivers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pinproctest/drivers.cpp b/examples/pinproctest/drivers.cpp index 6301025..9cf7164 100644 --- a/examples/pinproctest/drivers.cpp +++ b/examples/pinproctest/drivers.cpp @@ -131,7 +131,7 @@ void ConfigureDriverGroups(PRHandle proc, bool driverPolarity) // in the matrixRowEnableIndex variables. const int mappedDriverGroupRowEnableSelect[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}; - for (i = 0; i <= kPRDriverGroupsMax; i++) + for (i = 0; i < kPRDriverGroupsMax; i++) { PRDriverGroupConfig group; //memset(&group, 0x00, sizeof(PRDriverGroupConfig)); From bcd526a5589a63ab433d3e69266e1c9fdfa21773 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Thu, 25 Jun 2020 23:23:24 -0700 Subject: [PATCH 23/38] libpinproc: fix PRDevice::GetVersionInfo() API `combinedVersionRevision` is a 32-bit value. This API isn't exposed in the public pinproc.h header, so it's safe to make this change. --- src/PRDevice.cpp | 2 +- src/PRDevice.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index d6d43fe..1f19373 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -1383,7 +1383,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 ca1e869..c77ebac 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -95,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: From b2d9b4e000536c808b93fd090263c7402e851b4a Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Thu, 25 Jun 2020 23:24:47 -0700 Subject: [PATCH 24/38] API: change private constants to public macros Expose some useful values for code that interfaces with libpinproc. --- include/pinproc.h | 257 +++++++++++++++++++++++++++++++++++++++++++++- src/PRHardware.h | 253 --------------------------------------------- 2 files changed, 256 insertions(+), 254 deletions(-) diff --git a/include/pinproc.h b/include/pinproc.h index 60c02e7..2f465c5 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, @@ -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 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, From 954084d348ec1ce1aeea7bbc55f54738d590a16e Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Thu, 25 Jun 2020 23:28:13 -0700 Subject: [PATCH 25/38] pinproctest: code cleanup Includes check to limit accelerometer-related code to P3-ROC since it fails on the P-ROC (which doesn't have an accelerometer). --- examples/pinproctest/drivers.cpp | 2 - examples/pinproctest/pinproctest.cpp | 107 +++++++++++++++------------ examples/pinproctest/switches.cpp | 12 ++- 3 files changed, 64 insertions(+), 57 deletions(-) diff --git a/examples/pinproctest/drivers.cpp b/examples/pinproctest/drivers.cpp index 9cf7164..134ca37 100644 --- a/examples/pinproctest/drivers.cpp +++ b/examples/pinproctest/drivers.cpp @@ -222,8 +222,6 @@ void ConfigureDriverGlobals(PRHandle proc, bool driverPolarity) void ConfigureDrivers(PRHandle proc) { - int i; - // First set up a bunch of constants to use later: // The driverPolarity determines when the drivers go high or low when diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 10d2075..cf4bb63 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -27,115 +27,124 @@ * libpinproc */ #include "pinproctest.h" +uint32_t board_id = 0; PRMachineType machineType = kPRMachineInvalid; /** Demonstration of the custom logging callback. */ void TestLogger(PRLogLevel level, const char *text) { - fprintf(stderr, "TEST: %s", text); + printf("TEST: %s", text); } void ConfigureAccelerometerMotion(PRHandle proc) { uint32_t readData[5]; - PRReadData(proc, 6, 0x10D, 1, readData); + // Only the P3-ROC has an accelerometer. + if (board_id != P3_ROC_CHIP_ID) { + return; + } + + PRReadData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10D, 1, readData); printf("\nAccel chip id: %x\n", readData[0]); fflush(stdout); // Set FF_MT_COUNT (0x18) readData[0] = 1; - PRWriteData(proc, 6, 0x118, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x118, 1, readData); // Set FF_MT_THRESH (0x17) readData[0] = 1; - PRWriteData(proc, 6, 0x117, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x117, 1, readData); // Set FF_MT_CONFIG (0x15) readData[0] = 0xD8; - PRWriteData(proc, 6, 0x115, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x115, 1, readData); // Enable Motion interrupts readData[0] = 0x04; - PRWriteData(proc, 6, 0x12D, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12D, 1, readData); // Direct motion interrupt to int0 pin (default) readData[0] = 0x04; - PRWriteData(proc, 6, 0x12E, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12E, 1, readData); readData[0] = 0x3D; - PRWriteData(proc, 6, 0x12A, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12A, 1, readData); readData[0] = 0x02; - PRWriteData(proc, 6, 0x12B, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12B, 1, readData); // Enable auto-polling of accelerometer every 128 ms (8 times a sec). //readData[0] = 0x0F; // Enable polling, 8 times a second. readData[0] = 0x00; // Disable polling readData[0] = readData[0] | 0x1600; // Set IRQ status addr (FF_MT_SRC) - PRWriteData(proc, 6, 0x000, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x000, 1, readData); PRFlushWriteData(proc); - } void ConfigureAccelerometerTransient(PRHandle proc) { uint32_t readData[5]; - PRReadData(proc, 6, 0x10D, 1, readData); + // Only the P3-ROC has an accelerometer. + if (board_id != P3_ROC_CHIP_ID) { + return; + } + + PRReadData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10D, 1, readData); printf("\nAccel chip id: %x\n", readData[0]); fflush(stdout); // Set to standby so register changes will take. readData[0] = 0x0; - PRWriteData(proc, 6, 0x12A, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12A, 1, readData); - // Set HPF_OUT bit in XYZ_DATA_CFG (0xOE) + // Set HPF_OUT bit in XYZ_DATA_CFG (0x0E) //readData[0] = 0x10; - //PRWriteData(proc, 6, 0x10E, 1, readData); + //PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10E, 1, readData); // Set HP_FILTER_CUTOFF (0x0F) readData[0] = 0x03; - PRWriteData(proc, 6, 0x10F, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10F, 1, readData); // Set FF_TRANSIENT_COUNT (0x20) readData[0] = 1; - PRWriteData(proc, 6, 0x120, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x120, 1, readData); // Set FF_TRANSIENT_THRESH (0x1F) readData[0] = 1; - PRWriteData(proc, 6, 0x11F, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x11F, 1, readData); // Set FF_TRANSIENT_CONFIG (0x1D) readData[0] = 0x1E; - PRWriteData(proc, 6, 0x11D, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x11D, 1, readData); // Enable Motion interrupts readData[0] = 0x20; - PRWriteData(proc, 6, 0x12D, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12D, 1, readData); // Direct motion interrupt to int0 pin (default) readData[0] = 0x20; - PRWriteData(proc, 6, 0x12E, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12E, 1, readData); //readData[0] = 0x3D; readData[0] = 0x05; - PRWriteData(proc, 6, 0x12A, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12A, 1, readData); readData[0] = 0x02; - PRWriteData(proc, 6, 0x12B, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x12B, 1, readData); // Enable auto-polling of accelerometer every 128 ms (8 times a sec). //readData[0] = 0x0F; // Enable polling, 8 times a second. readData[0] = 0x00; // Disable polling readData[0] = readData[0] | 0x1E00; // Set IRQ status addr (FF_MT_SRC) - PRWriteData(proc, 6, 0x000, 1, readData); + PRWriteData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x000, 1, readData); PRFlushWriteData(proc); - } time_t startTime; @@ -174,19 +183,6 @@ void RunLoop(PRHandle proc) { PRDriverWatchdogTickle(proc); -// PRReadData(proc, 6, 0x115, 1, readData); -// printf("\n\n\nAccel chip id: %x\n", readData[0]); -// PRReadData(proc, 6, 0x116, 1, readData); -// printf("\nAccel chip id: %x\n", readData[0]); -// PRReadData(proc, 6, 0x117, 1, readData); -// printf("\nAccel chip id: %x\n", readData[0]); -// PRReadData(proc, 6, 0x118, 1, readData); -// printf("\nAccel chip id: %x\n", readData[0]); -// PRReadData(proc, 6, 0x12D, 1, readData); -// printf("\nAccel chip id: %x\n", readData[0]); -// PRReadData(proc, 6, 0x12E, 1, readData); -// printf("\nAccel chip id: %x\n", readData[0]); - int numEvents = PRGetEvents(proc, events, maxEvents); // if (numEvents > 0) printf("\nNum events: %x\n", numEvents); for (int i = 0; i < numEvents; i++) @@ -202,7 +198,7 @@ void RunLoop(PRHandle proc) } #ifdef _MSC_VER struct _timeb tv; - _ftime(&tv); + _ftime_s(&tv); #else struct timeval tv; gettimeofday(&tv, NULL); @@ -215,9 +211,9 @@ void RunLoop(PRHandle proc) 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; @@ -265,6 +261,9 @@ void RunLoop(PRHandle proc) } } } + if (numEvents > 0) { + fflush(stdout); + } PRFlushWriteData(proc); #ifdef _MSC_VER Sleep(10); @@ -328,22 +327,35 @@ int main(int argc, const char **argv) // 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); + 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); @@ -385,7 +397,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/switches.cpp b/examples/pinproctest/switches.cpp index 75a99d5..641e560 100644 --- a/examples/pinproctest/switches.cpp +++ b/examples/pinproctest/switches.cpp @@ -151,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 { @@ -162,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"); } } From 83f8f116f9c558e1efaa2f78913b2ac81d745abc Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Thu, 25 Jun 2020 23:28:45 -0700 Subject: [PATCH 26/38] pinprocfw: code cleanup --- utils/pinprocfw/pinprocfw.cpp | 275 ++++++++++++++++------------------ 1 file changed, 131 insertions(+), 144 deletions(-) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index 11649eb..870b64a 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 */ @@ -540,7 +546,7 @@ void readByte(unsigned char *data) long int bytesPer200th = numBytesTotal / 200; numBytesCurrent++; if (numBytesCurrent % bytesPerTenth == 0) { - printf("\n%ld0%% ",numBytesCurrent/bytesPerTenth); + printf("\n%d0%% ",(int) (numBytesCurrent/bytesPerTenth)); fflush(stdout); } else if (numBytesCurrent % bytesPer200th == 0) { @@ -549,7 +555,7 @@ void readByte(unsigned char *data) } } -unsigned char readTDOBit() +unsigned char readTDOBit(void) { PRJTAGStatus jtagStatus; @@ -1853,7 +1859,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 +1880,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 +1888,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 +1904,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> 11 | - (board_rev & 0x400) >> 10 | - (board_rev & 0x200) >> 9 | - (board_rev & 0x100) >> 8; - fprintf(stderr, "\nReading P3-ROC board_rev: %d", board_rev); + 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 { - board_rev = (board_rev & 0x80) >> 7 | - (board_rev & 0x40) >> 6 | - (board_rev & 0x20) >> 5 | - (board_rev & 0x10) >> 4; - fprintf(stderr, "\nReading P-ROC board_rev: %d", board_rev); + 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); - return 0; + if (board_id == file_board_id) { + fprintf(stderr, "Board ID verified\n"); } - else fprintf(stderr, "\nBoard ID verified"); - - if (board_rev > max_board_rev) { - fprintf(stderr, "\nERROR: board_rev %d > max_board_rev %d", board_rev, max_board_rev); - } - if (board_rev < min_board_rev) { - fprintf(stderr, "\nERROR: board_rev < min_board_rev"); + 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; } 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++; @@ -2235,7 +2226,7 @@ uint32_t 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; } @@ -2264,11 +2255,8 @@ 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); - iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); - pzXsvfFileName = 0; + pzXsvfFileName = NULL; //printf( "XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION ); @@ -2296,62 +2284,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: - fprintf(stderr, "Failed to parse file.\n"); - break; + case P3_ROC_CHIP_ID: + preparePROCFile(); + processP3ROCFile(); + break; + default: + fprintf(stderr, "Failed to parse file.\n"); + break; } - // Destroy the P-ROC device handle created by openPROC() - PRDelete(proc); - proc = kPRHandleInvalid; } } } - // 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 */ From caa09f6473f1eddb8e8540058bb46c9cc023a825 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 08:22:55 -0700 Subject: [PATCH 27/38] cmake: remove CMAKE_CXX_STANDARD requirement Added for yaml-cpp, which is no longer a dependency for pinproctest. --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed39e89..e0e39be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,6 @@ endif() ### project(PINPROC) -set (CMAKE_CXX_STANDARD 11) - set(PINPROC_VERSION_MAJOR "2") set(PINPROC_VERSION_MINOR "0") set(PINPROC_VERSION "${PINPROC_VERSION_MAJOR}.${PINPROC_VERSION_MINOR}") From 624f7780a155e38351cb45ade22fa23262713b9a Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 08:26:06 -0700 Subject: [PATCH 28/38] cmake: update minimum required version to 2.8.1 This is a reasonable requirement. It allows removal of two OLD policies and gives us consistent behavior for relative link directories. --- CMakeLists.txt | 17 ++++------------- README.markdown | 4 ++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0e39be..5422b5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,19 +1,11 @@ ### ### 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 +# 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() @@ -162,7 +154,6 @@ if(MSVC) # c) Correct suffixes for static libraries if(NOT BUILD_SHARED_LIBS) - ### General stuff set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}") endif() endif() diff --git a/README.markdown b/README.markdown index 425c44d..ea94a1a 100644 --- a/README.markdown +++ b/README.markdown @@ -61,9 +61,9 @@ Make sure you have cmake installed for i686 (MinGW32) or x86_64 (MinGW64): `pacm cd libpinproc mkdir build; cd build cmake .. -A Win32 - # configure paths for td2xxx; use `cmake .. -L` to list configured options + # configure paths for ftd2xxx; use `cmake .. -L` to list configured options cmake .. -D EXTRA_INC="../ftd2xx" - cmake .. -D EXTRA_LINK="../../ftd2xx/i386" + cmake .. -D EXTRA_LINK="../ftd2xx/i386" Then 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`. From 5ad464b167373456b5538c807cd7553b49d30b1a Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 09:05:55 -0700 Subject: [PATCH 29/38] pinproctest: use standard strcmp() vs. strcmpi() While case-insensitive compare of the machine type passed on the command line would be nice, the function to do so has different names on different platforms, and its behavior may be impacted by the user's locale setting. --- examples/pinproctest/pinproctest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index cf4bb63..a802f9e 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -314,7 +314,7 @@ int main(int argc, const char **argv) PRLogSetCallback(TestLogger); for (i = 0; i < MACHINE_TYPES; i++) { - if (_strcmpi(argv[1], machine_types[i].name) == 0) { + if (strcmp(argv[1], machine_types[i].name) == 0) { machineType = machine_types[i].type; break; } From 705a2d25e6cf6d18f28e66888fc8810276ea4ed0 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 11:51:50 -0700 Subject: [PATCH 30/38] pinproctest: more cleanup --- examples/pinproctest/pinproctest.cpp | 48 ++++++++++++---------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index a802f9e..21a45d7 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -47,7 +47,7 @@ void ConfigureAccelerometerMotion(PRHandle proc) } PRReadData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10D, 1, readData); - printf("\nAccel chip id: %x\n", readData[0]); + printf("Accel chip id: %x\n", readData[0]); fflush(stdout); // Set FF_MT_COUNT (0x18) @@ -95,7 +95,7 @@ void ConfigureAccelerometerTransient(PRHandle proc) } PRReadData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10D, 1, readData); - printf("\nAccel chip id: %x\n", readData[0]); + printf("Accel chip id: %x\n", readData[0]); fflush(stdout); // Set to standby so register changes will take. @@ -184,17 +184,25 @@ void RunLoop(PRHandle proc) PRDriverWatchdogTickle(proc); int numEvents = PRGetEvents(proc, events, maxEvents); -// if (numEvents > 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; @@ -209,7 +217,6 @@ void RunLoop(PRHandle proc) case kPREventTypeSwitchClosedDebounced: case kPREventTypeSwitchOpenNondebounced: case kPREventTypeSwitchClosedNondebounced: - { #ifdef _MSC_VER printf("%d.%03d switch %3d: %s\n", (int)(tv.time-startTime), tv.millitm, event->value, stateText); #else @@ -217,9 +224,7 @@ void RunLoop(PRHandle proc) #endif UpdateSwitchState( event ); break; - } case kPREventTypeDMDFrameDisplayed: - { if (machineType == kPRMachineWPCAlphanumeric) { //UpdateAlphaDisplay(proc, dotOffset++); } @@ -228,37 +233,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); } } if (numEvents > 0) { From d415ac8614fb1707f8d9a05a9cb1f991f0ac2300 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 11:55:33 -0700 Subject: [PATCH 31/38] cmake: on Linux/macOS, link libusb-1.0 vs. libusb --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5422b5a..08b3083 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,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 From bb14a68037747f45f7b26f076a7a02dda43991f3 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 15:58:44 -0700 Subject: [PATCH 32/38] cleanup: move "\n" from start to end of printf() output --- examples/pinproctest/alphanumeric.cpp | 18 +++++++++++------- src/PRDevice.cpp | 16 ++++++++++------ utils/pinprocfw/pinprocfw.cpp | 6 +++--- 3 files changed, 24 insertions(+), 16 deletions(-) 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; idriverNum = i; driver->polarity = mappedDriverGroupPolarity[i/8]; - DEBUG(PRLog(kPRLogInfo,"\nDriver Polarity for Driver: %d is %x.", i,driver->polarity)); + DEBUG(PRLog(kPRLogInfo, "Driver Polarity for Driver: %d is %x.\n", + i, driver->polarity)); if (resetFlags & kPRResetFlagUpdateDevice) res = DriverUpdateState(driver); } @@ -474,7 +475,8 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint 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; @@ -495,7 +497,8 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint 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; @@ -516,7 +519,8 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint 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; diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index 870b64a..b7d8401 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -2037,7 +2037,7 @@ int verifyP3ROCImage(void) } } - //fprintf(stderr, "\nWriting Page: %x", pageAddr); + //fprintf(stderr, "Writing Page: 0x%x\n", pageAddr); P3ROC_SPIReadPage(pageAddr, &readBuffer[0]); if (memcmp(readBuffer, dataBuffer, sizeof readBuffer) != 0) { @@ -2086,12 +2086,12 @@ void writeP3ROCImage(void) } } - //fprintf(stderr, "\nWriting Page: %x", pageAddr); + //fprintf(stderr, "Writing Page: 0x%x\n", pageAddr); P3ROC_SPIWritePage(pageAddr, &dataBuffer[0]); //for (int i=0; i<64; i++) //{ - // fprintf(stderr, "\nPage: %x, Byte: %x:%x", pageAddr, i*4, dataBuffer[i]); + // fprintf(stderr, "Page: %x, Byte: %x:%x\n", pageAddr, i*4, dataBuffer[i]); //} pageAddr++; From c36d48bc64f35d03941e68f0627daf6204128400 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 15:59:02 -0700 Subject: [PATCH 33/38] cleanup: remove dead (#if 0) code --- src/PRDevice.cpp | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 0add6de..3cab9cb 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -893,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) From ed6540858bbaeb15b892746cac134c6f041fbdbb Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 16:00:38 -0700 Subject: [PATCH 34/38] cleanup: unbuffered stdout to avoid fflush() By setting stdout to unbuffered, the user always sees our output and we can eliminate the fflush() calls sprinkled throughout the programs. --- examples/pinproctest/pinproctest.cpp | 8 +++----- utils/pinprocfw/pinprocfw.cpp | 14 +++----------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 21a45d7..77d8c3f 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -48,7 +48,6 @@ void ConfigureAccelerometerMotion(PRHandle proc) PRReadData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10D, 1, readData); printf("Accel chip id: %x\n", readData[0]); - fflush(stdout); // Set FF_MT_COUNT (0x18) readData[0] = 1; @@ -96,7 +95,6 @@ void ConfigureAccelerometerTransient(PRHandle proc) PRReadData(proc, P3_ROC_BUS_ACCELEROMETER_SELECT, 0x10D, 1, readData); printf("Accel chip id: %x\n", readData[0]); - fflush(stdout); // Set to standby so register changes will take. readData[0] = 0x0; @@ -255,9 +253,6 @@ void RunLoop(PRHandle proc) printf("Unknown event: %x:%x\n", event->type, event->value); } } - if (numEvents > 0) { - fflush(stdout); - } PRFlushWriteData(proc); #ifdef _MSC_VER Sleep(10); @@ -292,6 +287,9 @@ 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); diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index b7d8401..43c32ac 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -533,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 ); @@ -547,11 +545,9 @@ void readByte(unsigned char *data) numBytesCurrent++; if (numBytesCurrent % bytesPerTenth == 0) { printf("\n%d0%% ",(int) (numBytesCurrent/bytesPerTenth)); - fflush(stdout); } else if (numBytesCurrent % bytesPer200th == 0) { printf("."); - fflush(stdout); } } @@ -1968,7 +1964,6 @@ void P3ROC_SPIBulkErase(void) // Send bulk_erase command printf("\nErasing flash ."); - fflush(stdout); dataBuffer[0] = P3_ROC_SPI_OPCODE_BULK_ERASE << P3_ROC_SPI_OPCODE_SHIFT; PRWriteData (proc, P3_ROC_BUS_SPI_SELECT, addr, 1, dataBuffer); P3ROC_SPIWaitForReady(); @@ -2012,7 +2007,6 @@ int verifyP3ROCImage(void) P3ROC_SPIWaitForReady(); printf("\n\nVerifying image:\n0%% "); - fflush(stdout); while (!feof(in)) { for (int i=0; i<64; i++) { @@ -2024,11 +2018,9 @@ int verifyP3ROCImage(void) numBytesCurrent++; if (numBytesCurrent % bytesPerTenth == 0) { printf("\n%d0%% ", (int)(numBytesCurrent / bytesPerTenth)); - fflush(stdout); } else if (numBytesCurrent % bytesPer200th == 0) { printf("."); - fflush(stdout); } } @@ -2064,7 +2056,6 @@ void writeP3ROCImage(void) P3ROC_SPIWaitForReady(); printf("\nProgramming new image:\n0%% "); - fflush(stdout); while (!feof(in)) { for (int i=0; i<64; i++) { if (!feof(in)) { @@ -2073,11 +2064,9 @@ void writeP3ROCImage(void) numBytesCurrent++; if (numBytesCurrent % bytesPerTenth == 0) { printf("\n%d0%% ", (int)(numBytesCurrent / bytesPerTenth)); - fflush(stdout); } else if (numBytesCurrent % bytesPer200th == 0) { printf("."); - fflush(stdout); } } @@ -2255,6 +2244,9 @@ int main( int argc, char** argv ) int i; int iErrorCode; + // Set stdout unbuffered to eliminate need to fflush() + setbuf(stdout, NULL); + iErrorCode = XSVF_ERRORCODE( XSVF_ERROR_NONE ); pzXsvfFileName = NULL; From 7c202fc2f4e9297a4471bcae99640831dc360f68 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Fri, 26 Jun 2020 16:30:50 -0700 Subject: [PATCH 35/38] doc: update README --- README.markdown | 62 +++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/README.markdown b/README.markdown index ea94a1a..8e591b5 100644 --- a/README.markdown +++ b/README.markdown @@ -8,21 +8,13 @@ Library for [Multimorphic, Inc.'s](https://www.multimorphic.com/) P-ROC and P3-R 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. -##### libusb-1.0 and libusb-compat +#### Building with CMake (Linux and macOS) -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 @@ -33,45 +25,59 @@ The CMakeLists.txt file is presently designed to be run from a directory inside 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. - -To build libpinproc: +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. -- Use -DEXTRA_INC=";" and -DEXTRA_LINK=";" to add include/library paths for `ftd2xx.h` and `ftd2xx.sys`. +#### Building in Windows with CMake and Visual Studio 2019 -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 +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`. -#### Building in Windows with Visual Studio 2019 - -Assumes you are already running an MSYS2/MinGW64 system. - -Make sure you have cmake installed for i686 (MinGW32) or x86_64 (MinGW64): `pacman -S cmake mingw-w64-i686-cmake mingw-w64-x86_64-cmake` +Example: cd libpinproc - mkdir build; cd build + 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. -Then 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`. +### 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. ### 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 From 3b9d035fb5c74d603b9d4a9fbe425b5d951ddca4 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Wed, 15 Jul 2020 17:02:49 -0700 Subject: [PATCH 36/38] cleanup: quiet PRGetLastErrorText() compiler warning --- include/pinproc.h | 2 +- src/pinproc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pinproc.h b/include/pinproc.h index 2f465c5..ccc2fe8 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -351,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 diff --git a/src/pinproc.cpp b/src/pinproc.cpp index c59313c..3d682ac 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -82,7 +82,7 @@ void PRSetLastErrorText(const char *format, ...) PRLog(kPRLogError, "%s\n", lastErrorText); } -const char *PRGetLastErrorText() +const char *PRGetLastErrorText(void) { return lastErrorText; } From 378b7338700403c5f1fb15821bef11c5a8b617b2 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Mon, 20 Jul 2020 15:06:06 -0700 Subject: [PATCH 37/38] pinprocfw: leave out unnecessary checksum printf() --- utils/pinprocfw/pinprocfw.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/utils/pinprocfw/pinprocfw.cpp b/utils/pinprocfw/pinprocfw.cpp index 43c32ac..3322c50 100644 --- a/utils/pinprocfw/pinprocfw.cpp +++ b/utils/pinprocfw/pinprocfw.cpp @@ -2142,8 +2142,6 @@ uint32_t checkPROCFile(void) { fprintf(stderr, "File version %d, for board_id 0x%08X (board revs %d to %d)\n", proc_file_version, file_board_id, min_board_rev, max_board_rev); - fprintf(stderr, "%d-byte data checksum 0x%08X, header checksum 0x%08X\n", - file_i, file_checksum, header_checksum); uint32_t readdata[4], board_id; PRReadData(proc, P_ROC_MANAGER_SELECT, P_ROC_REG_CHIP_ID_ADDR, 4, readdata); From 286c56694dae9f068e6ba14f8f625026f15e54c7 Mon Sep 17 00:00:00 2001 From: Tom Collins Date: Tue, 4 Aug 2020 09:18:51 -0700 Subject: [PATCH 38/38] build: advance version to 2.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08b3083..612de28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,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}")