Unverified Commit b793ad55 authored by Earle F. Philhower, III's avatar Earle F. Philhower, III Committed by GitHub

Make Tone multicore safe (#106)

Add a mutex around the Tone mapping for multicore safety.
parent b5aeb84c
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include <Arduino.h> #include <Arduino.h>
#include "CoreMutex.h"
#include <hardware/gpio.h> #include <hardware/gpio.h>
#include <pico/time.h> #include <pico/time.h>
#include <map> #include <map>
...@@ -29,12 +30,21 @@ typedef struct { ...@@ -29,12 +30,21 @@ typedef struct {
int sm; int sm;
} Tone; } Tone;
// Keep std::map safe for multicore use
static bool _mutexInitted = false;
static mutex_t _mutex;
#include "tone.pio.h" #include "tone.pio.h"
static PIOProgram _tonePgm(&tone_program); static PIOProgram _tonePgm(&tone_program);
static std::map<pin_size_t, Tone *> _toneMap; static std::map<pin_size_t, Tone *> _toneMap;
void tone(uint8_t pin, unsigned int frequency, unsigned long duration) { void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
if (!_mutexInitted) {
mutex_init(&_mutex);
_mutexInitted = true;
}
if ((pin < 0) || (pin > 29)) { if ((pin < 0) || (pin > 29)) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin); DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return; return;
...@@ -43,6 +53,11 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) { ...@@ -43,6 +53,11 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
noTone(pin); noTone(pin);
return; 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; int us = 1000000 / frequency / 2;
if (us < 5) { if (us < 5) {
us = 5; us = 5;
...@@ -76,7 +91,14 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) { ...@@ -76,7 +91,14 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
} }
void noTone(uint8_t pin) { 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); DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment