mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 03:15:37 +00:00
Voice driver
This commit is contained in:
1 parent
554315bab5
commit
bf31740faa
7 files changed
+296
-102
No files matched your search
+1
-1
@@ -106,7 +106,7 @@ enable_feature(ENABLE_AIRCOPY
|
||||
)
|
||||
enable_feature(ENABLE_NOAA)
|
||||
enable_feature(ENABLE_VOICE
|
||||
driver/dac.c
|
||||
driver/voice.c
|
||||
)
|
||||
enable_feature(ENABLE_VOX)
|
||||
enable_feature(ENABLE_ALARM)
|
||||
|
||||
+97
-44
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2023 Dual Tachyon
|
||||
/* Copyright 2025 muzkr https://github.com/muzkr
|
||||
* Copyright 2023 Dual Tachyon
|
||||
* https://github.com/DualTachyon
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -25,6 +26,8 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/system.h"
|
||||
#include "driver/systick.h"
|
||||
#include "driver/voice.h"
|
||||
#include "driver/py25q16.h"
|
||||
#include "functions.h"
|
||||
#include "misc.h"
|
||||
#include "settings.h"
|
||||
@@ -198,31 +201,10 @@ void AUDIO_PlayBeep(BEEP_Type_t Beep)
|
||||
|
||||
#ifdef ENABLE_VOICE
|
||||
|
||||
static const uint8_t VoiceClipLengthChinese[58] =
|
||||
{
|
||||
0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32,
|
||||
0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64,
|
||||
0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64,
|
||||
0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64,
|
||||
0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69,
|
||||
0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F,
|
||||
0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E,
|
||||
0x5A, 0x64,
|
||||
};
|
||||
|
||||
static const uint8_t VoiceClipLengthEnglish[76] =
|
||||
{
|
||||
0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37,
|
||||
0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82,
|
||||
0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E,
|
||||
0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B,
|
||||
0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E,
|
||||
0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69,
|
||||
0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64,
|
||||
0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50,
|
||||
0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37,
|
||||
0x41, 0x32, 0x3C, 0x37,
|
||||
};
|
||||
uint16_t gVoiceBuf[VOICE_BUF_CAP][VOICE_BUF_LEN];
|
||||
uint8_t gVoiceBufReadIndex = 0;
|
||||
uint8_t gVoiceBufWriteIndex = 0;
|
||||
uint8_t gVoiceBufLen = 0;
|
||||
|
||||
VOICE_ID_t gVoiceID[8];
|
||||
uint8_t gVoiceReadIndex;
|
||||
@@ -231,29 +213,100 @@ volatile uint16_t gCountdownToPlayNextVoice_10ms;
|
||||
volatile bool gFlagPlayQueuedVoice;
|
||||
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
|
||||
|
||||
|
||||
static void AUDIO_PlayVoice(uint8_t VoiceID)
|
||||
static const uint16_t VOICE_SAMPLES[256] =
|
||||
{
|
||||
unsigned int i;
|
||||
0x06a8, 0x06b8, 0x0688, 0x0698, 0x06e8, 0x06f8, 0x06c8, 0x06d8, //
|
||||
0x0628, 0x0638, 0x0608, 0x0618, 0x0668, 0x0678, 0x0648, 0x0658, //
|
||||
0x0754, 0x075c, 0x0744, 0x074c, 0x0774, 0x077c, 0x0764, 0x076c, //
|
||||
0x0714, 0x071c, 0x0704, 0x070c, 0x0734, 0x073c, 0x0724, 0x072c, //
|
||||
0x02a0, 0x02e0, 0x0220, 0x0260, 0x03a0, 0x03e0, 0x0320, 0x0360, //
|
||||
0x00a0, 0x00e0, 0x0020, 0x0060, 0x01a0, 0x01e0, 0x0120, 0x0160, //
|
||||
0x0550, 0x0570, 0x0510, 0x0530, 0x05d0, 0x05f0, 0x0590, 0x05b0, //
|
||||
0x0450, 0x0470, 0x0410, 0x0430, 0x04d0, 0x04f0, 0x0490, 0x04b0, //
|
||||
0x07ea, 0x07eb, 0x07e8, 0x07e9, 0x07ee, 0x07ef, 0x07ec, 0x07ed, //
|
||||
0x07e2, 0x07e3, 0x07e0, 0x07e1, 0x07e6, 0x07e7, 0x07e4, 0x07e5, //
|
||||
0x07fa, 0x07fb, 0x07f8, 0x07f9, 0x07fe, 0x07ff, 0x07fc, 0x07fd, //
|
||||
0x07f2, 0x07f3, 0x07f0, 0x07f1, 0x07f6, 0x07f7, 0x07f4, 0x07f5, //
|
||||
0x07aa, 0x07ae, 0x07a2, 0x07a6, 0x07ba, 0x07be, 0x07b2, 0x07b6, //
|
||||
0x078a, 0x078e, 0x0782, 0x0786, 0x079a, 0x079e, 0x0792, 0x0796, //
|
||||
0x07d5, 0x07d7, 0x07d1, 0x07d3, 0x07dd, 0x07df, 0x07d9, 0x07db, //
|
||||
0x07c5, 0x07c7, 0x07c1, 0x07c3, 0x07cd, 0x07cf, 0x07c9, 0x07cb, //
|
||||
0x0958, 0x0948, 0x0978, 0x0968, 0x0918, 0x0908, 0x0938, 0x0928, //
|
||||
0x09d8, 0x09c8, 0x09f8, 0x09e8, 0x0998, 0x0988, 0x09b8, 0x09a8, //
|
||||
0x08ac, 0x08a4, 0x08bc, 0x08b4, 0x088c, 0x0884, 0x089c, 0x0894, //
|
||||
0x08ec, 0x08e4, 0x08fc, 0x08f4, 0x08cc, 0x08c4, 0x08dc, 0x08d4, //
|
||||
0x0d60, 0x0d20, 0x0de0, 0x0da0, 0x0c60, 0x0c20, 0x0ce0, 0x0ca0, //
|
||||
0x0f60, 0x0f20, 0x0fe0, 0x0fa0, 0x0e60, 0x0e20, 0x0ee0, 0x0ea0, //
|
||||
0x0ab0, 0x0a90, 0x0af0, 0x0ad0, 0x0a30, 0x0a10, 0x0a70, 0x0a50, //
|
||||
0x0bb0, 0x0b90, 0x0bf0, 0x0bd0, 0x0b30, 0x0b10, 0x0b70, 0x0b50, //
|
||||
0x0815, 0x0814, 0x0817, 0x0816, 0x0811, 0x0810, 0x0813, 0x0812, //
|
||||
0x081d, 0x081c, 0x081f, 0x081e, 0x0819, 0x0818, 0x081b, 0x081a, //
|
||||
0x0805, 0x0804, 0x0807, 0x0806, 0x0801, 0x0800, 0x0803, 0x0802, //
|
||||
0x080d, 0x080c, 0x080f, 0x080e, 0x0809, 0x0808, 0x080b, 0x080a, //
|
||||
0x0856, 0x0852, 0x085e, 0x085a, 0x0846, 0x0842, 0x084e, 0x084a, //
|
||||
0x0876, 0x0872, 0x087e, 0x087a, 0x0866, 0x0862, 0x086e, 0x086a, //
|
||||
0x082b, 0x0829, 0x082f, 0x082d, 0x0823, 0x0821, 0x0827, 0x0825, //
|
||||
0x083b, 0x0839, 0x083f, 0x083d, 0x0833, 0x0831, 0x0837, 0x0835 //
|
||||
};
|
||||
|
||||
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||
SYSTEM_DelayMs(20);
|
||||
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||
static struct
|
||||
{
|
||||
uint32_t Addr;
|
||||
uint32_t Size;
|
||||
} VoiceClipState = {0};
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
static bool LoadVoiceClip(uint8_t VoiceID)
|
||||
{
|
||||
if (VoiceID >= VOICE_ID_END)
|
||||
{
|
||||
if ((VoiceID & 0x80U) == 0)
|
||||
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
|
||||
else
|
||||
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
|
||||
|
||||
SYSTICK_DelayUs(1000);
|
||||
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||
SYSTICK_DelayUs(1200);
|
||||
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
|
||||
VoiceID <<= 1;
|
||||
SYSTICK_DelayUs(200);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t Addr = gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE ? 0x14c000 : 0x14c800;
|
||||
struct
|
||||
{
|
||||
uint32_t Offset;
|
||||
uint32_t Size;
|
||||
} Info;
|
||||
PY25Q16_ReadBuffer(Addr + 8 * VoiceID, &Info, 8);
|
||||
|
||||
if (Info.Offset > 0x0b0000 || Info.Size > 0x019000)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
VoiceClipState.Addr = 0x14d000 + Info.Offset;
|
||||
VoiceClipState.Size = Info.Size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline uint32_t CalcDelay(uint32_t Size)
|
||||
{
|
||||
return 2 * Size; // in ms!!
|
||||
}
|
||||
|
||||
static void LoadVoiceSamples() {
|
||||
if (0 == VoiceClipState.Addr || 0 == VoiceClipState.Size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (gVoiceBufLen >= VOICE_BUF_CAP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
extern uint8_t **gFrameBuffer;
|
||||
uint8_t *Buf = (uint8_t *)gFrameBuffer;
|
||||
PY25Q16_ReadBuffer(VoiceClipState.Addr, Buf, VOICE_BUF_LEN);
|
||||
VoiceClipState.Addr += VOICE_BUF_LEN;
|
||||
VoiceClipState.Size -= VOICE_BUF_LEN;
|
||||
|
||||
for (uint32_t i = 0; i < VOICE_BUF_LEN; i++)
|
||||
{
|
||||
gVoiceBuf[gVoiceBufWriteIndex][i] = VOICE_SAMPLES[Buf[i]];
|
||||
}
|
||||
VOCIE_BUF_ForwardWriteIndex();
|
||||
gVoiceBufLen++;
|
||||
}
|
||||
|
||||
void AUDIO_PlaySingleVoice(bool bFlag)
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@
|
||||
#include "py32f071_ll_gpio.h"
|
||||
#include "py32f071_ll_rcc.h"
|
||||
#include "py32f071_ll_adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "driver/voice.h"
|
||||
#include "driver/backlight.h"
|
||||
#ifdef ENABLE_FMRADIO
|
||||
#include "driver/bk1080.h"
|
||||
@@ -180,7 +180,7 @@ void BOARD_Init(void)
|
||||
BACKLIGHT_InitHardware();
|
||||
BOARD_ADC_Init();
|
||||
#ifdef ENABLE_VOICE
|
||||
DAC_Init();
|
||||
VOICE_Init();
|
||||
#endif
|
||||
PY25Q16_Init();
|
||||
ST7565_Init();
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/* Copyright 2025 muzkr https://github.com/muzkr
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "driver/dac.h"
|
||||
#include "driver/systick.h"
|
||||
#include "py32f071_ll_bus.h"
|
||||
#include "py32f071_ll_gpio.h"
|
||||
#include "py32f071_ll_dac.h"
|
||||
#include "py32f071_ll_tim.h"
|
||||
|
||||
#define TIMx TIM6
|
||||
#define DAC_CHANNEL LL_DAC_CHANNEL_1
|
||||
|
||||
static inline void TIM_Init()
|
||||
{
|
||||
LL_TIM_SetPrescaler(TIMx, 3);
|
||||
LL_TIM_SetAutoReload(TIMx, 1499);
|
||||
LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_UPDATE);
|
||||
}
|
||||
|
||||
void DAC_Init()
|
||||
{
|
||||
// Channel 1: PA4
|
||||
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
|
||||
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_4, LL_GPIO_MODE_ANALOG);
|
||||
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DAC1);
|
||||
LL_DAC_SetTriggerSource(DAC1, DAC_CHANNEL, LL_DAC_TRIG_EXT_TIM6_TRGO);
|
||||
LL_DAC_SetOutputBuffer(DAC1, DAC_CHANNEL, LL_DAC_OUTPUT_BUFFER_ENABLE);
|
||||
LL_DAC_EnableDMAReq(DAC1, DAC_CHANNEL);
|
||||
LL_DAC_Enable(DAC1, DAC_CHANNEL);
|
||||
|
||||
SYSTICK_DelayUs(15);
|
||||
|
||||
TIM_Init();
|
||||
|
||||
LL_DAC_EnableTrigger(DAC1, DAC_CHANNEL);
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/* Copyright 2025 muzkr https://github.com/muzkr
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "driver/voice.h"
|
||||
#include "driver/systick.h"
|
||||
#include "py32f071_ll_bus.h"
|
||||
#include "py32f071_ll_gpio.h"
|
||||
#include "py32f071_ll_dac.h"
|
||||
#include "py32f071_ll_tim.h"
|
||||
#include "py32f071_ll_dma.h"
|
||||
#include "py32f071_ll_system.h"
|
||||
#include <string.h>
|
||||
|
||||
#define TIMx TIM6
|
||||
#define DAC_CHANNEL LL_DAC_CHANNEL_1
|
||||
#define DMA_CHANNEL LL_DMA_CHANNEL_3
|
||||
|
||||
#define VOICE_BUF_SIZE (sizeof(uint16_t) * VOICE_BUF_LEN)
|
||||
|
||||
static uint16_t DAC_Buf[VOICE_BUF_LEN * 2];
|
||||
|
||||
static inline void DMA_Init()
|
||||
{
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
|
||||
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG);
|
||||
|
||||
LL_SYSCFG_SetDMARemap(DMA1, DMA_CHANNEL, LL_SYSCFG_DMA_MAP_DAC1);
|
||||
|
||||
LL_DMA_InitTypeDef InitStruct;
|
||||
// LL_DMA_StructInit( &InitStruct) ;
|
||||
InitStruct.PeriphOrM2MSrcAddress = (uint32_t)DAC_Buf;
|
||||
InitStruct.MemoryOrM2MDstAddress = LL_DAC_DMA_GetRegAddr(DAC1, DAC_CHANNEL, LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED);
|
||||
InitStruct.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
||||
InitStruct.Mode = LL_DMA_MODE_CIRCULAR;
|
||||
InitStruct.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
|
||||
InitStruct.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
|
||||
InitStruct.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD;
|
||||
InitStruct.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD;
|
||||
InitStruct.NbData = sizeof(DAC_Buf) / sizeof(uint16_t);
|
||||
InitStruct.Priority = LL_DMA_PRIORITY_HIGH;
|
||||
LL_DMA_Init(DMA1, DMA_CHANNEL, &InitStruct);
|
||||
|
||||
LL_DMA_EnableIT_HT(DMA1, DMA_CHANNEL);
|
||||
LL_DMA_EnableIT_TC(DMA1, DMA_CHANNEL);
|
||||
LL_DMA_EnableChannel(DMA1, DMA_CHANNEL);
|
||||
|
||||
NVIC_SetPriority(DMA1_Channel2_3_IRQn, 3);
|
||||
NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
|
||||
}
|
||||
|
||||
static inline void TIM_Init()
|
||||
{
|
||||
// Update freq = 48 MHz / 4 / 1500 == 8 KHz
|
||||
LL_TIM_SetPrescaler(TIMx, 3);
|
||||
LL_TIM_SetAutoReload(TIMx, 1499);
|
||||
LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_UPDATE);
|
||||
}
|
||||
|
||||
void VOICE_Init()
|
||||
{
|
||||
DMA_Init();
|
||||
|
||||
// Channel 1: PA4
|
||||
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
|
||||
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_4, LL_GPIO_MODE_ANALOG);
|
||||
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DAC1);
|
||||
LL_DAC_SetTriggerSource(DAC1, DAC_CHANNEL, LL_DAC_TRIG_EXT_TIM6_TRGO);
|
||||
LL_DAC_SetOutputBuffer(DAC1, DAC_CHANNEL, LL_DAC_OUTPUT_BUFFER_ENABLE);
|
||||
LL_DAC_EnableDMAReq(DAC1, DAC_CHANNEL);
|
||||
LL_DAC_Enable(DAC1, DAC_CHANNEL);
|
||||
|
||||
SYSTICK_DelayUs(15);
|
||||
|
||||
TIM_Init();
|
||||
|
||||
LL_DAC_EnableTrigger(DAC1, DAC_CHANNEL);
|
||||
}
|
||||
|
||||
void VOICE_Start()
|
||||
{
|
||||
LL_DAC_Enable(DAC1, DAC_CHANNEL);
|
||||
LL_TIM_DisableCounter(TIMx);
|
||||
|
||||
if (gVoiceBufLen > 0)
|
||||
{
|
||||
memcpy(DAC_Buf, gVoiceBuf[gVoiceBufReadIndex], VOICE_BUF_SIZE);
|
||||
VOCIE_BUF_ForwardReadIndex();
|
||||
gVoiceBufLen--;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(DAC_Buf, 0, VOICE_BUF_SIZE);
|
||||
}
|
||||
if (gVoiceBufLen > 0)
|
||||
{
|
||||
memcpy(DAC_Buf + VOICE_BUF_SIZE, //
|
||||
gVoiceBuf[gVoiceBufReadIndex], //
|
||||
VOICE_BUF_SIZE //
|
||||
);
|
||||
VOCIE_BUF_ForwardReadIndex();
|
||||
gVoiceBufLen--;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(DAC_Buf + VOICE_BUF_SIZE, 0, VOICE_BUF_SIZE);
|
||||
}
|
||||
|
||||
LL_DMA_ConfigAddresses(DMA1, DMA_CHANNEL, DAC_Buf, //
|
||||
LL_DAC_DMA_GetRegAddr(DAC1, DAC_CHANNEL, LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED), //
|
||||
LL_DMA_DIRECTION_MEMORY_TO_PERIPH //
|
||||
);
|
||||
LL_DMA_EnableChannel(DMA1, DMA_CHANNEL);
|
||||
LL_TIM_EnableCounter(TIMx);
|
||||
}
|
||||
|
||||
void VOICE_Stop()
|
||||
{
|
||||
LL_TIM_DisableCounter(TIMx);
|
||||
LL_DMA_DisableChannel(DMA1, DMA_CHANNEL);
|
||||
LL_DAC_Disable(DAC1, DAC_CHANNEL);
|
||||
}
|
||||
|
||||
void DMA1_Channel2_3_IRQHandler()
|
||||
{
|
||||
if (LL_DMA_IsActiveFlag_HT3(DMA1))
|
||||
{
|
||||
LL_DMA_ClearFlag_HT3(DMA1);
|
||||
if (gVoiceBufLen > 0)
|
||||
{
|
||||
memcpy(DAC_Buf, gVoiceBuf[gVoiceBufReadIndex], VOICE_BUF_SIZE);
|
||||
VOCIE_BUF_ForwardReadIndex();
|
||||
gVoiceBufLen--;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(DAC_Buf, 0, VOICE_BUF_SIZE);
|
||||
}
|
||||
}
|
||||
if (LL_DMA_IsActiveFlag_TC3(DMA1))
|
||||
{
|
||||
LL_DMA_ClearFlag_TC3(DMA1);
|
||||
if (gVoiceBufLen > 0)
|
||||
{
|
||||
memcpy(DAC_Buf + VOICE_BUF_SIZE, //
|
||||
gVoiceBuf[gVoiceBufReadIndex], //
|
||||
VOICE_BUF_SIZE //
|
||||
);
|
||||
VOCIE_BUF_ForwardReadIndex();
|
||||
gVoiceBufLen--;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(DAC_Buf + VOICE_BUF_SIZE, 0, VOICE_BUF_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_DAC_H
|
||||
#define DRIVER_DAC_H
|
||||
#ifndef DRIVER_VOICE_H
|
||||
#define DRIVER_VOICE_H
|
||||
|
||||
void DAC_Init();
|
||||
#include <stdint.h>
|
||||
|
||||
#endif // DRIVER_DAC_H
|
||||
#define VOICE_BUF_CAP 4
|
||||
#define VOICE_BUF_LEN 160
|
||||
|
||||
extern uint16_t gVoiceBuf[VOICE_BUF_CAP][VOICE_BUF_LEN];
|
||||
extern uint8_t gVoiceBufReadIndex;
|
||||
extern uint8_t gVoiceBufWriteIndex;
|
||||
extern uint8_t gVoiceBufLen;
|
||||
|
||||
static inline void VOCIE_BUF_ForwardReadIndex()
|
||||
{
|
||||
gVoiceBufReadIndex = (1 + gVoiceBufReadIndex) % VOICE_BUF_CAP;
|
||||
}
|
||||
|
||||
static inline void VOCIE_BUF_ForwardWriteIndex()
|
||||
{
|
||||
gVoiceBufWriteIndex = (1 + gVoiceBufWriteIndex) % VOICE_BUF_CAP;
|
||||
}
|
||||
|
||||
void VOICE_Init();
|
||||
void VOICE_Start();
|
||||
void VOICE_Stop();
|
||||
|
||||
#endif // DRIVER_VOICE_H
|
||||
+1
-1
@@ -76,7 +76,7 @@
|
||||
"name": "Custom",
|
||||
"inherits": "Broadcast",
|
||||
"cacheVariables": {
|
||||
"ENABLE_VOICE": false,
|
||||
"ENABLE_VOICE": true,
|
||||
"ENABLE_SWD": true,
|
||||
"ENABLE_AIRCOPY": false,
|
||||
"EDITION_STRING": "Custom",
|
||||
|
||||
Reference in new issue
Block a user