summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/nds/libnds/include/nds/interrupts.h
blob: 5f31190fdaed4c0b60fb98e3448e7a477758fb02 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*---------------------------------------------------------------------------------
	Interrupt registers and vector pointers

	Copyright (C) 2005
		Jason Rogers (dovoto)
		Dave Murphy (WinterMute)

	This software is provided 'as-is', without any express or implied
	warranty.  In no event will the authors be held liable for any
	damages arising from the use of this software.

	Permission is granted to anyone to use this software for any
	purpose, including commercial applications, and to alter it and
	redistribute it freely, subject to the following restrictions:

	1.	The origin of this software must not be misrepresented; you
		must not claim that you wrote the original software. If you use
		this software in a product, an acknowledgment in the product
		documentation would be appreciated but is not required.

	2.	Altered source versions must be plainly marked as such, and
		must not be misrepresented as being the original software.

	3.	This notice may not be removed or altered from any source
		distribution.


---------------------------------------------------------------------------------*/

/*! \file interrupts.h

    \brief nds interrupt support.

*/

#ifndef NDS_INTERRUPTS_INCLUDE
#define NDS_INTERRUPTS_INCLUDE

#include <nds/jtypes.h>

/*! \enum IRQ_MASKS
	\brief values allowed for REG_IE and REG_IF

*/
enum IRQ_MASKS {
	IRQ_VBLANK			=	BIT(0),		/*!< vertical blank interrupt mask */
	IRQ_HBLANK			=	BIT(1),		/*!< horizontal blank interrupt mask */
	IRQ_VCOUNT			=	BIT(2),		/*!< vcount match interrupt mask */
	IRQ_TIMER0			=	BIT(3),		/*!< timer 0 interrupt mask */
	IRQ_TIMER1			=	BIT(4),		/*!< timer 1 interrupt mask */
	IRQ_TIMER2			=	BIT(5),		/*!< timer 2 interrupt mask */
	IRQ_TIMER3			=	BIT(6),		/*!< timer 3 interrupt mask */
	IRQ_NETWORK			=	BIT(7),		/*!< serial interrupt mask */
	IRQ_DMA0			=	BIT(8),		/*!< DMA 0 interrupt mask */
	IRQ_DMA1			=	BIT(9),		/*!< DMA 1 interrupt mask */
	IRQ_DMA2			=	BIT(10),	/*!< DMA 2 interrupt mask */
	IRQ_DMA3			=	BIT(11),	/*!< DMA 3 interrupt mask */
	IRQ_KEYS			=	BIT(12),	/*!< Keypad interrupt mask */
	IRQ_CART			=	BIT(13),	/*!< GBA cartridge interrupt mask */
	IRQ_IPC_SYNC		=	BIT(16),	/*!< IPC sync interrupt mask */
	IRQ_FIFO_EMPTY		=	BIT(17),	/*!< Send FIFO empty interrupt mask */
	IRQ_FIFO_NOT_EMPTY	=	BIT(18),	/*!< Receive FIFO empty interrupt mask */
	IRQ_CARD			=	BIT(19),	/*!< interrupt mask */
	IRQ_CARD_LINE		=	BIT(20),	/*!< interrupt mask */
	IRQ_GEOMETRY_FIFO	=	BIT(21),	/*!< geometry FIFO interrupt mask */
	IRQ_LID				=	BIT(22),	/*!< interrupt mask */
	IRQ_SPI				=	BIT(23),	/*!< SPI interrupt mask */
	IRQ_WIFI			=	BIT(24),	/*!< WIFI interrupt mask (ARM7)*/
	IRQ_ALL				=	(~0)
};

#define MAX_INTERRUPTS  25

typedef enum IRQ_MASKS IRQ_MASK;

/*! \def REG_IE

    \brief Interrupt Enable Register.

	This is the activation mask for the internal interrupts.  Unless
	the corresponding bit is set, the IRQ will be masked out.
*/
#define REG_IE	(*(vuint32*)0x04000210)

/*! \def REG_IF

    \brief Interrupt Flag Register.

	Since there is only one hardware interrupt vector, the IF register
	contains flags to indicate when a particular of interrupt has occured.
	To acknowledge processing interrupts, set IF to the value of the
	interrupt handled.

*/
#define REG_IF	(*(vuint32*)0x04000214)

/*! \def REG_IME

    \brief Interrupt Master Enable Register.

	When bit 0 is clear, all interrupts are masked.  When it is 1,
	interrupts will occur if not masked out in REG_IE.

*/
#define REG_IME	(*(vuint16*)0x04000208)

/*! \enum IME_VALUE
	\brief values allowed for REG_IME
*/
enum IME_VALUE {
	IME_DISABLE = 0, 	/*!< Disable all interrupts. */
	IME_ENABLE = 1,	/*!< Enable all interrupts not masked out in REG_IE */
};


#ifdef __cplusplus
extern "C" {
#endif


extern VoidFunctionPointer	__irq_vector[];
extern	vuint32	__irq_flags[];
#define VBLANK_INTR_WAIT_FLAGS  *(__irq_flags)
#define IRQ_HANDLER             *(__irq_vector)

struct IntTable{IntFn handler; u32 mask;};

/*! \fn irqInit(void)
	\brief Initialise the libnds interrupt system.

	Call this function at the start of any application which requires interrupt support.
	This function should be used in preference to irqInitHandler.

*/
void irqInit(void);
/*! \fn irqSet(IRQ_MASK irq, VoidFunctionPointer handler)
	\brief Add a handler for the given interrupt mask.

	Specify the handler to use for the given interrupt. This only works with
	the default interrupt handler, do not mix the use of this routine with a
	user-installed IRQ handler.
	\param irq Mask associated with the interrupt.
	\param handler Address of the function to use as an interrupt service routine
	\note
	When any handler specifies using IRQ_VBLANK or IRQ_HBLANK, DISP_SR
	is automatically updated to include the corresponding DISP_VBLANK_IRQ or DISP_HBLANK_IRQ.

	\warning Only one IRQ_MASK can be specified with this function.
*/
void irqSet(IRQ_MASK irq, VoidFunctionPointer handler);
/*! \fn irqClear(IRQ_MASK irq)
	\brief remove the handler associated with the interrupt mask irq.
	\param irq Mask associated with the interrupt.
*/
void irqClear(IRQ_MASK irq);
/*! \fn irqInitHandler(VoidFunctionPointer handler)
	\brief Install a user interrupt dispatcher.

	This function installs the main interrupt function, all interrupts are serviced through this routine. For most
	purposes the libnds interrupt dispacther should be used in preference to user code unless you know *exactly* what you're doing.

	\param handler Address of the function to use as an interrupt dispatcher
	\note the function *must* be ARM code
*/
void irqInitHandler(VoidFunctionPointer handler);
/*! \fn irqEnable(uint32 irq)
	\brief Allow the given interrupt to occur.
	\param irq The set of interrupt masks to enable.
	\note Specify multiple interrupts to enable by ORing several IRQ_MASKS.
*/
void irqEnable(uint32 irq);
/*! \fn irqDisable(uint32 irq)
	\brief Prevent the given interrupt from occuring.
	\param irq The set of interrupt masks to disable.
	\note Specify multiple interrupts to disable by ORing several IRQ_MASKS.
*/
void irqDisable(uint32 irq);


#ifdef __cplusplus
}
#endif

#endif //NDS_INTERRUPTS_INCLUDE