#include "includes.h" #define APP_IDLE_TIME 3 //如果POC已休眠,APP没有操作一定秒数后休眠 nwy_osiThread_t *mainThreadPtr=NULL; int keyNum=0; APP_DEF sutApp; static void appDataInit(void){ memset((unsigned char *)&sutApp, 0, sizeof(APP_DEF)); sutApp.pcant=4;//默认免提 appSleepCtl(ASLEEP_POC, 1); appSleepCtl(ASLEEP_LCD, 1); readInfoNow(); sysIniRead(); } void dataInit(void){ appDataInit(); pocDataInit(); gpsDataInit(); uiDataInit(); } static void ledsProCtl(void){ if(sutApp.gtMode!=0) return; if(0==sutPocStatus.logined) uioStatusSet(UIO_INDOFFLINE); else if(sutPocStatus.spk>0)uioStatusSet(UIO_INDRX); else if(sutPocStatus.mic>0 )uioStatusSet(UIO_INDTX); else uioStatusSet(UIO_INDONLINE); } static void adcRead(void); char isKeyPress(void){ if(keyNum) return keyNum--; else return 0; } static void subTimerCtl(unsigned char sleep_or_not); /*APP休眠处理接口 ctlType, 操作对象 status,操作值,0 清除 else 设置 */ void appSleepCtl(ASLEEP_ENUM ctlType, char status){ if(status==0) sutApp.appSleepStatus &= ~(1<=(APP_IDLE_TIME*1000/APP_SUB_DIV_TIME)){ idleCnt=0; return 1; }else return 0; } /*处理UI操作*/ static void uiProcess(unsigned int exeInterval){ if(getAppObjStatus(ASLEEP_PWR) != 0) return;//关机后,不切换菜单,只显示关机页面 if(sutApp.gtMode!=0) return;//GT模式后按键无效 uiLoop(exeInterval); uiResponse(exeInterval); } /*触发关机操作*/ static void pwrShutPro(unsigned int exeInterval){ static char shutFlag=0; static int kcnt=0; if(sutApp.pwrKeyStatus==0){//按下了 kcnt++; appSleepCtl(ASLEEP_PWRKEY, 1); if(kcnt==(2500/exeInterval)){ appSleepCtl(ASLEEP_PWR, 1); } }else{//放开了 kcnt=0; appSleepCtl(ASLEEP_PWRKEY, 0); } if(getAppObjStatus(ASLEEP_PWR) == 0) return; CTL_LCD_BL(1); msgAtSend("AT+POC=050000\r\n"); msgAtSend("AT+CFUN=0\r\n"); if(shutFlag==0){ //显示关机界面 guiShowMessageBox("正在关机"); shutFlag=1; nwy_sleep(1000); } MSG_INFO(1, "Normal PwrOff"); //msgAtSend("AT+TRB=1\r\n");//normal power off 当前固件先不发模块关机指令,否则断电再上电有可能是起不来的 nwy_sleep(1000);//一秒后释放电源锁,防止软关机不成功 CTL_LCD_BL(0); MSG_INFO(1, "Release pwr"); guiFillRect(0,0,GLCD_WIDTH-1,GLCD_HEIGHT-1,guiGetBackColor());//防止下次开机能看到残留 CTL_POWER_HOLD(0); nwy_sleep(100); msgAtSend("AT+TRB=2\r\n");//软件复位模块 } void AntModeRun(void){ #ifdef ENABLE_ANT_MODE guiShowMessageBox("调天线模式"); for(;;){ nwy_sleep(2000); } #endif } void lcdReConfig(void){ if(sutApp.lcdReconfigCnt<=3) sutApp.lcdReconfigCnt++; if(sutApp.lcdReconfigCnt==3) recoverLightColor(); } static void paProCtl(void); /*主要应用程序入口*/ void appRun(void){ char cnt=0; nwy_osiEvent_t event = {}; //等待lcd初始化完成 MSG_INFO(1, "wait lcd init"); while(sutApp.guiStatus==0){nwy_sleep(50);}//是否检测超时? AntModeRun(); localAuthNow(); //等待poc启动完成 MSG_INFO(1, "lcd init done, wait poc start"); while(sutApp.pocInitStatus==0){ msgAtSend("AT\r\n"); nwy_sleep(50); }//是否检测超时? MSG_INFO(1, "app loop start"); //设置EQ数据 modifyEqData(); //修改音频输出增益配置 modifyAudioOutGainConfig(); //设置一下TTS msgAtSend("AT+HTTSSPEED=1284,-20000\r\n");//设置TTS音量 msgAtSend("AT+HTTSSPEED=1282,-5000\r\n");//设置TTS语速 //查询一下POC版本号 msgAtSend("AT+POC_VER\r\n"); msgAtSend("AT+GMR\r\n");//查询模块版本 msgAtSend("AT+MIC=6\r\n"); msgAtSend("AT+VSW=1\r\n");//打开留音功能 //msgAtSend("AT+CACCP=0,1,0,\"04000B00\"\r\n"); #ifndef ENABLE_PWM_BEEP if(newPara.KeySound!=0) msgAtSend("AT+TONES=1\r\n"); #endif splVolumeSet(newPara.spkVol*10); backLightReset(); if(newPara.ttsMessage[0]!=0){ if(newPara.ttsCodeType==0) ttsPlay(ENCODE_USER_UNICODE_BE, newPara.ttsMessage); else if(newPara.ttsCodeType==1) ttsPlay(ENCODE_USER_GBK, newPara.ttsMessage); else MSG_INFO(1, "ttsCodeType:%d not support", newPara.ttsCodeType); }else MSG_INFO(1, "tts null"); //检测卡是否存在 while(sutApp.cardStatus==0){ msgAtSend("AT+CPIN?\r\n"); nwy_sleep(1000); if(++cnt>=5){ MSG_INFO(1, "Check card timeout"); break; } } for(;;){ lcdReConfig(); ledsProCtl(); adcRead(); uiProcess(APP_SUB_DIV_TIME); gpsProCtl(APP_SUB_DIV_TIME); pocProCtl(APP_SUB_DIV_TIME); HookGroupUserInfo(); HookVolToutCheck(); LearnUsrInfoCheck(APP_SUB_DIV_TIME); IncomingSMS(); if(isSleepReady()==0) nwy_sleep(APP_TASK_SLEEP_TIME); else if(sutApp.gtMode==0){//正常模式下可以休眠 MSG_WARN(1, "APP SLEEP"); stopKeyTimer(); subTimerCtl(1);//切换为休眠状态定时器 sutApp.appStatus=1; CTL_LED2_GREEN(0); CTL_LED1_RED(0); #ifdef ENABLE_DEEP_SLEEP pwmDeInitToSleep(); lcdDrvPowerCtl(false); nwy_pm_state_set(NWY_ENTRY_SLEEP); #endif nwy_wait_thead_event(nwy_get_current_thread(), &event,0); lcdDrv_Init(1);//深度休眠唤醒后重新初始化SPI-LCD sutApp.appStatus=0; subTimerCtl(0);//切换为唤醒状态定时器 MSG_WARN(1, "APP WAKEUP"); } //检测是否关机,这里要放在唤醒后操作 pwrShutPro(APP_SUB_DIV_TIME); } } //////////////////////////////////////用于处理非耗时操作,如LED/////////////////////// nwy_osiTimer_t *pSubtimer_t = NULL; unsigned int subTimerInterval=100;//定时器定时的时间 static void subTimeroutcallback(void *param){ unsigned int *dlyTime=(unsigned int *)param; //处理灯的显示 uioProctl(*dlyTime); //控制功放的关闭 paProCtl(); } /*创建定时器*/ void subTask(void *param){ nwy_osiEvent_t event = {}; if(NULL == pSubtimer_t) pSubtimer_t = nwy_timer_init(nwy_get_current_thread(), subTimeroutcallback, (void *)&subTimerInterval); if(NULL == pSubtimer_t) MSG_WARN(1,"sub timer init failed"); else nwy_start_timer_periodic(pSubtimer_t,subTimerInterval); for(;;){nwy_wait_thead_event(nwy_get_current_thread(), &event,0);} } /* 为了做低功耗,此定时器在休眠时,设置为长时间定时 非休眠时,设置为短时间定时 sleep_or_not:0 未休眠, else 休眠 */ static void subTimerCtl(unsigned char sleep_or_not){ if(NULL==pSubtimer_t){ MSG_WARN(1, "subTimer null"); return; } nwy_stop_timer(pSubtimer_t); //打开定时器 if(sleep_or_not==0) subTimerInterval=100;//未休眠时,100ms else subTimerInterval=5000;//休眠时 5000ms nwy_start_timer_periodic(pSubtimer_t,subTimerInterval); } ////////////////////////////////////////////////////////////////////////////////////// void usbCmdHandler(const char *data,uint32 length){ static char buf[256]; static int len=0; static char lach; char ch; int i; if(sutApp.authReady==0){ authRecvPro(data, length); return; } for(i=0;i=(1000/KEY_TIMER_TICK)){//每秒产生持续值 keyCnt=0; needSendKey=1; } } } if(needSendKey){ if(sutApp.enableKey!=0)//延时期间不检测按键 threadSendEvent(nwy_get_current_thread(),OHPOC_EVENT_KEY_NOR, lkey,keyType,NULL); } } static char micPttPressed=0; static char pttPressed=0; static void pttHandler(char type, char ctl){ char needSend=0; char mic_spk; if(type==0){//ptt if(ctl==0){//放开 if(micPttPressed==0){ needSend=1;mic_spk=0; } pttPressed=0; }else{//按下 if(pttPressed==0 && micPttPressed==0){ needSend=1;mic_spk=1; } pttPressed=1; } }else{//mic ptt if(ctl==0){//放开 if(pttPressed==0){ needSend=1;mic_spk=0; } micPttPressed=0; }else{//按下 if(pttPressed==0 && micPttPressed==0){ needSend=1;mic_spk=1; } micPttPressed=1; } } if(isLearnBusy()==true){ MSG_WARN(1, "Learn task is busy, skip ptt"); return;//学习任务正在使用音频,POC不录音 } if(needSend!=0){ if(mic_spk==0) msgAtSend("AT+POC=0C0000\r\n"); else msgAtSend("AT+POC=0B0000\r\n"); } } /*打印键信息*/ const char freeSeg[]="Free"; const char pressSeg[]="Press"; void showKeyMessage(unsigned short key,unsigned char status){ char buf[50]="[Key_"; switch(key){ case KV_KEY_MIC_PTT: strcat(buf, "MIC_PTT]");break; default:return; } if(status==0) strcat(buf, freeSeg); else strcat(buf, pressSeg); MSG_INFO(1,buf); } void keyHandler(unsigned short key,unsigned char status){//普通按键值处理 tryWakeupApp();//有普通键按下或放开,唤醒休眠的系统 showKeyMessage(key,status); if(status==0){//key free switch(key){ case KV_KEY_MIC_PTT: pttHandler(1,0); break; default: break; } singleKeyInArow=0; appSleepCtl(ASLEEP_KEY, 0); }else{//key press appSleepCtl(ASLEEP_KEY, 1); backLightReset(); if(sutApp.keyLock!=0){ sutApp.lockShow=1; return; } switch(key){ case KV_KEY_MIC_PTT: singleKeyInArow=1; pttHandler(1,1); break; default: break; } } } //扫描矩阵按键 #define MATRIX_KEY_NUMS 2 //最多检测同时两个组合键 void keyStatusCtlAll(char high_low){ CTL_KEY_OUT1(high_low); CTL_KEY_OUT2(high_low); CTL_KEY_OUT3(high_low); } void keyStatusCtlOne(char outIndex){ switch(outIndex){ case 0:CTL_KEY_OUT1(0); CTL_KEY_OUT2(1); CTL_KEY_OUT3(1); break; case 1:CTL_KEY_OUT2(0); CTL_KEY_OUT1(1); CTL_KEY_OUT3(1); break; case 2:CTL_KEY_OUT3(0); CTL_KEY_OUT2(1); CTL_KEY_OUT1(1); break; } } int keyStatusGetOne(char outIndex){ int ret=2; switch(outIndex){ case 0:ret=INT_KEY_IN1();break; case 1:ret=INT_KEY_IN2();break; case 2:ret=INT_KEY_IN3();break; } return ret; } unsigned short matrixGetKey(unsigned char out, unsigned char in){ unsigned short vlaue=0; if(out >= MKS_KEY_OUS || in >=MKS_KEY_INS) return 0xffff; switch(in){ case 0: switch(out){ case 0:vlaue |= (1<=MATRIX_KEY_NUMS) goto MATRIX_END; } } } MATRIX_END: keyStatusCtlAll(0); if(num==0){//无键按下 goto MKEY_NO_KEY; } for(int w=0;w=(1000/KEY_TIMER_TICK)){//每秒产生持续值 keyCnt=0; needSendKey=1; } } } if(needSendKey){ if(sutApp.enableKey!=0) threadSendEvent(nwy_get_current_thread(),OHPOC_EVENT_KEY_MAT, keyCtl,NULL,NULL); } } void showKeyMsg(char *info, unsigned char keyCtl){ char buf[40]; char *ctl; if(keyCtl==0) ctl=freeSeg; else ctl=pressSeg; snprintf(buf, sizeof(buf),"[Key %s]%s",ctl,info); MSG_INFO(1, buf); } static void lockProcess(void){ if(sutApp.keyLock==0){ sutApp.keyLock=1; appSleepCtl(ASLEEP_GGROUP, 0); appSleepCtl(ASLEEP_GUSER, 0); if(sutUIstatus.Status==UIS_STANDBY) guiShowBmp(72,110, "lock.bmp");//锁关/锁开触发时更新状态 uISetNextStatus(UIS_STANDBY); }else{ sutApp.keyLock=0; sutApp.lockShow=0; if(sutUIstatus.Status==UIS_STANDBY) guiClearRect(72,110,72+17,110+17,guiGetBackColor());//锁关/锁开触发时更新状态 } } void keyToneStart(void){ if(newPara.KeySound==0) return; #ifdef ENABLE_PWM_BEEP beepStart(TONE_NORMAL); #else msgAtSend("AT+TONE\r\n"); #endif } void mKeyHandler(unsigned char keyCtl){ static unsigned char gtModeCnt=0; static unsigned char lockCnt=0; if(sutApp.keyLock!=0 && MKEY_VALUE_P2!=g_usKeyValue){ sutApp.lockShow=1; return; } if(keyCtl==0){//释放 switch(g_usKeyValue){ case MKEY_VALUE_PTT:showKeyMsg("PTT",keyCtl); pttHandler(0,0); break; case MKEY_VALUE_P1:showKeyMsg("P1",keyCtl); break; case MKEY_VALUE_P2:showKeyMsg("P2",keyCtl); lockCnt=0; break; case MKEY_VALUE_MENU:showKeyMsg("MENU",keyCtl); break; case MKEY_VALUE_ESC:showKeyMsg("ESC",keyCtl); break; case MKEY_VALUE_UP:showKeyMsg("UP",keyCtl); break; case MKEY_VALUE_DOWN:showKeyMsg("DOWN",keyCtl); break; case MKEY_VALUE_F1:showKeyMsg("F1",keyCtl); break; case MKEY_VALUE_F2:showKeyMsg("F2",keyCtl); break; case MKEY_VALUE_CB_GT:showKeyMsg("CB_GT",keyCtl); gtModeCnt=0; break; case MKEY_VALUE_CB_IP:showKeyMsg("CB_IP",keyCtl); break; default:MSG_WARN(1,"UnHande Key:%d Free",g_usKeyValue); break; } keyInArow=0; appSleepCtl(ASLEEP_MKEY, 0); }else{//按下 if(g_usKeyValue!=MKEY_VALUE_PTT && g_usKeyValue!=MKEY_VALUE_CB_GT) keyToneStart(); backLightReset(); appSleepCtl(ASLEEP_MKEY, 1); keyNum++; switch(g_usKeyValue){ case MKEY_VALUE_PTT:showKeyMsg("PTT",keyCtl); pttHandler(0,1); break; case MKEY_VALUE_P1:showKeyMsg("P1",keyCtl); break; case MKEY_VALUE_P2:showKeyMsg("P2",keyCtl); keyInArow=1; if(++lockCnt==3) lockProcess(); break; case MKEY_VALUE_MENU:showKeyMsg("MENU",keyCtl); break; case MKEY_VALUE_ESC:showKeyMsg("ESC",keyCtl); break; case MKEY_VALUE_UP:showKeyMsg("UP",keyCtl); break; case MKEY_VALUE_DOWN:showKeyMsg("DOWN",keyCtl); break; case MKEY_VALUE_F1:showKeyMsg("F1",keyCtl); break; case MKEY_VALUE_F2:showKeyMsg("F2",keyCtl); break; case MKEY_VALUE_CB_GT:showKeyMsg("CB_GT",keyCtl); keyInArow=1; if(++gtModeCnt==3){ if(sutApp.gtMode==0){ enterGTMode(); } } break; case MKEY_VALUE_CB_IP: keyInArow=1; showKeyMsg("CB_IP",keyCtl); break; default:MSG_WARN(1,"UnHande Key:%d Press",g_usKeyValue); break; } } } //////////////////////////////按键处理结束////////////////////////// //////////////////////////////其它处理接口////////////////////////// void hpDetStatusChanged(unsigned char hpStatus){ if(0==hpStatus){ MSG_WARN(1,"HP plug in"); }else{ MSG_WARN(1,"HP plug out"); } } //测试主板ADC为:150~1190范围 //实际使用ADC取:170~1210范围 /*输入adc值,输出音量等级*/ #define VOL_LEV_NUM 11 //档位数 #define VOL_LEV_DEF 10 //抖动上下限 unsigned char wisdomAdcProcess(int adcValueTmp){ const unsigned short volAdcTable[VOL_LEV_NUM]={170,200,240,300,400,500,700,900,1100,1140,1170};//中间ADC变化快,两端ADC变化慢 int i; static unsigned char ucVolLev=0; for(i=0;i= volAdcTable[ucVolLev]+VOL_LEV_DEF) ucVolLev++; }else if(ucVolLev= volAdcTable[ucVolLev]+VOL_LEV_DEF) ucVolLev++; else if(adcValueTmp < volAdcTable[ucVolLev-1]-VOL_LEV_DEF) ucVolLev--; }else{ if(ucVolLev==VOL_LEV_NUM-1) if(adcValueTmp < volAdcTable[ucVolLev-1]-VOL_LEV_DEF) ucVolLev--; } } return ucVolLev; } static void adcRead(void){ #define VBAT_READ_TIME 20 int adcValueTmp; static int siVbat=0; static int laSiVbat; static unsigned char index=0; int x=(GLCD_WIDTH-16)/2; int y=GLCD_HEIGHT-12; //检测音量旋钮电压 adcValueTmp=nwy_adc_get(NWY_ADC_CHANNEL3, NWY_ADC_SCALE_1V250); if(adcValueTmp>0){//15 1227 if(sutUIstatus.Status==UIS_STANDBY){ if(adcValueTmp > 1000){ if(sutApp.earStatus==0){ sutApp.pcant=2;//FM sutApp.earStatus=1; MSG_INFO(1, "FM MODE"); guiShowBmp(x, y, "ear.bmp"); } }else{ if(sutApp.earStatus!=0){ sutApp.pcant=4;//mianti sutApp.earStatus=0; MSG_INFO(1, "MIANTI MODE"); guiClearRect(x, y, x+16,y+12, guiGetBackColor()); } } }else if(sutApp.earStatus != 0) sutApp.earStatus=0;//切到其它菜单后再切回来还能显示 } //检测电池电压 adcValueTmp=nwy_adc_get(NWY_ADC_CHANNEL4, NWY_ADC_SCALE_5V000); siVbat += adcValueTmp; if(++index>=VBAT_READ_TIME){ sutApp.g_iBAT=siVbat / VBAT_READ_TIME / 10; if(laSiVbat!=sutApp.g_iBAT){ //MSG_INFO(1, "bat:%d", sutApp.g_iBAT); laSiVbat=sutApp.g_iBAT; } siVbat=0; index=0; } } void tryWakeupApp(void){ if(sutApp.appStatus!=0){ sutApp.appStatus=0; if(mainThreadPtr!=NULL){ sutApp.lcdReconfigCnt=0; #ifdef ENABLE_DEEP_SLEEP nwy_pm_state_set(NWY_WAKEUP); #endif threadSendEvent(mainThreadPtr,OHPOC_EVENT_MAIN,NULL,NULL,NULL); } } } /*背光时间到,熄灭*/ void backLightCb(void *param){ if(sutApp.gtMode!=0){ CTL_LCD_BL(1); return; } if(sutPocStatus.firstLogin==0) return;//未登录过,不灭屏 if(newPara.lcdParaList[newPara.lcdParaDefaultIndex]==0) return;//常亮 CTL_LCD_BL(0); appSleepCtl(ASLEEP_LCD, 0);//可以休眠 } /*点亮背光*/ void backLightReset(void){ unsigned short tmp; appSleepCtl(ASLEEP_LCD, 1);//不让休眠 tmp=newPara.lcdParaList[newPara.lcdParaDefaultIndex]; CTL_LCD_BL(1); startBackLightTimer(tmp*1000); } void sysPwrLock(void){ sutApp.pwrLock=1; } void sysPwrRlease(void){ sutApp.pwrLock=0; } //"3132" --> 0x31,0x32 void StrAsciiToHex(char *src, unsigned char *des){ unsigned char temp[2],i; if(strlen(src)%2) return; while(0!=*src) { for(i=0;i<2;i++) { temp[i] = *src++; if(temp[i] >= '0' && temp[i] <= '9') temp[i] -= 0x30; else if(temp[i] >= 'A' && temp[i] <= 'F') temp[i] -= 0x37; else temp[i] -= 0x57; } temp[0] <<= 4; temp[0] &= 0xf0; *des++=temp[0]|temp[1]; } *des=0; } /*调节音量,刷新音量进度条*/ void volAdjAction(char direction){ if(direction==0){ if(newPara.spkVol<10) newPara.spkVol++; else goto FLASH; }else{ if(newPara.spkVol>0) newPara.spkVol--; else goto FLASH; } splVolumeSet(newPara.spkVol*10); MSG_INFO(1,"SPK_VOL:%d",newPara.spkVol*10); sysIniSave(); //刷新进度条 FLASH: volUiFlash(newPara.spkVol); } //////////////////////////////其它处理结束////////////////////////// /////////////////////////////事件发送接口/////////////////////////// void threadSendEvent(nwy_osiThread_t *threadID, uint32 id, uint32 param1,uint32 param2,uint32 param3){ nwy_osiEvent_t pEventSend; pEventSend.id=id; pEventSend.param1=param1; pEventSend.param2=param2; pEventSend.param3=param3; nwy_send_thead_event(threadID, &pEventSend,0); } void ttsPlay(ENCODE_USER_ENUM type, char *tts){ char buf[20]; if(sutApp.skipTTS!=0){ MSG_WARN(1, "TTS is disable by learning task"); return; } MSG_INFO(1, "tts Play:%s",tts); paControl(true); snprintf(buf, sizeof(buf), "AT+HTTS=%d,\"", type); msgAtSend(buf); msgAtSend(tts); msgAtSend("\"\r\n"); sutPocStatus.TTS=1; } static void paProCtl(void){ //会被定时调用 if(sutPocStatus.TTS!=0) return; if(sutPocStatus.spk!=0) return; if(sutPocStatus.TONE!=0) return; if(sutPocStatus.beep!=0) return; if(sutApp.gtMode!=0) return; paControl(false); //MSG_INFO(1,"spk off"); } void splVolumeSet(unsigned char level){ char info[30]; snprintf(info, sizeof(info), "AT+SPK=%d\r\n", level); msgAtSend(info); } /////////////////////////////事件发送结束///////////////////////////