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 }