OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [demo_xirq/] [main.c] - Blame information for rev 64

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 61 zero_gravi
// #################################################################################################
2
// # << NEORV32 - External Interrupt Controller (XIRQ) Demo Program >>                             #
3
// # ********************************************************************************************* #
4
// # BSD 3-Clause License                                                                          #
5
// #                                                                                               #
6
// # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
7
// #                                                                                               #
8
// # Redistribution and use in source and binary forms, with or without modification, are          #
9
// # permitted provided that the following conditions are met:                                     #
10
// #                                                                                               #
11
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
12
// #    conditions and the following disclaimer.                                                   #
13
// #                                                                                               #
14
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
15
// #    conditions and the following disclaimer in the documentation and/or other materials        #
16
// #    provided with the distribution.                                                            #
17
// #                                                                                               #
18
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
19
// #    endorse or promote products derived from this software without specific prior written      #
20
// #    permission.                                                                                #
21
// #                                                                                               #
22
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
23
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
24
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
25
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
26
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
28
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
29
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
30
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
31
// # ********************************************************************************************* #
32
// # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
33
// #################################################################################################
34
 
35
 
36
/**********************************************************************//**
37
 * @file demo_xirq/main.c
38
 * @author Stephan Nolting
39 62 zero_gravi
 * @brief External interrupt controller (XIRQ) demo program (using hardware-assisted prioritization).
40 61 zero_gravi
 **************************************************************************/
41
 
42
#include <neorv32.h>
43
 
44
 
45
/**********************************************************************//**
46
 * @name User configuration
47
 **************************************************************************/
48
/**@{*/
49
/** UART BAUD rate */
50
#define BAUD_RATE 19200
51
/**@}*/
52
 
53
// prototypes
54
void xirq_handler_ch0(void);
55
void xirq_handler_ch1(void);
56
void xirq_handler_ch2(void);
57
void xirq_handler_ch3(void);
58
 
59
 
60
/**********************************************************************//**
61
 * Main function
62
 *
63 64 zero_gravi
 * @note This program requires the XIRQ and the UART to be synthesized.
64 61 zero_gravi
 *
65
 * @return 0 if execution was successful
66
 **************************************************************************/
