📄 voice.c
字号:
#include "config.h"
#include "regmap.h"
#include "memmap.h"
#include "global.h"
#include "sio.h"
#include "gpio.h"
#include "func.h"
#include "util.h"
#include "osdfont.h"
#ifdef SUPPORT_VOICE
static BYTE VoiceQueneTotal;
static UINT16 VoiceQuenePoint;
#endif
#ifdef SUPPORT_UART_VOICE
#ifdef SUPPORT_BOARD_TYPE_OLD
#define VOICE_WAKE 15
#define VOICE_VOLUME_UP 21
#define VOICE_VOLUME_DOWN 22
#define VOICE_WAKE_LOW (GPIO_O_SET(VOICE_WAKE, 0))
#define VOICE_WAKE_HIGH (GPIO_O_SET(VOICE_WAKE, 0))
#else
#define VOICE_RESET 47
#define VOICE_VOLUME_UP 46 // 21
#define VOICE_VOLUME_DOWN 45 // 22
#endif
#define VOICE_RESET_LOW (GPIO_O_SET(VOICE_RESET, 0))
#define VOICE_RESET_HIGH (GPIO_O_SET(VOICE_RESET, 1))
#define VOICE_VOLUME_UP_LOW (GPIO_O_SET(VOICE_VOLUME_UP, 0))
#define VOICE_VOLUME_UP_HIGH (GPIO_O_SET(VOICE_VOLUME_UP, 1))
#define VOICE_VOLUME_DOWN_LOW (GPIO_O_SET(VOICE_VOLUME_DOWN, 0))
#define VOICE_VOLUME_DOWN_HIGH (GPIO_O_SET(VOICE_VOLUME_DOWN, 1))
static BYTE VoiceVolumeTimer;
void VoiceInitGPIO()
{
#ifdef SUPPORT_BOARD_TYPE_OLD
// Output mode
GPIO_G_SET(0, 1, (1 << (VOICE_WAKE)));
VOICE_WAKE_HIGH; // Disable after init
#endif
// Output mode
GPIO_G_SET(2, 1, (1 << (VOICE_RESET - 32)) |
(1 << (VOICE_VOLUME_UP - 32)) |
(1 << (VOICE_VOLUME_DOWN - 32)));
VOICE_RESET_LOW;
MicroDelay(100);
VOICE_RESET_HIGH;
VOICE_VOLUME_UP_HIGH;
VOICE_VOLUME_DOWN_HIGH;
VoiceVolumeTimer = 0;
}
void VoiceSend(BYTE *pVoice)
{
BYTE *pData;
BYTE Index;
BYTE vData;
BYTE Length;
#ifdef SUPPORT_BOARD_TYPE_OLD
VOICE_WAKE_LOW;
MicroDelay(100);
VOICE_WAKE_HIGH;
MicroDelay(100);
VOICE_WAKE_LOW;
MicroDelay(100);
#endif
pData = pVoice;
Index = 0;
while (*pData) {
if (*pData > 0x80) {
VoiceUartBuffer[Index] = *pData;
VoiceUartBuffer[Index + 1] = *(pData + 1);
pData += 2;
Index += 2;
VoiceUartBuffer[Index] = ' ';
VoiceUartBuffer[Index + 1] = ' ';
Index += 2;
}
else {
VoiceUartBuffer[Index] = *pData;
pData += 1;
Index += 1;
VoiceUartBuffer[Index + 0] = ' ';
VoiceUartBuffer[Index + 1] = ' ';
Index += 2;
}
}
VoiceUartBuffer[Index] = 0;
Index = 0;
while (1) {
Length = strlen(&VoiceUartBuffer[Index]);
if (Length != 0) {
vData = 0x01;
UartSend(&vData, 1);
}
if (Length > 50) {
UartSend(&VoiceUartBuffer[Index], 50);
Index += 50;
}
else {
if (Length != 0) {
UartSend(&VoiceUartBuffer[Index], Length);
vData = 0x04;
UartSend(&vData, 1);
}
break;
}
}
#ifdef SUPPORT_BOARD_TYPE_OLD
VOICE_WAKE_HIGH;
#endif
}
#define VOICE_VOLUME_DELAY 50 // *10mS
void VoiceVolumeUp()
{
#ifdef SUPPORT_BOARD_TYPE_OLD
VOICE_WAKE_LOW;
MicroDelay(100);
VOICE_WAKE_HIGH;
MicroDelay(100);
VOICE_WAKE_LOW;
MicroDelay(100);
#endif
// psprintf(LineBuffer, "Volume Up");
// MenuPrintMessage(2);
VoiceSend("音量加");
VOICE_VOLUME_UP_LOW;
VoiceVolumeTimer = VOICE_VOLUME_DELAY;
#ifdef SUPPORT_BOARD_TYPE_OLD
VOICE_WAKE_HIGH;
#endif
}
void VoiceVolumeDown()
{
#ifdef SUPPORT_BOARD_TYPE_OLD
VOICE_WAKE_LOW;
MicroDelay(100);
VOICE_WAKE_HIGH;
MicroDelay(100);
VOICE_WAKE_LOW;
MicroDelay(100);
#endif
// psprintf(LineBuffer, "Volume Down");
// MenuPrintMessage(2);
VoiceSend("音量减");
VOICE_VOLUME_DOWN_LOW;
VoiceVolumeTimer = VOICE_VOLUME_DELAY;
#ifdef SUPPORT_BOARD_TYPE_OLD
VOICE_WAKE_HIGH;
#endif
}
void VoiceVolumeStop()
{
VOICE_VOLUME_UP_HIGH;
VOICE_VOLUME_DOWN_HIGH;
// psprintf(LineBuffer, "Volume Adjust Over!");
// MenuPrintMessage(2);
}
#endif
#ifdef SUPPORT_WINBOND_VOICE
#ifdef SUPPORT_GPIO_BUS_FUNCTION
#if TMBOARD_VERSION >= 2
#define VOICE_MUTE 48
#define VOICE_MUTE_LOW (GPIO_O_SET(VOICE_MUTE, 0))
#define VOICE_MUTE_HIGH (GPIO_O_SET(VOICE_MUTE, 1))
#define VOICE_MUTE_ON (VOICE_MUTE_HIGH)
#define VOICE_MUTE_OFF (VOICE_MUTE_LOW )
#define VOICE_RESET (1 << 4)
#define VOICE_RESET_LOW (Bus1SetBit(VOICE_RESET, 0))
#define VOICE_RESET_HIGH (Bus1SetBit(VOICE_RESET, 1))
#endif
#define VOICE_SS 53
#define VOICE_SCLK 21
#define VOICE_MOSI 22
#define VOICE_MISO 23
#else
#define VOICE_RESET 40
#define VOICE_SS 20
#define VOICE_SCLK 14
#define VOICE_MOSI 12
#define VOICE_MISO 13
#define VOICE_RESET_LOW (GPIO_O_SET(VOICE_RESET, 0))
#define VOICE_RESET_HIGH (GPIO_O_SET(VOICE_RESET, 1))
#endif
#define VOICE_SS_LOW (GPIO_O_SET(VOICE_SS, 0))
#define VOICE_SS_HIGH (GPIO_O_SET(VOICE_SS, 1))
#define VOICE_SCLK_LOW (GPIO_O_SET(VOICE_SCLK, 0))
#define VOICE_SCLK_HIGH (GPIO_O_SET(VOICE_SCLK, 1))
#define VOICE_MOSI_LOW (GPIO_O_SET(VOICE_MOSI, 0))
#define VOICE_MOSI_HIGH (GPIO_O_SET(VOICE_MOSI, 1))
#define VOICE_MISO_READ (GPIO_I_GET(VOICE_MISO))
#define VOICE_FIFO_MASK (VOICE_FIFO_SIZE - 1)
#define VOICE_FIFO_FI(d) *(VoiceFIFO + (VoiceFI++)) = (d); \
VoiceFI &= VOICE_FIFO_MASK
#define VOICE_FIFO_FO(d) (d) = *(VoiceFIFO + (VoiceFO++)); \
VoiceFO &= VOICE_FIFO_MASK
#define VOICE_FIFO_EMPTY (VoiceFI == VoiceFO)
static UINT16 VoiceFI;
static UINT16 VoiceFO;
#define VOICE_IDLE 0
#define VOICE_CONV 1
#define VOICE_CONV_DONE 2
static BYTE VoiceState;
static BYTE VoiceSwitchTimer;
void VoiceInitGPIO()
{
#ifdef SUPPORT_GPIO_BUS_FUNCTION
// Input mode
GPIO_M_SET(VOICE_MISO, 1); GPIO_E_SET(VOICE_MISO, 0);
// Output mode
GPIO_M_SET(VOICE_MOSI, 1); GPIO_E_SET(VOICE_MOSI, 1);
GPIO_M_SET(VOICE_SCLK, 1); GPIO_E_SET(VOICE_SCLK, 1);
GPIO_M_SET(VOICE_SS, 1); GPIO_E_SET(VOICE_SS, 1);
#if TMBOARD_VERSION >= 2
GPIO_M_SET(VOICE_MUTE, 1); GPIO_E_SET(VOICE_MUTE, 1);
#endif
#else
// Input mode
GPIO_M_SET(VOICE_MISO, 1); GPIO_E_SET(VOICE_MISO, 0);
// Output mode
GPIO_M_SET(VOICE_RESET, 1); GPIO_E_SET(VOICE_RESET, 1);
GPIO_M_SET(VOICE_MOSI, 1); GPIO_E_SET(VOICE_MOSI, 1);
GPIO_M_SET(VOICE_SCLK, 1); GPIO_E_SET(VOICE_SCLK, 1);
GPIO_M_SET(VOICE_SS, 1); GPIO_E_SET(VOICE_SS, 1);
#endif
#if TMBOARD_VERSION >= 2
VOICE_MUTE_ON;
#endif
#if TMBOARD_VERSION >= 2 || !defined(SUPPORT_GPIO_BUS_FUNCTION)
VOICE_RESET_LOW;
#endif
VOICE_SS_HIGH;
VOICE_SCLK_HIGH;
VoiceFI = 0;
VoiceFO = 0;
VoiceState = VOICE_IDLE;
VoiceSwitchTimer = 0;
}
#define WTS_RDST 0x0400 // Read Status
#define WTS_RINT 0x0600 // Read Interrupt
#define WTS_RVER 0x1200 // Read Version
#define WTS_PWUP 0x0200 // Exit Power Down Mode
#define WTS_PWDN 0x4000 // GoTo Power Down Mode
#define WTS_RST 0x1000 // Reset
#define WTS_CONV 0x8100 // Convert Text
#define WTS_PAUS 0x4900 // Pause Conversion
#define WTS_RES 0x4a00 // Resume Conversion
#define WTS_ST 0x4b00 // Stop Conversion
#define WTS_FINW 0x4d00 // Finish Word
#define WTS_FIN 0x4c00 // Finish
#define WTS_VLUP 0x5300 // Volume Up
#define WTS_VLDN 0x5400 // Volume Down
#define WTS_SPUP 0x5500 // Speed Up
#define WTS_SPDN 0x5600 // Speed Down
#define WTS_IDLE 0x5700 // Switch to Idle State
#define WTS_RREG 0xc000 // Read Configuration Register
#define WTS_SCOM 0x4e00 // Set COM Register
#define WTS_SCOD 0x4f00 // Set COD Register
#define WTS_SAUD 0x5000 // Set AUD Register
#define WTS_SVOL 0x5100 // Set VOL Register
#define WTS_SSPD 0x5200 // Set SPD Register
#define WTS_SCLC 0x1400 // Set CLC Register
#define WTS_SPTC 0x7700 // Set Speech Pitch
#define WTS_ABBR_NUM 0xc800 // Return Number of Abbreviation Entries
#define WTS_ABBR_RD 0xc900 // Read Abbreviation Table
#define WTS_ABBR_MEM 0xc700 // Return Abbreviation Memory
#define WTS_ABBR_ADD 0xaf00 // Add Abbreviation
#define WTS_ABBR_DEL 0x8300 // Delete Abbreviation Entry
#define WTS_ENTER_RRSM 0x0c00 // Swap Memory
#define WTS_ICNT (1 << 15)
#define WTS_IBUF (1 << 14)
#define WTS_ICNV (1 << 13)
#define WTS_COD (1 << 12)
#define WTS_BFUL (1 << 11)
#define WTS_BEMP (1 << 10)
#define WTS_CNVT (1 << 9)
#define WTS_RDY (1 << 8)
#define WTS_RB (1 << 7)
#define WTS_IABB (1 << 2)
#define WTS_ICMD (1 << 0)
static UINT16 VoiceStatus;
static UINT16 VoiceData;
static BYTE VoicePowerUpFlag;
static INT8 VoiceVolume;
UINT16 VoiceSendData(UINT16 Data)
{
BYTE i;
UINT16 BitMap;
UINT16 Resule = 0;
UINT16 DelayCount;
if (VoicePowerUpFlag)
DelayCount = 100;
else
DelayCount = 400;
BitMap = 0x01 << 15;
for (i = 0; i < 16; i++) {
Resule <<= 1;
MicroDelay(DelayCount);
VOICE_SCLK_LOW;
MicroDelay(DelayCount);
if (Data & BitMap) {
VOICE_MOSI_HIGH;
}
else {
VOICE_MOSI_LOW;
}
MicroDelay(DelayCount);
VOICE_SCLK_HIGH;
MicroDelay(DelayCount);
if (VOICE_MISO_READ)
Resule |= 0x01;
BitMap >>= 1;
}
return Resule;
}
UINT16 VoiceSendCommand(UINT16 Data)
{
UINT16 Result;
VOICE_SS_LOW;
Result = VoiceSendData(Data);
VOICE_SS_HIGH;
return Result;
}
void VoiceReadStatus()
{
VOICE_SS_LOW;
VoiceStatus = VoiceSendData(WTS_RDST);
VoiceData = VoiceSendData(0x0000);
VOICE_SS_HIGH;
}
void VoiceReadVersion()
{
VOICE_SS_LOW;
VoiceStatus = VoiceSendData(WTS_RVER);
VoiceData = VoiceSendData(0x0000);
VOICE_SS_HIGH;
}
void VoicePowerUp()
{
VoicePowerUpFlag = 0;
/*
MicroDelay(100);
VOICE_RESET_LOW;
MicroDelay(100);
VOICE_RESET_HIGH;
MicroDelay(100);
VOICE_RESET_LOW;
MicroDelay(100);
*/
VoiceSendCommand(WTS_SCLC);
VoiceSendCommand(WTS_PWUP);
VoiceReadStatus();
/*
VoiceReadVersion();
psprintf(LineBuffer, "VOICE:%04x-%04x", VoiceStatus, VoiceData);
MenuPrintMessage(3);
*/
#ifdef SUPPORT_I2C_DEVICE
if (TestI2COK)
VoiceInitLoadEEP();
else
#endif
VoiceVolumeLevel = VOICE_VOLUME_MAX;
VoiceSendCommand(WTS_SCOM | 0x00);
VoiceSendCommand(WTS_SCOD | 0x01);
VoiceSendCommand(WTS_SAUD | 0x43);
VoiceSendCommand(WTS_SVOL | (VOICE_VOLUME_MAX - VoiceVolumeLevel));
#ifdef SUPPORT_ENGLISH_VOICE
VoiceSendCommand(WTS_SSPD | 0x01);
#else
VoiceSendCommand(WTS_SSPD | 0x03);
#endif
VoiceSendCommand(WTS_SPTC | 0x05);
VoicePowerUpFlag = 1;
VoiceVolume = 0;
}
void VoiceSend(BYTE *Text)
{
#if 0
while (1) {
VoiceReadStatus();
psprintf(LineBuffer, "VOICE:%04x-%04x", VoiceStatus, VoiceData);
MenuPrintMessage(2);
if (VoiceStatus & WTS_RDY)
break;
}
VOICE_SS_LOW;
VoiceSendData(WTS_CONV);
VoiceSendData(0xfffe);
while (1) {
if (*Text == 0x00) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -