Skip to content

Commit 50a8b2c

Browse files
committed
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 300cfb9 commit 50a8b2c

File tree

2 files changed

+48
-14
lines changed

2 files changed

+48
-14
lines changed

Kconfig

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

37+
config ARDUINO_MAX_TONES
38+
int "Specify the number of sounds that can be played simultaneously with tone()"
39+
default -1
40+
3741
endif

cores/arduino/zephyrCommon.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -212,26 +212,49 @@ PinStatus digitalRead(pin_size_t pinNumber) {
212212
return (gpio_pin_get_dt(&arduino_pins[pinNumber]) == 1) ? HIGH : LOW;
213213
}
214214

215-
#ifndef MAX_TONE_PINS
215+
#if CONFIG_ARDUINO_MAX_TONES < 0
216216
#define MAX_TONE_PINS DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios)
217+
#else
218+
#define MAX_TONE_PINS CONFIG_ARDUINO_MAX_TONES
217219
#endif
218220

219221
#define TOGGLES_PER_CYCLE 2ULL
220222

221223
static struct pin_timer {
222224
struct k_timer timer;
223225
uint32_t count;
224-
pin_size_t pin;
226+
pin_size_t pin{pin_size_t(-1)};
225227
bool infinity;
226228
} arduino_pin_timers[MAX_TONE_PINS];
227229

230+
static struct pin_timer* find_pin_timer(pin_size_t pinNumber, bool active_only) {
231+
size_t unusedIndex = size_t(-1);
232+
233+
for (size_t i = 0; i < ARRAY_SIZE(arduino_pin_timers); i++) {
234+
if (arduino_pin_timers[i].pin == pin_size_t(-1)) {
235+
unusedIndex = i;
236+
}
237+
238+
if (arduino_pin_timers[i].pin == pinNumber) {
239+
return &arduino_pin_timers[i];
240+
}
241+
}
242+
243+
if (unusedIndex != size_t(-1) && active_only) {
244+
return &arduino_pin_timers[unusedIndex];
245+
}
246+
247+
return NULL;
248+
}
249+
228250
void tone_expiry_cb(struct k_timer *timer) {
229251
struct pin_timer *pt = CONTAINER_OF(timer, struct pin_timer, timer);
230252
const struct gpio_dt_spec *spec = &arduino_pins[pt->pin];
231253

232254
if (pt->count == 0 && !pt->infinity) {
233255
k_timer_stop(timer);
234256
gpio_pin_set_dt(spec, 0);
257+
pt->pin = pin_size_t(-1);
235258
} else {
236259
gpio_pin_toggle_dt(spec);
237260
pt->count--;
@@ -241,17 +264,17 @@ void tone_expiry_cb(struct k_timer *timer) {
241264
void tone(pin_size_t pinNumber, unsigned int frequency,
242265
unsigned long duration) {
243266
const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
244-
struct k_timer *timer;
267+
struct pin_timer *pt;
245268
k_timeout_t timeout;
246269

247-
if (pinNumber >= MAX_TONE_PINS) {
270+
pt = find_pin_timer(pinNumber, false);
271+
272+
if (pt == nullptr) {
248273
return;
249274
}
250275

251-
timer = &arduino_pin_timers[pinNumber].timer;
252-
253276
pinMode(pinNumber, OUTPUT);
254-
k_timer_stop(&arduino_pin_timers[pinNumber].timer);
277+
k_timer_stop(&pt->timer);
255278

256279
if (frequency == 0) {
257280
gpio_pin_set_dt(spec, 0);
@@ -263,21 +286,28 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
263286
timeout.ticks = 1;
264287
}
265288

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);
289+
pt->infinity = (duration == 0);
290+
pt->count = (uint64_t)duration * frequency * (MSEC_PER_SEC / TOGGLES_PER_CYCLE);
291+
pt->pin = pinNumber;
292+
k_timer_init(&pt->timer, tone_expiry_cb, NULL);
271293

272294
gpio_pin_set_dt(spec, 0);
273-
k_timer_start(timer, timeout, timeout);
295+
k_timer_start(&pt->timer, timeout, timeout);
274296
}
275297

276298
void noTone(pin_size_t pinNumber) {
277299
const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
300+
struct pin_timer *pt;
301+
302+
pt = find_pin_timer(pinNumber, true);
303+
304+
if (pt == nullptr) {
305+
return;
306+
}
278307

279-
k_timer_stop(&arduino_pin_timers[pinNumber].timer);
308+
k_timer_stop(&pt->timer);
280309
gpio_pin_set_dt(spec, 0);
310+
pt->pin = pin_size_t(-1);
281311
}
282312

283313
void delay(unsigned long ms) {

0 commit comments

Comments
 (0)