@@ -212,49 +212,74 @@ PinStatus digitalRead(pin_size_t pinNumber) {
212212 return (gpio_pin_get_dt (&arduino_pins[pinNumber]) == 1 ) ? HIGH : LOW;
213213}
214214
215- struct k_timer arduino_pin_timers[ARRAY_SIZE(arduino_pins)];
216- struct k_timer arduino_pin_timers_timeout[ARRAY_SIZE(arduino_pins)];
215+ #ifndef MAX_TONE_PINS
216+ #define MAX_TONE_PINS DT_PROP_LEN (DT_PATH(zephyr_user), digital_pin_gpios)
217+ #endif
218+
219+ #define TOGGLES_PER_CYCLE 2ULL
220+
221+ static struct pin_timer {
222+ struct k_timer timer;
223+ uint32_t count;
224+ pin_size_t pin;
225+ bool infinity;
226+ } arduino_pin_timers[MAX_TONE_PINS];
217227
218228void tone_expiry_cb (struct k_timer *timer) {
219- const struct gpio_dt_spec *spec = (gpio_dt_spec*)k_timer_user_data_get (timer);
220- gpio_pin_toggle_dt (spec);
221- }
229+ struct pin_timer *pt = CONTAINER_OF (timer, struct pin_timer , timer);
230+ const struct gpio_dt_spec *spec = &arduino_pins[pt->pin ];
222231
223- void tone_timeout_cb (struct k_timer *timer) {
224- pin_size_t pinNumber = (pin_size_t )(uintptr_t )k_timer_user_data_get (timer);
225- noTone (pinNumber);
232+ if (pt->count == 0 ) {
233+ k_timer_stop (timer);
234+ gpio_pin_set_dt (spec, 0 );
235+ } else {
236+ gpio_pin_toggle_dt (spec);
237+ if (!pt->infinity ) {
238+ pt->count --;
239+ }
240+ }
226241}
227242
228- void tone (pin_size_t pinNumber, unsigned int frequency, unsigned long duration) {
229- struct k_timer *timer = &arduino_pin_timers[pinNumber];
243+ void tone (pin_size_t pinNumber, unsigned int frequency,
244+ unsigned long duration) {
230245 const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
246+ struct k_timer *timer;
231247 k_timeout_t timeout;
232248
249+ if (pinNumber >= MAX_TONE_PINS) {
250+ return ;
251+ }
252+
253+ timer = &arduino_pin_timers[pinNumber].timer ;
254+
233255 pinMode (pinNumber, OUTPUT);
256+ k_timer_stop (&arduino_pin_timers[pinNumber].timer );
234257
235258 if (frequency == 0 ) {
236259 gpio_pin_set_dt (spec, 0 );
237260 return ;
238261 }
239262
240- timeout = K_NSEC (NSEC_PER_SEC / (2 * frequency));
263+ timeout = K_NSEC (NSEC_PER_SEC / (TOGGLES_PER_CYCLE * frequency));
264+ if (timeout.ticks == 0 ) {
265+ timeout.ticks = 1 ;
266+ }
241267
268+ arduino_pin_timers[pinNumber].infinity = (duration == 0 );
269+ arduino_pin_timers[pinNumber].count = (uint64_t )duration * frequency *
270+ (MSEC_PER_SEC / TOGGLES_PER_CYCLE);
271+ arduino_pin_timers[pinNumber].pin = pinNumber;
242272 k_timer_init (timer, tone_expiry_cb, NULL );
243- k_timer_user_data_set (timer, (void *)spec);
244- gpio_pin_set_dt (spec, 1 );
245- k_timer_start (timer, timeout, timeout);
246273
247- if (duration > 0 ) {
248- timer = &arduino_pin_timers_timeout[pinNumber];
249- k_timer_init (timer, tone_timeout_cb, NULL );
250- k_timer_user_data_set (timer, (void *)(uintptr_t )pinNumber);
251- k_timer_start (timer, K_MSEC (duration), K_NO_WAIT);
252- }
274+ gpio_pin_set_dt (spec, 0 );
275+ k_timer_start (timer, timeout, timeout);
253276}
254277
255278void noTone (pin_size_t pinNumber) {
256- k_timer_stop (&arduino_pin_timers[pinNumber]);
257- gpio_pin_set_dt (&arduino_pins[pinNumber], 0 );
279+ const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
280+
281+ k_timer_stop (&arduino_pin_timers[pinNumber].timer );
282+ gpio_pin_set_dt (spec, 0 );
258283}
259284
260285void delay (unsigned long ms) {
0 commit comments