Skip to content
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

Buzzer - No polling #2846

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 34 additions & 34 deletions TFT/src/User/API/BuzzerControl.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,93 +51,93 @@ void Buzzer_play(SOUND sound)
case SOUND_OK:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_ALERT))
{
Buzzer_TurnOn(A_BASE, 50);
Buzzer_TurnOn(SILENCE, 40);
Buzzer_TurnOn(E_OCTAVE1, 50);
Buzzer_AddSound(A_BASE, 50);
Buzzer_AddSound(SILENCE, 40);
Buzzer_AddSound(E_OCTAVE1, 50);
}
break;

case SOUND_SUCCESS:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_ALERT))
{
Buzzer_TurnOn(A_BASE, 50);
Buzzer_TurnOn(SILENCE, 50);
Buzzer_TurnOn(A_BASE, 50);
Buzzer_TurnOn(SILENCE, 50);
Buzzer_TurnOn(A_BASE, 50);
Buzzer_AddSound(A_BASE, 50);
Buzzer_AddSound(SILENCE, 50);
Buzzer_AddSound(A_BASE, 50);
Buzzer_AddSound(SILENCE, 50);
Buzzer_AddSound(A_BASE, 50);
}
break;

case SOUND_CANCEL:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_ALERT))
{
Buzzer_TurnOn(E_OCTAVE1, 50);
Buzzer_TurnOn(SILENCE, 20);
Buzzer_TurnOn(A_BASE, 40);
Buzzer_AddSound(E_OCTAVE1, 50);
Buzzer_AddSound(SILENCE, 20);
Buzzer_AddSound(A_BASE, 40);
}
break;

case SOUND_NOTIFY:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_ALERT))
{
Buzzer_TurnOn(G_BASE, 50);
Buzzer_TurnOn(SILENCE, 50);
Buzzer_TurnOn(C_OCTAVE1, 50);
Buzzer_AddSound(G_BASE, 50);
Buzzer_AddSound(SILENCE, 50);
Buzzer_AddSound(C_OCTAVE1, 50);
}
break;

case SOUND_ERROR:
{
Buzzer_TurnOn(C_SHARP_BASE, 200);
Buzzer_TurnOn(SILENCE, 60);
Buzzer_TurnOn(C_SHARP_BASE, 200);
Buzzer_TurnOn(SILENCE, 60);
Buzzer_TurnOn(C_SHARP_BASE, 200);
Buzzer_AddSound(C_SHARP_BASE, 200);
Buzzer_AddSound(SILENCE, 60);
Buzzer_AddSound(C_SHARP_BASE, 200);
Buzzer_AddSound(SILENCE, 60);
Buzzer_AddSound(C_SHARP_BASE, 200);
}
break;

case SOUND_DENY:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_ALERT))
{
Buzzer_TurnOn(B_SUBOCTAVE3, 10);
Buzzer_TurnOn(E_OCTAVE2, 20);
Buzzer_AddSound(B_SUBOCTAVE3, 10);
Buzzer_AddSound(E_OCTAVE2, 20);
}
break;

case SOUND_TOAST:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_TOAST))
{
Buzzer_TurnOn(F_SHARP_SUBOCTAVE1, 30);
Buzzer_TurnOn(B_SUBOCTAVE1, 30);
Buzzer_AddSound(F_SHARP_SUBOCTAVE1, 30);
Buzzer_AddSound(B_SUBOCTAVE1, 30);
}
break;

case SOUND_HEATED:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_HEATER))
{
Buzzer_TurnOn(G_BASE, 50);
Buzzer_TurnOn(SILENCE, 50);
Buzzer_TurnOn(B_BASE, 50);
Buzzer_TurnOn(SILENCE, 100);
Buzzer_TurnOn(B_BASE, 50);
Buzzer_AddSound(G_BASE, 50);
Buzzer_AddSound(SILENCE, 50);
Buzzer_AddSound(B_BASE, 50);
Buzzer_AddSound(SILENCE, 100);
Buzzer_AddSound(B_BASE, 50);
}
break;

