Added to MDx tone generator API functions allowing user code to temporarily disable generation of 'beep' tones

This commit is contained in:
Silvano Seva 2022-01-21 11:53:27 +01:00
parent f9c23452bc
commit 10b8b59e21
2 changed files with 56 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * * Copyright (C) 2020 - 2022 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN * * Niccolò Izzo IU2KIN *
* Frederik Saraci IU2NRO * * Frederik Saraci IU2NRO *
* Silvano Seva IU2KWO * * Silvano Seva IU2KWO *
@ -53,8 +53,8 @@ uint32_t beepTableIndex = 0; // Current sine table index for "beep" generator
uint32_t beepTableIncr = 0; // "beep" sine table index increment per tick uint32_t beepTableIncr = 0; // "beep" sine table index increment per tick
uint32_t beepTimerCount = 0; // Downcounter for timed "beep" uint32_t beepTimerCount = 0; // Downcounter for timed "beep"
uint8_t beepVolume = 0; // "beep" volume level uint8_t beepVolume = 0; // "beep" volume level
uint8_t beepLockCount = 0; // Counter for management of "beep" generation locking
bool tonesLocked = false; // If true tone channel is in use by FSK/playback
bool circularMode = false; // Circular mode enabled bool circularMode = false; // Circular mode enabled
using namespace miosix; using namespace miosix;
@ -72,7 +72,7 @@ void __attribute__((used)) TIM8_TRG_COM_TIM14_IRQHandler()
TIM3->CCR2 = sineTable[(toneTableIndex >> 16) & 0xFF]; TIM3->CCR2 = sineTable[(toneTableIndex >> 16) & 0xFF];
if(!tonesLocked) if(beepLockCount == 0)
{ {
TIM3->CCR3 = (sineTable[(beepTableIndex >> 16) & 0xFF] * beepVolume) >> 8; TIM3->CCR3 = (sineTable[(beepTableIndex >> 16) & 0xFF] * beepVolume) >> 8;
} }
@ -111,7 +111,7 @@ void __attribute__((used)) DMA_Handler()
RCC->APB1ENR &= ~RCC_APB1ENR_TIM7EN; // Turn off TIM7 RCC->APB1ENR &= ~RCC_APB1ENR_TIM7EN; // Turn off TIM7
__DSB(); __DSB();
tonesLocked = false; // Finally, unlock tones toneGen_unlockBeep(); // Finally, unlock tones
} }
if(dmaWaiting == 0) return; // Wake up eventual pending threads if(dmaWaiting == 0) return; // Wake up eventual pending threads
@ -219,7 +219,7 @@ void toneGen_beepOn(const float beepFreq, const uint8_t volume,
{ {
// Do not generate "beep" if the PWM channel is busy, critical section // Do not generate "beep" if the PWM channel is busy, critical section
FastInterruptDisableLock dLock; FastInterruptDisableLock dLock;
if(tonesLocked) return; if(beepLockCount > 0) return;
} }
float dividend = beepFreq * 65536.0f; float dividend = beepFreq * 65536.0f;
@ -244,14 +244,36 @@ void toneGen_beepOff()
* Locking interrupts to avoid race conditions. * Locking interrupts to avoid race conditions.
*/ */
FastInterruptDisableLock dLock; FastInterruptDisableLock dLock;
if(tonesLocked) return; if(beepLockCount > 0) return;
TIM3->CCER &= ~TIM_CCER_CC3E; TIM3->CCER &= ~TIM_CCER_CC3E;
} }
void toneGen_encodeAFSK1200(const uint8_t* buf, const size_t len) void toneGen_lockBeep()
{ {
(void) buf; // Critical section, disable interrupts only if they are active
(void) len; bool interrupts = areInterruptsEnabled();
if(interrupts) fastDisableInterrupts();
if(beepLockCount < 255) beepLockCount++;
beepTimerCount = 0;
if(interrupts) fastEnableInterrupts();
}
void toneGen_unlockBeep()
{
// Critical section, disable interrupts only if they are active
bool interrupts = areInterruptsEnabled();
if(interrupts) fastDisableInterrupts();
if(beepLockCount > 0) beepLockCount--;
if(interrupts) fastEnableInterrupts();
}
bool toneGen_beepLocked()
{
return (beepLockCount > 0) ? true : false;
} }
void toneGen_playAudioStream(const uint16_t* buf, const size_t len, void toneGen_playAudioStream(const uint16_t* buf, const size_t len,
@ -259,12 +281,7 @@ void toneGen_playAudioStream(const uint16_t* buf, const size_t len,
{ {
if((buf == NULL) || (len == 0) || (sampleRate == 0)) return; if((buf == NULL) || (len == 0) || (sampleRate == 0)) return;
{ toneGen_lockBeep();
// Critical section to avoid race conditions on "tonesLocked"
FastInterruptDisableLock dLock;
tonesLocked = true;
beepTimerCount = 0;
}
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM7EN; RCC->APB1ENR |= RCC_APB1ENR_TIM7EN;
@ -333,7 +350,7 @@ bool toneGen_waitForStreamEnd()
{ {
FastInterruptDisableLock dLock; FastInterruptDisableLock dLock;
Thread *curThread = Thread::IRQgetCurrentThread(); Thread *curThread = Thread::IRQgetCurrentThread();
if(tonesLocked == false) return false; if(toneGen_beepLocked() == false) return false;
if((dmaWaiting != 0) && (dmaWaiting != curThread)) return false; if((dmaWaiting != 0) && (dmaWaiting != curThread)) return false;
dmaWaiting = curThread; dmaWaiting = curThread;
do do
@ -371,7 +388,8 @@ void toneGen_stopAudioStream()
__DSB(); __DSB();
// Unlock tones and wake up the thread waiting for completion // Unlock tones and wake up the thread waiting for completion
tonesLocked = false; toneGen_unlockBeep();
if(dmaWaiting) if(dmaWaiting)
{ {
dmaWaiting->IRQwakeup(); dmaWaiting->IRQwakeup();

View File

@ -89,14 +89,25 @@ void toneGen_beepOn(const float beepFreq, const uint8_t volume,
void toneGen_beepOff(); void toneGen_beepOff();
/** /**
* Encode a given data stream using Bell 202 scheme at 1200 baud, sending the * Disable the generation of "beep" tones until the unlock function is called.
* audio stream to both the speaker and the rtx baseband IC. * This function supports recursive call: multiple subsequent calls require an
* This function blocks the execution flow until all data has been sent. * equal number of calls of the unlock function to effectively unlock beeps.
* * This function can be called safely from an interrupt routine.
* @param buf: pointer to a buffer containing data to be encoded.
* @param len: length of the data buffer.
*/ */
void toneGen_encodeAFSK1200(const uint8_t *buf, const size_t len); void toneGen_lockBeep();
/**
* Enable the generation of "beep" tones previously unlocked.
* This function can be called safely from an interrupt routine.
*/
void toneGen_unlockBeep();
/**
* Check if generation of "beep" tones is disabled.
*
* @return if generation of "beep" tones is disabled.
*/
bool toneGen_beepLocked();
/** /**
* Reproduce an audio stream, sending audio stream to both the speaker and the * Reproduce an audio stream, sending audio stream to both the speaker and the