|
#include "LD3320.h"
#include "LD3320_config.h"
#define DATE_A Enum_Number //數組二維數值
#define DATE_B 30 //數組一維數值
uint8 nAsrStatus = 0;
uint8 nLD_Mode = LD_MODE_IDLE
uint8 ucRegVal;
uint8 LD3320_Identified_Flag_bit = LD_ASR_NONE
uint8 nAsrRes=0;
uint8 k, flag;
uint8 nAsrAddLength;
uint8 pCode[DATE_A];
unsigned int Number_C = 0;
static uint8 LD_AsrAddFixed(void)
{
//添加關鍵詞用戶添加或修改
uint8 sRecog[Enum_Number][DATE_B] = {
"ni hao",
"kai qi zhu wo deng", //開啟主臥燈
"guan bi zhu wo deng", //關閉主臥燈
"kai qi ci wo deng", //開啟次臥燈
"guan bi ci wo deng", //關閉次臥燈
"kai qi chu fang deng", //開啟廚房燈
"guan bi chu fang deng", //關閉廚房燈
"kai qi ke ting deng", //開啟客廳燈
"guan bi ke ting deng", //關閉客廳燈
"kai qi feng shan", //開啟客廳燈
"guan bi feng shan", //關閉客廳燈
"jie shao yi xia zi ji",
"ying tao xiao wan zi",
"xiao wan zi",
"quan bu kai qi",
"quan bu guan bi",
"kai qi ge ren mo shi",
"kai qi pu tong mo shi",
"cha kan wen shi du",
"cha kan guang du"
};
for(Number_C=0;Number_C < Enum_Number;Number_C++)
{
pCode[Number_C]=Number_C+1;
}
flag = 1;
for (k=0; k<DATE_A; k++)
{
if(LD_Check_ASRBusyFlag_b2() == 0)
{
flag = 0;
break;
}
LD_WriteReg(0xc1, pCode[k] );
LD_WriteReg(0xc3, 0);
LD_WriteReg(0x08, 0x04);
LD3320_delay(1);
LD_WriteReg(0x08, 0x00);
LD3320_delay(1);
for (nAsrAddLength=0; nAsrAddLength<DATE_B; nAsrAddLength++)
{
if (sRecog[k][nAsrAddLength] == 0)
break;
LD_WriteReg(0x5, sRecog[k][nAsrAddLength]);
}
LD_WriteReg(0xb9, nAsrAddLength);
LD_WriteReg(0xb2, 0xff);
LD_WriteReg(0x37, 0x04);
}
return flag;
}
///相關初始化
void LD3320_init(void)
{
//delay_init();
LD3320_GPIO_Cfg();
LD3320_EXTI_Cfg();
LD3320_SPI_cfg();
LD_reset();
nAsrStatus = LD_ASR_NONE;//初始狀態:沒有在作ASR
}
void LD3320_Subject(void)
{
switch(nAsrStatus)
{
case LD_ASR_RUNING: //表示LD3320正在作ASR識別中
break;
case LD_ASR_ERROR: // 表示一次識別流程中LD3320芯片內部出現不正確的狀態
break;
case LD_ASR_NONE: //表示沒有在作ASR識別
nAsrStatus=LD_ASR_RUNING;
if (RunASR()==0) //啟動一次ASR識別流程:ASR初始化,ASR添加關鍵詞語,啟動ASR運算
{
nAsrStatus = LD_ASR_ERROR;
}
break;
case LD_ASR_FOUNDOK: //表示一次識別流程結束后,有一個識別結果
nAsrRes = LD_GetResult();//一次ASR識別流程結束,去取ASR識別結果
printf("\r\n識別碼:%d\r\n", nAsrRes);
LD3320_Identified_Flag_bit=LD_ASR_FOUNDOK;
nAsrStatus = LD_ASR_NONE;
break;
case LD_ASR_FOUNDZERO:
default:
nAsrStatus = LD_ASR_NONE;
break;
}//switch
}
static void LD3320_GPIO_Cfg(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(LD3320RST_GPIO_CLK | LD3320CS_GPIO_CLK,ENABLE);
//LD_CS /RSET
GPIO_InitStructure.GPIO_Pin =LD3320CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LD3320CS_GPIO_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =LD3320RST_PIN;
GPIO_Init(LD3320RST_GPIO_PORT,&GPIO_InitStructure);
}
static void LD3320_EXTI_Cfg(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(LD3320IRQ_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin =LD3320IRQ_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LD3320IRQ_GPIO_PORT, &GPIO_InitStructure);
//外部中斷線配置
GPIO_EXTILineConfig(LD3320IRQEXIT_PORTSOURCE, LD3320IRQPINSOURCE);
EXTI_InitStructure.EXTI_Line = LD3320IRQEXITLINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//中斷嵌套配置
NVIC_InitStructure.NVIC_IRQChannel = LD3320IRQN;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void LD3320_SPI_cfg(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//spi端口配置
RCC_APB2PeriphClockCmd(LD3320SPI_CLK,ENABLE);
RCC_APB2PeriphClockCmd(LD3320WR_GPIO_CLK | LD3320SPIMISO_GPIO_CLK | LD3320SPIMOSI_GPIO_CLK | LD3320SPISCK_GPIO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Pin = LD3320SPIMISO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(LD3320SPIMISO_GPIO_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LD3320SPIMOSI_PIN;
GPIO_Init(LD3320SPIMOSI_GPIO_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LD3320SPISCK_PIN;
GPIO_Init(LD3320SPISCK_GPIO_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LD3320WR_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LD3320WR_GPIO_PORT, &GPIO_InitStructure);
LD_CS_H();
SPI_Cmd(LD3320SPI, DISABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全雙工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //時鐘極性 空閑狀態時,SCK保持低電平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //時鐘相位 數據采樣從第一個時鐘邊沿開始
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //軟件產生NSS
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //波特率控制 SYSCLK/128
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //數據高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC多項式寄存器初始值為7
SPI_Init(LD3320SPI, &SPI_InitStructure);
SPI_Cmd(LD3320SPI, ENABLE);
}
///中間層
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(LD3320IRQEXITLINE)!= RESET )
{
ProcessInt();
printf("\r\n運行中,您請說!\r\n");
EXTI_ClearFlag(LD3320IRQEXITLINE);
EXTI_ClearITPendingBit(LD3320IRQEXITLINE);//清除LINE上的中斷標志位
}
}
static void LD3320_delay(unsigned long uldata)
{
delay_ms(uldata);
}
static uint8 RunASR(void)
{
uint8 i=0;
uint8 asrflag=0;
for (i=0; i<5; i++) //防止由于硬件原因導致LD3320芯片工作不正常,所以一共嘗試5次啟動ASR識別流程
{
LD_AsrStart(); //初始化ASR
LD3320_delay(10);
if (LD_AsrAddFixed()==0) //添加關鍵詞語到LD3320芯片中
{
LD_reset(); //LD3320芯片內部出現不正常,立即重啟LD3320芯片
LD3320_delay(20); //并從初始化開始重新ASR識別流程
continue;
}
LD3320_delay(10);
if (LD_AsrRun() == 0)
{
LD_reset(); //LD3320芯片內部出現不正常,立即重啟LD3320芯片
LD3320_delay(20);//并從初始化開始重新ASR識別流程
continue;
}
asrflag=1;
break; //ASR流程啟動成功,退出當前for循環。開始等待LD3320送出的中斷信號
}
return asrflag;
}
static void LD_reset(void)
{
LD_RST_H();
LD3320_delay(10);
LD_RST_L();
LD3320_delay(10);
LD_RST_H();
LD3320_delay(10);
LD_CS_L();
LD3320_delay(10);
LD_CS_H();
LD3320_delay(10);
}
static void LD_AsrStart(void)
{
LD_Init_ASR();
}
uint8 LD_Check_ASRBusyFlag_b2(void)
{
uint8 j;
uint8 flag = 0;
for (j=0; j<10; j++)
{
if (LD_ReadReg(0xb2) == 0x21)
{
flag = 1;
break;
}
LD3320_delay(10);
}
return flag;
}
///中間層end
///寄存器操作
static uint8 spi_send_byte(uint8 byte)
{
while (SPI_I2S_GetFlagStatus(LD3320SPI, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(LD3320SPI,byte);
while (SPI_I2S_GetFlagStatus(LD3320SPI,SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(LD3320SPI);
}
static void LD_WriteReg(uint8 data1,uint8 data2)
{
LD_CS_L();
LD_SPIS_L();
spi_send_byte(0x04);
spi_send_byte(data1);
spi_send_byte(data2);
LD_CS_H();
}
static uint8 LD_ReadReg(uint8 reg_add)
{
uint8 i;
LD_CS_L();
LD_SPIS_L();
spi_send_byte(0x05);
spi_send_byte(reg_add);
i=spi_send_byte(0x00);
LD_CS_H();
return(i);
}
static uint8 LD_GetResult(void)
{
return LD_ReadReg(0xc5);
}
static uint8 LD_AsrRun(void)
{
LD_WriteReg(0x35, MIC_VOL);
LD_WriteReg(0x1C, 0x09);
LD_WriteReg(0xBD, 0x20);
LD_WriteReg(0x08, 0x01);
LD3320_delay( 5 );
LD_WriteReg(0x08, 0x00);
LD3320_delay( 5);
if(LD_Check_ASRBusyFlag_b2() == 0)
{
return 0;
}
LD_WriteReg(0xB2, 0xff);
LD_WriteReg(0x37, 0x06);
LD_WriteReg(0x37, 0x06);
LD3320_delay(5);
LD_WriteReg(0x1C, 0x0b);
LD_WriteReg(0x29, 0x10);
LD_WriteReg(0xBD, 0x00);
return 1;
}
static void ProcessInt(void)
{
uint8 nAsrResCount=0;
ucRegVal = LD_ReadReg(0x2B);
// 語音識別產生的中斷
//(有聲音輸入,不論識別成功或失敗都有中斷)
LD_WriteReg(0x29,0) ;
LD_WriteReg(0x02,0) ;
if((ucRegVal & 0x10) && LD_ReadReg(0xb2)==0x21 && LD_ReadReg(0xbf)==0x35)
{
nAsrResCount = LD_ReadReg(0xba);
if(nAsrResCount>0 && nAsrResCount<=4)
{
nAsrStatus=LD_ASR_FOUNDOK;
}
else
{
nAsrStatus=LD_ASR_FOUNDZERO;
}
}
else
{
nAsrStatus=LD_ASR_FOUNDZERO;//執行沒有識別
}
LD_WriteReg(0x2b,0);
LD_WriteReg(0x1C,0);//寫0:ADC不可用
LD_WriteReg(0x29,0);
LD_WriteReg(0x02,0);
LD_WriteReg(0x2B,0);
LD_WriteReg(0xBA,0);
LD_WriteReg(0xBC,0);
LD_WriteReg(0x08,1);//清除FIFO_DATA
LD_WriteReg(0x08,0);//清除FIFO_DATA后 再次寫0
}
static void LD_Init_Common(void)
{
LD_ReadReg(0x06);
LD_WriteReg(0x17, 0x35);
LD3320_delay(5);
LD_ReadReg(0x06);
LD_WriteReg(0x89, 0x03);
LD3320_delay(5);
LD_WriteReg(0xCF, 0x43);
LD3320_delay(5);
LD_WriteReg(0xCB, 0x02);
/*PLL setting*/
LD_WriteReg(0x11, LD_PLL_11);
if (nLD_Mode == LD_MODE_MP3)
{
LD_WriteReg(0x1E, 0x00);
LD_WriteReg(0x19, LD_PLL_MP3_19);
LD_WriteReg(0x1B, LD_PLL_MP3_1B);
LD_WriteReg(0x1D, LD_PLL_MP3_1D);
}
else
{
LD_WriteReg(0x1E,0x00);
LD_WriteReg(0x19, LD_PLL_ASR_19);
LD_WriteReg(0x1B, LD_PLL_ASR_1B);
LD_WriteReg(0x1D, LD_PLL_ASR_1D);
}
LD3320_delay(5);
LD_WriteReg(0xCD, 0x04);
LD_WriteReg(0x17, 0x4c);
LD3320_delay(1);
LD_WriteReg(0xB9, 0x00);
LD_WriteReg(0xCF, 0x4F);
LD_WriteReg(0x6F, 0xFF);
}
static void LD_Init_ASR(void)
{
nLD_Mode=LD_MODE_ASR_RUN;
LD_Init_Common();
LD_WriteReg(0xBD, 0x00);
LD_WriteReg(0x17, 0x48);
LD3320_delay(5);
LD_WriteReg(0x3C, 0x80);
LD_WriteReg(0x3E, 0x07);
LD_WriteReg(0x38, 0xff);
LD_WriteReg(0x3A, 0x07);
LD_WriteReg(0x40, 0);
LD_WriteReg(0x42, 8);
LD_WriteReg(0x44, 0);
LD_WriteReg(0x46, 8);
LD3320_delay( 1 );
}
|
|