KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lm32.c
1 #include "lm32soc/lm32.h"
2 #include "util/macro.h"
3 
4 #include "cfg_soc.h"
5 
6 
7 #include <stdint.h>
8 #include <stdio.h>
9 
10 // when set, the specified IRQ is used to display debugging information
11 
12 
13 // using X-macro's to create IRQ stubs.
14 #define IRQS \
15  X(0) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) \
16  X(10) X(11) X(12) X(13) X(14) X(15) /* X(16) X(17) X(18) X(19) \
17  X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29) \
18  X(30) X(31)*/
19 
20 // X-macro to create handler declarations
21 #define X(IRQ) void irq ## IRQ ## Handler() __attribute__((weak));
22 IRQS
23 #undef X
24 
25 
26 #define IRQ_HI(IRQ) ( ( ( 1 << IRQ ) && ( 0xFFFF0000 ) ) >> 16 )
27 
28 uint32_t * pState;
29 
30 volatile bool inIrqContext;
31 
32 
33 
34 void _handle_irq(uint32_t * sp)
35 {
36  pState = sp + 1;
37  register uint32_t ip;
38  inIrqContext = true;
39  while (1)
40  {
41  asm volatile (
42  "rcsr r15, im ;" // read interrupt mask in r15
43  "rcsr %0, ip ;" // read interrupt pending
44  "and %0, %0, r15 ;" // AND interrupt mask with pending
45  : "=r" (ip)
46  :
47  : "r15");
48  if (ip == 0) break;
49 
50  // X-macro to create handler implementation.
51 #define X(IRQ) \
52  if ((ip & (1 << IRQ) ) && irq ## IRQ ## Handler) { \
53  asm volatile ( \
54  "ori r15, r0, " STR(1 << IRQ) ";" \
55  "wcsr ip, r15 ;" \
56  ::: "r15"); \
57  irq ## IRQ ## Handler(); \
58  continue; \
59  }
60 // Write this handler for each IRQ
61  IRQS
62 #undef X
63 
64  // clear all remaining interrupts
65  asm volatile ( "wcsr ip, %0" : : "r"(ip));
66  }
67  inIrqContext = false;
68 }
69 
70 
71 void _handle_sys_error(uint32_t syserr)
72 {
73  puts("SYS ERROR");
74 }
75 
76 
77 void irqMaskSet(int irq, bool set)
78 {
79  uint32_t mask = 1 << irq;
80  if (set)
81  {
82  // set the mask for the specified IRQ
83  asm ("rcsr r15, im ;" // load interrupt mask into r15
84  "or r15, r15, %0 ;" // or it with our mask
85  "wcsr im, r15 ;" // write it back
86  : // no output */
87  : "r" (mask) // one input 'mask'
88  : "r15" // clobbered register
89  );
90  }
91  else
92  {
93  // clears the mask for the specified IRQ
94  asm ("not %0, %0 ;" // invert our mark
95  "rcsr r15, im ;" // load the interrupt mask
96  "and r15, r15, %0 ;" // and it with our mask
97  "wcsr im, r15 ;" // set the mask again
98  : // no output
99  : "r" (mask) // one input 'mask' */
100  : "r15" // clobbered register
101  );
102  }
103 }
104 
105 bool irqMaskGet(int irq)
106 {
107  uint32_t im;
108  asm ("rcsr %0, im;" : "=r" (im) );
109  return ( im & (1 << irq) ) != 0;
110 }
111 
112 void reboot()
113 {
114 
115  asm(
116  "mvi r1, 0 ;" // disable interrupts
117  "wcsr ie, r1 ;"
118  "bi _reset_handler ;" // call reset handler
119  );
120 }
121 
Defines the configuration of the LM32 SOC for the CLBv2.
Low level routines for LM32, including interrupt handling.
void irqMaskSet(int irq, bool set)
Set/clear the interrupt mask for the specified IRQ.
Definition: lm32.c:77
bool irqMaskGet(int irq)
Returns the current IRQ mask for the specified IRQ.
Definition: lm32.c:105
uint32_t * pState
Program state before IRQ.
Definition: lm32.c:28
void reboot()
Soft reboot the LM32.
Definition: lm32.c:112
Provides common macros.
volatile bool inIrqContext
Returns whether or not we&#39;re in an IRQ context.
Definition: lm32.c:30