Skip to content

Commit e1956cd

Browse files
soburiDhruvaG2000
authored andcommitted
zephyrCommon: Make configurable the max number of tones
Allows you to change the maximum number of notes that can be played with `tone()`. Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
1 parent 45891a0 commit e1956cd

2 files changed

Lines changed: 94 additions & 24 deletions

File tree

Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,11 @@ config ARDUINO_ENTRY
3434
bool "Provide arduino setup and loop entry points"
3535
default y
3636

37+
config ARDUINO_MAX_TONES
38+
int "Maximum number of tones that can be played simultaneously with tone()"
39+
default -1
40+
help
41+
Specify the maximum number of tones that can be played simultaneously with tone().
42+
If set to a negative value, the maximum number will be determined from the
43+
system's digital pin configuration.
3744
endif

cores/arduino/zephyrCommon.cpp

Lines changed: 87 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <Arduino.h>
88
#include "zephyrInternal.h"
99

10+
#include <zephyr/spinlock.h>
11+
1012
static const struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP(
1113
DT_PATH(zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))};
1214

@@ -212,49 +214,97 @@ PinStatus digitalRead(pin_size_t pinNumber) {
212214
return (gpio_pin_get_dt(&arduino_pins[pinNumber]) == 1) ? HIGH : LOW;
213215
}
214216

215-
#ifndef MAX_TONE_PINS
217+
#if CONFIG_ARDUINO_MAX_TONES < 0
216218
#define MAX_TONE_PINS DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios)
219+
#else
220+
#define MAX_TONE_PINS CONFIG_ARDUINO_MAX_TONES
217221
#endif
218222

219223
#define TOGGLES_PER_CYCLE 2ULL
220224

221225
static struct pin_timer {
222226
struct k_timer timer;
223-
uint32_t count;
224-
pin_size_t pin;
225-
bool infinity;
227+
uint32_t count{0};
228+
pin_size_t pin{pin_size_t(-1)};
229+
bool infinity{false};
230+
struct k_spinlock lock;
226231
} arduino_pin_timers[MAX_TONE_PINS];
227232

233+
static struct pin_timer* find_pin_timer(pin_size_t pinNumber, bool active_only) {
234+
for (size_t i = 0; i < ARRAY_SIZE(arduino_pin_timers); i++) {
235+
k_spinlock_key_t key = k_spin_lock(&arduino_pin_timers[i].lock);
236+
237+
if (arduino_pin_timers[i].pin == pinNumber) {
238+
k_spin_unlock(&arduino_pin_timers[i].lock, key);
239+
return &arduino_pin_timers[i];
240+
}
241+
242+
k_spin_unlock(&arduino_pin_timers[i].lock, key);
243+
}
244+
245+
if (active_only) {
246+
return nullptr;
247+
}
248+
249+
for (size_t i = 0; i < ARRAY_SIZE(arduino_pin_timers); i++) {
250+
k_spinlock_key_t key = k_spin_lock(&arduino_pin_timers[i].lock);
251+
252+
if (arduino_pin_timers[i].pin == pin_size_t(-1)) {
253+
arduino_pin_timers[i].pin = pinNumber;
254+
k_spin_unlock(&arduino_pin_timers[i].lock, key);
255+
return &arduino_pin_timers[i];
256+
}
257+
258+
k_spin_unlock(&arduino_pin_timers[i].lock, key);
259+
}
260+
261+
return nullptr;
262+
}
263+
228264
void tone_expiry_cb(struct k_timer *timer) {
229265
struct pin_timer *pt = CONTAINER_OF(timer, struct pin_timer, timer);
230-
const struct gpio_dt_spec *spec = &arduino_pins[pt->pin];
266+
k_spinlock_key_t key = k_spin_lock(&pt->lock);
267+
pin_size_t pin = pt->pin;
231268

232269
if (pt->count == 0 && !pt->infinity) {
270+
if (pin != pin_size_t(-1)) {
271+
gpio_pin_set_dt(&arduino_pins[pin], 0);
272+
}
273+
233274
k_timer_stop(timer);
234-
gpio_pin_set_dt(spec, 0);
275+
pt->pin = pin_size_t(-1);
235276
} else {
236-
gpio_pin_toggle_dt(spec);
277+
if (pin != pin_size_t(-1)) {
278+
gpio_pin_toggle_dt(&arduino_pins[pin]);
279+
}
280+
237281
pt->count--;
238282
}
283+
284+
k_spin_unlock(&pt->lock, key);
239285
}
240286

241287
void tone(pin_size_t pinNumber, unsigned int frequency,
242288
unsigned long duration) {
243-
const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
244-
struct k_timer *timer;
289+
k_spinlock_key_t key;
290+
struct pin_timer *pt;
245291
k_timeout_t timeout;
246292

247-
if (pinNumber >= MAX_TONE_PINS) {
293+
pt = find_pin_timer(pinNumber, false);
294+
295+
if (pt == nullptr) {
248296
return;
249297
}
250298

251-
timer = &arduino_pin_timers[pinNumber].timer;
252-
253299
pinMode(pinNumber, OUTPUT);
254-
k_timer_stop(&arduino_pin_timers[pinNumber].timer);
300+
k_timer_stop(&pt->timer);
255301

256302
if (frequency == 0) {
257-
gpio_pin_set_dt(spec, 0);
303+
key = k_spin_lock(&pt->lock);
304+
pt->pin = pin_size_t(-1);
305+
k_spin_unlock(&pt->lock, key);
306+
307+
gpio_pin_set_dt(&arduino_pins[pinNumber], 0);
258308
return;
259309
}
260310

@@ -263,21 +313,34 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
263313
timeout.ticks = 1;
264314
}
265315

266-
arduino_pin_timers[pinNumber].infinity = (duration == 0);
267-
arduino_pin_timers[pinNumber].count = (uint64_t)duration * frequency *
268-
(MSEC_PER_SEC / TOGGLES_PER_CYCLE);
269-
arduino_pin_timers[pinNumber].pin = pinNumber;
270-
k_timer_init(timer, tone_expiry_cb, NULL);
316+
key = k_spin_lock(&pt->lock);
317+
pt->infinity = (duration == 0);
318+
pt->count = min((uint64_t)duration * frequency * TOGGLES_PER_CYCLE / MSEC_PER_SEC, UINT32_MAX);
319+
pt->pin = pinNumber;
320+
k_spin_unlock(&pt->lock, key);
321+
322+
k_timer_init(&pt->timer, tone_expiry_cb, NULL);
271323

272-
gpio_pin_set_dt(spec, 0);
273-
k_timer_start(timer, timeout, timeout);
324+
gpio_pin_set_dt(&arduino_pins[pinNumber], 0);
325+
k_timer_start(&pt->timer, timeout, timeout);
274326
}
275327

276328
void noTone(pin_size_t pinNumber) {
277-
const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
329+
struct pin_timer *pt;
330+
k_spinlock_key_t key;
331+
332+
pt = find_pin_timer(pinNumber, true);
333+
334+
if (pt == nullptr) {
335+
return;
336+
}
337+
338+
key = k_spin_lock(&pt->lock);
339+
k_timer_stop(&pt->timer);
340+
pt->pin = pin_size_t(-1);
341+
k_spin_unlock(&pt->lock, key);
278342

279-
k_timer_stop(&arduino_pin_timers[pinNumber].timer);
280-
gpio_pin_set_dt(spec, 0);
343+
gpio_pin_set_dt(&arduino_pins[pinNumber], 0);
281344
}
282345

283346
void delay(unsigned long ms) {

0 commit comments

Comments
 (0)