Skip to content

Commit

Permalink
Make Tone multicore safe (#106)
Browse files Browse the repository at this point in the history
Add a mutex around the Tone mapping for multicore safety.
  • Loading branch information
earlephilhower committed Apr 15, 2021
1 parent b5aeb84 commit b793ad5
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion cores/rp2040/Tone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

#include <Arduino.h>
#include "CoreMutex.h"
#include <hardware/gpio.h>
#include <pico/time.h>
#include <map>
Expand All @@ -29,12 +30,21 @@ typedef struct {
int sm;
} Tone;

// Keep std::map safe for multicore use
static bool _mutexInitted = false;
static mutex_t _mutex;


#include "tone.pio.h"
static PIOProgram _tonePgm(&tone_program);

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

void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
if (!_mutexInitted) {
mutex_init(&_mutex);
_mutexInitted = true;
}
if ((pin < 0) || (pin > 29)) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
Expand All @@ -43,6 +53,11 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
noTone(pin);
return;
}

// Ensure only 1 core can start or stop at a time
CoreMutex m(&_mutex);
if (!m) return; // Weird deadlock case

int us = 1000000 / frequency / 2;
if (us < 5) {
us = 5;
Expand Down Expand Up @@ -76,7 +91,14 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
}

void noTone(uint8_t pin) {
if ((pin < 0) || (pin > 29)) {
if (!_mutexInitted) {
mutex_init(&_mutex);
_mutexInitted = true;
}

CoreMutex m(&_mutex);

if ((pin < 0) || (pin > 29) || !m) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
}
Expand Down

0 comments on commit b793ad5

Please sign in to comment.