4242#include " PIOProgram.h"
4343#include " ccount.pio.h"
4444#include < malloc.h>
45-
4645#include " _freertos.h"
4746
4847extern " C" volatile bool __otherCoreIdled;
@@ -54,6 +53,110 @@ extern "C" {
5453#endif
5554}
5655
56+
57+ #ifdef PICO_RP2350
58+ class _MFIFO {
59+ public:
60+ _MFIFO () { /* noop */ };
61+ ~_MFIFO () { /* noop */ };
62+
63+ void begin (int cores) {
64+ if (cores == 1 ) {
65+ _multicore = false ;
66+ return ;
67+ }
68+ _doorbell = multicore_doorbell_claim_unused (0b11 , true );
69+ _multicore = true ;
70+ __otherCoreIdled = false ;
71+ }
72+
73+ void registerCore () {
74+ #ifndef __FREERTOS
75+ multicore_doorbell_clear_current_core (_doorbell);
76+ uint32_t irq = multicore_doorbell_irq_num (_doorbell);
77+ irq_add_shared_handler (irq, _irq, 128 );
78+ irq_set_enabled (irq, true );
79+ #else
80+ // FreeRTOS port.c will handle the IRQ hooking
81+ #endif
82+ }
83+
84+ void push (uint32_t val) {
85+ multicore_fifo_push_blocking_inline (val);
86+ }
87+
88+ bool push_nb (uint32_t val) {
89+ if (multicore_fifo_wready ()) {
90+ multicore_fifo_push_blocking_inline (val);
91+ return true ;
92+ }
93+ return false ;
94+ }
95+
96+ uint32_t pop () {
97+ return multicore_fifo_pop_blocking_inline ();
98+ }
99+
100+ bool pop_nb (uint32_t *val) {
101+ if (multicore_fifo_rvalid ()) {
102+ *val = multicore_fifo_pop_blocking_inline ();
103+ return true ;
104+ }
105+ return false ;
106+ }
107+
108+ int available () {
109+ return multicore_fifo_rvalid () ? 1 : 0 ; // Can't really say how many, but at least one is there
110+ }
111+
112+ void clear () {
113+ multicore_fifo_drain ();
114+ }
115+
116+ void idleOtherCore () {
117+ if (!_multicore) {
118+ return ;
119+ }
120+ #ifdef __FREERTOS
121+ __freertos_idle_other_core ();
122+ #else
123+ __otherCoreIdled = false ;
124+ multicore_doorbell_set_other_core (_doorbell);
125+ while (!__otherCoreIdled) { /* noop */ }
126+ #endif
127+ }
128+
129+ void resumeOtherCore () {
130+ if (!_multicore) {
131+ return ;
132+ }
133+ __otherCoreIdled = false ;
134+ #ifdef __FREERTOS
135+ __freertos_resume_other_core ();
136+ #endif
137+ // Other core will exit busy-loop and return to operation
138+ // once __otherCoreIdled == false.
139+ }
140+
141+ static uint8_t _doorbell;
142+
143+ private:
144+ static void __no_inline_not_in_flash_func (_irq)() {
145+ #ifndef __FREERTOS
146+ if (multicore_doorbell_is_set_current_core (_doorbell)) {
147+ noInterrupts (); // We need total control, can't run anything
148+ __otherCoreIdled = true ;
149+ while (__otherCoreIdled) { /* noop */ }
150+ interrupts ();
151+ multicore_doorbell_clear_current_core (_doorbell);
152+ }
153+ #endif
154+ }
155+
156+ bool _multicore = false ;
157+ };
158+
159+ #else
57160class _MFIFO {
58161public:
59162 _MFIFO () { /* noop */ };
@@ -75,13 +178,8 @@ class _MFIFO {
75178 void registerCore () {
76179#ifndef __FREERTOS
77180 multicore_fifo_clear_irq ();
78- #ifdef PICO_RP2350
79- irq_set_exclusive_handler (SIO_IRQ_FIFO, _irq);
80- irq_set_enabled (SIO_IRQ_FIFO, true );
81- #else
82181 irq_set_exclusive_handler (SIO_IRQ_PROC0 + get_core_num (), _irq);
83182 irq_set_enabled (SIO_IRQ_PROC0 + get_core_num (), true );
84- #endif
85183#else
86184 // FreeRTOS port.c will handle the IRQ hooking
87185#endif
@@ -172,7 +270,7 @@ class _MFIFO {
172270 queue_t *_queue; // Only allocated as [2] if multicore
173271 static constexpr uint32_t _GOTOSLEEP = 0xC0DED02E ;
174272};
175-
273+ # endif
176274
177275class RP2040 ;
178276extern RP2040 rp2040;
0 commit comments