KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lm32.h
Go to the documentation of this file.
1 /*
2  * KM3NeT CLB v2 Firmware
3  *
4  * Copyright 2013 KM3NeT Collaboration
5  *
6  * All Rights Reserved.
7  *
8  *
9  * File : lm32.h
10  * Created : 25 jan 2013
11  * Author : Vincent van Beveren
12  */
13 
14 
15 #ifndef LM32_H_
16 #define LM32_H_
17 
18 #include <stdio.h>
19 /**
20  * @file
21  *
22  * @ingroup lm32soc
23  *
24  * Low level routines for LM32, including interrupt handling.
25  *
26  */
27 
28 #include <stdbool.h>
29 #include <stdint.h>
30 #include "util/macro.h"
31 
32 #define _IRQ_HANDLER(IRQ) \
33  irq ## IRQ ## Handler()
34 
35 
36 /**
37  * Defines an IRQ handler. Should be used by the driver to capture IRQ's.
38  *
39  * @code
40  * void IRQ_HANDLER(UART_IRQ) {
41  * // get character
42  * }
43  * @endcode
44  *
45  * @param IRQ The IRQ number.
46  */
47 #define IRQ_HANDLER(IRQ) _IRQ_HANDLER(IRQ)
48 
49 
50 /**
51  * Disables IRQ's on a global level. It does not clear the interrupt masks, so when re-enabled
52  * all previously enabled IRQs will be handled.
53  */
54 
55 /*#define __irqDisable() \
56  __asm__ __volatile__ ("mvi r15, 0;" \
57  "wcsr ie, r15 ;" \
58  ::: "r15" \
59  );
60 */
61 
62 static inline __attribute__ ((always_inline)) void __irqDisable()
63 {
64  asm volatile ("mvi r15, 0;"
65  "wcsr ie, r15 ;"
66  ::: "r15" // clobbered
67  );
68 }
69 
70 
71 
72 /**
73  * Enabled IRQ's on a global level. Pending IRQs will be handled.
74  */
75 static inline __attribute__ ((always_inline)) void __irqEnable()
76 {
77  asm volatile ("mvi r15, 1;"
78  "wcsr ie, r15 ;"
79  ::: "r15"
80  );
81 }
82 
83 
84 static inline bool __isIrqEnable()
85 {
86 
87  register uint32_t r;
88 
89  asm volatile ("rcsr %0, ie ;"
90  : "=r" (r)
91  );
92 
93  return (r & 0x1) != 0;
94 }
95 
96 
97 /**
98  * No-operation
99  */
100 static inline void __nop()
101 {
102  asm volatile("nop");
103 }
104 
105 
106 /**
107  * Program state before IRQ.
108  *
109  * For example, to get the program counter at interrupt, use this in an interrupt routine:
110  * uint32_t pcAtIrq = pState[PSTATE_RA];
111  */
112 extern uint32_t * pState;
113 
114 /**
115  * Returns whether or not we're in an IRQ context.
116  *
117  * Do not write this value!
118  */
119 extern volatile bool inIrqContext;
120 
121 
122 #define PSTATE_R1 0 ///< register 1
123 #define PSTATE_R2 1 ///< register 2
124 #define PSTATE_R3 2 ///< register 3
125 #define PSTATE_R4 3 ///< register 4
126 #define PSTATE_R5 4 ///< register 5
127 #define PSTATE_R6 5 ///< register 6
128 #define PSTATE_R7 6 ///< register 7
129 #define PSTATE_R8 7 ///< register 8
130 #define PSTATE_R9 8 ///< register 9
131 #define PSTATE_R10 9 ///< register 10
132 #define PSTATE_RA 10 ///< return address (from IRQ = PC at the moment or interrupt)
133 #define PSTATE_EA 11 ///< exception address
134 #define PSTATE_BA 12 ///< break pointer address
135 
136 /**
137  * Set/clear the interrupt mask for the specified IRQ.
138  *
139  * @param irq The IRQ to set or clear.
140  * @param set When 0, clears the IRQ, when 1 sets it.
141  *
142  * Note that when enabling IRQ's, any pending IRQs may be activated.
143  */
144 void irqMaskSet(int irq, bool set);
145 
146 /**
147  * Returns the current IRQ mask for the specified IRQ.
148  *
149  * @param irq The IRQ to check.
150  */
151 bool irqMaskGet(int irq);
152 
153 
154 /**
155  * Returns the value of the cycle counter.
156  */
157 static inline uint32_t cycCount()
158 {
159  uint32_t cc;
160 
161  __asm__("rcsr %0, cc" : "=r" (cc));
162 
163  return cc;
164 }
165 
166 /**
167  * Soft reboot the LM32
168  */
169 void reboot();
170 
171 // external (linker script provided) values for ROM/RAM information.
172 extern uint32_t _end;
173 extern const uint8_t _ram_offset;
174 extern const uint8_t _ram_size;
175 extern const uint8_t _rom_offset;
176 extern const uint8_t _rom_end;
177 extern const uint8_t _rom_size;
178 
179 /**
180  * Get the of the RAM
181  *
182  * @return Size of RAM in bytes.
183  */
184 static inline uint32_t ramSize()
185 {
186  return (uint32_t)&_ram_size;
187 }
188 
189 /**
190  * Get the RAM used by variables (excluding stack).
191  *
192  * @return Used RAM in bytes.
193  */
194 static inline uint32_t ramUsed()
195 {
196  uint32_t end = (uint32_t)&_end;
197  uint32_t start = (uint32_t)&_ram_offset;
198  return end - start;
199 }
200 
201 
202 /**
203  * Get the of the ROM
204  *
205  * @return Size of ROM in bytes.
206  */
207 static inline uint32_t romSize()
208 {
209  return (uint32_t)&_rom_size;
210 }
211 
212 
213 /**
214  * Get the ROM used by code, variables and constants.
215  *
216  * @return Used ROM in bytes.
217  */
218 static inline uint32_t romUsed()
219 {
220  uint32_t start = (uint32_t)&_rom_offset;
221  uint32_t end = (uint32_t)&_rom_end;
222  return end - start;
223 }
224 
225 
226 #endif /* IRQ_H_ */
static uint32_t romUsed()
Get the ROM used by code, variables and constants.
Definition: lm32.h:218
static void __irqEnable()
Enabled IRQ&#39;s on a global level.
Definition: lm32.h:75
static uint32_t ramUsed()
Get the RAM used by variables (excluding stack).
Definition: lm32.h:194
static void __irqDisable()
Disables IRQ&#39;s on a global level.
Definition: lm32.h:62
static uint32_t cycCount()
Returns the value of the cycle counter.
Definition: lm32.h:157
void irqMaskSet(int irq, bool set)
Set/clear the interrupt mask for the specified IRQ.
Definition: lm32.c:77
static uint32_t romSize()
Get the of the ROM.
Definition: lm32.h:207
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
static void __nop()
No-operation.
Definition: lm32.h:100
static uint32_t ramSize()
Get the of the RAM.
Definition: lm32.h:184