app.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. #include "includes.h"
  2. #define APP_IDLE_TIME 3 //如果POC已休眠,APP没有操作一定秒数后休眠
  3. nwy_osiThread_t *mainThreadPtr=NULL;
  4. int keyNum=0;
  5. APP_DEF sutApp;
  6. static void appDataInit(void){
  7. memset((unsigned char *)&sutApp, 0, sizeof(APP_DEF));
  8. sutApp.pcant=4;//默认免提
  9. appSleepCtl(ASLEEP_POC, 1);
  10. appSleepCtl(ASLEEP_LCD, 1);
  11. readInfoNow();
  12. sysIniRead();
  13. }
  14. void dataInit(void){
  15. appDataInit();
  16. pocDataInit();
  17. gpsDataInit();
  18. uiDataInit();
  19. }
  20. static void ledsProCtl(void){
  21. if(sutApp.gtMode!=0) return;
  22. if(0==sutPocStatus.logined) uioStatusSet(UIO_INDOFFLINE);
  23. else if(sutPocStatus.spk>0)uioStatusSet(UIO_INDRX);
  24. else if(sutPocStatus.mic>0 )uioStatusSet(UIO_INDTX);
  25. else uioStatusSet(UIO_INDONLINE);
  26. }
  27. static void adcRead(void);
  28. char isKeyPress(void){
  29. if(keyNum) return keyNum--;
  30. else return 0;
  31. }
  32. static void subTimerCtl(unsigned char sleep_or_not);
  33. /*APP休眠处理接口
  34. ctlType, 操作对象
  35. status,操作值,0 清除 else 设置
  36. */
  37. void appSleepCtl(ASLEEP_ENUM ctlType, char status){
  38. if(status==0) sutApp.appSleepStatus &= ~(1<<ctlType);
  39. else sutApp.appSleepStatus |= 1<<ctlType;
  40. }
  41. /*APP休眠状态接口*/
  42. char isAppSleepReady(void){
  43. if(sutApp.appSleepStatus==0) return 1;
  44. else return 0;
  45. }
  46. /*获取指定休眠控制成员锁定的状态
  47. 0 未锁定 否则锁定,锁定即可以休眠
  48. */
  49. char getAppObjStatus(ASLEEP_ENUM ctlType){
  50. if(sutApp.appSleepStatus & (1<<ctlType)) return 1;
  51. else return 0;
  52. }
  53. /*检测是否APP可以休眠操作*/
  54. char isSleepReady(void){
  55. static unsigned int idleCnt=0;
  56. #ifdef DISABLE_SLEEP
  57. return 0;//不休眠
  58. #endif
  59. if(isAppSleepReady()==0){
  60. idleCnt=0;
  61. return 0;
  62. }
  63. if(++idleCnt>=(APP_IDLE_TIME*1000/APP_SUB_DIV_TIME)){
  64. idleCnt=0;
  65. return 1;
  66. }else return 0;
  67. }
  68. /*处理UI操作*/
  69. static void uiProcess(unsigned int exeInterval){
  70. if(getAppObjStatus(ASLEEP_PWR) != 0) return;//关机后,不切换菜单,只显示关机页面
  71. //if(sutApp.gtTMode!=0) return;//GT模式后按键无效
  72. uiLoop(exeInterval);
  73. uiResponse(exeInterval);
  74. }
  75. static void pwrKeyDetect(unsigned int exeInterval){
  76. static char pressed=0;
  77. static int kcnt=0,cnt=0;
  78. if(sutApp.pwrKeyStatus==0){//按下了
  79. appSleepCtl(ASLEEP_PWRKEY, 1);
  80. if(pressed==0){
  81. kcnt=1;
  82. pressed=1;
  83. cnt=0;
  84. }
  85. if(++cnt>=(1000/exeInterval)){
  86. cnt=0;
  87. if(++kcnt>=3){
  88. backLightReset();
  89. if(sutApp.activePwrShut==0){
  90. sutApp.activePwrShut=1;
  91. uISetNextStatus(UIS_MENU_SHUT_UI);
  92. }
  93. }
  94. }
  95. }else{//放开了
  96. if(kcnt==1){//短按
  97. keyToneStart();
  98. switch(sutUIstatus.Status){
  99. case UIS_STANDBY:switchBackLight();break;//切换背光
  100. case UIS_MENU_TASK_SEL:taskSelBackToStandby(false);break;
  101. case UIS_MENU_TASK_QUERY:taskBackToStandby();break;
  102. case UIS_MENU_RANK_SEL:rankSelBackToStandby();break;
  103. case UIS_MENU_RANK_DETAIL:rankBackToStandby();break;
  104. case UIS_MENU_CLASS_SEL:
  105. case UIS_MENU_STUDENT_SEL:
  106. GUBackToStandby();break;
  107. case UIS_MENU_LOCATION_CLASS:classBackToStandby();break;
  108. case UIS_MENU_LOCATION_NOTICE:noticeBackToStandby();break;
  109. case UIS_MENU_LOCATION_NOTICE_DETAIL:noticeDetailBackToStandby();break;
  110. case UIS_MENU_SHUT_UI:break;
  111. default:uISetNextStatus(UIS_STANDBY);break;
  112. }
  113. }
  114. pressed=0;
  115. kcnt=0;
  116. if(sutApp.activePwrShut==0) appSleepCtl(ASLEEP_PWRKEY, 0);
  117. }
  118. }
  119. static void antModePwrDet(void){
  120. static int kcnt=0;
  121. if(sutApp.pwrKeyStatus==0){
  122. if(++kcnt==3){
  123. guiShowMessageBox("正在关机");
  124. msgAtSend("AT+TRB=2\r\n");
  125. nwy_sleep(1000);
  126. CTL_LCD_BL(0);
  127. CTL_POWER_HOLD(0);
  128. }
  129. }else kcnt=0;
  130. }
  131. void uiShowShutOption(char update){
  132. if(update){
  133. guiClearAll(guiGetBackColor());
  134. guiShowCaption(0,"关机",UI_STATUS_ITEM_Y+1,guiGetBackColor(),guiGetForeColor(),FONT_MODE_12X12);
  135. guiShowMessageBox("确定关机?");
  136. uiMenuShowBottomLine();
  137. uiMenuShowBottomIndacitor("确定", "取消");
  138. return;
  139. }
  140. }
  141. void uiShowShutOptionResponse(void){
  142. switch(getKeyValue()){
  143. case MKEY_VALUE_MENU:
  144. appSleepCtl(ASLEEP_PWR, 1);
  145. uISetNextStatus(UIS_STANDBY);
  146. break;
  147. case MKEY_VALUE_ESC:
  148. sutApp.activePwrShut=0;
  149. uISetNextStatus(UIS_STANDBY);
  150. break;
  151. }
  152. }
  153. /*触发关机操作*/
  154. static void pwrShutPro(unsigned int exeInterval){
  155. static char shutFlag=0;
  156. pwrKeyDetect(exeInterval);
  157. if(getAppObjStatus(ASLEEP_PWR) == 0) return;
  158. CTL_LCD_BL(1);
  159. msgAtSend("AT+POC=050000\r\n");
  160. msgAtSend("AT+CFUN=0\r\n");
  161. if(shutFlag==0){
  162. //显示关机界面
  163. guiShowMessageBox("正在关机");
  164. shutFlag=1;
  165. nwy_sleep(1000);
  166. }
  167. MSG_INFO(1, "Normal PwrOff");
  168. //msgAtSend("AT+TRB=1\r\n");//normal power off 当前固件先不发模块关机指令,否则断电再上电有可能是起不来的
  169. nwy_sleep(1000);//一秒后释放电源锁,防止软关机不成功
  170. CTL_LCD_BL(0);
  171. MSG_INFO(1, "Release pwr");
  172. guiFillRect(0,0,GLCD_WIDTH-1,GLCD_HEIGHT-1,guiGetBackColor());//防止下次开机能看到残留
  173. CTL_POWER_HOLD(0);
  174. nwy_sleep(100);
  175. msgAtSend("AT+TRB=2\r\n");//软件复位模块
  176. }
  177. void AntModeRun(void){
  178. #ifdef ENABLE_ANT_MODE
  179. guiShowMessageBox("调天线模式");
  180. for(;;){
  181. nwy_sleep(2000);
  182. }
  183. #endif
  184. }
  185. void lcdReConfig(void){
  186. if(sutApp.lcdReconfigCnt<=3) sutApp.lcdReconfigCnt++;
  187. if(sutApp.lcdReconfigCnt==3) recoverLightColor();
  188. }
  189. static void paProCtl(void);
  190. /*主要应用程序入口*/
  191. void appRun(void){
  192. char cnt=0;
  193. nwy_osiEvent_t event = {};
  194. //等待lcd初始化完成
  195. MSG_INFO(1, "wait lcd init");
  196. while(sutApp.guiStatus==0){nwy_sleep(50);}//是否检测超时?
  197. AntModeRun();
  198. localAuthNow();
  199. //等待poc启动完成
  200. MSG_INFO(1, "lcd init done, wait poc start");
  201. while(sutApp.pocInitStatus==0){
  202. msgAtSend("AT\r\n");
  203. nwy_sleep(50);
  204. }//是否检测超时?
  205. MSG_INFO(1, "app loop start");
  206. //设置EQ数据
  207. modifyEqData();
  208. //修改音频输出增益配置
  209. modifyAudioOutGainConfig();
  210. //设置一下TTS
  211. msgAtSend("AT+HTTSSPEED=1284,-20000\r\n");//设置TTS音量
  212. msgAtSend("AT+HTTSSPEED=1282,-5000\r\n");//设置TTS语速
  213. //查询一下POC版本号
  214. msgAtSend("AT+POC_VER\r\n");
  215. msgAtSend("AT+GMR\r\n");//查询模块版本
  216. msgAtSend("AT+MIC=6\r\n");
  217. #ifdef ENABLE_PTT_VOICE
  218. msgAtSend("AT+VSW=1\r\n");//打开留音功能
  219. #endif
  220. //msgAtSend("AT+CACCP=0,1,0,\"04000B00\"\r\n");
  221. #ifndef ENABLE_PWM_BEEP
  222. if(newPara.KeySound!=0) msgAtSend("AT+TONES=1\r\n");
  223. #endif
  224. splVolumeSet(newPara.spkVol*10);
  225. backLightReset();
  226. if(newPara.ttsMessage[0]!=0){
  227. if(newPara.ttsCodeType==0) ttsPlay(ENCODE_USER_UNICODE_BE, newPara.ttsMessage);
  228. else if(newPara.ttsCodeType==1) ttsPlay(ENCODE_USER_GBK, newPara.ttsMessage);
  229. else MSG_INFO(1, "ttsCodeType:%d not support", newPara.ttsCodeType);
  230. }else MSG_INFO(1, "tts null");
  231. //检测卡是否存在
  232. while(sutApp.cardStatus==0){
  233. msgAtSend("AT+CPIN?\r\n");
  234. nwy_sleep(1000);
  235. if(++cnt>=5){
  236. MSG_INFO(1, "Check card timeout");
  237. break;
  238. }
  239. }
  240. for(;;){
  241. if(sutApp.antMode){
  242. msgAtSend("AT+POC=050000\r\n");
  243. cnt=0;
  244. break;
  245. }
  246. lcdReConfig();
  247. ledsProCtl();
  248. adcRead();
  249. uiProcess(APP_SUB_DIV_TIME);
  250. gpsProCtl(APP_SUB_DIV_TIME);
  251. pocProCtl(APP_SUB_DIV_TIME);
  252. HookGroupUserInfo();
  253. HookVolToutCheck();
  254. LearnUsrInfoCheck(APP_SUB_DIV_TIME);
  255. IncomingSMS();
  256. if(isSleepReady()==0) nwy_sleep(APP_TASK_SLEEP_TIME);
  257. else if(sutApp.gtMode==0){//正常模式下可以休眠
  258. MSG_WARN(1, "APP SLEEP");
  259. stopKeyTimer();
  260. subTimerCtl(1);//切换为休眠状态定时器
  261. sutApp.appStatus=1;
  262. CTL_LED2_GREEN(0);
  263. CTL_LED1_RED(0);
  264. #ifdef ENABLE_DEEP_SLEEP
  265. pwmDeInitToSleep();
  266. lcdDrvPowerCtl(false);
  267. nwy_pm_state_set(NWY_ENTRY_SLEEP);
  268. #endif
  269. nwy_wait_thead_event(nwy_get_current_thread(), &event,0);
  270. lcdDrv_Init(1);//深度休眠唤醒后重新初始化SPI-LCD
  271. sutApp.appStatus=0;
  272. subTimerCtl(0);//切换为唤醒状态定时器
  273. MSG_WARN(1, "APP WAKEUP");
  274. }
  275. //检测是否关机,这里要放在唤醒后操作
  276. pwrShutPro(APP_SUB_DIV_TIME);
  277. }
  278. //检测是否关机了
  279. for(;;){
  280. antModePwrDet();
  281. nwy_sleep(900);
  282. }
  283. }
  284. //////////////////////////////////////用于处理非耗时操作,如LED///////////////////////
  285. nwy_osiTimer_t *pSubtimer_t = NULL;
  286. unsigned int subTimerInterval=100;//定时器定时的时间
  287. static void subTimeroutcallback(void *param){
  288. unsigned int *dlyTime=(unsigned int *)param;
  289. //处理灯的显示
  290. uioProctl(*dlyTime);
  291. //控制功放的关闭
  292. paProCtl();
  293. }
  294. /*创建定时器*/
  295. void subTask(void *param){
  296. nwy_osiEvent_t event = {};
  297. if(NULL == pSubtimer_t) pSubtimer_t = nwy_timer_init(nwy_get_current_thread(), subTimeroutcallback, (void *)&subTimerInterval);
  298. if(NULL == pSubtimer_t) MSG_WARN(1,"sub timer init failed");
  299. else nwy_start_timer_periodic(pSubtimer_t,subTimerInterval);
  300. for(;;){nwy_wait_thead_event(nwy_get_current_thread(), &event,0);}
  301. }
  302. /*
  303. 为了做低功耗,此定时器在休眠时,设置为长时间定时
  304. 非休眠时,设置为短时间定时
  305. sleep_or_not:0 未休眠, else 休眠
  306. */
  307. static void subTimerCtl(unsigned char sleep_or_not){
  308. if(NULL==pSubtimer_t){
  309. MSG_WARN(1, "subTimer null");
  310. return;
  311. }
  312. nwy_stop_timer(pSubtimer_t);
  313. //打开定时器
  314. if(sleep_or_not==0) subTimerInterval=100;//未休眠时,100ms
  315. else subTimerInterval=5000;//休眠时 5000ms
  316. nwy_start_timer_periodic(pSubtimer_t,subTimerInterval);
  317. }
  318. //////////////////////////////////////////////////////////////////////////////////////
  319. void usbCmdHandler(const char *data,uint32 length){
  320. static char buf[256];
  321. static int len=0;
  322. static char lach;
  323. char ch;
  324. int i;
  325. if(sutApp.authReady==0){
  326. authRecvPro(data, length);
  327. return;
  328. }
  329. for(i=0;i<length;i++){
  330. ch=data[i];
  331. if(len<sizeof(buf)-1) buf[len++]=ch;
  332. else{
  333. MSG_WARN(1, "USB Buf Over");
  334. len=0;
  335. buf[len++]=ch;
  336. }
  337. if(lach=='\r' && ch=='\n'){
  338. buf[len]=0;
  339. cmdSetting(buf);
  340. len=0;
  341. }
  342. lach=ch;
  343. }
  344. }
  345. //////////////////////////////按键处理接口//////////////////////////
  346. //普通按键处理
  347. unsigned char singleKeyInArow=0;
  348. void keyCheck(unsigned short keyStatus){//定时被调用
  349. static unsigned short lkey=0;
  350. static unsigned char keyCtl=0,keyCnt=0;
  351. unsigned char keyType,needSendKey=0;
  352. if(keyStatus==KS_ALL_IDLE){
  353. keyType=0;
  354. if(keyCtl==1){
  355. keyCtl=0;
  356. needSendKey=1;
  357. }
  358. }else{
  359. keyType=1;
  360. if(lkey != keyStatus) keyCtl=0;//值变化
  361. if(keyCtl==0){
  362. lkey=keyStatus;
  363. keyCtl=1;
  364. keyCnt=0;
  365. needSendKey=1;
  366. }else if(singleKeyInArow!=0){//是否输出持续值
  367. if(++keyCnt>=(1000/KEY_TIMER_TICK)){//每秒产生持续值
  368. keyCnt=0;
  369. needSendKey=1;
  370. }
  371. }
  372. }
  373. if(needSendKey){
  374. if(sutApp.enableKey!=0)//延时期间不检测按键
  375. threadSendEvent(nwy_get_current_thread(),OHPOC_EVENT_KEY_NOR, lkey,keyType,NULL);
  376. }
  377. }
  378. static char micPttPressed=0;
  379. static char pttPressed=0;
  380. static void pttHandler(char type, char ctl){
  381. char needSend=0;
  382. char mic_spk;
  383. if(type==0){//ptt
  384. if(ctl==0){//放开
  385. if(micPttPressed==0){
  386. needSend=1;mic_spk=0;
  387. }
  388. pttPressed=0;
  389. }else{//按下
  390. if(pttPressed==0 && micPttPressed==0){
  391. needSend=1;mic_spk=1;
  392. }
  393. pttPressed=1;
  394. }
  395. }else{//mic ptt
  396. if(ctl==0){//放开
  397. if(pttPressed==0){
  398. needSend=1;mic_spk=0;
  399. }
  400. micPttPressed=0;
  401. }else{//按下
  402. if(pttPressed==0 && micPttPressed==0){
  403. needSend=1;mic_spk=1;
  404. }
  405. micPttPressed=1;
  406. }
  407. }
  408. if(isLearnBusy()==true){
  409. MSG_WARN(1, "Learn task is busy, skip ptt");
  410. return;//学习任务正在使用音频,POC不录音
  411. }
  412. if(needSend!=0){
  413. if(mic_spk==0) msgAtSend("AT+POC=0C0000\r\n");
  414. else msgAtSend("AT+POC=0B0000\r\n");
  415. }
  416. }
  417. /*打印键信息*/
  418. const char freeSeg[]="Free";
  419. const char pressSeg[]="Press";
  420. void showKeyMessage(unsigned short key,unsigned char status){
  421. char buf[50]="[Key_";
  422. switch(key){
  423. case KV_KEY_MIC_PTT: strcat(buf, "MIC_PTT]");break;
  424. default:return;
  425. }
  426. if(status==0) strcat(buf, freeSeg);
  427. else strcat(buf, pressSeg);
  428. MSG_INFO(1,buf);
  429. }
  430. void keyHandler(unsigned short key,unsigned char status){//普通按键值处理
  431. tryWakeupApp();//有普通键按下或放开,唤醒休眠的系统
  432. showKeyMessage(key,status);
  433. if(status==0){//key free
  434. switch(key){
  435. case KV_KEY_MIC_PTT:
  436. pttHandler(1,0);
  437. break;
  438. default:
  439. break;
  440. }
  441. singleKeyInArow=0;
  442. appSleepCtl(ASLEEP_KEY, 0);
  443. }else{//key press
  444. appSleepCtl(ASLEEP_KEY, 1);
  445. backLightReset();
  446. if(sutApp.keyLock!=0){
  447. sutApp.lockShow=1;
  448. return;
  449. }
  450. switch(key){
  451. case KV_KEY_MIC_PTT:
  452. singleKeyInArow=1;
  453. pttHandler(1,1);
  454. break;
  455. default:
  456. break;
  457. }
  458. }
  459. }
  460. //扫描矩阵按键
  461. #define MATRIX_KEY_NUMS 2 //最多检测同时两个组合键
  462. void keyStatusCtlAll(char high_low){
  463. CTL_KEY_OUT1(high_low);
  464. CTL_KEY_OUT2(high_low);
  465. CTL_KEY_OUT3(high_low);
  466. }
  467. void keyStatusCtlOne(char outIndex){
  468. switch(outIndex){
  469. case 0:CTL_KEY_OUT1(0);
  470. CTL_KEY_OUT2(1);
  471. CTL_KEY_OUT3(1);
  472. break;
  473. case 1:CTL_KEY_OUT2(0);
  474. CTL_KEY_OUT1(1);
  475. CTL_KEY_OUT3(1);
  476. break;
  477. case 2:CTL_KEY_OUT3(0);
  478. CTL_KEY_OUT2(1);
  479. CTL_KEY_OUT1(1);
  480. break;
  481. }
  482. }
  483. int keyStatusGetOne(char outIndex){
  484. int ret=2;
  485. switch(outIndex){
  486. case 0:ret=INT_KEY_IN1();break;
  487. case 1:ret=INT_KEY_IN2();break;
  488. case 2:ret=INT_KEY_IN3();break;
  489. }
  490. return ret;
  491. }
  492. unsigned short matrixGetKey(unsigned char out, unsigned char in){
  493. unsigned short vlaue=0;
  494. if(out >= MKS_KEY_OUS || in >=MKS_KEY_INS) return 0xffff;
  495. switch(in){
  496. case 0:
  497. switch(out){
  498. case 0:vlaue |= (1<<MKEY_VALUE_1);break;
  499. case 1:vlaue |= (1<<MKEY_VALUE_2);break;
  500. case 2:vlaue |= (1<<MKEY_VALUE_3);break;
  501. default:vlaue=0xffff;break;
  502. }
  503. break;
  504. case 1:
  505. switch(out){
  506. case 0:vlaue |= (1<<MKEY_VALUE_4);break;
  507. case 1:vlaue |= (1<<MKEY_VALUE_5);break;
  508. case 2:vlaue |= (1<<MKEY_VALUE_6);break;
  509. default:vlaue=0xffff;break;
  510. }
  511. break;
  512. case 2:
  513. switch(out){
  514. case 0:vlaue |= (1<<MKEY_VALUE_7);break;
  515. case 1:vlaue |= (1<<MKEY_VALUE_8);break;
  516. case 2:vlaue |= (1<<MKEY_VALUE_9);break;
  517. default:vlaue=0xffff;break;
  518. }
  519. break;
  520. default:vlaue=0xffff;break;
  521. }
  522. return vlaue;
  523. }
  524. /*进入GT模式*/
  525. static void enterGTMode(void){
  526. if(sutApp.gtMode!=0) return;
  527. #ifndef ENABLE_PWM_BEEP
  528. msgAtSend("AT+TONES=1\r\n");
  529. #endif
  530. sutApp.gtMode=1;
  531. uioStatusSet(UIO_INDGT);
  532. paControl(true);//GT下常开喇叭
  533. #ifdef ENABLE_PWM_BEEP
  534. beepStart(TONE_SPECIAL);
  535. nwy_sleep(50);
  536. beepStart(TONE_NORMAL);
  537. nwy_sleep(50);
  538. beepStart(TONE_SPECIAL);
  539. #else
  540. msgAtSend("AT+TONE\r\n");
  541. nwy_sleep(200);
  542. msgAtSend("AT+TONE\r\n");
  543. #endif
  544. MSG_WARN(1, "Enter GT Mode");
  545. guiShowMessageBox("GT模式");
  546. }
  547. static unsigned short g_usKeyValue=0;
  548. unsigned short getKeyValue(void){return g_usKeyValue;}
  549. unsigned char keyInArow=0;//键值是否持续产生
  550. void mKeyCheck(void){//定时被调用
  551. unsigned char matrix[MATRIX_KEY_NUMS][2],num;
  552. unsigned char in,out,i,j,update;
  553. int value;
  554. unsigned short keys[MATRIX_KEY_NUMS];
  555. static unsigned short finalKey=0;
  556. unsigned short tKey;
  557. static unsigned char keyCtl=0;
  558. static unsigned char keyCnt=0;
  559. unsigned char needSendKey=0;
  560. for(i=0;i<MATRIX_KEY_NUMS;i++){
  561. for(j=0;j<2;j++) matrix[i][j]=0xff;
  562. }
  563. num=0;
  564. for(out=0;out<MKS_KEY_OUS;out++){
  565. keyStatusCtlOne(out);
  566. for(in=0;in<MKS_KEY_INS;in++){
  567. if(keyStatusGetOne(in)==0){
  568. matrix[num][0]=out;
  569. matrix[num][1]=in;
  570. if(++num>=MATRIX_KEY_NUMS) goto MATRIX_END;
  571. }
  572. }
  573. }
  574. MATRIX_END:
  575. keyStatusCtlAll(0);
  576. if(num==0){//无键按下
  577. goto MKEY_NO_KEY;
  578. }
  579. for(int w=0;w<num;w++)
  580. //检测值
  581. for(i=0;i<MATRIX_KEY_NUMS;i++) keys[i]=matrixGetKey(matrix[i][0],matrix[i][1]);
  582. tKey=0;
  583. for(i=0;i<MATRIX_KEY_NUMS;i++){
  584. if(keys[i]!=0xffff) tKey |= keys[i];
  585. }
  586. needSendKey=0;
  587. //得出键值
  588. if(tKey==MKEY_VALUE_IDLE){//无键按键
  589. MKEY_NO_KEY:
  590. if(keyCtl==1){
  591. keyCtl=0;
  592. needSendKey=1;
  593. }
  594. }else{//有键按下
  595. if(tKey != g_usKeyValue) keyCtl=0;//值变化
  596. if(keyCtl==0){
  597. g_usKeyValue=tKey;
  598. keyCtl=1;
  599. keyCnt=0;
  600. needSendKey=1;
  601. }else if(keyInArow!=0){//是否输出持续值
  602. if(++keyCnt>=(1000/KEY_TIMER_TICK)){//每秒产生持续值
  603. keyCnt=0;
  604. needSendKey=1;
  605. }
  606. }
  607. }
  608. if(needSendKey){
  609. if(sutApp.enableKey!=0)
  610. threadSendEvent(nwy_get_current_thread(),OHPOC_EVENT_KEY_MAT, keyCtl,NULL,NULL);
  611. }
  612. }
  613. void showKeyMsg(char *info, unsigned char keyCtl){
  614. char buf[40];
  615. char *ctl;
  616. if(keyCtl==0) ctl=freeSeg;
  617. else ctl=pressSeg;
  618. snprintf(buf, sizeof(buf),"[Key %s]%s",ctl,info);
  619. MSG_INFO(1, buf);
  620. }
  621. static void lockProcess(void){
  622. if(sutApp.keyLock==0){
  623. if(sutApp.activePwrShut!=0) return;//触发了关机界面时,不能加锁键盘
  624. sutApp.keyLock=1;
  625. appSleepCtl(ASLEEP_GGROUP, 0);
  626. appSleepCtl(ASLEEP_GUSER, 0);
  627. if(sutUIstatus.Status==UIS_STANDBY) guiShowBmp(72,110, "lock.bmp");//锁关/锁开触发时更新状态
  628. uISetNextStatus(UIS_STANDBY);
  629. }else{
  630. sutApp.keyLock=0;
  631. sutApp.lockShow=0;
  632. if(sutUIstatus.Status==UIS_STANDBY) guiClearRect(72,110,72+17,110+17,guiGetBackColor());//锁关/锁开触发时更新状态
  633. }
  634. }
  635. void keyToneStart(void){
  636. if(newPara.KeySound==0) return;
  637. #ifdef ENABLE_PWM_BEEP
  638. beepStart(TONE_NORMAL);
  639. #else
  640. msgAtSend("AT+TONE\r\n");
  641. #endif
  642. }
  643. void quickUiSwitch(int uistatus){
  644. if(sutApp.activePwrShut!=0) return;//触发了关机界面时,快捷键无效
  645. if(sutApp.keyLock!=0) return;//锁了后,快捷键无效
  646. if(true==isUiSwitchReady()) return;
  647. uISetNextStatus(uistatus);
  648. getStackStruct()->FastUiChange=1;
  649. }
  650. void mKeyHandler(unsigned char keyCtl){
  651. static unsigned char gtModeCnt=0;
  652. static unsigned char lockCnt=0;
  653. static unsigned char f1Cnt=0;
  654. static unsigned char f2Cnt=0;
  655. char lock_but_enable_key=0;//锁键盘后,也能够关机
  656. if(sutUIstatus.Status==UIS_MENU_SHUT_UI &&
  657. (MKEY_VALUE_MENU==g_usKeyValue || MKEY_VALUE_ESC==g_usKeyValue)) lock_but_enable_key=1;
  658. if(sutApp.keyLock!=0 && MKEY_VALUE_PTT!=g_usKeyValue && MKEY_VALUE_P1!=g_usKeyValue && lock_but_enable_key==0){
  659. sutApp.lockShow=1;
  660. return;
  661. }
  662. if(keyCtl==0){//释放
  663. switch(g_usKeyValue){
  664. case MKEY_VALUE_PTT:showKeyMsg("PTT",keyCtl);
  665. pttHandler(0,0);
  666. break;
  667. case MKEY_VALUE_P1:showKeyMsg("P1",keyCtl);
  668. if(lockCnt==1){
  669. switch(sutUIstatus.Status){
  670. case UIS_MENU_TASK_SEL:
  671. case UIS_MENU_RANK_SEL:
  672. case UIS_MENU_TASK_QUERY:
  673. case UIS_MENU_RANK_DETAIL:
  674. case UIS_MENU_LOCATION_CLASS:
  675. case UIS_MENU_LOCATION_NOTICE:
  676. case UIS_MENU_LOCATION_NOTICE_DETAIL:
  677. break;
  678. default:quickUiSwitch(UIS_MENU_TASK_SEL);
  679. }
  680. }
  681. lockCnt=0;
  682. break;
  683. case MKEY_VALUE_P2:showKeyMsg("P2",keyCtl);
  684. break;
  685. case MKEY_VALUE_MENU:showKeyMsg("MENU",keyCtl);
  686. break;
  687. case MKEY_VALUE_ESC:showKeyMsg("ESC",keyCtl);
  688. break;
  689. case MKEY_VALUE_UP:showKeyMsg("UP",keyCtl);
  690. break;
  691. case MKEY_VALUE_DOWN:showKeyMsg("DOWN",keyCtl);
  692. break;
  693. case MKEY_VALUE_F1:showKeyMsg("F1",keyCtl);
  694. if(f1Cnt==1) volAdjAction(0);
  695. f1Cnt=0;
  696. break;
  697. case MKEY_VALUE_F2:showKeyMsg("F2",keyCtl);
  698. if(f2Cnt==1) volAdjAction(1);
  699. f2Cnt=0;
  700. break;
  701. case MKEY_VALUE_CB_GT:showKeyMsg("CB_GT",keyCtl);
  702. gtModeCnt=0;
  703. break;
  704. case MKEY_VALUE_CB_IP:showKeyMsg("CB_IP",keyCtl);
  705. break;
  706. default:MSG_WARN(1,"UnHande Key:%d Free",g_usKeyValue);
  707. break;
  708. }
  709. keyInArow=0;
  710. appSleepCtl(ASLEEP_MKEY, 0);
  711. }else{//按下
  712. if(g_usKeyValue!=MKEY_VALUE_PTT && g_usKeyValue!=MKEY_VALUE_CB_GT) keyToneStart();
  713. backLightReset();
  714. appSleepCtl(ASLEEP_MKEY, 1);
  715. keyNum++;
  716. switch(g_usKeyValue){
  717. case MKEY_VALUE_PTT:showKeyMsg("PTT",keyCtl);
  718. pttHandler(0,1);
  719. break;
  720. case MKEY_VALUE_P1:showKeyMsg("P1",keyCtl);
  721. keyInArow=1;
  722. if(++lockCnt==3) lockProcess();
  723. break;
  724. case MKEY_VALUE_P2:showKeyMsg("P2",keyCtl);
  725. break;
  726. case MKEY_VALUE_MENU:showKeyMsg("MENU",keyCtl);
  727. break;
  728. case MKEY_VALUE_ESC:showKeyMsg("ESC",keyCtl);
  729. break;
  730. case MKEY_VALUE_UP:showKeyMsg("UP",keyCtl);
  731. break;
  732. case MKEY_VALUE_DOWN:showKeyMsg("DOWN",keyCtl);
  733. break;
  734. case MKEY_VALUE_F1:showKeyMsg("F1",keyCtl);
  735. keyInArow=1;
  736. if(++f1Cnt==3) quickUiSwitch(UIS_MENU_CLASS_SEL);
  737. break;
  738. case MKEY_VALUE_F2:showKeyMsg("F2",keyCtl);
  739. keyInArow=1;
  740. if(++f2Cnt==3) quickUiSwitch(UIS_MENU_STUDENT_SEL);
  741. break;
  742. case MKEY_VALUE_CB_GT:showKeyMsg("CB_GT",keyCtl);
  743. keyInArow=1;
  744. if(++gtModeCnt==3){
  745. if(sutApp.gtMode==0){
  746. enterGTMode();
  747. }
  748. }
  749. break;
  750. case MKEY_VALUE_CB_IP:
  751. keyInArow=1;
  752. showKeyMsg("CB_IP",keyCtl);
  753. break;
  754. default:MSG_WARN(1,"UnHande Key:%d Press",g_usKeyValue);
  755. break;
  756. }
  757. }
  758. }
  759. //////////////////////////////按键处理结束//////////////////////////
  760. //////////////////////////////其它处理接口//////////////////////////
  761. void hpDetStatusChanged(unsigned char hpStatus){
  762. if(0==hpStatus){
  763. MSG_WARN(1,"HP plug in");
  764. }else{
  765. MSG_WARN(1,"HP plug out");
  766. }
  767. }
  768. //测试主板ADC为:150~1190范围
  769. //实际使用ADC取:170~1210范围
  770. /*输入adc值,输出音量等级*/
  771. #define VOL_LEV_NUM 11 //档位数
  772. #define VOL_LEV_DEF 10 //抖动上下限
  773. unsigned char wisdomAdcProcess(int adcValueTmp){
  774. const unsigned short volAdcTable[VOL_LEV_NUM]={170,200,240,300,400,500,700,900,1100,1140,1170};//中间ADC变化快,两端ADC变化慢
  775. int i;
  776. static unsigned char ucVolLev=0;
  777. for(i=0;i<VOL_LEV_NUM;i++){
  778. if(ucVolLev==0){
  779. if(adcValueTmp >= volAdcTable[ucVolLev]+VOL_LEV_DEF) ucVolLev++;
  780. }else if(ucVolLev<VOL_LEV_NUM-1){
  781. if(adcValueTmp >= volAdcTable[ucVolLev]+VOL_LEV_DEF) ucVolLev++;
  782. else if(adcValueTmp < volAdcTable[ucVolLev-1]-VOL_LEV_DEF) ucVolLev--;
  783. }else{
  784. if(ucVolLev==VOL_LEV_NUM-1) if(adcValueTmp < volAdcTable[ucVolLev-1]-VOL_LEV_DEF) ucVolLev--;
  785. }
  786. }
  787. return ucVolLev;
  788. }
  789. static void adcRead(void){
  790. #define VBAT_READ_TIME 20
  791. int adcValueTmp;
  792. static int siVbat=0;
  793. static int laSiVbat;
  794. static unsigned char index=0;
  795. int x=(GLCD_WIDTH-16)/2;
  796. int y=GLCD_HEIGHT-12;
  797. //检测音量旋钮电压
  798. adcValueTmp=nwy_adc_get(NWY_ADC_CHANNEL3, NWY_ADC_SCALE_1V250);
  799. if(adcValueTmp>0){//15 1227
  800. if(sutUIstatus.Status==UIS_STANDBY){
  801. if(adcValueTmp > 1000){
  802. if(sutApp.earStatus==0){
  803. sutApp.pcant=2;//FM
  804. sutApp.earStatus=1;
  805. MSG_INFO(1, "FM MODE");
  806. guiShowBmp(x, y, "ear.bmp");
  807. }
  808. }else{
  809. if(sutApp.earStatus!=0){
  810. sutApp.pcant=4;//mianti
  811. sutApp.earStatus=0;
  812. MSG_INFO(1, "MIANTI MODE");
  813. guiClearRect(x, y, x+16,y+12, guiGetBackColor());
  814. }
  815. }
  816. }else if(sutApp.earStatus != 0) sutApp.earStatus=0;//切到其它菜单后再切回来还能显示
  817. }
  818. //检测电池电压
  819. adcValueTmp=nwy_adc_get(NWY_ADC_CHANNEL4, NWY_ADC_SCALE_5V000);
  820. siVbat += adcValueTmp;
  821. if(++index>=VBAT_READ_TIME){
  822. sutApp.g_iBAT=siVbat / VBAT_READ_TIME / 10;
  823. if(laSiVbat!=sutApp.g_iBAT){
  824. //MSG_INFO(1, "bat:%d", sutApp.g_iBAT);
  825. laSiVbat=sutApp.g_iBAT;
  826. }
  827. siVbat=0;
  828. index=0;
  829. }
  830. }
  831. void tryWakeupApp(void){
  832. if(sutApp.appStatus!=0){
  833. sutApp.appStatus=0;
  834. if(mainThreadPtr!=NULL){
  835. sutApp.lcdReconfigCnt=0;
  836. #ifdef ENABLE_DEEP_SLEEP
  837. nwy_pm_state_set(NWY_WAKEUP);
  838. #endif
  839. threadSendEvent(mainThreadPtr,OHPOC_EVENT_MAIN,NULL,NULL,NULL);
  840. }
  841. }
  842. }
  843. bool backlightstatus=true;
  844. /*背光时间到,熄灭*/
  845. void backLightCb(void *param){
  846. if(sutApp.gtMode!=0){
  847. CTL_LCD_BL(1);backlightstatus=true;
  848. return;
  849. }
  850. if(sutPocStatus.firstLogin==0) return;//未登录过,不灭屏
  851. if(newPara.lcdParaList[newPara.lcdParaDefaultIndex]==0) return;//常亮
  852. CTL_LCD_BL(0);backlightstatus=false;
  853. appSleepCtl(ASLEEP_LCD, 0);//可以休眠
  854. }
  855. /*点亮背光*/
  856. void backLightReset(void){
  857. unsigned short tmp;
  858. appSleepCtl(ASLEEP_LCD, 1);//不让休眠
  859. tmp=newPara.lcdParaList[newPara.lcdParaDefaultIndex];
  860. CTL_LCD_BL(1);backlightstatus=true;
  861. startBackLightTimer(tmp*1000);
  862. }
  863. void switchBackLight(void){
  864. if(backlightstatus==true){
  865. if(newPara.lcdParaList[newPara.lcdParaDefaultIndex]==0) return;//常亮
  866. CTL_LCD_BL(0);backlightstatus=false;
  867. appSleepCtl(ASLEEP_LCD, 0);//可以休眠
  868. }else backLightReset();
  869. }
  870. void sysPwrLock(void){
  871. sutApp.pwrLock=1;
  872. }
  873. void sysPwrRlease(void){
  874. sutApp.pwrLock=0;
  875. }
  876. //"3132" --> 0x31,0x32
  877. void StrAsciiToHex(char *src, unsigned char *des){
  878. unsigned char temp[2],i;
  879. if(strlen(src)%2) return;
  880. while(0!=*src)
  881. {
  882. for(i=0;i<2;i++)
  883. {
  884. temp[i] = *src++;
  885. if(temp[i] >= '0' && temp[i] <= '9') temp[i] -= 0x30;
  886. else if(temp[i] >= 'A' && temp[i] <= 'F') temp[i] -= 0x37;
  887. else temp[i] -= 0x57;
  888. }
  889. temp[0] <<= 4;
  890. temp[0] &= 0xf0;
  891. *des++=temp[0]|temp[1];
  892. }
  893. *des=0;
  894. }
  895. /*调节音量,刷新音量进度条*/
  896. void volAdjAction(char direction){
  897. if(direction==0){
  898. if(newPara.spkVol<10) newPara.spkVol++;
  899. else goto FLASH;
  900. }else{
  901. if(newPara.spkVol>0) newPara.spkVol--;
  902. else goto FLASH;
  903. }
  904. splVolumeSet(newPara.spkVol*10);
  905. MSG_INFO(1,"SPK_VOL:%d",newPara.spkVol*10);
  906. sysIniSave();
  907. //刷新进度条
  908. FLASH:
  909. volUiFlash(newPara.spkVol);
  910. }
  911. //////////////////////////////其它处理结束//////////////////////////
  912. /////////////////////////////事件发送接口///////////////////////////
  913. void threadSendEvent(nwy_osiThread_t *threadID, uint32 id, uint32 param1,uint32 param2,uint32 param3){
  914. nwy_osiEvent_t pEventSend;
  915. pEventSend.id=id;
  916. pEventSend.param1=param1;
  917. pEventSend.param2=param2;
  918. pEventSend.param3=param3;
  919. nwy_send_thead_event(threadID, &pEventSend,0);
  920. }
  921. void ttsPlay(ENCODE_USER_ENUM type, char *tts){
  922. char buf[20];
  923. if(sutApp.skipTTS!=0){
  924. MSG_WARN(1, "TTS is disable by learning task");
  925. return;
  926. }
  927. MSG_INFO(1, "tts Play:%s",tts);
  928. paControl(true);
  929. snprintf(buf, sizeof(buf), "AT+HTTS=%d,\"", type);
  930. msgAtSend(buf);
  931. msgAtSend(tts);
  932. msgAtSend("\"\r\n");
  933. sutPocStatus.TTS=1;
  934. }
  935. static void paProCtl(void){
  936. //会被定时调用
  937. if(sutPocStatus.TTS!=0) return;
  938. if(sutPocStatus.spk!=0) return;
  939. if(sutPocStatus.TONE!=0) return;
  940. if(sutPocStatus.beep!=0) return;
  941. if(sutApp.gtMode!=0) return;
  942. paControl(false);
  943. //MSG_INFO(1,"spk off");
  944. }
  945. void splVolumeSet(unsigned char level){
  946. char info[30];
  947. snprintf(info, sizeof(info), "AT+SPK=%d\r\n", level);
  948. msgAtSend(info);
  949. }
  950. /////////////////////////////事件发送结束///////////////////////////