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,88 @@ 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+ size_t unusedIndex = size_t (-1 );
235+
236+ for (size_t i = 0 ; i < ARRAY_SIZE (arduino_pin_timers); i++) {
237+ k_spinlock_key_t key = k_spin_lock (&arduino_pin_timers[i].lock );
238+ pin_size_t pin = arduino_pin_timers[i].pin ;
239+
240+ k_spin_unlock (&arduino_pin_timers[i].lock , key);
241+
242+
243+ if (pin == pin_size_t (-1 )) {
244+ unusedIndex = i;
245+ }
246+
247+ if (pin == pinNumber) {
248+ return &arduino_pin_timers[i];
249+ }
250+ }
251+
252+ if (unusedIndex != size_t (-1 ) && !active_only) {
253+ return &arduino_pin_timers[unusedIndex];
254+ }
255+
256+ return nullptr ;
257+ }
258+
228259void tone_expiry_cb (struct k_timer *timer) {
229260 struct pin_timer *pt = CONTAINER_OF (timer, struct pin_timer , timer);
230- const struct gpio_dt_spec *spec = &arduino_pins[pt->pin ];
261+ k_spinlock_key_t key = k_spin_lock (&pt->lock );
262+ pin_size_t pin = pt->pin ;
231263
232264 if (pt->count == 0 && !pt->infinity ) {
265+ if (pin >= 0 ) {
266+ gpio_pin_set_dt (&arduino_pins[pin], 0 );
267+ }
268+
233269 k_timer_stop (timer);
234- gpio_pin_set_dt (spec, 0 );
270+ pt-> pin = pin_size_t (- 1 );
235271 } else {
236- gpio_pin_toggle_dt (spec);
272+ if (pin >= 0 ) {
273+ gpio_pin_toggle_dt (&arduino_pins[pin]);
274+ }
275+
237276 pt->count --;
238277 }
278+
279+ k_spin_unlock (&pt->lock , key);
239280}
240281
241282void tone (pin_size_t pinNumber, unsigned int frequency,
242283 unsigned long duration) {
243- const struct gpio_dt_spec *spec = &arduino_pins[pinNumber] ;
244- struct k_timer *timer ;
284+ k_spinlock_key_t key ;
285+ struct pin_timer *pt ;
245286 k_timeout_t timeout;
246287
247- if (pinNumber >= MAX_TONE_PINS) {
288+ pt = find_pin_timer (pinNumber, false );
289+
290+ if (pt == nullptr ) {
248291 return ;
249292 }
250293
251- timer = &arduino_pin_timers[pinNumber].timer ;
252-
253294 pinMode (pinNumber, OUTPUT);
254- k_timer_stop (&arduino_pin_timers[pinNumber]. timer );
295+ k_timer_stop (&pt-> timer );
255296
256297 if (frequency == 0 ) {
257- gpio_pin_set_dt (spec , 0 );
298+ gpio_pin_set_dt (&arduino_pins[pinNumber] , 0 );
258299 return ;
259300 }
260301
@@ -263,21 +304,34 @@ void tone(pin_size_t pinNumber, unsigned int frequency,
263304 timeout.ticks = 1 ;
264305 }
265306
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 );
307+ key = k_spin_lock (&pt-> lock );
308+ pt-> infinity = (duration == 0 );
309+ pt-> count = ( uint64_t )duration * frequency * TOGGLES_PER_CYCLE / MSEC_PER_SEC ;
310+ pt-> pin = pinNumber;
311+ k_spin_unlock (&pt-> lock , key );
271312
272- gpio_pin_set_dt (spec, 0 );
273- k_timer_start (timer, timeout, timeout);
313+ k_timer_init (&pt->timer , tone_expiry_cb, NULL );
314+
315+ gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
316+ k_timer_start (&pt->timer , timeout, timeout);
274317}
275318
276319void noTone (pin_size_t pinNumber) {
277- const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
320+ struct pin_timer *pt;
321+ k_spinlock_key_t key;
322+
323+ pt = find_pin_timer (pinNumber, true );
324+
325+ if (pt == nullptr ) {
326+ return ;
327+ }
328+
329+ key = k_spin_lock (&pt->lock );
330+ k_timer_stop (&pt->timer );
331+ pt->pin = pin_size_t (-1 );
332+ k_spin_unlock (&pt->lock , key);
278333
279- k_timer_stop (&arduino_pin_timers[pinNumber].timer );
280- gpio_pin_set_dt (spec, 0 );
334+ gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
281335}
282336
283337void delay (unsigned long ms) {
0 commit comments