@@ -223,9 +223,15 @@ static struct pin_timer {
223223 uint32_t count{0 };
224224 pin_size_t pin{pin_size_t (-1 )};
225225 bool infinity{false };
226- struct k_spinlock lock;
226+ bool timer_initialized{false };
227+ struct k_spinlock lock{};
227228} arduino_pin_timers[MAX_TONE_PINS];
228229
230+ K_MUTEX_DEFINE (timer_cfg_lock);
231+
232+ void tone_expiry_cb (struct k_timer *timer);
233+
234+ /* Callers must hold timer_cfg_lock while using this helper. */
229235static struct pin_timer *find_pin_timer (pin_size_t pinNumber, bool active_only) {
230236 for (size_t i = 0 ; i < ARRAY_SIZE (arduino_pin_timers); i++) {
231237 k_spinlock_key_t key = k_spin_lock (&arduino_pin_timers[i].lock );
@@ -268,12 +274,13 @@ void tone_expiry_cb(struct k_timer *timer) {
268274 }
269275
270276 k_timer_stop (timer);
277+ pt->count = 0 ;
278+ pt->infinity = false ;
271279 pt->pin = pin_size_t (-1 );
272280 } else {
273281 if (pin != pin_size_t (-1 )) {
274282 gpio_pin_toggle_dt (&arduino_pins[pin]);
275283 }
276-
277284 pt->count --;
278285 }
279286
@@ -282,24 +289,42 @@ void tone_expiry_cb(struct k_timer *timer) {
282289
283290void tone (pin_size_t pinNumber, unsigned int frequency, unsigned long duration) {
284291 k_spinlock_key_t key;
292+ uint64_t toggles_count;
285293 struct pin_timer *pt;
286294 k_timeout_t timeout;
287295
296+ if (k_is_in_isr ()) {
297+ return ;
298+ }
299+
300+ k_mutex_lock (&timer_cfg_lock, K_FOREVER);
301+
288302 pt = find_pin_timer (pinNumber, false );
289303
290304 if (pt == nullptr ) {
305+ k_mutex_unlock (&timer_cfg_lock);
291306 return ;
292307 }
293308
309+ if (!pt->timer_initialized ) {
310+ k_timer_init (&pt->timer , tone_expiry_cb, NULL );
311+ pt->timer_initialized = true ;
312+ }
313+
294314 pinMode (pinNumber, OUTPUT);
295315 k_timer_stop (&pt->timer );
296316
297- if (frequency == 0 ) {
317+ toggles_count = ((uint64_t )duration * frequency / (MSEC_PER_SEC / TOGGLES_PER_CYCLE));
318+ if (frequency == 0 || (toggles_count == 0 && duration != 0 )) {
298319 key = k_spin_lock (&pt->lock );
320+ pt->count = 0 ;
321+ pt->infinity = false ;
299322 pt->pin = pin_size_t (-1 );
300323 k_spin_unlock (&pt->lock , key);
301324
302325 gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
326+
327+ k_mutex_unlock (&timer_cfg_lock);
303328 return ;
304329 }
305330
@@ -310,32 +335,43 @@ void tone(pin_size_t pinNumber, unsigned int frequency, unsigned long duration)
310335
311336 key = k_spin_lock (&pt->lock );
312337 pt->infinity = (duration == 0 );
313- pt->count = min (( uint64_t )duration * frequency * TOGGLES_PER_CYCLE / MSEC_PER_SEC , UINT32_MAX);
338+ pt->count = min (toggles_count , UINT32_MAX);
314339 pt->pin = pinNumber;
315340 k_spin_unlock (&pt->lock , key);
316341
317- k_timer_init (&pt->timer , tone_expiry_cb, NULL );
318-
319- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
342+ gpio_pin_set_dt (&arduino_pins[pinNumber], 1 );
320343 k_timer_start (&pt->timer , timeout, timeout);
344+
345+ k_mutex_unlock (&timer_cfg_lock);
321346}
322347
323348void noTone (pin_size_t pinNumber) {
324349 struct pin_timer *pt;
325350 k_spinlock_key_t key;
326351
352+ if (k_is_in_isr ()) {
353+ return ;
354+ }
355+
356+ k_mutex_lock (&timer_cfg_lock, K_FOREVER);
357+
327358 pt = find_pin_timer (pinNumber, true );
328359
329360 if (pt == nullptr ) {
361+ k_mutex_unlock (&timer_cfg_lock);
330362 return ;
331363 }
332364
333365 key = k_spin_lock (&pt->lock );
334366 k_timer_stop (&pt->timer );
367+ pt->count = 0 ;
368+ pt->infinity = false ;
335369 pt->pin = pin_size_t (-1 );
336370 k_spin_unlock (&pt->lock , key);
337371
338372 gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
373+
374+ k_mutex_unlock (&timer_cfg_lock);
339375}
340376
341377void delay (unsigned long ms) {
0 commit comments