77#include < Arduino.h>
88#include " zephyrInternal.h"
99
10+ #include < zephyr/spinlock.h>
11+
1012static 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
221225static 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+
228264void 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
241287void 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
276328void 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
283346void delay (unsigned long ms) {
0 commit comments