case SOUND_COOLED:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_HEATER))
{
Buzzer_TurnOn(B_BASE, 50);
Buzzer_TurnOn(SILENCE, 50);
Buzzer_TurnOn(G_BASE, 50);
Buzzer_TurnOn(SILENCE, 100);
Buzzer_TurnOn(G_BASE, 50);
Buzzer_AddSound(B_BASE, 50);
Buzzer_AddSound(SILENCE, 50);
Buzzer_AddSound(G_BASE, 50);
Buzzer_AddSound(SILENCE, 100);
Buzzer_AddSound(G_BASE, 50);
}
break;

case SOUND_KEYPRESS:
default:
if (GET_BIT(infoSettings.sounds, SOUND_TYPE_TOUCH))
Buzzer_TurnOn(BUZZER_FREQUENCY_HZ, BUZZER_FREQUENCY_DURATION_MS);
Buzzer_AddSound(BUZZER_FREQUENCY_HZ, BUZZER_FREQUENCY_DURATION_MS);
break;
}
} // Buzzer_play
Expand Down
2 changes: 1 addition & 1 deletion TFT/src/User/API/interfaceCmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ void sendQueueCmd(void)
{
uint16_t ms = cmd_value();

Buzzer_TurnOn(hz, ms);
Buzzer_AddSound(hz, ms);

if (!fromTFT && cmd_seen_from(cmd_base_index, "TFT")) // "M300 TFT"
{
Expand Down
5 changes: 0 additions & 5 deletions TFT/src/User/API/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,11 +1236,6 @@ void loopBackEnd(void)
// Speed & flow monitor
loopSpeed();

// Buzzer handling
#ifdef BUZZER_PIN
loopBuzzer();
#endif

// Handle a print from (remote) onboard media, if any
if (infoMachineSettings.onboardSD == ENABLED)
loopPrintFromOnboard();
Expand Down
157 changes: 100 additions & 57 deletions TFT/src/User/Hal/buzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ typedef struct
uint16_t count;
} BUZZER;

static BUZZER buzzer;
volatile uint32_t buzzerEndTime = 0;
volatile static BUZZER buzzer;
volatile uint32_t toggles = 0;

void TIM3_Config(void)
static inline void BuzzerTimerConfig(void)
{
#ifdef GD32F2XX
nvic_irq_enable(TIMER2_IRQn, 1U, 0U);
Expand All @@ -28,7 +27,10 @@ void TIM3_Config(void)
TIMER_CTL0(TIMER2) &= ~TIMER_CTL0_CEN;
TIMER_DMAINTEN(TIMER2) |= TIMER_DMAINTEN_UPIE;
TIMER_INTF(TIMER2) &= ~TIMER_INTF_UPIF;
TIMER_CAR(TIMER2) = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1;

// initial values
TIMER_CAR(TIMER2) = 10 - 1;
TIMER_PSC(TIMER2) = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1;
#else
NVIC_InitTypeDef NVIC_InitStructure;

Expand All @@ -42,7 +44,10 @@ void TIM3_Config(void)
TIM3->CR1 &= ~TIM_CR1_CEN;
TIM3->DIER |= TIM_DIER_UIE;
TIM3->SR &= ~TIM_SR_UIF;
TIM3->ARR = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1; // 20hz to 1Mhz

// initial values
TIM3->ARR = 10 - 1;
TIM3->PSC = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1;
#endif
}

Expand All @@ -58,7 +63,40 @@ void TIMER2_IRQHandler(void)
}
else
{
TIMER_CTL0(TIMER2) &= ~TIMER_CTL0_CEN; // stop timer
TIMER_CTL0(TIMER2) &= ~TIMER_CTL0_CEN; // disable timer
TIMER_CNT(TIMER2) = 0;

if (buzzer.count == 0) // end sound generation
{
GPIO_SetLevel(BUZZER_PIN, BUZZER_STOP_LEVEL);

// initial values
TIMER_CAR(TIMER2) = 10 - 1;
TIMER_PSC(TIMER2) = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1;
}
else // step to the sound to play
{
toggles = 2 * ((buzzer.frequency[buzzer.rIndex]) * buzzer.duration[buzzer.rIndex] / 1000); // must have an even value

if (buzzer.frequency[buzzer.rIndex] == 0) // handle pause (silence)
{ // handle pause (silence)
TIMER_CAR(TIMER2) = (10 * buzzer.duration[buzzer.rIndex]) - 1; // keep values in range (TIMER2 CAR is only 16 bit)
TIMER_PSC(TIMER2) = mcuClocks.PCLK1_Timer_Frequency / 10000 - 1; // keep values in range (TIMER2 PSC is only 16 bit)
}
else
{ // handle sound
TIMER_CAR(TIMER2) = (1000000 / (2 * buzzer.frequency[buzzer.rIndex])) - 1; // keep values in range (TIMER2 CAR is only 16 bit)
TIMER_PSC(TIMER2) = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1; // keep values in range (TIMER2 PSC is only 16 bit)
}

TIMER_SWEVG(TIMER2) |= TIMER_SWEVG_UPG; // initialize PSC and CAR
TIMER_CTL0(TIMER2) |= TIMER_CTL0_CEN; // re-enable timer

if (++buzzer.rIndex == BUZZER_CACHE_SIZE)
buzzer.rIndex = 0;

buzzer.count--;
}
}
TIMER_INTF(TIMER2) &= ~TIMER_INTF_UPIF; // clear interrupt flag
}
Expand All @@ -76,6 +114,39 @@ void TIM3_IRQHandler(void)
else
{
TIM3->CR1 &= ~TIM_CR1_CEN; // stop timer
TIM3->CNT = 0;

if (buzzer.count == 0) // end sound generation
{
GPIO_SetLevel(BUZZER_PIN, BUZZER_STOP_LEVEL);

// initial values
TIM3->ARR = 10 - 1;
TIM3->PSC = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1;
}
else // step to the next sound
{
toggles = 2 * ((buzzer.frequency[buzzer.rIndex]) * buzzer.duration[buzzer.rIndex] / 1000); // must have an even value

if (buzzer.frequency[buzzer.rIndex] == 0) // handle pause (silence)
{ // handle pause (silence)
TIM3->ARR = (10 * buzzer.duration[buzzer.rIndex]) - 1; // keep values in range (TIMER3 ARR is only 16 bit)
TIM3->PSC = mcuClocks.PCLK1_Timer_Frequency / 10000 - 1; // keep values in range (TIMER3 PSC is only 16 bit)
}
else
{ // handle sound
TIM3->ARR = (1000000 / (2 * buzzer.frequency[buzzer.rIndex])) - 1; // keep values in range (TIMER3 ARR is only 16 bit)
TIM3->PSC = mcuClocks.PCLK1_Timer_Frequency / 1000000 - 1; // keep values in range (TIMER3 PSC is only 16 bit)
}

TIM3->EGR |= TIM_EGR_UG; // initialize PSC and ARR
TIM3->CR1 |= TIM_CR1_CEN; // re-enable timer

if (++buzzer.rIndex == BUZZER_CACHE_SIZE)
buzzer.rIndex = 0;

buzzer.count--;
}
}
TIM3->SR &= ~TIM_SR_UIF; // clear interrupt flag
}
Expand All @@ -85,75 +156,47 @@ void TIM3_IRQHandler(void)
void Buzzer_Config(void)
{
GPIO_InitSet(BUZZER_PIN, MGPIO_MODE_OUT_PP, 0);
TIM3_Config();
BuzzerTimerConfig();
}

