-
Notifications
You must be signed in to change notification settings - Fork 59
zephyrCommon: Make configurable the max number of tones #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,8 @@ | |
| #include <Arduino.h> | ||
| #include "zephyrInternal.h" | ||
|
|
||
| #include <zephyr/spinlock.h> | ||
|
|
||
| static const struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP( | ||
| DT_PATH(zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))}; | ||
|
|
||
|
|
@@ -212,51 +214,97 @@ PinStatus digitalRead(pin_size_t pinNumber) { | |
| return (gpio_pin_get_dt(&arduino_pins[pinNumber]) == 1) ? HIGH : LOW; | ||
| } | ||
|
|
||
| #ifndef MAX_TONE_PINS | ||
| #if CONFIG_ARDUINO_MAX_TONES < 0 | ||
| #define MAX_TONE_PINS DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios) | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #else | ||
| #define MAX_TONE_PINS CONFIG_ARDUINO_MAX_TONES | ||
| #endif | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| #define TOGGLES_PER_CYCLE 2ULL | ||
|
|
||
| static struct pin_timer { | ||
| struct k_timer timer; | ||
| uint32_t count; | ||
| pin_size_t pin; | ||
| bool infinity; | ||
| uint32_t count{0}; | ||
| pin_size_t pin{pin_size_t(-1)}; | ||
| bool infinity{false}; | ||
| struct k_spinlock lock; | ||
| } arduino_pin_timers[MAX_TONE_PINS]; | ||
|
|
||
| static struct pin_timer* find_pin_timer(pin_size_t pinNumber, bool active_only) { | ||
| for (size_t i = 0; i < ARRAY_SIZE(arduino_pin_timers); i++) { | ||
| k_spinlock_key_t key = k_spin_lock(&arduino_pin_timers[i].lock); | ||
|
|
||
| if (arduino_pin_timers[i].pin == pinNumber) { | ||
| k_spin_unlock(&arduino_pin_timers[i].lock, key); | ||
| return &arduino_pin_timers[i]; | ||
| } | ||
|
|
||
| k_spin_unlock(&arduino_pin_timers[i].lock, key); | ||
| } | ||
|
|
||
| if (active_only) { | ||
| return nullptr; | ||
| } | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove extra newline please
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've overhauled this entire function. |
||
| for (size_t i = 0; i < ARRAY_SIZE(arduino_pin_timers); i++) { | ||
| k_spinlock_key_t key = k_spin_lock(&arduino_pin_timers[i].lock); | ||
|
|
||
| if (arduino_pin_timers[i].pin == pin_size_t(-1)) { | ||
| arduino_pin_timers[i].pin = pinNumber; | ||
| k_spin_unlock(&arduino_pin_timers[i].lock, key); | ||
| return &arduino_pin_timers[i]; | ||
| } | ||
|
|
||
| k_spin_unlock(&arduino_pin_timers[i].lock, key); | ||
| } | ||
|
|
||
| return nullptr; | ||
| } | ||
|
|
||
| void tone_expiry_cb(struct k_timer *timer) { | ||
| struct pin_timer *pt = CONTAINER_OF(timer, struct pin_timer, timer); | ||
| const struct gpio_dt_spec *spec = &arduino_pins[pt->pin]; | ||
| k_spinlock_key_t key = k_spin_lock(&pt->lock); | ||
| pin_size_t pin = pt->pin; | ||
|
|
||
| if (pt->count == 0 && !pt->infinity) { | ||
| if (pin != pin_size_t(-1)) { | ||
| gpio_pin_set_dt(&arduino_pins[pin], 0); | ||
| } | ||
|
|
||
| if (pt->count == 0) { | ||
| k_timer_stop(timer); | ||
| gpio_pin_set_dt(spec, 0); | ||
| pt->pin = pin_size_t(-1); | ||
| } else { | ||
| gpio_pin_toggle_dt(spec); | ||
| if (!pt->infinity) { | ||
| pt->count--; | ||
| if (pin != pin_size_t(-1)) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are these changes inside add tone_doremi sample? Can be very misleading, please split into another commit.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops! |
||
| gpio_pin_toggle_dt(&arduino_pins[pin]); | ||
| } | ||
|
|
||
| pt->count--; | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| k_spin_unlock(&pt->lock, key); | ||
| } | ||
|
|
||
| void tone(pin_size_t pinNumber, unsigned int frequency, | ||
| unsigned long duration) { | ||
| const struct gpio_dt_spec *spec = &arduino_pins[pinNumber]; | ||
| struct k_timer *timer; | ||
| k_spinlock_key_t key; | ||
| struct pin_timer *pt; | ||
| k_timeout_t timeout; | ||
|
|
||
| if (pinNumber >= MAX_TONE_PINS) { | ||
| pt = find_pin_timer(pinNumber, false); | ||
|
|
||
| if (pt == nullptr) { | ||
| return; | ||
| } | ||
|
|
||
| timer = &arduino_pin_timers[pinNumber].timer; | ||
|
|
||
| pinMode(pinNumber, OUTPUT); | ||
| k_timer_stop(&arduino_pin_timers[pinNumber].timer); | ||
| k_timer_stop(&pt->timer); | ||
|
|
||
| if (frequency == 0) { | ||
| gpio_pin_set_dt(spec, 0); | ||
| key = k_spin_lock(&pt->lock); | ||
| pt->pin = pin_size_t(-1); | ||
| k_spin_unlock(&pt->lock, key); | ||
|
|
||
| gpio_pin_set_dt(&arduino_pins[pinNumber], 0); | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return; | ||
| } | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
@@ -265,21 +313,34 @@ void tone(pin_size_t pinNumber, unsigned int frequency, | |
| timeout.ticks = 1; | ||
| } | ||
|
|
||
| arduino_pin_timers[pinNumber].infinity = (duration == 0); | ||
| arduino_pin_timers[pinNumber].count = (uint64_t)duration * frequency * | ||
| (MSEC_PER_SEC / TOGGLES_PER_CYCLE); | ||
| arduino_pin_timers[pinNumber].pin = pinNumber; | ||
| k_timer_init(timer, tone_expiry_cb, NULL); | ||
| key = k_spin_lock(&pt->lock); | ||
| pt->infinity = (duration == 0); | ||
| pt->count = min((uint64_t)duration * frequency * TOGGLES_PER_CYCLE / MSEC_PER_SEC, UINT32_MAX); | ||
| pt->pin = pinNumber; | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| k_spin_unlock(&pt->lock, key); | ||
|
|
||
| gpio_pin_set_dt(spec, 0); | ||
| k_timer_start(timer, timeout, timeout); | ||
| k_timer_init(&pt->timer, tone_expiry_cb, NULL); | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| gpio_pin_set_dt(&arduino_pins[pinNumber], 0); | ||
| k_timer_start(&pt->timer, timeout, timeout); | ||
| } | ||
|
|
||
| void noTone(pin_size_t pinNumber) { | ||
| const struct gpio_dt_spec *spec = &arduino_pins[pinNumber]; | ||
| struct pin_timer *pt; | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| k_spinlock_key_t key; | ||
|
|
||
| pt = find_pin_timer(pinNumber, true); | ||
|
|
||
| if (pt == nullptr) { | ||
| return; | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| key = k_spin_lock(&pt->lock); | ||
| k_timer_stop(&pt->timer); | ||
| pt->pin = pin_size_t(-1); | ||
| k_spin_unlock(&pt->lock, key); | ||
|
|
||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| k_timer_stop(&arduino_pin_timers[pinNumber].timer); | ||
| gpio_pin_set_dt(spec, 0); | ||
| gpio_pin_set_dt(&arduino_pins[pinNumber], 0); | ||
| } | ||
|
|
||
| void delay(unsigned long ms) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| cmake_minimum_required(VERSION 3.20.0) | ||
|
|
||
| # get value of NORMALIZED_BOARD_TARGET early | ||
| find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) | ||
|
|
||
| if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}_${BOARD_REVISION}) | ||
| set(variant_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}_${BOARD_REVISION}) | ||
| elseif (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}) | ||
| set(variant_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}) | ||
| elseif (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../variants/${BOARD}) | ||
| set(variant_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../variants/${BOARD}) | ||
| endif() | ||
|
|
||
| if (EXISTS ${variant_dir}/${NORMALIZED_BOARD_TARGET}_${BOARD_REVISION}.overlay) | ||
| set(DTC_OVERLAY_FILE ${variant_dir}/${NORMALIZED_BOARD_TARGET}_${BOARD_REVISION}.overlay) | ||
| elseif (EXISTS ${variant_dir}/${NORMALIZED_BOARD_TARGET}.overlay) | ||
| set(DTC_OVERLAY_FILE ${variant_dir}/${NORMALIZED_BOARD_TARGET}.overlay) | ||
| elseif (EXISTS ${variant_dir}/${BOARD}.overlay) | ||
| set(DTC_OVERLAY_FILE ${variant_dir}/${BOARD}.overlay) | ||
| endif() | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
| project(tone_doremi) | ||
|
|
||
| target_sources(app PRIVATE src/app.cpp) | ||
|
|
||
| zephyr_compile_options(-Wno-unused-variable -Wno-comment) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| .. _tone_doremi: | ||
|
|
||
| Tone DoReMi | ||
| ########### | ||
|
|
||
| Overview | ||
| ******** | ||
|
|
||
| Use tone to play the scale. | ||
| Play Do, Re, Mi on D4 pin, then Fa, So, La on D5 pin. | ||
|
|
||
| Building and Running | ||
| ******************** | ||
|
|
||
| Build and flash tone_doremi sample as follows, | ||
|
|
||
| .. code-block:: sh | ||
| $> west build -p -b arduino_nano_33_ble samples/tone_doremi/ | ||
| $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| CONFIG_ARDUINO_API=y | ||
| CONFIG_ARDUINO_MAX_TONES=2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| /* | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * | ||
| * Copyright (c) 2026 TOKITA Hiroshi | ||
| */ | ||
|
|
||
| #include <Arduino.h> | ||
| #include "zephyrSerial.h" | ||
|
|
||
| #define NOTE_C4 262 | ||
| #define NOTE_D4 294 | ||
| #define NOTE_E4 330 | ||
| #define NOTE_F4 349 | ||
| #define NOTE_G4 392 | ||
| #define NOTE_A4 440 | ||
|
|
||
| void setup() { | ||
| Serial.begin(115200); | ||
| } | ||
|
|
||
| void loop() { | ||
| Serial.println("Do@D4"); | ||
| tone(D4, NOTE_C4, 1000); | ||
| delay(2000); | ||
| Serial.println("Re@D4"); | ||
| tone(D4, NOTE_D4, 1000); | ||
| delay(2000); | ||
| Serial.println("Mi@D4 - Infinity"); | ||
| tone(D4, NOTE_E4, 0); | ||
| delay(2000); | ||
| Serial.println("Fa@D5"); | ||
| tone(D5, NOTE_F4, 1000); | ||
| delay(2000); | ||
| Serial.println("So@D5"); | ||
| tone(D5, NOTE_G4, 1000); | ||
| delay(2000); | ||
| Serial.println("La@D5 - Infinity"); | ||
| tone(D5, NOTE_A4, 0); | ||
|
|
||
| while(true) { | ||
| delay(1000); | ||
| } | ||
| } | ||
soburi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.