jerrym | f157933 | 2013-02-07 01:56:28 +0000 | [diff] [blame] | 1 | /*----------------------------------------------------------------------------*/
|
| 2 | /* Copyright (c) FIRST 2008. All Rights Reserved. */
|
| 3 | /* Open Source Software - may be modified and shared by FRC teams. The code */
|
| 4 | /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
| 5 | /*----------------------------------------------------------------------------*/
|
| 6 |
|
| 7 | #include "Watchdog.h"
|
| 8 |
|
| 9 | const double Watchdog::kDefaultWatchdogExpiration;
|
| 10 |
|
| 11 | /**
|
| 12 | * The Watchdog is born.
|
| 13 | */
|
| 14 | Watchdog::Watchdog()
|
| 15 | : m_fpgaWatchDog(NULL)
|
| 16 | {
|
| 17 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 18 | m_fpgaWatchDog = tWatchdog::create(&localStatus);
|
| 19 | wpi_setError(localStatus);
|
| 20 | SetExpiration(kDefaultWatchdogExpiration);
|
| 21 | SetEnabled(true);
|
| 22 | }
|
| 23 |
|
| 24 | /**
|
| 25 | * Time to bury him in the back yard.
|
| 26 | */
|
| 27 | Watchdog::~Watchdog()
|
| 28 | {
|
| 29 | SetEnabled(false);
|
| 30 | delete m_fpgaWatchDog;
|
| 31 | m_fpgaWatchDog = NULL;
|
| 32 | }
|
| 33 |
|
| 34 | /**
|
| 35 | * Throw the dog a bone.
|
| 36 | *
|
| 37 | * When everything is going well, you feed your dog when you get home.
|
| 38 | * Let's hope you don't drive your car off a bridge on the way home...
|
| 39 | * Your dog won't get fed and he will starve to death.
|
| 40 | *
|
| 41 | * By the way, it's not cool to ask the neighbor (some random task) to
|
| 42 | * feed your dog for you. He's your responsibility!
|
| 43 | *
|
| 44 | * @returns Returns the previous state of the watchdog before feeding it.
|
| 45 | */
|
| 46 | bool Watchdog::Feed()
|
| 47 | {
|
| 48 | bool previous = GetEnabled();
|
| 49 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 50 | m_fpgaWatchDog->strobeFeed(&localStatus);
|
| 51 | wpi_setError(localStatus);
|
| 52 | return previous;
|
| 53 | }
|
| 54 |
|
| 55 | /**
|
| 56 | * Put the watchdog out of its misery.
|
| 57 | *
|
| 58 | * Don't wait for your dying robot to starve when there is a problem.
|
| 59 | * Kill it quickly, cleanly, and humanely.
|
| 60 | */
|
| 61 | void Watchdog::Kill()
|
| 62 | {
|
| 63 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 64 | m_fpgaWatchDog->strobeKill(&localStatus);
|
| 65 | wpi_setError(localStatus);
|
| 66 | }
|
| 67 |
|
| 68 | /**
|
| 69 | * Read how long it has been since the watchdog was last fed.
|
| 70 | *
|
| 71 | * @return The number of seconds since last meal.
|
| 72 | */
|
| 73 | double Watchdog::GetTimer()
|
| 74 | {
|
| 75 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 76 | UINT32 timer = m_fpgaWatchDog->readTimer(&localStatus);
|
| 77 | wpi_setError(localStatus);
|
| 78 | return timer / (kSystemClockTicksPerMicrosecond * 1e6);
|
| 79 | }
|
| 80 |
|
| 81 | /**
|
| 82 | * Read what the current expiration is.
|
| 83 | *
|
| 84 | * @return The number of seconds before starvation following a meal (watchdog starves if it doesn't eat this often).
|
| 85 | */
|
| 86 | double Watchdog::GetExpiration()
|
| 87 | {
|
| 88 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 89 | UINT32 expiration = m_fpgaWatchDog->readExpiration(&localStatus);
|
| 90 | wpi_setError(localStatus);
|
| 91 | return expiration / (kSystemClockTicksPerMicrosecond * 1e6);
|
| 92 | }
|
| 93 |
|
| 94 | /**
|
| 95 | * Configure how many seconds your watchdog can be neglected before it starves to death.
|
| 96 | *
|
| 97 | * @param expiration The number of seconds before starvation following a meal (watchdog starves if it doesn't eat this often).
|
| 98 | */
|
| 99 | void Watchdog::SetExpiration(double expiration)
|
| 100 | {
|
| 101 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 102 | m_fpgaWatchDog->writeExpiration((UINT32)(expiration * (kSystemClockTicksPerMicrosecond * 1e6)), &localStatus);
|
| 103 | wpi_setError(localStatus);
|
| 104 | }
|
| 105 |
|
| 106 | /**
|
| 107 | * Find out if the watchdog is currently enabled or disabled (mortal or immortal).
|
| 108 | *
|
| 109 | * @return Enabled or disabled.
|
| 110 | */
|
| 111 | bool Watchdog::GetEnabled()
|
| 112 | {
|
| 113 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 114 | bool enabled = !m_fpgaWatchDog->readImmortal(&localStatus);
|
| 115 | wpi_setError(localStatus);
|
| 116 | return enabled;
|
| 117 | }
|
| 118 |
|
| 119 | /**
|
| 120 | * Enable or disable the watchdog timer.
|
| 121 | *
|
| 122 | * When enabled, you must keep feeding the watchdog timer to
|
| 123 | * keep the watchdog active, and hence the dangerous parts
|
| 124 | * (motor outputs, etc.) can keep functioning.
|
| 125 | * When disabled, the watchdog is immortal and will remain active
|
| 126 | * even without being fed. It will also ignore any kill commands
|
| 127 | * while disabled.
|
| 128 | *
|
| 129 | * @param enabled Enable or disable the watchdog.
|
| 130 | */
|
| 131 | void Watchdog::SetEnabled(bool enabled)
|
| 132 | {
|
| 133 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 134 | m_fpgaWatchDog->writeImmortal(!enabled, &localStatus);
|
| 135 | wpi_setError(localStatus);
|
| 136 | }
|
| 137 |
|
| 138 | /**
|
| 139 | * Check in on the watchdog and make sure he's still kicking.
|
| 140 | *
|
| 141 | * This indicates that your watchdog is allowing the system to operate.
|
| 142 | * It is still possible that the network communications is not allowing the
|
| 143 | * system to run, but you can check this to make sure it's not your fault.
|
| 144 | * Check IsSystemActive() for overall system status.
|
| 145 | *
|
| 146 | * If the watchdog is disabled, then your watchdog is immortal.
|
| 147 | *
|
| 148 | * @return Is the watchdog still alive?
|
| 149 | */
|
| 150 | bool Watchdog::IsAlive()
|
| 151 | {
|
| 152 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 153 | bool alive = m_fpgaWatchDog->readStatus_Alive(&localStatus);
|
| 154 | wpi_setError(localStatus);
|
| 155 | return alive;
|
| 156 | }
|
| 157 |
|
| 158 | /**
|
| 159 | * Check on the overall status of the system.
|
| 160 | *
|
| 161 | * @return Is the system active (i.e. PWM motor outputs, etc. enabled)?
|
| 162 | */
|
| 163 | bool Watchdog::IsSystemActive()
|
| 164 | {
|
| 165 | tRioStatusCode localStatus = NiFpga_Status_Success;
|
| 166 | bool alive = m_fpgaWatchDog->readStatus_SystemActive(&localStatus);
|
| 167 | wpi_setError(localStatus);
|
| 168 | return alive;
|
| 169 | }
|
| 170 |
|