void Buzzer_DeConfig(void)
{
GPIO_InitSet(BUZZER_PIN, MGPIO_MODE_IPN, 0);
}

void Buzzer_TurnOn(const uint16_t frequency, const uint16_t duration)
void Buzzer_AddSound(const uint16_t frequency, const uint16_t duration)
{
while (buzzer.count == BUZZER_CACHE_SIZE)
{
loopBuzzer();
}
// If the sound cache is full than the oldest sound data
// will be overwritten with the newest one that arrives.

buzzer.duration[buzzer.wIndex] = duration;
buzzer.frequency[buzzer.wIndex] = frequency;
buzzer.wIndex = (buzzer.wIndex + 1) % BUZZER_CACHE_SIZE;
buzzer.count++;
}

void tone(const uint16_t frequency, const uint16_t duration)
{
if (frequency == 0 || duration == 0) return;
#ifdef GD32F2XX
nvic_irq_disable(TIMER2_IRQn);
toggles = 2 * (frequency * duration / 1000); // must have an even value

TIMER_CTL0(TIMER2) &= ~TIMER_CTL0_CEN; // disable timer2
TIMER_CNT(TIMER2) = 0;
TIMER_PSC(TIMER2) = (1000000 / (2 * frequency)) - 1;
TIMER_CTL0(TIMER2) |= TIMER_CTL0_CEN;

nvic_irq_enable(TIMER2_IRQn, 1, 0);
#else
NVIC_DisableIRQ(TIM3_IRQn);
toggles = 2 * (frequency * duration / 1000); // must have an even value

TIM3->CR1 &= ~TIM_CR1_CEN;
TIM3->CNT =0;
TIM3->PSC = (1000000 / (2 * frequency)) - 1;
TIM3->CR1 |= TIM_CR1_CEN;

NVIC_EnableIRQ(TIM3_IRQn);
#endif
}
if (++buzzer.wIndex == BUZZER_CACHE_SIZE)
buzzer.wIndex = 0;

