copied everything over from 2012 and removed all of the actual robot code except the drivetrain stuff
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4078 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/aos/crio/shared_libs/interrupt_bridge.h b/aos/crio/shared_libs/interrupt_bridge.h
new file mode 100644
index 0000000..85ecd0f
--- /dev/null
+++ b/aos/crio/shared_libs/interrupt_bridge.h
@@ -0,0 +1,140 @@
+#ifndef AOS_CRIO_SHARED_LIBS_INTERRUPT_BRIDGE_H_
+#define AOS_CRIO_SHARED_LIBS_INTERRUPT_BRIDGE_H_
+
+#include <wdLib.h>
+#include <semLib.h>
+#include <timers.h>
+#include <signal.h>
+
+#include "aos/common/scoped_ptr.h"
+
+#include "aos/aos_core.h"
+
+class Task;
+
+namespace aos {
+namespace crio {
+
+// Handles creating a separate Task at a high priority with a semaphore to
+// link it to something else that provides timing information (likely in an ISR
+// context).
+template<typename T>
+class InterruptBridge {
+ public:
+ // The default priority. Here as a constant for subclasses to use as a default
+ // too.
+ static const int kDefaultPriority = 96;
+ typedef void (*Handler)(T *param);
+
+ // Stops calling the handler at all until a Start function is called again.
+ void Stop();
+
+ protected:
+ // < 95 priority does not work, and < 100 isn't guaranteed to work
+ InterruptBridge(Handler handler, T *param, int priority);
+ // Subclasses should call StopNotifications.
+ virtual ~InterruptBridge();
+
+ // Subclasses should call this whenever the Notifier triggers.
+ // It is safe to call from an ISR.
+ void Notify();
+ // Starts the actual Task.
+ void StartTask();
+
+ private:
+ const Handler handler_;
+ T *const param_;
+
+ // Subclasses should do whatever they have to to stop calling Notify().
+ virtual void StopNotifications() = 0;
+
+ // The function that the Task runs.
+ // Loops forever, waiting for sem_ and then calling handler_.
+ static void HandlerLoop(void *self_in);
+ const scoped_ptr<Task> task_;
+ // For synchronizing between the Task and Notify().
+ SEM_ID sem_;
+ DISALLOW_COPY_AND_ASSIGN(InterruptBridge<T>);
+};
+
+// An accurate version of WPILib's Notifier class.
+template<typename T>
+class PeriodicNotifier : public InterruptBridge<T> {
+ public:
+ // Period is how much (in seconds) to wait between running the handler.
+ void StartPeriodic(double period);
+
+ protected:
+ PeriodicNotifier(typename InterruptBridge<T>::Handler handler, T *param,
+ int priority);
+ virtual ~PeriodicNotifier() {}
+
+ private:
+ virtual void StopNotifications() = 0;
+ // Subclasses should do whatever they have to to start calling Notify() every
+ // period seconds.
+ virtual void StartNotifications(double period) = 0;
+};
+
+// This one works accurately, but it has the potential to drift over time.
+// It has only sysClockRateGet() resolution.
+template<typename T>
+class WDInterruptNotifier : public PeriodicNotifier<T> {
+ public:
+ WDInterruptNotifier(typename InterruptBridge<T>::Handler handler,
+ T *param = NULL,
+ int priority = InterruptBridge<T>::kDefaultPriority);
+ virtual ~WDInterruptNotifier();
+
+ private:
+ // The argument is the general callback parameter which will be a pointer to
+ // an instance. This function calls Notify() on that instance.
+ static void StaticNotify(void *self_in);
+ virtual void StopNotifications();
+ virtual void StartNotifications(double period);
+
+ WDOG_ID wd_;
+ int delay_; // what to pass to wdStart
+ DISALLOW_COPY_AND_ASSIGN(WDInterruptNotifier<T>);
+};
+
+// Vxworks (really really) should take care of making sure that this one
+// doesn't drift over time, but IT DOESN'T!! Brian found the implementation
+// online (file timerLib.c), and it's just doing the same thing as
+// WDInterruptNotifier, except with extra conversions and overhead to implement
+// the POSIX standard. There really is no reason to use this.
+// It has only sysClockRateGet() resolution.
+template<typename T>
+class TimerNotifier : public PeriodicNotifier<T> {
+ public:
+ // unique should be different for all instances created in the same Task. It
+ // can range from 0 to (SIGRTMAX - SIGRTMIN). This instance will use the
+ // signal (SIGRTMIN + unique), so nothing else should use that signal.
+ TimerNotifier(typename InterruptBridge<T>::Handler handler,
+ T *param = NULL,
+ int unique = 0,
+ int priority = InterruptBridge<T>::kDefaultPriority);
+ virtual ~TimerNotifier();
+
+ private:
+ // The first argument is the signal number that is being triggered. This
+ // function looks up a pointer to an instance in timer_notifiers using that
+ // and calls Notify() on that instance.
+ static void StaticNotify(int signum);
+ virtual void StopNotifications();
+ virtual void StartNotifications(double period);
+
+ timer_t timer_;
+ // Which signal timer_ will notify on.
+ const int signal_;
+ // What the action for signal_ was before we started messing with it.
+ struct sigaction old_sa_;
+ DISALLOW_COPY_AND_ASSIGN(TimerNotifier<T>);
+};
+
+} // namespace crio
+} // namespace aos
+
+#include "aos/crio/shared_libs/interrupt_bridge-tmpl.h"
+
+#endif // AOS_CRIO_SHARED_LIBS_INTERRUPT_BRIDGE_H_