Skip to content

Commit 00a01fa

Browse files
soburiDhruvaG2000
authored andcommitted
zephyrCommon: Improved tone implementation
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 <[email protected]>
1 parent 607c419 commit 00a01fa

File tree

1 file changed

+47
-22
lines changed

1 file changed

+47
-22
lines changed

cores/arduino/zephyrCommon.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

218228
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-
}
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

255278
void 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

260285
void delay(unsigned long ms) {

0 commit comments

Comments
 (0)