blob: 55c4660f8e1e1d1e86df276ab3008f534f3bfe4c [file] [log] [blame]
Brian Silverman1a675112016-02-20 20:42:49 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2016. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
Brian Silverman26e4e522015-12-17 01:56:40 -05008#include "HAL/Interrupts.hpp"
9#include "ChipObject.h"
10
11extern void remapDigitalSource(bool analogTrigger, uint32_t &pin, uint8_t &module);
12
13struct Interrupt // FIXME: why is this internal?
14{
15 tInterrupt *anInterrupt;
16 tInterruptManager *manager;
17};
18
Brian Silverman1a675112016-02-20 20:42:49 -050019extern "C" {
20
Brian Silverman26e4e522015-12-17 01:56:40 -050021void* initializeInterrupts(uint32_t interruptIndex, bool watcher, int32_t *status)
22{
23 Interrupt* anInterrupt = new Interrupt();
24 // Expects the calling leaf class to allocate an interrupt index.
25 anInterrupt->anInterrupt = tInterrupt::create(interruptIndex, status);
26 anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
27 anInterrupt->manager = new tInterruptManager(
28 (1 << interruptIndex) | (1 << (interruptIndex + 8)), watcher, status);
29 return anInterrupt;
30}
31
32void cleanInterrupts(void* interrupt_pointer, int32_t *status)
33{
34 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
35 delete anInterrupt->anInterrupt;
36 delete anInterrupt->manager;
37 anInterrupt->anInterrupt = NULL;
38 anInterrupt->manager = NULL;
39}
40
41/**
42 * In synchronous mode, wait for the defined interrupt to occur.
43 * @param timeout Timeout in seconds
44 * @param ignorePrevious If true, ignore interrupts that happened before
45 * waitForInterrupt was called.
46 * @return The mask of interrupts that fired.
47 */
48uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, bool ignorePrevious, int32_t *status)
49{
50 uint32_t result;
51 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
52
53 result = anInterrupt->manager->watch((int32_t)(timeout * 1e3), ignorePrevious, status);
54
55 // Don't report a timeout as an error - the return code is enough to tell
56 // that a timeout happened.
57 if(*status == -NiFpga_Status_IrqTimeout) {
58 *status = NiFpga_Status_Success;
59 }
60
61 return result;
62}
63
64/**
65 * Enable interrupts to occur on this input.
66 * Interrupts are disabled when the RequestInterrupt call is made. This gives time to do the
67 * setup of the other options before starting to field interrupts.
68 */
69void enableInterrupts(void* interrupt_pointer, int32_t *status)
70{
71 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
72 anInterrupt->manager->enable(status);
73}
74
75/**
76 * Disable Interrupts without without deallocating structures.
77 */
78void disableInterrupts(void* interrupt_pointer, int32_t *status)
79{
80 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
81 anInterrupt->manager->disable(status);
82}
83
84/**
85 * Return the timestamp for the rising interrupt that occurred most recently.
86 * This is in the same time domain as GetClock().
87 * @return Timestamp in seconds since boot.
88 */
89double readRisingTimestamp(void* interrupt_pointer, int32_t *status)
90{
91 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
92 uint32_t timestamp = anInterrupt->anInterrupt->readRisingTimeStamp(status);
93 return timestamp * 1e-6;
94}
95
96/**
97* Return the timestamp for the falling interrupt that occurred most recently.
98* This is in the same time domain as GetClock().
99* @return Timestamp in seconds since boot.
100*/
101double readFallingTimestamp(void* interrupt_pointer, int32_t *status)
102{
103 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
104 uint32_t timestamp = anInterrupt->anInterrupt->readFallingTimeStamp(status);
105 return timestamp * 1e-6;
106}
107
108void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, uint32_t routing_pin,
109 bool routing_analog_trigger, int32_t *status)
110{
111 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
112 anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
113 remapDigitalSource(routing_analog_trigger, routing_pin, routing_module);
114 anInterrupt->anInterrupt->writeConfig_Source_AnalogTrigger(routing_analog_trigger, status);
115 anInterrupt->anInterrupt->writeConfig_Source_Channel(routing_pin, status);
116 anInterrupt->anInterrupt->writeConfig_Source_Module(routing_module, status);
117}
118
119void attachInterruptHandler(void* interrupt_pointer, InterruptHandlerFunction handler, void* param,
120 int32_t *status)
121{
122 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
123 anInterrupt->manager->registerHandler(handler, param, status);
124}
125
126void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, bool fallingEdge,
127 int32_t *status)
128{
129 Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
130 anInterrupt->anInterrupt->writeConfig_RisingEdge(risingEdge, status);
131 anInterrupt->anInterrupt->writeConfig_FallingEdge(fallingEdge, status);
132}
Brian Silverman1a675112016-02-20 20:42:49 -0500133
134} // extern "C"