app.c 24 KB

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