Files
ArduinoCore-AT32F4/cores/arduino/Tone.cpp

129 lines
3.2 KiB
C++
Raw Normal View History

2022-07-10 21:37:33 +08:00
/*
* MIT License
* Copyright (c) 2017 - 2022 _VIFEXTech
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "Tone.h"
#include "Arduino.h"
#define TONE_FREQ_MAX 500000U
static tmr_type* Tone_Timer = NULL;
static bool Tone_IsContinuousModeEnable = false;
static uint8_t Tone_Pin = NOT_A_PIN;
static uint32_t Tone_ToggleCounter = 0;
/**
* @brief tone中断入口
* @param
* @retval
*/
static void Tone_TimerHandler()
{
if(!Tone_IsContinuousModeEnable)
{
if(Tone_ToggleCounter == 0)
{
noTone(Tone_Pin);
return;
}
Tone_ToggleCounter--;
}
togglePin(Tone_Pin);
}
/**
* @brief tone所使用的定时器
* @param TIMx:
* @retval
*/
void toneSetTimer(tmr_type* TIMx)
{
Timer_SetInterruptBase(
TIMx,
0xFF,
0xFF,
Tone_TimerHandler,
TONE_PREEMPTIONPRIORITY_DEFAULT,
TONE_SUBPRIORITY_DEFAULT
);
Tone_Timer = TIMx;
}
/**
* @brief Pin上生成指定频率 (50%)
* @param pin: Pin
* @param freq: (Hz)
* @param duration: ()
* @retval
*/
void tone(uint8_t pin, uint32_t freq, uint32_t duration)
{
noTone(pin);
if(duration == 0 || freq == 0 || freq > TONE_FREQ_MAX)
{
return;
}
Tone_Pin = pin;
Tone_IsContinuousModeEnable = (duration == TONE_DURATION_INFINITE) ? true : false;
if(!Tone_IsContinuousModeEnable)
{
Tone_ToggleCounter = freq * duration / 1000 * 2;
if(Tone_ToggleCounter == 0)
{
return;
}
Tone_ToggleCounter--;
}
if(Tone_Timer == NULL)
{
toneSetTimer(TONE_TIMER_DEFAULT);
}
Timer_SetInterruptTimeUpdate(Tone_Timer, TONE_FREQ_MAX / freq);
Timer_SetEnable(Tone_Timer, true);
}
/**
* @brief
* @param Pin:
* @retval
*/
void noTone(uint8_t pin)
{
if(Tone_Timer)
{
Timer_SetEnable(Tone_Timer, false);
}
digitalWrite(pin, LOW);
Tone_IsContinuousModeEnable = false;
Tone_Pin = NOT_A_PIN;
Tone_ToggleCounter = 0;
}