10 #include "WPIErrors.h"
12 const uint32_t Notifier::kTimerInterruptNumber;
13 Notifier *Notifier::timerQueueHead = NULL;
15 tAlarm *Notifier::talarm = NULL;
16 tInterruptManager *Notifier::manager = NULL;
17 int Notifier::refcount = 0;
27 wpi_setWPIErrorWithContext(NullParameter,
"handler must not be NULL");
35 m_handlerSemaphore = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
36 tRioStatusCode localStatus = NiFpga_Status_Success;
42 manager =
new tInterruptManager(1 << kTimerInterruptNumber,
false, &localStatus);
43 manager->registerHandler(ProcessQueue, NULL, &localStatus);
44 manager->enable(&localStatus);
45 talarm = tAlarm::create(&localStatus);
49 wpi_setError(localStatus);
59 tRioStatusCode localStatus = NiFpga_Status_Success;
67 talarm->writeEnable(
false, &localStatus);
70 manager->disable(&localStatus);
75 wpi_setError(localStatus);
79 semTake(m_handlerSemaphore, WAIT_FOREVER);
81 semDelete(m_handlerSemaphore);
91 void Notifier::UpdateAlarm()
93 if (timerQueueHead != NULL)
95 tRioStatusCode localStatus = NiFpga_Status_Success;
97 talarm->writeTriggerTime((uint32_t)(timerQueueHead->m_expirationTime * 1e6), &localStatus);
99 talarm->writeEnable(
true, &localStatus);
100 wpi_setStaticError(timerQueueHead, localStatus);
110 void Notifier::ProcessQueue(uint32_t mask,
void *params)
117 double currentTime = GetClock();
118 current = timerQueueHead;
119 if (current == NULL || current->m_expirationTime > currentTime)
124 timerQueueHead = current->m_nextEvent;
125 if (current->m_periodic)
129 current->InsertInQueue(
true);
134 current->m_queued =
false;
138 semTake(current->m_handlerSemaphore, WAIT_FOREVER);
141 current->m_handler(current->m_param);
142 semGive(current->m_handlerSemaphore);
158 void Notifier::InsertInQueue(
bool reschedule)
162 m_expirationTime += m_period;
166 m_expirationTime = GetClock() + m_period;
168 if (timerQueueHead == NULL || timerQueueHead->m_expirationTime >= this->m_expirationTime)
172 this->m_nextEvent = timerQueueHead;
173 timerQueueHead =
this;
182 for (
Notifier **npp = &(timerQueueHead->m_nextEvent); ; npp = &(*npp)->m_nextEvent)
185 if (n == NULL || n->m_expirationTime > this->m_expirationTime)
188 this->m_nextEvent = n;
203 void Notifier::DeleteFromQueue()
208 wpi_assert(timerQueueHead != NULL);
209 if (timerQueueHead ==
this)
212 timerQueueHead = this->m_nextEvent;
217 for (
Notifier *n = timerQueueHead; n != NULL; n = n->m_nextEvent)
219 if (n->m_nextEvent ==
this)
222 n->m_nextEvent = this->m_nextEvent;
240 InsertInQueue(
false);
255 InsertInQueue(
false);
void StartPeriodic(double period)
Notifier(TimerEventHandler handler, void *param=NULL)
void StartSingle(double delay)