@@ -230,12 +230,32 @@ PinStatus digitalRead(pin_size_t pinNumber) {
230230 return (gpio_pin_get_dt (&arduino_pins[pinNumber]) == 1 ) ? HIGH : LOW;
231231}
232232
233- struct k_timer arduino_pin_timers[ARRAY_SIZE(arduino_pins)];
234- struct k_timer arduino_pin_timers_timeout[ARRAY_SIZE(arduino_pins)];
233+ #ifndef MAX_TONE_PINS
234+ #define MAX_TONE_PINS DT_PROP_LEN (DT_PATH(zephyr_user), digital_pin_gpios)
235+ #endif
236+
237+ #define TOGGLES_PER_CYCLE 2ULL
238+
239+ static struct pin_timer {
240+ struct k_timer timer;
241+ uint32_t count;
242+ pin_size_t pin;
243+ bool infinity;
244+ } arduino_pin_timers[MAX_TONE_PINS];
235245
236246void tone_expiry_cb (struct k_timer *timer) {
237- const struct gpio_dt_spec *spec = (gpio_dt_spec *)k_timer_user_data_get (timer);
238- gpio_pin_toggle_dt (spec);
247+ struct pin_timer *pt = CONTAINER_OF (timer, struct pin_timer , timer);
248+ const struct gpio_dt_spec *spec = &arduino_pins[pt->pin ];
249+
250+ if (pt->count == 0 ) {
251+ k_timer_stop (timer);
252+ gpio_pin_set_dt (spec, 0 );
253+ } else {
254+ gpio_pin_toggle_dt (spec);
255+ if (!pt->infinity ) {
256+ pt->count --;
257+ }
258+ }
239259}
240260
241261void tone_timeout_cb (struct k_timer *timer) {
@@ -244,35 +264,44 @@ void tone_timeout_cb(struct k_timer *timer) {
244264}
245265
246266void tone (pin_size_t pinNumber, unsigned int frequency, unsigned long duration) {
247- struct k_timer *timer = &arduino_pin_timers[pinNumber];
248267 const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
268+ struct k_timer *timer;
249269 k_timeout_t timeout;
250270
271+ if (pinNumber >= MAX_TONE_PINS) {
272+ return ;
273+ }
274+
275+ timer = &arduino_pin_timers[pinNumber].timer ;
276+
251277 pinMode (pinNumber, OUTPUT);
278+ k_timer_stop (&arduino_pin_timers[pinNumber].timer );
252279
253280 if (frequency == 0 ) {
254281 gpio_pin_set_dt (spec, 0 );
255282 return ;
256283 }
257284
258- timeout = K_NSEC (NSEC_PER_SEC / (2 * frequency));
285+ timeout = K_NSEC (NSEC_PER_SEC / (TOGGLES_PER_CYCLE * frequency));
286+ if (timeout.ticks == 0 ) {
287+ timeout.ticks = 1 ;
288+ }
259289
290+ arduino_pin_timers[pinNumber].infinity = (duration == 0 );
291+ arduino_pin_timers[pinNumber].count = (uint64_t )duration * frequency *
292+ (MSEC_PER_SEC / TOGGLES_PER_CYCLE);
293+ arduino_pin_timers[pinNumber].pin = pinNumber;
260294 k_timer_init (timer, tone_expiry_cb, NULL );
261- k_timer_user_data_set (timer, (void *)spec);
262- gpio_pin_set_dt (spec, 1 );
263- k_timer_start (timer, timeout, timeout);
264295
265- if (duration > 0 ) {
266- timer = &arduino_pin_timers_timeout[pinNumber];
267- k_timer_init (timer, tone_timeout_cb, NULL );
268- k_timer_user_data_set (timer, (void *)(uintptr_t )pinNumber);
269- k_timer_start (timer, K_MSEC (duration), K_NO_WAIT);
270- }
296+ gpio_pin_set_dt (spec, 0 );
297+ k_timer_start (timer, timeout, timeout);
271298}
272299
273300void noTone (pin_size_t pinNumber) {
274- k_timer_stop (&arduino_pin_timers[pinNumber]);
275- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
301+ const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
302+
303+ k_timer_stop (&arduino_pin_timers[pinNumber].timer );
304+ gpio_pin_set_dt (spec, 0 );
276305}
277306
278307__attribute__ ((always_inline)) void delay(unsigned long ms) {
0 commit comments