diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 521a642..3137f1b 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -216,7 +216,32 @@ int main(int argc, const char **argv) //PRDriverSchedule(proc, 0, 0xFF00AAAA, 1, 1); // Pitter-patter a feature lamp for testing purposes. //PRDriverPatter(proc, 84, 127, 127, 0); + + +/* + PRDriverAuxCommand auxCommands[256]; + + // Disable the first entry so the Aux logic won't begin immediately. + PRDriverAuxPrepareDisable(&auxCommands[0]); + // Set up a sequence of outputs. + for (i=0; i<16; i++) { + PRDriverAuxPrepareOutput(&(auxCommands[i+1]), i, 0, false, 8, false); + } + // Disable the last command so the sequence stops. + // PRDriverAuxPrepareDisable(&auxCommands[17]); + // Jump from addr 17 to 1 to repeat. + PRDriverAuxPrepareDelay(&auxCommands[17],1000); + PRDriverAuxPrepareJump(&auxCommands[18],1); + + // Send the commands. + PRDriverAuxSendCommands(proc, auxCommands, 19, 0); + + // Jump from addr 0 to 1 to begin. + PRDriverAuxPrepareJump(&auxCommands[0],1); + PRDriverAuxSendCommands(proc, auxCommands, 1, 0); + PRFlushWriteData(proc); +*/ printf("Running. Hit Ctrl-C to exit.\n"); @@ -231,6 +256,5 @@ int main(int argc, const char **argv) // Destroy the P-ROC device handle: PRDelete(proc); proc = kPRHandleInvalid; - return 0; } diff --git a/include/pinproc.h b/include/pinproc.h index 4515098..381b626 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -136,6 +136,10 @@ PR_EXPORT PRResult PRReadData(PRHandle handle, uint32_t moduleSelect, uint32_t s #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; @@ -176,6 +180,18 @@ typedef struct PRDriverState { bool_t patterEnable; } PRDriverState; +typedef struct PRDriverAuxCommand { + bool_t active; + bool_t useExtraData; + 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. */ PR_EXPORT PRResult PRDriverUpdateGlobalConfig(PRHandle handle, PRDriverGlobalConfig *driverGlobalConfig); @@ -218,6 +234,32 @@ PR_EXPORT PRResult PRDriverSchedule(PRHandle handle, uint16_t driverNum, uint32_ * This function is provided for convenience. See PRDriverStatePatter() for a full description. */ PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); +/** + * Assigns a pitter-patter schedule (repeating on/off) to the given driver for the given duration. + * This function is provided for convenience. See PRDriverStatePatter() for a full description. + */ +PR_EXPORT PRResult PRDriverPulsedPatter(PRHandle handle, uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); +/** + * Prepares an Aux Command to drive the Aux bus. + * This function is provided for convenience. + */ +PR_EXPORT void PRDriverAuxPrepareOutput(PRDriverAuxCommand *auxCommand, uint8_t data, uint8_t extraData, bool_t useExtraData, uint8_t enables, bool_t muxEnables); +/** + * Prepares an Aux Command to delay the Aux logic. + * This function is provided for convenience. + */ +PR_EXPORT 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. + */ +PR_EXPORT void PRDriverAuxPrepareJump(PRDriverAuxCommand *auxCommand, uint8_t jumpAddr); +/** + * Prepares a disabled Aux Command. + * This function is provided for convenience. + */ +PR_EXPORT void PRDriverAuxPrepareDisable(PRDriverAuxCommand *auxCommand); + /** Tickle the watchdog timer. */ PR_EXPORT PRResult PRDriverWatchdogTickle(PRHandle handle); @@ -247,6 +289,19 @@ PR_EXPORT void PRDriverStateSchedule(PRDriverState *driverState, uint32_t schedu */ PR_EXPORT void PRDriverStatePatter(PRDriverState *driverState, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); +/** + * @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. + */ +PR_EXPORT void PRDriverStatePulsedPatter(PRDriverState *driverState, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t patterTime); + +/** + * Write Aux Port commands into the Aux Port command memory. + */ + +PR_EXPORT 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). diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index a7a3567..cc9022f 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -90,6 +90,11 @@ PRResult PRDevice::Reset(uint32_t resetFlags) collected_bytes_wr_addr = 0; num_collected_bytes = 0; + // Initialize Ver/Rev + version = 0; + revision = 0; + combinedVersionRevision = 0; + // Make sure the data queues are empty. while (!unrequestedDataQueue.empty()) unrequestedDataQueue.pop(); while (!requestedDataQueue.empty()) requestedDataQueue.pop(); @@ -480,10 +485,30 @@ PRResult PRDevice::DriverLoadMachineTypeDefaults(PRMachineType machineType, uint else driverGlobalConfig = globals; - return res; } +PRResult PRDevice::DriverAuxSendCommands(PRDriverAuxCommand * commands, uint8_t numCommands, uint8_t startingAddr) +{ + int32_t k; + uint32_t commandBuffer[513]; + uint32_t convertedCommand; + uint32_t addr; + + addr = (P_ROC_DRIVER_AUX_MEM_DECODE << P_ROC_DRIVER_CTRL_DECODE_SHIFT) | + startingAddr; + + commandBuffer[0] = CreateBurstCommand(P_ROC_BUS_DRIVER_CTRL_SELECT, + addr, numCommands); + for (k=0; k> 16, buffer[2] & 0xffff)); + revision = buffer[2] & 0xffff; + version = buffer[2] >> 16; + DEBUG(PRLog(kPRLogError, "FPGA Chip Version/Rev: %d.%d\n", version, revision)); DEBUG(PRLog(kPRLogInfo, "Watchdog Settings: 0x%x\n", buffer[3])); DEBUG(PRLog(kPRLogInfo, "Switches: 0x%x\n", buffer[4])); @@ -1198,3 +1225,15 @@ PRResult PRDevice::SortReturningData() } return kPRSuccess; } + +int PRDevice::CalcCombinedVerRevision() +{ + combinedVersionRevision = (version * 0x10000) + revision; +} + +int PRDevice::GetVersionInfo(uint16_t *verPtr, uint16_t *revPtr, uint16_t *combinedPtr) +{ + *verPtr = version; + *revPtr = revision; + *combinedPtr = combinedVersionRevision; +} diff --git a/src/PRDevice.h b/src/PRDevice.h index 97a0f57..264ff7c 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -63,13 +63,13 @@ public: PRResult DriverGetState(uint8_t driverNum, PRDriverState *driverState); PRResult DriverUpdateState(PRDriverState *driverState); PRResult DriverLoadMachineTypeDefaults(PRMachineType machineType, uint32_t resetFlags = kPRResetFlagDefault); + PRResult DriverAuxSendCommands( PRDriverAuxCommand *commands, uint8_t numCommands, uint8_t startingAddr); + PRResult DriverWatchdogTickle(); PRResult SwitchUpdateConfig(PRSwitchConfig *switchConfig); PRResult SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers); PRResult SwitchGetStates(PREventType * switchStates, uint16_t numSwitches); - PRResult DriverWatchdogTickle(); - PRResult DMDUpdateConfig(PRDMDConfig *dmdConfig); PRResult DMDDraw(uint8_t * dots); @@ -79,6 +79,9 @@ public: PRResult PRJTAGReadTDIMemory(uint16_t tableOffset, uint16_t numWords, uint32_t * tdiData); PRResult PRJTAGGetStatus(PRJTAGStatus * status); + + int GetVersionInfo(uint16_t *verPtr, uint16_t *revPtr, uint16_t *combinedPtr); + protected: // Device I/O @@ -128,6 +131,14 @@ protected: queue unrequestedDataQueue; /**< Queue of words received from the device that were not requested via RequestData(). Usually switch events. */ queue requestedDataQueue; /**< Queue of words received from the device as the result of a call to RequestData(). */ + uint16_t version; + uint16_t revision; + uint16_t combinedVersionRevision; + /** + * Calculated combined Version/Revision number. + */ + int CalcCombinedVerRevision(); + uint32_t preparedWriteWords[maxWriteWords]; int32_t numPreparedWriteWords; diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index ef9df31..fede420 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -133,6 +133,44 @@ int32_t CreateDriverUpdateBurst ( uint32_t * burst, PRDriverState *driver) { return kPRSuccess; } +uint32_t CreateDriverAuxCommand ( PRDriverAuxCommand command) { + switch (command.command) { + case (kPRDriverAuxCmdOutput) : { + return (command.active << P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT) | + (command.useExtraData << P_ROC_DRIVER_AUX_USE_EXTRA_DATA_SHIFT) | + (command.muxEnables << P_ROC_DRIVER_AUX_MUX_ENABLES_SHIFT) | + ((command.command & P_ROC_DRIVER_AUX_COMMAND_MASK) << + P_ROC_DRIVER_AUX_COMMAND_SHIFT) | + ((command.enables & P_ROC_DRIVER_AUX_ENABLES_MASK) << + P_ROC_DRIVER_AUX_ENABLES_SHIFT) | + ((command.extraData & P_ROC_DRIVER_AUX_EXTRA_DATA_MASK) << + P_ROC_DRIVER_AUX_EXTRA_DATA_SHIFT) | + ((command.data & P_ROC_DRIVER_AUX_DATA_MASK) << + P_ROC_DRIVER_AUX_DATA_SHIFT); + } + break; + case (kPRDriverAuxCmdDelay) : { + return (command.active << P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT) | + ((command.command & P_ROC_DRIVER_AUX_COMMAND_MASK) << + P_ROC_DRIVER_AUX_COMMAND_SHIFT) | + ((command.delayTime & P_ROC_DRIVER_AUX_DELAY_TIME_MASK) << + P_ROC_DRIVER_AUX_DELAY_TIME_SHIFT); + } + break; + case (kPRDriverAuxCmdJump) : { + return (command.active << P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT) | + ((command.command & P_ROC_DRIVER_AUX_COMMAND_MASK) << + P_ROC_DRIVER_AUX_COMMAND_SHIFT) | + ((command.jumpAddr & P_ROC_DRIVER_AUX_JUMP_ADDR_MASK) << + P_ROC_DRIVER_AUX_JUMP_ADDR_SHIFT); + } + break; + default : { + return (false << P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT); + } + } +} + int32_t CreateWatchdogConfigBurst ( uint32_t * burst, bool_t watchdogExpired, bool_t watchdogEnable, uint16_t watchdogResetTime) { uint32_t addr; diff --git a/src/PRHardware.h b/src/PRHardware.h index c1c310d..28ea5ba 100644 --- a/src/PRHardware.h +++ b/src/PRHardware.h @@ -133,7 +133,7 @@ const uint32_t P_ROC_EVENT_SWITCH_DEBOUNCED_SHIFT = 9; 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_STATE_TABLE_DECODE = 2; +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; @@ -159,18 +159,38 @@ 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_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_TABLE_DRIVER_NUM_SHIFT = 1; +const uint32_t P_ROC_DRIVER_AUX_ENTRY_ACTIVE_SHIFT = 31; +const uint32_t P_ROC_DRIVER_AUX_USE_EXTRA_DATA_SHIFT = 20; +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 = 0x67; +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; @@ -225,12 +245,16 @@ uint32_t CreateBurstCommand ( uint32_t select, uint32_t addr, uint32_t num_words int32_t CreateDriverUpdateGlobalConfigBurst ( uint32_t * burst, PRDriverGlobalConfig *driver_globals); int32_t CreateDriverUpdateGroupConfigBurst ( uint32_t * burst, PRDriverGroupConfig *driver_group); int32_t CreateDriverUpdateBurst ( uint32_t * burst, PRDriverState *driver); -int32_t CreateSwitchUpdateConfigBurst ( uint32_t * burst, PRSwitchConfig *switchConfig); -int32_t CreateSwitchUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal *rule_record); +uint32_t CreateDriverAuxCommand ( PRDriverAuxCommand command); + int32_t CreateWatchdogConfigBurst ( uint32_t * burst, bool_t watchdogExpired, bool_t watchdogEnable, uint16_t watchdogResetTime); + int32_t CreateDMDUpdateConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config); +int32_t CreateSwitchUpdateConfigBurst ( uint32_t * burst, PRSwitchConfig *switchConfig); +int32_t CreateSwitchUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal *rule_record); + void ParseSwitchRuleIndex(uint16_t index, uint8_t *switchNum, PREventType *eventType); int16_t CreateSwitchRuleIndex(uint8_t switchNum, PREventType eventType); int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType); @@ -239,7 +263,6 @@ int32_t CreateJTAGLatchOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutpu int32_t CreateJTAGForceOutputsBurst ( uint32_t * burst, PRJTAGOutputs *jtagOutputs); int32_t CreateJTAGShiftTDODataBurst ( uint32_t * burst, uint16_t numBits, bool_t dataBlockComplete); - PRResult PRHardwareOpen(); void PRHardwareClose(); int PRHardwareRead(uint8_t *buffer, int maxBytes); diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 2f0a8a3..9eb70dd 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -186,6 +186,41 @@ PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t PRDriverStatePatter(&driver, millisecondsOn, millisecondsOff, originalOnTime); return handleAsDevice->DriverUpdateState(&driver); } +PR_EXPORT PRResult PRDriverAuxSendCommands(PRHandle handle, PRDriverAuxCommand * commands, uint8_t numCommands, uint8_t startingAddr) +{ + return handleAsDevice->DriverAuxSendCommands(commands, numCommands, startingAddr); +} + +PR_EXPORT void PRDriverAuxPrepareOutput(PRDriverAuxCommand *auxCommand, uint8_t data, uint8_t extraData, bool_t useExtraData, uint8_t enables, bool_t muxEnables) +{ + auxCommand->active = true; + auxCommand->data = data; + auxCommand->extraData = extraData; + auxCommand->enables = enables; + auxCommand->muxEnables = muxEnables; + auxCommand->useExtraData = useExtraData; + auxCommand->command = kPRDriverAuxCmdOutput; +} + +PR_EXPORT void PRDriverAuxPrepareDelay(PRDriverAuxCommand *auxCommand, uint16_t delayTime) +{ + auxCommand->active = true; + auxCommand->delayTime = delayTime; + auxCommand->command = kPRDriverAuxCmdDelay; +} + +PR_EXPORT void PRDriverAuxPrepareJump(PRDriverAuxCommand *auxCommand, uint8_t jumpAddr) +{ + auxCommand->active = true; + auxCommand->jumpAddr = jumpAddr; + auxCommand->command = kPRDriverAuxCmdJump; +} + +PR_EXPORT void PRDriverAuxPrepareDisable(PRDriverAuxCommand *auxCommand) +{ + auxCommand->active = false; +} + PR_EXPORT PRResult PRDriverWatchdogTickle(PRHandle handle) { return handleAsDevice->DriverWatchdogTickle(); @@ -223,7 +258,7 @@ PR_EXPORT void PRDriverStateSchedule(PRDriverState *driver, uint32_t schedule, u } PR_EXPORT void PRDriverStatePatter(PRDriverState *driver, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime) { - driver->state = originalOnTime != 0; + driver->state = true; driver->timeslots = 0; driver->waitForFirstTimeSlot = false; driver->outputDriveTime = originalOnTime; @@ -232,6 +267,17 @@ PR_EXPORT void PRDriverStatePatter(PRDriverState *driver, uint16_t millisecondsO driver->patterEnable = true; } +PR_EXPORT void PRDriverStatePulsedPatter(PRDriverState *driver, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t patterTime) +{ + driver->state = false; + driver->timeslots = 0; + driver->waitForFirstTimeSlot = false; + driver->outputDriveTime = patterTime; + driver->patterOnTime = millisecondsOn; + driver->patterOffTime = millisecondsOff; + driver->patterEnable = true; +} + PR_EXPORT uint16_t PRDecode(PRMachineType machineType, const char *str) { uint16_t x;