25
25
#include < hardware/structs/systick.h>
26
26
#include < pico/multicore.h>
27
27
#include < pico/util/queue.h>
28
- #include < CoreMutex.h>
28
+ #include " CoreMutex.h"
29
+ #include " ccount.pio.h"
30
+
31
+
32
+ extern " C" volatile bool __otherCoreIdled;
29
33
30
34
class _MFIFO {
31
35
public:
@@ -45,9 +49,12 @@ class _MFIFO {
45
49
}
46
50
47
51
void registerCore () {
48
- multicore_fifo_clear_irq ();
49
- irq_set_exclusive_handler (SIO_IRQ_PROC0 + get_core_num (), _irq);
50
- irq_set_enabled (SIO_IRQ_PROC0 + get_core_num (), true );
52
+ if (!__isFreeRTOS) {
53
+ multicore_fifo_clear_irq ();
54
+ irq_set_exclusive_handler (SIO_IRQ_PROC0 + get_core_num (), _irq);
55
+ irq_set_enabled (SIO_IRQ_PROC0 + get_core_num (), true );
56
+ }
57
+ // FreeRTOS port.c will handle the IRQ hooking
51
58
}
52
59
53
60
void push (uint32_t val) {
@@ -79,19 +86,19 @@ class _MFIFO {
79
86
return ;
80
87
}
81
88
mutex_enter_blocking (&_idleMutex);
82
- _otherIdled = false ;
89
+ __otherCoreIdled = false ;
83
90
multicore_fifo_push_blocking (_GOTOSLEEP);
84
- while (!_otherIdled ) { /* noop */ }
91
+ while (!__otherCoreIdled ) { /* noop */ }
85
92
}
86
93
87
94
void resumeOtherCore () {
88
95
if (!_multicore) {
89
96
return ;
90
97
}
91
98
mutex_exit (&_idleMutex);
92
- _otherIdled = false ;
99
+ __otherCoreIdled = false ;
93
100
// Other core will exit busy-loop and return to operation
94
- // once otherIdled == false.
101
+ // once __otherCoreIdled == false.
95
102
}
96
103
97
104
void clear () {
@@ -108,98 +115,31 @@ class _MFIFO {
108
115
109
116
private:
110
117
static void __no_inline_not_in_flash_func (_irq)() {
111
- multicore_fifo_clear_irq ();
112
- noInterrupts (); // We need total control, can't run anything
113
- while (multicore_fifo_rvalid ()) {
114
- if (_GOTOSLEEP == multicore_fifo_pop_blocking ()) {
115
- _otherIdled = true ;
116
- while (_otherIdled) { /* noop */ }
117
- break ;
118
+ if (!__isFreeRTOS) {
119
+ multicore_fifo_clear_irq ();
120
+ noInterrupts (); // We need total control, can't run anything
121
+ while (multicore_fifo_rvalid ()) {
122
+ if (_GOTOSLEEP == multicore_fifo_pop_blocking ()) {
123
+ __otherCoreIdled = true ;
124
+ while (__otherCoreIdled) { /* noop */ }
125
+ break ;
126
+ }
118
127
}
128
+ interrupts ();
119
129
}
120
- interrupts ();
121
130
}
122
- bool _multicore = false ;
123
131
132
+ bool _multicore = false ;
124
133
mutex_t _idleMutex;
125
- static volatile bool _otherIdled;
126
134
queue_t _queue[2 ];
127
-
128
- static constexpr int _GOTOSLEEP = 0x66666666 ;
135
+ static constexpr uint32_t _GOTOSLEEP = 0xC0DED02E ;
129
136
};
130
137
138
+
131
139
class RP2040 ;
132
140
extern RP2040 rp2040;
133
141
extern " C" void main1 ();
134
-
135
- class RP2040 {
136
- public:
137
- RP2040 () {
138
- _epoch = 0 ;
139
- // Enable SYSTICK exception
140
- exception_set_exclusive_handler (SYSTICK_EXCEPTION, _SystickHandler);
141
- systick_hw->csr = 0x7 ;
142
- systick_hw->rvr = 0x00FFFFFF ;
143
- }
144
-
145
- ~RP2040 () { /* noop */ }
146
-
147
-
148
- // Convert from microseconds to PIO clock cycles
149
- static int usToPIOCycles (int us) {
150
- // Parenthesis needed to guarantee order of operations to avoid 32bit overflow
151
- return (us * (clock_get_hz (clk_sys) / 1000000 ));
152
- }
153
-
154
- // Get current clock frequency
155
- static int f_cpu () {
156
- return clock_get_hz (clk_sys);
157
- }
158
-
159
- // Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
160
- volatile uint64_t _epoch = 0 ;
161
- inline uint32_t getCycleCount () {
162
- uint32_t epoch;
163
- uint32_t ctr;
164
- do {
165
- epoch = (uint32_t )_epoch;
166
- ctr = systick_hw->cvr ;
167
- } while (epoch != (uint32_t )_epoch);
168
- return epoch + (1 << 24 ) - ctr; /* CTR counts down from 1<<24-1 */
169
- }
170
-
171
- inline uint64_t getCycleCount64 () {
172
- uint64_t epoch;
173
- uint64_t ctr;
174
- do {
175
- epoch = _epoch;
176
- ctr = systick_hw->cvr ;
177
- } while (epoch != _epoch);
178
- return epoch + (1LL << 24 ) - ctr;
179
- }
180
-
181
- void idleOtherCore () {
182
- fifo.idleOtherCore ();
183
- }
184
-
185
- void resumeOtherCore () {
186
- fifo.resumeOtherCore ();
187
- }
188
-
189
- void restartCore1 () {
190
- multicore_reset_core1 ();
191
- fifo.clear ();
192
- multicore_launch_core1 (main1);
193
- }
194
-
195
- // Multicore comms FIFO
196
- _MFIFO fifo;
197
-
198
- private:
199
- static void _SystickHandler () {
200
- rp2040._epoch += 1LL << 24 ;
201
- }
202
- };
142
+ class PIOProgram ;
203
143
204
144
// Wrapper class for PIO programs, abstracting common operations out
205
145
// TODO - Add unload/destructor
@@ -255,3 +195,90 @@ class PIOProgram {
255
195
const pio_program_t *_pgm;
256
196
};
257
197
198
+ class RP2040 {
199
+ public:
200
+ RP2040 () { /* noop */ }
201
+ ~RP2040 () { /* noop */ }
202
+
203
+ void begin () {
204
+ _epoch = 0 ;
205
+ if (!__isFreeRTOS) {
206
+ // Enable SYSTICK exception
207
+ exception_set_exclusive_handler (SYSTICK_EXCEPTION, _SystickHandler);
208
+ systick_hw->csr = 0x7 ;
209
+ systick_hw->rvr = 0x00FFFFFF ;
210
+ } else {
211
+ int off = 0 ;
212
+ _ccountPgm = new PIOProgram (&ccount_program);
213
+ _ccountPgm->prepare (&_pio, &_sm, &off);
214
+ ccount_program_init (_pio, _sm, off);
215
+ pio_sm_set_enabled (_pio, _sm, true );
216
+ }
217
+ }
218
+
219
+ // Convert from microseconds to PIO clock cycles
220
+ static int usToPIOCycles (int us) {
221
+ // Parenthesis needed to guarantee order of operations to avoid 32bit overflow
222
+ return (us * (clock_get_hz (clk_sys) / 1000000 ));
223
+ }
224
+
225
+ // Get current clock frequency
226
+ static int f_cpu () {
227
+ return clock_get_hz (clk_sys);
228
+ }
229
+
230
+ // Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
231
+ volatile uint64_t _epoch = 0 ;
232
+ inline uint32_t getCycleCount () {
233
+ if (!__isFreeRTOS) {
234
+ uint32_t epoch;
235
+ uint32_t ctr;
236
+ do {
237
+ epoch = (uint32_t )_epoch;
238
+ ctr = systick_hw->cvr ;
239
+ } while (epoch != (uint32_t )_epoch);
240
+ return epoch + (1 << 24 ) - ctr; /* CTR counts down from 1<<24-1 */
241
+ } else {
242
+ return ccount_read (_pio, _sm);
243
+ }
244
+ }
245
+
246
+ inline uint64_t getCycleCount64 () {
247
+ if (!__isFreeRTOS) {
248
+ uint64_t epoch;
249
+ uint64_t ctr;
250
+ do {
251
+ epoch = _epoch;
252
+ ctr = systick_hw->cvr ;
253
+ } while (epoch != _epoch);
254
+ return epoch + (1LL << 24 ) - ctr;
255
+ } else {
256
+ return ccount_read (_pio, _sm);
257
+ }
258
+ }
259
+
260
+ void idleOtherCore () {
261
+ fifo.idleOtherCore ();
262
+ }
263
+
264
+ void resumeOtherCore () {
265
+ fifo.resumeOtherCore ();
266
+ }
267
+
268
+ void restartCore1 () {
269
+ multicore_reset_core1 ();
270
+ fifo.clear ();
271
+ multicore_launch_core1 (main1);
272
+ }
273
+
274
+ // Multicore comms FIFO
275
+ _MFIFO fifo;
276
+
277
+ private:
278
+ static void _SystickHandler () {
279
+ rp2040._epoch += 1LL << 24 ;
280
+ }
281
+ PIO _pio;
282
+ int _sm;
283
+ PIOProgram *_ccountPgm;
284
+ };
0 commit comments