Skip to content

Commit b793ad5

Browse files
Make Tone multicore safe (#106)
Add a mutex around the Tone mapping for multicore safety.
1 parent b5aeb84 commit b793ad5

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

cores/rp2040/Tone.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
#include <Arduino.h>
22+
#include "CoreMutex.h"
2223
#include <hardware/gpio.h>
2324
#include <pico/time.h>
2425
#include <map>
@@ -29,12 +30,21 @@ typedef struct {
2930
int sm;
3031
} Tone;
3132

33+
// Keep std::map safe for multicore use
34+
static bool _mutexInitted = false;
35+
static mutex_t _mutex;
36+
37+
3238
#include "tone.pio.h"
3339
static PIOProgram _tonePgm(&tone_program);
3440

3541
static std::map<pin_size_t, Tone *> _toneMap;
3642

3743
void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
44+
if (!_mutexInitted) {
45+
mutex_init(&_mutex);
46+
_mutexInitted = true;
47+
}
3848
if ((pin < 0) || (pin > 29)) {
3949
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
4050
return;
@@ -43,6 +53,11 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
4353
noTone(pin);
4454
return;
4555
}
56+
57+
// Ensure only 1 core can start or stop at a time
58+
CoreMutex m(&_mutex);
59+
if (!m) return; // Weird deadlock case
60+
4661
int us = 1000000 / frequency / 2;
4762
if (us < 5) {
4863
us = 5;
@@ -76,7 +91,14 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
7691
}
7792

7893
void noTone(uint8_t pin) {
79-
if ((pin < 0) || (pin > 29)) {
94+
if (!_mutexInitted) {
95+
mutex_init(&_mutex);
96+
_mutexInitted = true;
97+
}
98+
99+
CoreMutex m(&_mutex);
100+
101+
if ((pin < 0) || (pin > 29) || !m) {
80102
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
81103
return;
82104
}

0 commit comments

Comments
 (0)