void loopBuzzer(void)
{
if (!buzzerEndTime)
if (buzzer.count == BUZZER_CACHE_SIZE)
{
if (buzzer.count == 0) return;
buzzerEndTime = OS_GetTimeMs() + buzzer.duration[buzzer.rIndex];
if (buzzer.frequency[buzzer.rIndex] > 0)
{
tone(buzzer.frequency[buzzer.rIndex], buzzer.duration[buzzer.rIndex]);
}
buzzer.rIndex = (buzzer.rIndex + 1) % BUZZER_CACHE_SIZE;
buzzer.count--;
// disable timer to avoid an eventual race condition
#ifdef GD32F2XX
TIMER_CTL0(TIMER2) &= ~TIMER_CTL0_CEN;
#else
TIM3->CR1 &= ~TIM_CR1_CEN;
#endif

buzzer.rIndex = buzzer.wIndex;
}
else if (OS_GetTimeMs() > buzzerEndTime && toggles == 0)
else
{
buzzerEndTime = 0;
buzzer.count++;
}

// (re)enable timer
#ifdef GD32F2XX
TIMER_CTL0(TIMER2) &= ~TIMER_CTL0_CEN;
TIMER_CTL0(TIMER2) |= TIMER_CTL0_CEN;
#else
TIM3->CR1 &= ~TIM_CR1_CEN; // stop timer (for safety)
TIM3->CR1 |= TIM_CR1_CEN;
#endif
GPIO_SetLevel(BUZZER_PIN, BUZZER_STOP_LEVEL);
}
}

#endif // BUZZER_PIN
9 changes: 5 additions & 4 deletions TFT/src/User/Hal/buzzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ extern "C" {
#include "variants.h" // for BUZZER_PIN etc...

#ifdef BUZZER_PIN
void Buzzer_Config(void);
void Buzzer_DeConfig(void);
void Buzzer_TurnOn(const uint16_t frequency, const uint16_t duration);
void loopBuzzer(void);

void Buzzer_Config(void);
void Buzzer_DeConfig(void);
void Buzzer_AddSound(const uint16_t frequency, const uint16_t duration);

#endif

#ifdef __cplusplus
Expand Down
Loading