Skip to content

Commit

Permalink
Buzzer - No polling
Browse files Browse the repository at this point in the history
  • Loading branch information
kisslorand committed Sep 27, 2023
1 parent 7d638de commit 1729564
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 101 deletions.
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 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)
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

0 comments on commit 1729564

Please sign in to comment.