Merge "Move interrupt methods to InterruptableSensorBase"

This commit is contained in:
Brad Miller (WPI)
2014-10-08 12:51:28 -07:00
committed by Gerrit Code Review
9 changed files with 83 additions and 214 deletions

View File

@@ -14,15 +14,15 @@ class AnalogTrigger;
* This class is used to get the current output value and also as a DigitalSource
* to provide routing of an output to digital subsystems on the FPGA such as
* Counter, Encoder, and Interrupt.
*
*
* The TriggerState output indicates the primary output value of the trigger. If the analog
* signal is less than the lower limit, the output is false. If the analog value is greater
* than the upper limit, then the output is true. If the analog value is in between, then
* the trigger output state maintains its most recent value.
*
*
* The InWindow output indicates whether or not the analog signal is inside the range defined
* by the limits.
*
*
* The RisingPulse and FallingPulse outputs detect an instantaneous transition from above the
* upper limit to below the lower limit, and vise versa. These pulses represent a rollover
* condition of a sensor and can be routed to an up / down couter or to interrupts. Because
@@ -40,7 +40,7 @@ class AnalogTriggerOutput : public DigitalSource
{
friend class AnalogTrigger;
public:
virtual ~AnalogTriggerOutput();
bool Get();
@@ -48,8 +48,6 @@ public:
virtual uint32_t GetChannelForRouting();
virtual uint32_t GetModuleForRouting();
virtual bool GetAnalogTriggerForRouting();
virtual void RequestInterrupts(InterruptHandlerFunction handler, void *param = NULL); ///< Asynchronus handler version.
virtual void RequestInterrupts(); ///< Synchronus Wait version.
protected:
AnalogTriggerOutput(AnalogTrigger *trigger, AnalogTriggerType outputType);

View File

@@ -28,11 +28,6 @@ public:
virtual uint32_t GetModuleForRouting();
virtual bool GetAnalogTriggerForRouting();
// Interruptable Interface
virtual void RequestInterrupts(InterruptHandlerFunction handler, void *param = NULL); ///< Asynchronus handler version.
virtual void RequestInterrupts(); ///< Synchronus Wait version.
void SetUpSourceEdge(bool risingEdge, bool fallingEdge);
void UpdateTable();
void StartLiveWindowMode();
void StopLiveWindowMode();

View File

@@ -32,10 +32,6 @@ public:
virtual uint32_t GetChannelForRouting();
virtual uint32_t GetModuleForRouting();
virtual bool GetAnalogTriggerForRouting();
virtual void RequestInterrupts(InterruptHandlerFunction handler, void *param);
virtual void RequestInterrupts();
void SetUpSourceEdge(bool risingEdge, bool fallingEdge);
virtual void ValueChanged(ITable* source, const std::string& key, EntryValue value, bool isNew);
void UpdateTable();

View File

@@ -21,6 +21,4 @@ public:
virtual uint32_t GetChannelForRouting() = 0;
virtual uint32_t GetModuleForRouting() = 0;
virtual bool GetAnalogTriggerForRouting() = 0;
virtual void RequestInterrupts(InterruptHandlerFunction handler, void *param) = 0;
virtual void RequestInterrupts() = 0;
};

View File

@@ -21,14 +21,18 @@ public:
InterruptableSensorBase();
virtual ~InterruptableSensorBase();
virtual void RequestInterrupts(InterruptHandlerFunction handler, void *param) = 0; ///< Asynchronus handler version.
virtual void RequestInterrupts() = 0; ///< Synchronus Wait version.
virtual uint32_t GetChannelForRouting() = 0;
virtual uint32_t GetModuleForRouting() = 0;
virtual bool GetAnalogTriggerForRouting() = 0;
virtual void RequestInterrupts(InterruptHandlerFunction handler, void *param); ///< Asynchronus handler version.
virtual void RequestInterrupts(); ///< Synchronus Wait version.
virtual void CancelInterrupts(); ///< Free up the underlying chipobject functions.
virtual WaitResult WaitForInterrupt(float timeout, bool ignorePrevious = true); ///< Synchronus version.
virtual void EnableInterrupts(); ///< Enable interrupts - after finishing setup.
virtual void DisableInterrupts(); ///< Disable, but don't deallocate.
virtual double ReadRisingTimestamp();///< Return the timestamp for the rising interrupt that occurred.
virtual double ReadFallingTimestamp();///< Return the timestamp for the falling interrupt that occurred.
virtual void SetUpSourceEdge(bool risingEdge, bool fallingEdge);
protected:
void* m_interrupt;
uint32_t m_interruptIndex;

View File

@@ -72,54 +72,3 @@ bool AnalogTriggerOutput::GetAnalogTriggerForRouting()
{
return true;
}
/**
* Request interrupts asynchronously on this analog trigger output.
* @param handler The address of the interrupt handler function of type tInterruptHandler that
* will be called whenever there is an interrupt on the digitial input port.
* Request interrupts in synchronus mode where the user program interrupt handler will be
* called when an interrupt occurs.
*/
void AnalogTriggerOutput::RequestInterrupts(InterruptHandlerFunction handler, void *param)
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Async Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
AllocateInterrupts(false);
int32_t status = 0;
requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
attachInterruptHandler(m_interrupt, handler, param, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
/**
* Request interrupts synchronously on this analog trigger output.
* Request interrupts in asynchronus mode where the user program will have to
* explicitly wait for the interrupt to occur.
*/
void AnalogTriggerOutput::RequestInterrupts()
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Sync Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
AllocateInterrupts(true);
int32_t status = 0;
requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}

View File

