diff --git a/examples/pinproctest/pinproctest.cpp b/examples/pinproctest/pinproctest.cpp index 68edb68..1a489b2 100644 --- a/examples/pinproctest/pinproctest.cpp +++ b/examples/pinproctest/pinproctest.cpp @@ -52,8 +52,11 @@ void ConfigureDrivers(PRHandle proc) globals.matrixRowEnableIndex1 = 12; globals.matrixRowEnableIndex0 = 6; globals.activeLowMatrixRows = true; - globals.tickleWatchdog = false; + globals.tickleSternWatchdog = false; globals.encodeEnables = false; + globals.watchdogExpired = false; + globals.watchdogEnable = true; + globals.watchdogResetTime = 1000; // milliseconds // 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: @@ -118,6 +121,8 @@ void RunLoop(PRHandle proc) PREvent events[maxEvents]; while (runLoopRun) { + PRDriverWatchdogTickle(proc); + int numEvents = PRGetEvents(proc, events, maxEvents); for (int i = 0; i < numEvents; i++) { @@ -158,14 +163,18 @@ int main(const char **argv, int argc) printf("Configuring P-ROC...\n"); - ConfigureDrivers(proc); ConfigureSwitches(proc); + // Make Drivers the last thing to configure so watchdog doesn't expire + // before the RunLoop begins + ConfigureDrivers(proc); printf("Running. Hit Ctrl-C to exit.\n"); // Pulse a coil to test: // PRDriverDisable(proc, 80); -// PRDriverPulse(proc, 53, 100); + PRDriverPulse(proc, 53, 100); + PRDriverSchedule(proc, 80, 0xFF00FF00, 0, 0); + PRDriverPatter(proc, 84, 127, 127, 0); RunLoop(proc); diff --git a/include/pinproc.h b/include/pinproc.h index 9b2c1d8..923aece 100644 --- a/include/pinproc.h +++ b/include/pinproc.h @@ -122,7 +122,10 @@ typedef struct PRDriverGlobalConfig { uint8_t matrixRowEnableIndex0; bool_t activeLowMatrixRows; bool_t encodeEnables; - bool_t tickleWatchdog; + bool_t tickleSternWatchdog; + bool_t watchdogExpired; + bool_t watchdogEnable; + uint16_t watchdogResetTime; } PRDriverGlobalConfig; typedef struct PRDriverGroupConfig { @@ -168,9 +171,10 @@ PR_EXPORT PRResult PRDriverDisable(PRHandle handle, uint16_t driverNum); PR_EXPORT PRResult PRDriverPulse(PRHandle handle, uint16_t driverNum, int milliseconds); /** Assigns a repeating schedule to the given driver. */ PR_EXPORT PRResult PRDriverSchedule(PRHandle handle, uint16_t driverNum, uint32_t schedule, uint8_t cycleSeconds, bool_t now); - +/** Assigns a pitter-patter schedule (repeating on/off) to the given driver. */ PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t millisecondsOn, uint16_t millisecondsOff, uint16_t originalOnTime); - +/** Tickle the watchdog timer. */ +PR_EXPORT PRResult PRDriverWatchdogTickle(PRHandle handle); /** Disables (turns off) the given driver. */ PR_EXPORT void PRDriverStateDisable(PRDriverState *driverState); diff --git a/src/PRDevice.cpp b/src/PRDevice.cpp index 35b8a46..db14858 100644 --- a/src/PRDevice.cpp +++ b/src/PRDevice.cpp @@ -123,10 +123,9 @@ int PRDevice::GetEvents(PREvent *events, int maxEvents) return i; } - PRResult PRDevice::DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalConfig) { - const int burstWords = 2; + const int burstWords = 4; uint32_t burst[burstWords]; int32_t rc; @@ -134,8 +133,12 @@ PRResult PRDevice::DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalCo this->driverGlobalConfig = *driverGlobalConfig; rc = CreateDriverUpdateGlobalConfigBurst(burst, driverGlobalConfig); + rc = CreateWatchdogConfigBurst(burst+2, driverGlobalConfig->watchdogExpired, + driverGlobalConfig->watchdogEnable, + driverGlobalConfig->watchdogResetTime); - DEBUG(PRLog("Words: %x %x\n", burst[0], burst[1])); + DEBUG(PRLog("Driver Global words: %x %x\n", burst[0], burst[1])); + DEBUG(PRLog("Watchdog words: %x %x\n", burst[2], burst[3])); return WriteData(burst, burstWords); } @@ -188,6 +191,19 @@ PRResult PRDevice::DriverUpdateState(PRDriverState *driverState) } +PRResult PRDevice::DriverWatchdogTickle() +{ + const int burstWords = 2; + uint32_t burst[burstWords]; + int32_t rc; + + rc = CreateWatchdogConfigBurst(burst, driverGlobalConfig.watchdogExpired, + driverGlobalConfig.watchdogEnable, + driverGlobalConfig.watchdogResetTime); + + return WriteData(burst, burstWords); +} + PRSwitchRuleInternal *PRDevice::GetSwitchRuleByAddress(uint32_t addr) diff --git a/src/PRDevice.h b/src/PRDevice.h index 11498e8..a181458 100644 --- a/src/PRDevice.h +++ b/src/PRDevice.h @@ -66,6 +66,8 @@ public: PRResult SwitchesUpdateRule(uint8_t switchNum, PREventType eventType, PRSwitchRule *rule, PRDriverState *linkedDrivers, int numDrivers); + PRResult DriverWatchdogTickle(); + PRResult DMDUpdateGlobalConfig(PRDMDGlobalConfig *dmdGlobalConfig); PRResult DMDDraw(uint8_t * dots, uint16_t columns, uint8_t rows, uint8_t numSubFrames); diff --git a/src/PRHardware.cpp b/src/PRHardware.cpp index e5ba16c..a9a276e 100644 --- a/src/PRHardware.cpp +++ b/src/PRHardware.cpp @@ -72,8 +72,9 @@ int32_t CreateDriverUpdateGlobalConfigBurst ( uint32_t * burst, PRDriverGlobalCo P_ROC_DRIVER_GLOBAL_ACTIVE_LOW_MATRIX_ROWS_SHIFT) | (driver_globals->encodeEnables << P_ROC_DRIVER_GLOBAL_ENCODE_ENABLES_SHIFT) | - (driver_globals->tickleWatchdog << + (driver_globals->tickleSternWatchdog << P_ROC_DRIVER_GLOBAL_TICKLE_WATCHDOG_SHIFT) ); + return kPRSuccess; } @@ -125,6 +126,19 @@ int32_t CreateDriverUpdateBurst ( uint32_t * burst, PRDriverState *driver) { return kPRSuccess; } +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; +} + int32_t CreateSwitchRuleAddr(uint8_t switchNum, PREventType eventType) { uint32_t debounce = (eventType == kPREventTypeSwitchOpenDebounced) || (eventType == kPREventTypeSwitchClosedDebounced) ? 1 : 0; diff --git a/src/PRHardware.h b/src/PRHardware.h index 86640e1..0ec8f74 100644 --- a/src/PRHardware.h +++ b/src/PRHardware.h @@ -69,6 +69,10 @@ 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_EVENT_SWITCH_NUM_MASK = 0xFF; const uint32_t P_ROC_EVENT_SWITCH_STATE_MASK = 0x100; const uint32_t P_ROC_EVENT_SWITCH_STATE_SHIFT = 8; @@ -157,6 +161,8 @@ int32_t CreateDriverUpdateGlobalConfigBurst ( uint32_t * burst, PRDriverGlobalCo int32_t CreateDriverUpdateGroupConfigBurst ( uint32_t * burst, PRDriverGroupConfig *driver_group); int32_t CreateDriverUpdateBurst ( uint32_t * burst, PRDriverState *driver); int32_t CreateSwitchesUpdateRulesBurst ( uint32_t * burst, PRSwitchRuleInternal *rule_record); +int32_t CreateWatchdogConfigBurst ( uint32_t * burst, bool_t watchdogExpired, + bool_t watchdogEnable, uint16_t watchdogResetTime); int32_t CreateDMDUpdateGlobalConfigBurst ( uint32_t * burst, PRDMDConfig *dmd_config); void ParseSwitchAddress(uint32_t addr, uint8_t *switchNum, PREventType *eventType); diff --git a/src/pinproc.cpp b/src/pinproc.cpp index 8b1aa7d..e223f6f 100644 --- a/src/pinproc.cpp +++ b/src/pinproc.cpp @@ -133,7 +133,10 @@ PR_EXPORT PRResult PRDriverPatter(PRHandle handle, uint16_t driverNum, uint16_t PRDriverStatePatter(&driver, millisecondsOn, millisecondsOff, originalOnTime); return handleAsDevice->DriverUpdateState(&driver); } - +PR_EXPORT PRResult PRDriverWatchdogTickle(PRHandle handle) +{ + return handleAsDevice->DriverWatchdogTickle(); +} PR_EXPORT void PRDriverStateDisable(PRDriverState *driver) {