67
int main() {
68
 
69
  // initialize the neorv32 runtime environment
70
  // this will take care of handling all CPU traps (interrupts and exceptions)
71
  neorv32_rte_setup();
72
 
73
  // setup UART0 at default baud rate, no parity bits, ho hw flow control
74
  neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
75
 
76
  // check if XIRQ unit is implemented at all
77
  if (neorv32_xirq_available() == 0) {
78
    neorv32_uart0_printf("XIRQ not synthesized!\n");
79
    return 1;
80
  }
81
 
82
 
83
  // intro
84
  neorv32_uart0_printf("External interrupt controller (XIRQ) demo program\n\n");
85
 
86
  int err_cnt = 0;
87
 
88
 
89
  // initialize XIRQ controller
90
  // this will disable all XIRQ channels and will also clear any pending external interrupts
91
  // (details: this will register the XIRQ's second-level interrupt handler in the NEORV32 RTE)
92
  err_cnt = neorv32_xirq_setup();
93
 
94
  // check if setup went fine
95
  if (err_cnt) {
96
    neorv32_uart0_printf("Error during XIRQ setup!\n");
97
    return 1;
98
  }
99
 
100
 
101
  // install handler functions for XIRQ channel 0,1,2,3. note that these functions are "normal" functions!
102 64 zero_gravi
  // (details: these are "third-level" interrupt handlers)
103
  // neorv32_xirq_install() also enables the specified XIRQ channel and clears any pending interrupts
104 61 zero_gravi
  err_cnt = 0;
105
  err_cnt += neorv32_xirq_install(0, xirq_handler_ch0); // handler function for channel 0
106
  err_cnt += neorv32_xirq_install(1, xirq_handler_ch1); // handler function for channel 1
107
  err_cnt += neorv32_xirq_install(2, xirq_handler_ch2); // handler function for channel 2
108
  err_cnt += neorv32_xirq_install(3, xirq_handler_ch3); // handler function for channel 3
109
 
110
  // check if installation went fine
111
  if (err_cnt) {
112
    neorv32_uart0_printf("Error during XIRQ install!\n");
113
    return 1;
114
  }
115
 
116
 
117
  // allow XIRQ to trigger CPU interrupt
118
  neorv32_xirq_global_enable();
119
 
120
 
121
  // enable global interrupts
122
  neorv32_cpu_eint();
123
 
124
 
125
  // the code below assumes the XIRQ inputs are connected to the processor's GPIO output port
126
  // so we can trigger the IRQs from software; if you have connected the XIRQs to buttons you
127
  // can remove the code below (note the trigger configuration using the XIRQ generics!)
128
  {
129
    // trigger XIRQs 3:0 at once
130 64 zero_gravi
    // assumes xirq_i(31:0) <= gpio.output(31:0)
131 61 zero_gravi
 
132
    // due to the prioritization this will execute
133
    // -> xirq_handler_ch0
134
    // -> xirq_handler_ch1
135
    // -> xirq_handler_ch2
136
    // -> xirq_handler_ch3
137
    neorv32_gpio_port_set(0xF); // set output pins 3:0 -> trigger XIRQ 3:0
138
    neorv32_gpio_port_set(0x0);
139
  }
140
 
141
 
142 62 zero_gravi
  // --- wait for interrupts ---
143
  // All incoming XIRQ interrupt requests are "prioritized" in this example. The XIRQ FIRQ handler
144
  // reads the ID of the interrupt with the highest priority from the XIRQ controller ("source" register) and calls the according
145 64 zero_gravi
  // handler function (installed via neorv32_xirq_install();).
146 62 zero_gravi
  // Non-prioritized handling of interrupts (or custom prioritization) can be implemented by manually reading the
147 64 zero_gravi
  // XIRQ controller's "pending" register. Then it is up to the software to define which pending IRQ should be served first.
148 61 zero_gravi
  while(1);
149
 
150
 
151
  // just as an example: to disable certain XIRQ interrupt channels, we can
152 62 zero_gravi
  // un-install the according handler. this will also clear a pending interrupt for that channel
153 61 zero_gravi
  neorv32_xirq_uninstall(0); // disable XIRQ channel 0 and remove associated handler
154
  neorv32_xirq_uninstall(1); // disable XIRQ channel 1 and remove associated handler
155
  neorv32_xirq_uninstall(2); // disable XIRQ channel 2 and remove associated handler
156
  neorv32_xirq_uninstall(3); // disable XIRQ channel 3 and remove associated handler
157
 
158 64 zero_gravi
  // you can also manually clear pending interrupts
159
  neorv32_xirq_clear_pending(0); // clear pending interrupt of channel 0
160 61 zero_gravi
 
161 64 zero_gravi
  // manually enable and disable XIRQ channels
162
  neorv32_xirq_channel_enable(0); // enable channel 0
163
  neorv32_xirq_channel_disable(0); // disable channel 0
164
 
165
  // globally enable/disable XIRQ CPU interrupt
166
  // this will not affect the XIR configuration / pending interrupts
167
  neorv32_xirq_global_enable();
168
  neorv32_xirq_global_disable();
169
 
170 61 zero_gravi
  return 0;
171
}
172
 
173
 
174
/**********************************************************************//**
175
 * XIRQ handler channel 0.
176
 *
177
 * @warning This function has to be of type "void xyz(void)" and must not use any interrupt attributes!
178
 **************************************************************************/
179
void xirq_handler_ch0(void) {
180
 
181
  neorv32_uart0_printf("XIRQ interrupt from channel %i\n", 0);
182
}
183
 
184
/**********************************************************************//**
185
 * XIRQ handler channel 1.
186
 *
187
 * @warning This function has to be of type "void xyz(void)" and must not use any interrupt attributes!
188
 **************************************************************************/
189
void xirq_handler_ch1(void) {
190
 
191
  neorv32_uart0_printf("XIRQ interrupt from channel %i\n", 1);
192
}
193
 
194
/**********************************************************************//**
195
 * XIRQ handler channel 2.
196
 *
197
 * @warning This function has to be of type "void xyz(void)" and must not use any interrupt attributes!
198
 **************************************************************************/
199
void xirq_handler_ch2(void) {
200
 
201
  neorv32_uart0_printf("XIRQ interrupt from channel %i\n", 2);
202
}
203
 
204
/**********************************************************************//**
205
 * XIRQ handler channel 3.
206
 *
207
 * @warning This function has to be of type "void xyz(void)" and must not use any interrupt attributes!
208
 **************************************************************************/
209
void xirq_handler_ch3(void) {
210
 
211
  neorv32_uart0_printf("XIRQ interrupt from channel %i\n", 3);
212
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.