Skip to content

Commit b78e5b1

Browse files
committed
zephyrCommon: Improved tone implemetation
Improved to align more closely with the standard Arduino implementation. - Eliminated the end timer and used counting to determine the end. - Improved to handle infinity correctly. - Added a guard to prevent the timeout value from reaching 0. - Set the GPIO value to 0 when the timer starts. Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
1 parent c85c470 commit b78e5b1

File tree

1 file changed

+37
-21
lines changed

1 file changed

+37
-21
lines changed

cores/arduino/zephyrCommon.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -212,49 +212,65 @@ 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+
struct pin_timer {
220+
struct k_timer timer;
221+
pin_size_t pin;
222+
bool infinity;
223+
uint32_t count;
224+
} arduino_pin_timers[MAX_TONE_PINS];
217225

218226
void 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-
}
227+
struct pin_timer *pt = CONTAINER_OF(timer, struct pin_timer, timer);
228+
const struct gpio_dt_spec *spec = &arduino_pins[pt->pin];
222229

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);
230+
if (pt->infinity) {
231+
k_timer_stop(timer);
232+
gpio_pin_set_dt(spec, 0);
233+
} else {
234+
gpio_pin_toggle_dt(spec);
235+
if (pt->count != UINT32_MAX) {
236+
pt->count--;
237+
}
238+
}
226239
}
227240

228-
void tone(pin_size_t pinNumber, unsigned int frequency, unsigned long duration) {
229-
struct k_timer *timer = &arduino_pin_timers[pinNumber];
241+
void tone(pin_size_t pinNumber, unsigned int frequency,
242+
unsigned long duration) {
230243
const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
244+
struct k_timer *timer = &arduino_pin_timers[pinNumber].timer;
231245
k_timeout_t timeout;
232246

233247
pinMode(pinNumber, OUTPUT);
248+
k_timer_stop(&arduino_pin_timers[pinNumber].timer);
234249

235250
if (frequency == 0) {
236251
gpio_pin_set_dt(spec, 0);
237252
return;
238253
}
239254

240255
timeout = K_NSEC(NSEC_PER_SEC / (2 * frequency));
256+
if (timeout.ticks == 0) {
257+
timeout.ticks = 1;
258+
}
241259

260+
arduino_pin_timers[pinNumber].infinity = (duration == 0);
261+
arduino_pin_timers[pinNumber].count = ((uint64_t)duration * frequency) / 500ULL;
262+
arduino_pin_timers[pinNumber].pin = pinNumber;
242263
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);
246264

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-
}
265+
gpio_pin_set_dt(spec, 0);
266+
k_timer_start(timer, timeout, timeout);
253267
}
254268

255269
void noTone(pin_size_t pinNumber) {
256-
k_timer_stop(&arduino_pin_timers[pinNumber]);
257-
gpio_pin_set_dt(&arduino_pins[pinNumber], 0);
270+
const struct gpio_dt_spec *spec = &arduino_pins[pinNumber];
271+
272+
k_timer_stop(&arduino_pin_timers[pinNumber].timer);
273+
gpio_pin_set_dt(spec, 0);
258274
}
259275

260276
void delay(unsigned long ms) { k_sleep(K_MSEC(ms)); }

0 commit comments

Comments
 (0)