@@ -109,78 +109,6 @@ bool DigitalInput::GetAnalogTriggerForRouting()
return false;
}
/**
* Request interrupts asynchronously on this digital input.
* @param handler The address of the interrupt handler function of type tInterruptHandler that
* will be called whenever there is an interrupt on the digitial input port.
* Request interrupts in asynchronus mode where the user program interrupt handler will be
* called when an interrupt occurs.
* The default is interrupt on rising edges only.
*/
void DigitalInput::RequestInterrupts(InterruptHandlerFunction handler, void *param)
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Async Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
// Creates a manager too
AllocateInterrupts(false);
int32_t status = 0;
requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
SetUpSourceEdge(true, false);
attachInterruptHandler(m_interrupt, handler, param, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
/**
* Request interrupts synchronously on this digital input.
* Request interrupts in synchronus mode where the user program will have to explicitly
* wait for the interrupt to occur.
* The default is interrupt on rising edges only.
*/
void DigitalInput::RequestInterrupts()
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Sync Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
AllocateInterrupts(true);
int32_t status = 0;
requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
SetUpSourceEdge(true, false);
}
void DigitalInput::SetUpSourceEdge(bool risingEdge, bool fallingEdge)
{
if (StatusIsFatal()) return;
if (m_interrupt == NULL)
{
wpi_setWPIErrorWithContext(NullParameter, "You must call RequestInterrupts before SetUpSourceEdge");
return;
}
if (m_interrupt != NULL)
{
int32_t status = 0;
setInterruptUpSourceEdge(m_interrupt, risingEdge, fallingEdge, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
void DigitalInput::UpdateTable() {
if (m_table != NULL) {
m_table->PutBoolean("Value", Get());

View File

@@ -222,78 +222,6 @@ bool DigitalOutput::GetAnalogTriggerForRouting()
return false;
}
/**
* Request interrupts asynchronously on this digital output.
* @param handler The address of the interrupt handler function of type tInterruptHandler that
* will be called whenever there is an interrupt on the digitial output port.
* Request interrupts in synchronus mode where the user program interrupt handler will be
* called when an interrupt occurs.
* The default is interrupt on rising edges only.
*/
void DigitalOutput::RequestInterrupts(InterruptHandlerFunction handler, void *param)
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Sync Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
// Creates a manager too
AllocateInterrupts(false);
int32_t status = 0;
requestInterrupts(m_interrupt, 1, GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
SetUpSourceEdge(true, false);
attachInterruptHandler(m_interrupt, handler, param, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
/**
* Request interrupts synchronously on this digital output.
* Request interrupts in synchronus mode where the user program will have to explicitly
* wait for the interrupt to occur.
* The default is interrupt on rising edges only.
*/
void DigitalOutput::RequestInterrupts()
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Sync Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
AllocateInterrupts(true);
int32_t status = 0;
requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
SetUpSourceEdge(true, false);
}
void DigitalOutput::SetUpSourceEdge(bool risingEdge, bool fallingEdge)
{
if (StatusIsFatal()) return;
if (m_interrupt == NULL)
{
wpi_setWPIErrorWithContext(NullParameter, "You must call RequestInterrupts before SetUpSourceEdge");
return;
}
if (m_interrupt != NULL)
{
int32_t status = 0;
setInterruptUpSourceEdge(m_interrupt, risingEdge, fallingEdge, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}
void DigitalOutput::ValueChanged(ITable* source, const std::string& key, EntryValue value, bool isNew) {
Set(value.b);
}

View File

@@ -6,6 +6,7 @@
#include "InterruptableSensorBase.h"
#include "Utility.h"
#include "WPIErrors.h"
Resource *InterruptableSensorBase::m_interrupts = NULL;
@@ -20,6 +21,54 @@ InterruptableSensorBase::~InterruptableSensorBase()
}
void InterruptableSensorBase::RequestInterrupts(InterruptHandlerFunction handler, void *param)
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Async Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
// Creates a manager too
AllocateInterrupts(false);
int32_t status = 0;
requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
SetUpSourceEdge(true, false);
attachInterruptHandler(m_interrupt, handler, param, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
/**
* Request interrupts synchronously on this digital input.
* Request interrupts in synchronus mode where the user program will have to explicitly
* wait for the interrupt to occur.
* The default is interrupt on rising edges only.
*/
void InterruptableSensorBase::RequestInterrupts()
{
if (StatusIsFatal()) return;
uint32_t index = m_interrupts->Allocate("Sync Interrupt");
if (index == ~0ul)
{
CloneError(m_interrupts);
return;
}
m_interruptIndex = index;
AllocateInterrupts(true);
int32_t status = 0;
requestInterrupts(m_interrupt, GetModuleForRouting(), GetChannelForRouting(),
GetAnalogTriggerForRouting(), &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
SetUpSourceEdge(true, false);
}
void InterruptableSensorBase::AllocateInterrupts(bool watcher)
{
wpi_assert(m_interrupt == NULL);
@@ -117,3 +166,27 @@ double InterruptableSensorBase::ReadFallingTimestamp()
wpi_setErrorWithContext(status, getHALErrorMessage(status));
return timestamp;
}
/**
* Set which edge to trigger interrupts on
*
* @param risingEdge
* true to interrupt on rising edge
* @param fallingEdge
* true to interrupt on falling edge
*/
void InterruptableSensorBase::SetUpSourceEdge(bool risingEdge, bool fallingEdge)
{
if (StatusIsFatal()) return;
if (m_interrupt == NULL)
{
wpi_setWPIErrorWithContext(NullParameter, "You must call RequestInterrupts before SetUpSourceEdge");
return;
}
if (m_interrupt != NULL)
{
int32_t status = 0;
setInterruptUpSourceEdge(m_interrupt, risingEdge, fallingEdge, &status);
wpi_setErrorWithContext(status, getHALErrorMessage(status));
}
}