001 /*----------------------------------------------------------------------------*/
002 /* Copyright (c) FIRST 2008-2012. All Rights Reserved. */
003 /* Open Source Software - may be modified and shared by FRC teams. The code */
004 /* must be accompanied by the FIRST BSD license file in the root directory of */
005 /* the project. */
006 /*----------------------------------------------------------------------------*/
007
008 package edu.wpi.first.wpilibj;
009
010 import edu.wpi.first.wpilibj.fpga.tInterrupt;
011 import edu.wpi.first.wpilibj.fpga.tInterruptManager;
012
013 /**
014 * Base for sensors to be used with interrupts
015 */
016 public abstract class InterruptableSensorBase extends SensorBase {
017
018 /**
019 * The interrupt resource
020 */
021 protected tInterrupt m_interrupt;
022 /**
023 * The interrupt manager resource
024 */
025 protected tInterruptManager m_manager;
026 /**
027 * The index of the interrupt
028 */
029 protected int m_interruptIndex;
030 /**
031 * Resource manager
032 */
033 protected static Resource interrupts = new Resource(8);
034
035 /**
036 * Create a new InterrupatableSensorBase
037 */
038 public InterruptableSensorBase() {
039 m_manager = null;
040 m_interrupt = null;
041 }
042
043 /**
044 * Allocate the interrupt
045 * @param watcher
046 */
047 public void allocateInterrupts(boolean watcher) {
048 if (!watcher) {
049 throw new IllegalArgumentException("Interrupt callbacks not yet supported");
050 }
051 // Expects the calling leaf class to allocate an interrupt index.
052 m_interrupt = new tInterrupt((byte) m_interruptIndex);
053 m_interrupt.writeConfig_WaitForAck(false);
054 m_manager = new tInterruptManager(1 << m_interruptIndex, watcher);
055 }
056
057 /**
058 * Cancel interrupts on this device.
059 * This deallocates all the chipobject structures and disables any interrupts.
060 */
061 public void cancelInterrupts() {
062 if (m_interrupt == null || m_manager == null) {
063 throw new IllegalStateException();
064 }
065 m_interrupt.Release();
066 m_interrupt = null;
067 m_manager.Release();
068 m_manager = null;
069 }
070
071 /**
072 * In synchronous mode, wait for the defined interrupt to occur.
073 * @param timeout Timeout in seconds
074 */
075 public void waitForInterrupt(double timeout) {
076 m_manager.watch((int) (timeout * 1e3));
077 }
078
079 /**
080 * Enable interrupts to occur on this input.
081 * Interrupts are disabled when the RequestInterrupt call is made. This gives time to do the
082 * setup of the other options before starting to field interrupts.
083 */
084 public void enableInterrupts() {
085 throw new IllegalArgumentException("Interrupt callbacks not yet supported");
086 }
087
088 /**
089 * Disable Interrupts without without deallocating structures.
090 */
091 public void disableInterrupts() {
092 throw new IllegalArgumentException("Interrupt callbacks not yet supported");
093 }
094
095 /**
096 * Return the timestamp for the interrupt that occurred most recently.
097 * This is in the same time domain as getClock().
098 * @return Timestamp in seconds since boot.
099 */
100 public double readInterruptTimestamp() {
101 return m_interrupt.readTimeStamp() * 1e-6;
102 }
103 }