app.c 26 KB

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