|
|
@@ -36,7 +36,7 @@ libmaple proper interfaces.
|
|
36
|
36
|
--------------------------------
|
|
37
|
37
|
|
|
38
|
38
|
The libmaple proper interfaces all use functions named
|
|
39
|
|
-foo_attach_interrupt(). So tehre's the exti_attach_interrupt() and
|
|
|
39
|
+foo_attach_interrupt(). So there's the exti_attach_interrupt() and
|
|
40
|
40
|
timer_attach_interrupt() routines that have already been mentioned,
|
|
41
|
41
|
but there are also some others which (at time of writing) don't have
|
|
42
|
42
|
Wirish equivalents, like dma_attach_interrupt().
|
|
|
@@ -48,28 +48,28 @@ the user's function gets called exactly when that interrupt occurs.
|
|
48
|
48
|
|
|
49
|
49
|
This in itself is a useful abstraction above the hardware. To
|
|
50
|
50
|
understand why, here's a bullet-point primer on how interrupts work on
|
|
51
|
|
-STM32/Cortex M3 (read about the NVIC in a Cortex M3s book to
|
|
52
|
|
-understand all the details; these are just the basics):
|
|
|
51
|
+STM32/Cortex M3 (read about the NVIC in a Cortex M3 book to understand
|
|
|
52
|
+all the details; these are just the basics):
|
|
53
|
53
|
|
|
54
|
|
-- Each of the series of STM32 microcontroller specifies a certain
|
|
55
|
|
- number of IRQs (the libmaple type which enumerates the IRQs is
|
|
56
|
|
- nvic_irq_num; see the libmaple/nvic.h documentation for all the
|
|
57
|
|
- details).
|
|
|
54
|
+- Each series of STM32 microcontroller (STM32F1, STM32F2, etc.)
|
|
|
55
|
+ specifies a certain number of IRQs (the libmaple type which
|
|
|
56
|
+ enumerates the IRQs is nvic_irq_num; see the libmaple/nvic.h
|
|
|
57
|
+ documentation for all the details).
|
|
58
|
58
|
|
|
59
|
59
|
- Each IRQ has a number, which corresponds to a real, physical
|
|
60
|
60
|
interrupt line inside the processor. When you talk about an "IRQ",
|
|
61
|
61
|
you usually mean one of these interrupt lines.
|
|
62
|
62
|
|
|
63
|
63
|
- The interrupt hardware can be configured to call a single function
|
|
64
|
|
- per IRQ line when the interrupt associated with the IRQ has happened
|
|
|
64
|
+ per IRQ line when an interrupt associated with the IRQ has happened
|
|
65
|
65
|
(e.g. when a pin changes from low to high for an external
|
|
66
|
66
|
interrupt).
|
|
67
|
67
|
|
|
68
|
|
-- However, sometimes, various interrupts /share/ an IRQ line. For
|
|
|
68
|
+- However, sometimes, various interrupts share an IRQ line. For
|
|
69
|
69
|
example, on Maple, external interrupts 5 through 9 all share a
|
|
70
|
70
|
single IRQ line (which has nvic_irq_num NVIC_EXTI_9_5). That means
|
|
71
|
|
- that when any one of those interrupts occurs, the _same_ function
|
|
72
|
|
- (the IRQ handler for NVIC_EXTI_9_5) gets called.
|
|
|
71
|
+ that when any one (or any subset!) of those interrupts occurs, the
|
|
|
72
|
+ _same_ function (the IRQ handler for NVIC_EXTI_9_5) gets called.
|
|
73
|
73
|
|
|
74
|
74
|
When that happens, your IRQ handler has to figure out which
|
|
75
|
75
|
interrupt(s) it needs to handle (usually by looking at bitfields in
|
|
|
@@ -89,8 +89,7 @@ hit, but the convenience is usually worth it.
|
|
89
|
89
|
|
|
90
|
90
|
As noted above, for each nvic_irq_num, there's an IRQ line, and for
|
|
91
|
91
|
each IRQ line, you can set up a single function to call. This section
|
|
92
|
|
-explains where libmaple keep these functions, what they're called, and
|
|
93
|
|
-how you can write your own.
|
|
|
92
|
+explains where libmaple keeps these functions and what they're called.
|
|
94
|
93
|
|
|
95
|
94
|
You typically will only need the information in this section if
|
|
96
|
95
|
there's no foo_attach_interrupt() routine for the kind of interrupt
|
|
|
@@ -111,13 +110,12 @@ You can find the names libmaple expects for IRQ handlers by looking in
|
|
111
|
110
|
the vector table file for the microcontroller you're interested
|
|
112
|
111
|
in. This file is always named vector_table.S, but there are multiple
|
|
113
|
112
|
such files throughout the libmaple source tree. This is because the
|
|
114
|
|
-different STM32 series (like STM32F1, STM32F2) and even lines and
|
|
115
|
|
-densities within a series (like the value and performance lines and
|
|
116
|
|
-low/medium/high/XL-densities for STM32F1) each have different sets of
|
|
117
|
|
-IRQs.
|
|
|
113
|
+different STM32 series and even lines and densities within a series
|
|
|
114
|
+(like the value and performance lines and low/medium/high/XL-densities
|
|
|
115
|
+for STM32F1) each have different sets of IRQs.
|
|
118
|
116
|
|
|
119
|
|
-For portability, then, the various vector_table.S must live somewhere
|
|
120
|
|
-where nonportable code goes: somewhere under libmaple/stm32f1/,
|
|
|
117
|
+For portability, then, the vector table files must live somewhere
|
|
|
118
|
+where nonportable code goes, namely, under libmaple/stm32f1/,
|
|
121
|
119
|
libmaple/stm32f2/, etc. as appropriate. The libmaple build system
|
|
122
|
120
|
knows which one to use for each board.
|
|
123
|
121
|
|
|
|
@@ -155,9 +153,9 @@ to make sure which IRQ line a function is associated with.
|
|
155
|
153
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
156
|
154
|
|
|
157
|
155
|
The vector table file is just an assembly stub which defines the
|
|
158
|
|
-actual vector table (i.e., the stack table and table of function
|
|
159
|
|
-pointers that go at address 0x0), but it doesn't define the interrupts
|
|
160
|
|
-themselves. It leaves that up to the rest of libmaple.
|
|
|
156
|
+actual vector table (i.e., the initial stack pointer and table of
|
|
|
157
|
+function pointers that go at address 0x0), but it doesn't define the
|
|
|
158
|
+interrupts themselves. It leaves that up to the rest of libmaple.
|
|
161
|
159
|
|
|
162
|
160
|
Though it doesn't handle them all, libmaple does provide many
|
|
163
|
161
|
interrupt handlers when it can provide some useful default
|
|
|
@@ -199,9 +197,9 @@ These aren't complicated; read the source to see how they work.
|
|
199
|
197
|
-------------------------------------
|
|
200
|
198
|
|
|
201
|
199
|
When adding an interrupt handler (or overriding a default one), you
|
|
202
|
|
-need to decide whether you want it for a particular program, or
|
|
203
|
|
-whether what you're writing is general-purpose enough that it should
|
|
204
|
|
-live in libmaple itself.
|
|
|
200
|
+need to decide whether you want it for a particular program, or if
|
|
|
201
|
+what you're writing is general-purpose enough that it should live in
|
|
|
202
|
+libmaple itself.
|
|
205
|
203
|
|
|
206
|
204
|
4.1 Adding a special-purpose interrupt handler
|
|
207
|
205
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
@@ -278,10 +276,10 @@ that require special-purpose workarounds. When in doubt, leave your
|
|
278
|
276
|
handler in the series directory you can test. It can always be moved
|
|
279
|
277
|
later.
|
|
280
|
278
|
|
|
281
|
|
-After you've added the handler, you need to add an IRQ enable and
|
|
282
|
|
-disable routines for the peripheral. At the very least, this needs to
|
|
283
|
|
-take a pointer to the peripheral's device and an argument specifying
|
|
284
|
|
-which IRQ or IRQs to enable. For example, here are some timer IRQ
|
|
|
279
|
+After you've added the handler, you need to add IRQ enable and disable
|
|
|
280
|
+routines for the peripheral. At the very least, this needs to take a
|
|
|
281
|
+pointer to the peripheral's device and an argument specifying which
|
|
|
282
|
+IRQ or IRQs to enable. For example, here are some timer IRQ
|
|
285
|
283
|
enable/disable routines present in <libmaple/timer.h>:
|
|
286
|
284
|
|
|
287
|
285
|
/**
|