Skip to content

Commit ca4d300

Browse files
committed
fixup! [rp] Add core support for RP2040 device
1 parent 5557d17 commit ca4d300

File tree

1 file changed

+186
-184
lines changed

1 file changed

+186
-184
lines changed

src/modm/platform/core/rp/multicore.hpp.in

Lines changed: 186 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -16,205 +16,207 @@
1616

1717
namespace modm::platform::multicore
1818
{
19-
/**
20-
* The RP2040 contains two FIFOs for passing data, messages or ordered events between the two cores. Each FIFO is 32 bits
21-
* wide, and 8 entries deep. One of the FIFOs can only be written by core 0, and read by core 1. The other can only be written
22-
* by core 1, and read by core 0.
23-
* @ingroup modm_platform_multicore
24-
*/
25-
struct Mailbox
26-
{
27-
static inline bool canRead()
28-
{
29-
return sio_hw->fifo_st & SIO_FIFO_ST_VLD_BITS;
30-
}
31-
static inline bool canWrite()
32-
{
33-
return sio_hw->fifo_st & SIO_FIFO_ST_RDY_BITS;
34-
}
35-
static inline bool push(uint32_t msg)
36-
{
37-
if (!canWrite()) return false;
38-
sio_hw->fifo_wr = msg;
39-
__SEV();
40-
return true;
41-
}
42-
static inline bool pop(uint32_t& msg)
43-
{
44-
if (!canRead()) return false;
45-
msg = sio_hw->fifo_rd;
46-
return true;
47-
}
48-
static inline void pushBlocked(uint32_t msg)
49-
{
50-
while (!canWrite()) __NOP();
51-
sio_hw->fifo_wr = msg;
52-
__SEV();
53-
}
54-
static inline uint32_t popBlocked()
55-
{
56-
while (!canRead()) __WFE();
57-
return sio_hw->fifo_rd;
58-
}
59-
static inline void drain()
60-
{
61-
while (canRead())
62-
(void) sio_hw->fifo_rd;
63-
}
64-
};
65-
66-
/**
67-
* The RP2040 provides 32 hardware spin locks, which can be used to manage mutually-exclusive access to shared software
68-
* and hardware resources.
69-
*
70-
* Instance 0 allocated for modm usage.
71-
*
72-
* Acquire a spin lock without disabling interrupts (hence unsafe)
73-
* @ingroup modm_platform_multicore
74-
*/
75-
template <uint8_t instance>
76-
class SpinLockUnsafe
77-
{
78-
static_assert(instance < 32);
79-
using LockType = volatile uint32_t;
80-
81-
private:
82-
static inline LockType* getInstance()
83-
{
84-
return (LockType *) (SIO_BASE + SIO_SPINLOCK0_OFFSET + instance * 4);
85-
}
8619

87-
public:
88-
static void init()
89-
{
90-
unlock();
91-
}
92-
static inline void lock()
93-
{
94-
auto l = getInstance();
95-
while (*l == 0);
96-
std::atomic_thread_fence(std::memory_order_acquire);
97-
}
98-
static inline void unlock()
99-
{
100-
auto l = getInstance();
101-
std::atomic_thread_fence(std::memory_order_release);
102-
*l = 0;
103-
}
104-
};
20+
/**
21+
* The RP2040 contains two FIFOs for passing data, messages or ordered events between the two cores. Each FIFO is 32 bits
22+
* wide, and 8 entries deep. One of the FIFOs can only be written by core 0, and read by core 1. The other can only be written
23+
* by core 1, and read by core 0.
24+
* @ingroup modm_platform_multicore
25+
*/
26+
struct Mailbox
27+
{
28+
static inline bool canRead()
29+
{
30+
return sio_hw->fifo_st & SIO_FIFO_ST_VLD_BITS;
31+
}
32+
static inline bool canWrite()
33+
{
34+
return sio_hw->fifo_st & SIO_FIFO_ST_RDY_BITS;
35+
}
36+
static inline bool push(uint32_t msg)
37+
{
38+
if (!canWrite()) return false;
39+
sio_hw->fifo_wr = msg;
40+
__SEV();
41+
return true;
42+
}
43+
static inline bool pop(uint32_t& msg)
44+
{
45+
if (!canRead()) return false;
46+
msg = sio_hw->fifo_rd;
47+
return true;
48+
}
49+
static inline void pushBlocked(uint32_t msg)
50+
{
51+
while (!canWrite()) __NOP();
52+
sio_hw->fifo_wr = msg;
53+
__SEV();
54+
}
55+
static inline uint32_t popBlocked()
56+
{
57+
while (!canRead()) __WFE();
58+
return sio_hw->fifo_rd;
59+
}
60+
static inline void drain()
61+
{
62+
while (canRead())
63+
(void) sio_hw->fifo_rd;
64+
}
65+
};
66+
67+
/**
68+
* The RP2040 provides 32 hardware spin locks, which can be used to manage mutually-exclusive access to shared software
69+
* and hardware resources.
70+
*
71+
* Instance 0 allocated for modm usage.
72+
*
73+
* Acquire a spin lock without disabling interrupts (hence unsafe)
74+
* @ingroup modm_platform_multicore
75+
*/
76+
template <uint8_t instance>
77+
class SpinLockUnsafe
78+
{
79+
static_assert(instance < 32);
80+
using LockType = volatile uint32_t;
81+
82+
private:
83+
static inline LockType* getInstance()
84+
{
85+
return (LockType *) (SIO_BASE + SIO_SPINLOCK0_OFFSET + instance * 4);
86+
}
10587

106-
/// @cond
107-
// for use in modm::atomic::Lock
108-
struct CoreLock
88+
public:
89+
static void init()
90+
{
91+
unlock();
92+
}
93+
static inline void lock()
94+
{
95+
auto l = getInstance();
96+
while (*l == 0);
97+
std::atomic_thread_fence(std::memory_order_acquire);
98+
}
99+
static inline void unlock()
109100
{
110-
CoreLock() { SpinLockUnsafe<0>::lock(); }
111-
~CoreLock() { SpinLockUnsafe<0>::unlock(); }
112-
};
113-
/// @endcond
101+
auto l = getInstance();
102+
std::atomic_thread_fence(std::memory_order_release);
103+
*l = 0;
104+
}
105+
};
106+
107+
/// @cond
108+
// for use in modm::atomic::Lock
109+
struct CoreLock
110+
{
111+
CoreLock() { SpinLockUnsafe<0>::lock(); }
112+
~CoreLock() { SpinLockUnsafe<0>::unlock(); }
113+
};
114+
/// @endcond
114115

