@@ -249,9 +249,15 @@ static struct pin_timer {
249249 uint32_t count{0 };
250250 pin_size_t pin{pin_size_t (-1 )};
251251 bool infinity{false };
252- struct k_spinlock lock;
252+ bool timer_initialized{false };
253+ struct k_spinlock lock{};
253254} arduino_pin_timers[MAX_TONE_PINS ];
254255
256+ K_MUTEX_DEFINE (timer_cfg_lock);
257+
258+ void tone_expiry_cb (struct k_timer *timer);
259+
260+ /* Callers must hold timer_cfg_lock while using this helper. */
255261static struct pin_timer *find_pin_timer (pin_size_t pinNumber, bool active_only) {
256262 for (size_t i = 0 ; i < ARRAY_SIZE (arduino_pin_timers); i++) {
257263 k_spinlock_key_t key = k_spin_lock (&arduino_pin_timers[i].lock );
@@ -294,12 +300,13 @@ void tone_expiry_cb(struct k_timer *timer) {
294300 }
295301
296302 k_timer_stop (timer);
303+ pt->count = 0 ;
304+ pt->infinity = false ;
297305 pt->pin = pin_size_t (-1 );
298306 } else {
299307 if (pin != pin_size_t (-1 )) {
300308 gpio_pin_toggle_dt (&arduino_pins[pin]);
301309 }
302-
303310 pt->count --;
304311 }
305312
@@ -308,24 +315,42 @@ void tone_expiry_cb(struct k_timer *timer) {
308315
309316void tone (pin_size_t pinNumber, unsigned int frequency, unsigned long duration) {
310317 k_spinlock_key_t key;
318+ uint64_t toggles_count;
311319 struct pin_timer *pt;
312320 k_timeout_t timeout;
313321
322+ if (k_is_in_isr ()) {
323+ return ;
324+ }
325+
326+ k_mutex_lock (&timer_cfg_lock, K_FOREVER );
327+
314328 pt = find_pin_timer (pinNumber, false );
315329
316330 if (pt == nullptr ) {
331+ k_mutex_unlock (&timer_cfg_lock);
317332 return ;
318333 }
319334
335+ if (!pt->timer_initialized ) {
336+ k_timer_init (&pt->timer , tone_expiry_cb, NULL );
337+ pt->timer_initialized = true ;
338+ }
339+
320340 pinMode (pinNumber, OUTPUT );
321341 k_timer_stop (&pt->timer );
322342
323- if (frequency == 0 ) {
343+ toggles_count = ((uint64_t )duration * frequency / (MSEC_PER_SEC / TOGGLES_PER_CYCLE ));
344+ if (frequency == 0 || (toggles_count == 0 && duration != 0 )) {
324345 key = k_spin_lock (&pt->lock );
346+ pt->count = 0 ;
347+ pt->infinity = false ;
325348 pt->pin = pin_size_t (-1 );
326349 k_spin_unlock (&pt->lock , key);
327350
328351 gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
352+
353+ k_mutex_unlock (&timer_cfg_lock);
329354 return ;
330355 }
331356
@@ -336,32 +361,43 @@ void tone(pin_size_t pinNumber, unsigned int frequency, unsigned long duration)
336361
337362 key = k_spin_lock (&pt->lock );
338363 pt->infinity = (duration == 0 );
339- pt->count = min (( uint64_t )duration * frequency * TOGGLES_PER_CYCLE / MSEC_PER_SEC , UINT32_MAX );
364+ pt->count = min (toggles_count , UINT32_MAX );
340365 pt->pin = pinNumber;
341366 k_spin_unlock (&pt->lock , key);
342367
343- k_timer_init (&pt->timer , tone_expiry_cb, NULL );
344-
345- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
368+ gpio_pin_set_dt (&arduino_pins[pinNumber], 1 );
346369 k_timer_start (&pt->timer , timeout, timeout);
370+
371+ k_mutex_unlock (&timer_cfg_lock);
347372}
348373
349374void noTone (pin_size_t pinNumber) {
350375 struct pin_timer *pt;
351376 k_spinlock_key_t key;
352377
378+ if (k_is_in_isr ()) {
379+ return ;
380+ }
381+
382+ k_mutex_lock (&timer_cfg_lock, K_FOREVER );
383+
353384 pt = find_pin_timer (pinNumber, true );
354385
355386 if (pt == nullptr ) {
387+ k_mutex_unlock (&timer_cfg_lock);
356388 return ;
357389 }
358390
359391 key = k_spin_lock (&pt->lock );
360392 k_timer_stop (&pt->timer );
393+ pt->count = 0 ;
394+ pt->infinity = false ;
361395 pt->pin = pin_size_t (-1 );
362396 k_spin_unlock (&pt->lock , key);
363397
364398 gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
399+
400+ k_mutex_unlock (&timer_cfg_lock);
365401}
366402
367403unsigned long micros (void ) {
0 commit comments