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
|
/*
* File: dyn_SWI.h
* Author: xxxajk@gmail.com
*
* Created on December 5, 2014, 9:12 AM
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DYN_SWI_H
#define DYN_SWI_H
#if defined(__arm__) || defined(ARDUINO_ARCH_PIC32)
#ifdef ARDUINO_ARCH_PIC32
#include <p32xxxx.h>
#endif
#ifdef __cplusplus
#ifdef true
#undef true
#endif
#ifdef false
#undef false
#endif
#endif
#ifdef ARDUINO_spresense_ast
#define SWI_IRQ_NUM 666 // because this board is totally evil.
#elif defined(ARDUINO_ARCH_PIC32)
#ifndef SWI_IRQ_NUM
#ifdef _DSPI0_IPL_ISR
#define SWI_IPL _DSPI0_IPL_ISR
#define SWI_VECTOR _DSPI0_ERR_IRQ
#define SWI_IRQ_NUM _DSPI0_ERR_IRQ
#elif defined(_PMP_ERROR_IRQ)
#define SWI_IRQ_NUM _PMP_ERROR_IRQ
#define SWI_VECTOR _PMP_VECTOR
#else
#error SWI_IRQ_NUM and SWI_VECTOR need a definition
#endif
#ifdef __cplusplus
extern "C"
{
void
#ifdef __PIC32MZXX__
__attribute__((nomips16,at_vector(SWI_VECTOR),interrupt(SWI_IPL)))
#else
__attribute__((interrupt(),nomips16))
#endif
softISR();
}
#endif
#endif
#elif !defined(NVIC_NUM_INTERRUPTS)
// Assume CMSIS
#define __USE_CMSIS_VECTORS__
#ifdef NUMBER_OF_INT_VECTORS
#define NVIC_NUM_INTERRUPTS (NUMBER_OF_INT_VECTORS-16)
#else
#define NVIC_NUM_INTERRUPTS ((int)PERIPH_COUNT_IRQn)
#endif
#define VECTORTABLE_SIZE (NVIC_NUM_INTERRUPTS+16)
#define VECTORTABLE_ALIGNMENT (0x100UL)
#define NVIC_GET_ACTIVE(n) NVIC_GetActive((IRQn_Type)n)
#define NVIC_GET_PENDING(n) NVIC_GetPendingIRQ((IRQn_Type)n)
#define NVIC_SET_PENDING(n) NVIC_SetPendingIRQ((IRQn_Type)n)
#define NVIC_ENABLE_IRQ(n) NVIC_EnableIRQ((IRQn_Type)n)
#define NVIC_SET_PRIORITY(n ,p) NVIC_SetPriority((IRQn_Type)n, (uint32_t) p)
//extern "C" {
// extern uint32_t _VectorsRam[VECTORTABLE_SIZE] __attribute__((aligned(VECTORTABLE_ALIGNMENT)));
//}
#ifndef SWI_IRQ_NUM
#if defined(__SAM3X8E__) && defined(_VARIANT_ARDUINO_DUE_X_)
// DUE
// Choices available:
// HSMCI_IRQn Multimedia Card Interface (HSMCI)
// EMAC_IRQn Ethernet MAC (EMAC)
// EMAC is not broken out on the official DUE, but is on clones.
// SPI0_IRQn Serial Peripheral Interface (SPI0)
// SPI0_IRQn seems to be the best choice, as long as nobody uses an ISR based master
#define SWI_IRQ_NUM SPI0_IRQn
#elif defined(ARDUINO_SAMD_ZERO)
// Just use sercom4's unused IRQ vector.
#define SWI_IRQ_NUM I2S_IRQn
//#define SWI_IRQ_NUM SERCOM4_IRQn
#endif
#endif
#ifndef SWI_IRQ_NUM
#error SWI_IRQ_NUM not defined (CMSIS)
#endif
#elif defined(CORE_TEENSY)
#ifndef NVIC_GET_ACTIVE
#define NVIC_GET_ACTIVE(n) (*((volatile uint32_t *)0xE000E300 + ((n) >> 5)) & (1 << ((n) & 31)))
#endif
#ifndef NVIC_GET_PENDING
#define NVIC_GET_PENDING(n) (*((volatile uint32_t *)0xE000E200 + ((n) >> 5)) & (1 << ((n) & 31)))
#ifndef SWI_IRQ_NUM
#ifdef __MK20DX256__
#define SWI_IRQ_NUM 17
#elif defined(__MK20DX128__)
#define SWI_IRQ_NUM 5
#elif defined(__MKL26Z64__)
#define SWI_IRQ_NUM 4
#elif defined(__MK66FX1M0__)
#define SWI_IRQ_NUM 30
#elif defined(__MK64FX512__)
#define SWI_IRQ_NUM 30
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
#define SWI_IRQ_NUM 71
#else
#error Do not know how to relocate IRQ vectors for this pjrc product
#endif
#endif
#endif
#else // Not CMSIS or PJRC CORE_TEENSY or PIC32 or SPRESENSE
#error Do not know how to relocate IRQ vectors or perform SWI
#endif // SWI_IRQ_NUM
#ifndef SWI_IRQ_NUM
#error SWI_IRQ_NUM not defined
#else
/**
* Use this class to extend your class, in order to provide
* a C++ context callable SWI.
*/
class dyn_SWI {
public:
/**
* Override this method with your code.
*/
virtual void dyn_SWISR() {
};
};
extern int exec_SWI(const dyn_SWI* klass);
#include "SWI_INLINE.h"
// IMPORTANT! Define this so that you do NOT end up with a NULL stub!
#define SWI_NO_STUB
#endif /* SWI_IRQ_NUM */
#endif /* __arm__ */
// if no SWI for CPU (e.g. AVR) make a void stub.
#ifndef SWI_NO_STUB
#define Init_dyn_SWI() (void(0))
#ifndef DDSB
#define DDSB() (void(0))
#endif
#endif
#endif /* DYN_SWI_H */
|