From ada82c0a3b41791ee4f209bbe4e81b16e1bab484 Mon Sep 17 00:00:00 2001 From: TianpeiLee <124117623+TianpeiLee@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:21:27 +0800 Subject: [PATCH] add function of tone (#111) add function of tone for this issue #24 --- cores/arduino/Arduino.h | 15 +- cores/arduino/HardwareTimer.cpp | 2 +- cores/arduino/Tone.cpp | 149 ++++++++++++++++++ cores/arduino/Tone.h | 41 +++++ cores/arduino/wiring.h | 6 +- .../CH32V00x/CH32V003F4/variant_CH32V003F4.h | 9 ++ .../CH32VM00X/CH32V006K8/variant_CH32V006K8.h | 7 + 7 files changed, 218 insertions(+), 11 deletions(-) create mode 100644 cores/arduino/Tone.cpp create mode 100644 cores/arduino/Tone.h diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 40e6666..9db92a8 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -49,13 +49,14 @@ void yield(void); } // extern "C" #endif // __cplusplus -#ifdef __cplusplus -# include "WCharacter.h" -# include "WString.h" -# include "WMath.h" -//# include -# include -#endif +// Move the following content to the file wiring.h //by TempersLee +// #ifdef __cplusplus +// #include "WCharacter.h" +// #include "WString.h" +// #include "WMath.h" +// # include +// # include +// #endif // Include pins variant #include "pins_arduino.h" diff --git a/cores/arduino/HardwareTimer.cpp b/cores/arduino/HardwareTimer.cpp index 75af5ec..05cfbea 100644 --- a/cores/arduino/HardwareTimer.cpp +++ b/cores/arduino/HardwareTimer.cpp @@ -73,7 +73,7 @@ HardwareTimer::HardwareTimer(TIM_TypeDef *instance) NVIC_EnableIRQ(TIM2_IRQn); #endif -#if defined(TIM3_BASE) && defined(TIM3_IRQn) //v006 has no interruption +#if defined(TIM3_BASE) && !defined(CH32VM00X) //v006 has no interruption NVIC_EnableIRQ(TIM3_IRQn); #endif diff --git a/cores/arduino/Tone.cpp b/cores/arduino/Tone.cpp new file mode 100644 index 0000000..95a4d96 --- /dev/null +++ b/cores/arduino/Tone.cpp @@ -0,0 +1,149 @@ +/* Tone.cpp + + A Tone Generator Library + + Written by Brett Hagman + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +//Modified 3 june 2024 by TempersLee for CH32duino + +#include "Arduino.h" +#include "HardwareTimer.h" + +#if defined(TIM_MODULE_ENABLED) && defined(TIMER_TONE) && !defined(TIM_MODULE_ONLY) + +#define MAX_FREQ 65535 + +typedef struct { + PinName pin; + int32_t count; +} timerPinInfo_t; + +static void timerTonePinInit(PinName p, uint32_t frequency, uint32_t duration); +static void tonePeriodElapsedCallback(); +static timerPinInfo_t TimerTone_pinInfo = {NC, 0}; +static HardwareTimer *TimerTone = NULL; + +/** + * @brief Tone Period elapsed callback in non-blocking mode + * @param htim : timer handle + * @retval None + */ +static void tonePeriodElapsedCallback() +{ + GPIO_TypeDef *port = get_GPIO_Port(CH_PORT(TimerTone_pinInfo.pin)); + + if (port != NULL) { + if (TimerTone_pinInfo.count != 0) { + if (TimerTone_pinInfo.count > 0) { + TimerTone_pinInfo.count--; + } + digital_io_toggle(port, CH_MAP_GPIO_PIN(TimerTone_pinInfo.pin)); + } else { + digital_io_write(port, CH_MAP_GPIO_PIN(TimerTone_pinInfo.pin), 0); + } + } +} + +/** + * @brief This function will reset the tone timer + * @param port : pointer to port + * @param pin : pin number to toggle + * @retval None + */ +static void timerTonePinDeinit() +{ + if (TimerTone != NULL) { + TimerTone->timerHandleDeinit(); + } + if (TimerTone_pinInfo.pin != NC) { + pin_function(TimerTone_pinInfo.pin, CH_PIN_DATA(CH_MODE_INPUT, CH_CNF_INPUT_FLOAT, NOPULL, AFIO_NONE)); + TimerTone_pinInfo.pin = NC; + } +} + +static void timerTonePinInit(PinName p, uint32_t frequency, uint32_t duration) +{ + uint32_t timFreq = 2 * frequency; + + if (frequency <= MAX_FREQ) { + if (frequency == 0) { + if (TimerTone != NULL) { + TimerTone->pause(); + } + } else { + TimerTone_pinInfo.pin = p; + + //Calculate the toggle count + if (duration > 0) { + TimerTone_pinInfo.count = ((timFreq * duration) / 1000); + } else { + TimerTone_pinInfo.count = -1; + } + + pin_function(TimerTone_pinInfo.pin, CH_PIN_DATA(CH_MODE_OUTPUT_50MHz, CH_CNF_OUTPUT_PP, NOPULL, AFIO_NONE)); + + TimerTone->setOverflow(timFreq, HERTZ_FORMAT); + TimerTone->attachInterrupt(tonePeriodElapsedCallback); + TimerTone->resume(); + } + } +} + +// frequency (in hertz) and duration (in milliseconds). +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) +{ + PinName p = digitalPinToPinName(_pin); + + if (TimerTone == NULL) { + TimerTone = new HardwareTimer(TIMER_TONE); + } + + if (p != NC) { + if ((TimerTone_pinInfo.pin == NC) || (TimerTone_pinInfo.pin == p)) { + timerTonePinInit(p, frequency, duration); + } + } +} + +void noTone(uint8_t _pin, bool destruct) +{ + PinName p = digitalPinToPinName(_pin); + if ((p != NC) && (TimerTone_pinInfo.pin == p) && (TimerTone != NULL)) { + if (destruct) { + timerTonePinDeinit(); + delete (TimerTone); + TimerTone = NULL; + } else { + TimerTone->pause(); + } + } +} +#else +#warning "TIMER_TONE or TIM_MODULE_ENABLED not defined" +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) +{ + (void)(_pin); + (void)(frequency); + (void)(duration); +} + +void noTone(uint8_t _pin, bool destruct) +{ + (void)(_pin); + (void)(destruct); +} +#endif /* TIM_MODULE_ENABLED && TIMER_TONE && !TIM_MODULE_ONLY*/ diff --git a/cores/arduino/Tone.h b/cores/arduino/Tone.h new file mode 100644 index 0000000..98db001 --- /dev/null +++ b/cores/arduino/Tone.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_TONE_ +#define _WIRING_TONE_ + +#ifdef __cplusplus + /* + * \brief Generate a tone to a pin. + * + * \param _pin + * \param frequency Tone frequency (in hertz) + * \param duration Tone duration (in milliseconds) + */ + extern void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); + + /* + * \brief Stop tone generation on pin. + * + * \param _pin + */ + extern void noTone(uint8_t _pin, bool destruct = false); + +#endif + +#endif /* _WIRING_TONE_ */ diff --git a/cores/arduino/wiring.h b/cores/arduino/wiring.h index 2d9e798..37dd658 100644 --- a/cores/arduino/wiring.h +++ b/cores/arduino/wiring.h @@ -40,9 +40,9 @@ #include #ifdef __cplusplus - // #include "HardwareTimer.h" - // #include "Tone.h" - // #include "WCharacter.h" + #include "HardwareTimer.h" + #include "Tone.h" + #include "WCharacter.h" #include "WInterrupts.h" #include "WMath.h" #include "WSerial.h" diff --git a/variants/CH32V00x/CH32V003F4/variant_CH32V003F4.h b/variants/CH32V00x/CH32V003F4/variant_CH32V003F4.h index 453d6f9..9bf293a 100644 --- a/variants/CH32V00x/CH32V003F4/variant_CH32V003F4.h +++ b/variants/CH32V00x/CH32V003F4/variant_CH32V003F4.h @@ -103,6 +103,15 @@ #define PIN_WIRE_SCL PC2 #endif +// Timer Definitions +#ifndef TIMER_TONE + #define TIMER_TONE TIM2 +#endif +#ifndef TIMER_SERVO + #define TIMER_SERVO TIM1 +#endif + + /*---------------------------------------------------------------------------- * Arduino objects - C++ only *----------------------------------------------------------------------------*/ diff --git a/variants/CH32VM00X/CH32V006K8/variant_CH32V006K8.h b/variants/CH32VM00X/CH32V006K8/variant_CH32V006K8.h index 338fad7..53da306 100644 --- a/variants/CH32VM00X/CH32V006K8/variant_CH32V006K8.h +++ b/variants/CH32VM00X/CH32V006K8/variant_CH32V006K8.h @@ -116,6 +116,13 @@ #define PIN_WIRE_SCL PC2 #endif +#ifndef TIMER_TONE + #define TIMER_TONE TIM2 +#endif +#ifndef TIMER_SERVO + #define TIMER_SERVO TIM1 +#endif + /*---------------------------------------------------------------------------- * Arduino objects - C++ only *----------------------------------------------------------------------------*/