115-
/// This class will disable interrupts prior to acquiring the spinlock
116-
/// @ingroup modm_platform_multicore
117-
template <uint8_t instance>
118-
class SpinLockBlocking : public SpinLockUnsafe<instance>
116+
/// This class will disable interrupts prior to acquiring the spinlock
117+
/// @ingroup modm_platform_multicore
118+
template <uint8_t instance>
119+
class SpinLockBlocking : public SpinLockUnsafe<instance>
120+
{
121+
using Base = SpinLockUnsafe<instance>;
122+
123+
public:
124+
static inline uint32_t lock()
119125
{
120-
using Base = SpinLockUnsafe<instance>;
126+
uint32_t is = __get_PRIMASK();
127+
__disable_irq();
128+
Base::lock();
129+
return is;
130+
}
131+
static inline void unlock(uint32_t is)
132+
{
133+
Base::unlock();
134+
__set_PRIMASK(is);
135+
}
136+
};
137+
/// @ingroup modm_platform_multicore
138+
using SystemSpinLock = SpinLockBlocking<0>;
121139

122-
public:
123-
static inline uint32_t lock()
124-
{
125-
uint32_t is = __get_PRIMASK();
126-
__disable_irq();
127-
Base::lock();
128-
return is;
129-
}
130-
static inline void unlock(uint32_t is)
131-
{
132-
Base::unlock();
133-
__set_PRIMASK(is);
134-
}
135-
};
136-
/// @ingroup modm_platform_multicore
137-
using SystemSpinLock = SpinLockBlocking<0>;
138-
139-
140-
/// RAI lock acquiring and releasing
141-
/// @ingroup modm_platform_multicore
142-
template <class SpinLock>
143-
class SpinLockGuard
144-
{
145-
private:
146-
SpinLockGuard(const SpinLockGuard& ) = delete;
147-
SpinLockGuard(SpinLockGuard&&) = delete;
148-
public:
149-
inline SpinLockGuard() { SpinLock::lock(); }
150-
inline ~SpinLockGuard() { SpinLock::unlock(); }
151-
};
152-
153-
/// @ingroup modm_platform_multicore
154-
template <uint8_t instance>
155-
class SpinLockGuard<SpinLockBlocking<instance>>
156-
{
157-
private:
158-
using SpinLock = SpinLockBlocking<instance>;
159-
uint32_t is;
160-
SpinLockGuard(const SpinLockGuard& ) = delete;
161-
SpinLockGuard(SpinLockGuard&&) = delete;
162-
public:
163-
inline SpinLockGuard() : is(SpinLock::lock()) {}
164-
inline ~SpinLockGuard() { SpinLock::unlock(is); }
165-
};
166-
/// @ingroup modm_platform_multicore
167-
using SystemSpinLockGuard = SpinLockGuard<SystemSpinLock>;
168-
169-
/// @ingroup modm_platform_multicore
170-
class Mutex
171-
{
172-
private:
173-
volatile bool locked = false;
174-
Mutex(const Mutex& ) = delete;
175-
Mutex(Mutex&&) = delete;
176-
public:
177-
Mutex() {}
178-
void lock()
140+
141+
/// RAI lock acquiring and releasing
142+
/// @ingroup modm_platform_multicore
143+
template <class SpinLock>
144+
class SpinLockGuard
145+
{
146+
private:
147+
SpinLockGuard(const SpinLockGuard& ) = delete;
148+
SpinLockGuard(SpinLockGuard&&) = delete;
149+
public:
150+
inline SpinLockGuard() { SpinLock::lock(); }
151+
inline ~SpinLockGuard() { SpinLock::unlock(); }
152+
};
153+
154+
/// @ingroup modm_platform_multicore
155+
template <uint8_t instance>
156+
class SpinLockGuard<SpinLockBlocking<instance>>
157+
{
158+
private:
159+
using SpinLock = SpinLockBlocking<instance>;
160+
uint32_t is;
161+
SpinLockGuard(const SpinLockGuard& ) = delete;
162+
SpinLockGuard(SpinLockGuard&&) = delete;
163+
public:
164+
inline SpinLockGuard() : is(SpinLock::lock()) {}
165+
inline ~SpinLockGuard() { SpinLock::unlock(is); }
166+
};
167+
/// @ingroup modm_platform_multicore
168+
using SystemSpinLockGuard = SpinLockGuard<SystemSpinLock>;
169+
170+
/// @ingroup modm_platform_multicore
171+
class Mutex
172+
{
173+
private:
174+
volatile bool locked = false;
175+
Mutex(const Mutex& ) = delete;
176+
Mutex(Mutex&&) = delete;
177+
public:
178+
Mutex() {}
179+
void lock()
180+
{
181+
while(true)
179182
{
180-
while(true)
181183
{
182-
{
183-
SystemSpinLockGuard g;
184-
if (!locked) {
185-
locked = true;
186-
return;
187-
}
184+
SystemSpinLockGuard g;
185+
if (!locked) {
186+
locked = true;
187+
return;
188188
}
189-
__WFE();
190189
}
190+
__WFE();
191191
}
192-
void unlock()
192+
}
193+
void unlock()
194+
{
193195
{
194-
{
195-
SystemSpinLockGuard g;
196-
locked = false;
197-
}
198-
__SEV();
196+
SystemSpinLockGuard g;
197+
locked = false;
199198
}
200-
};
199+
__SEV();
200+
}
201+
};
201202

202-
/// @ingroup modm_platform_multicore
203-
struct Core
203+
/// @ingroup modm_platform_multicore
204+
struct Core
205+
{
206+
static inline uint32_t cpuId()
204207
{
205-
static inline uint32_t cpuId()
206-
{
207-
return sio_hw->cpuid;
208-
}
209-
};
210-
/// Wake up (a previously reset) core 1 and enter the given function on
211-
/// core 1 using the default core 1 stack (below core 0 stack).
212-
/// @ingroup modm_platform_multicore
213-
struct Core1 : Core
214-
{
215-
static void run(void(*func)());
216-
};
217-
}
208+
return sio_hw->cpuid;
209+
}
210+
};
211+
/// Wake up (a previously reset) core 1 and enter the given function on
212+
/// core 1 using the default core 1 stack (below core 0 stack).
213+
/// @ingroup modm_platform_multicore
214+
struct Core1 : Core
215+
{
216+
static void run(void(*func)());
217+
};
218+
219+
} // namespace modm::platform::multicore
218220

219221
/// @ingroup modm_platform_multicore
220222
/// @{

0 commit comments

Comments
 (0)