app(4756).c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. #include "includes.h"
  2. #define APP_IDLE_TIME 3 //如果POC已休眿APP没有操作一定秒数后休眠
  3. int keyNum=0;
  4. APP_DEF sutApp;
  5. static void appDataInit(void){
  6. memset((unsigned char *)&sutApp, 0, sizeof(APP_DEF));
  7. sutApp.updateStatusBar=1;
  8. sutApp.g_iBAT=-1;
  9. sutApp.copstype=-1;
  10. sutApp.pcant=4;
  11. sutApp.enableKey=1;
  12. appSleepCtl(ASLEEP_POC, 1);
  13. appSleepCtl(ASLEEP_LCD, 1);
  14. readInfoNow();
  15. sysIniRead();
  16. }
  17. void dataInit(void){
  18. appDataInit();
  19. pocDataInit();
  20. gpsDataInit();
  21. uiDataInit();
  22. }
  23. static void ledsProCtl(void){
  24. if(sutApp.gtMode!=0) return;
  25. if(0==sutPocStatus.logined) uioStatusSet(UIO_INDOFFLINE);
  26. else if(sutPocStatus.spk>0)uioStatusSet(UIO_INDRX);
  27. else if(sutPocStatus.mic>0 )uioStatusSet(UIO_INDTX);
  28. else uioStatusSet(UIO_INDONLINE);
  29. }
  30. static void adcRead(unsigned int interval);
  31. char isKeyPress(void){
  32. if(keyNum) return keyNum--;
  33. else return 0;
  34. }
  35. /*APP休眠处理接口
  36. ctlType, 操作对象
  37. status,操作值,0 清除 else 设置
  38. */
  39. void appSleepCtl(ASLEEP_ENUM ctlType, char status){
  40. if(status==0) sutApp.appSleepStatus &= ~(1<<ctlType);
  41. else sutApp.appSleepStatus |= 1<<ctlType;
  42. }
  43. /*APP休眠状态接叿*/
  44. char isAppSleepReady(void){
  45. if(sutApp.appSleepStatus==0) return 1;
  46. else return 0;
  47. }
  48. /*获取指定休眠控制成员锁定的状怿
  49. 0 未锁宿否则锁定,锁定即可以休眠
  50. */
  51. char getAppObjStatus(ASLEEP_ENUM ctlType){
  52. if(sutApp.appSleepStatus & (1<<ctlType)) return 1;
  53. else return 0;
  54. }
  55. /*检测是否APP可以休眠操作*/
  56. char isSleepReady(void){
  57. static unsigned int idleCnt=0;
  58. #ifdef DISABLE_SLEEP
  59. return 0;//不休眿
  60. #endif
  61. if(isAppSleepReady()==0){
  62. idleCnt=0;
  63. return 0;
  64. }
  65. if(++idleCnt>=(APP_IDLE_TIME*1000/APP_SUB_DIV_TIME)){
  66. idleCnt=0;
  67. return 1;
  68. }else return 0;
  69. }
  70. void usbCmdHandler(const char *data,unsigned int length){
  71. static char buf[256];
  72. static int len=0;
  73. static char lach;
  74. char ch;
  75. int i;
  76. if(sutApp.authReady==0){
  77. //authRecvPro(data, length);
  78. return;
  79. }
  80. for(i=0;i<length;i++){
  81. ch=data[i];
  82. if(len<sizeof(buf)-1) buf[len++]=ch;
  83. else{
  84. MSG_WARN(1, "USB Buf Over");
  85. len=0;
  86. buf[len++]=ch;
  87. }
  88. if(lach=='\r' && ch=='\n'){
  89. buf[len]=0;
  90. cmdSetting(buf);
  91. len=0;
  92. }
  93. lach=ch;
  94. }
  95. }
  96. static void pttHandler(char type, char ctl){
  97. #if 1//主PTT, 耳机PTT以及组合PTT都可以触发,即矩阵驱动时,任何一个按下如果没发请麦,则发请麦,只要有一个放开,则直接发放麦指令。因为组合按放后,放开,只有一个放开键值出来
  98. static char micPttPressed=0;
  99. static char pttPressed=0;
  100. static char maxPressed=0;
  101. if(type==0){//ptt
  102. if(ctl==0){//free
  103. pttPressed=0;
  104. }else{//press
  105. pttPressed=1;
  106. }
  107. }else if(type==1){//mic ptt
  108. if(ctl==0){//free
  109. micPttPressed=0;
  110. }else{//press
  111. micPttPressed=1;
  112. }
  113. }else if(type==2){//mic ptt
  114. if(ctl==0){//free
  115. maxPressed=0;
  116. }else{//press
  117. maxPressed=1;
  118. }
  119. }else return;
  120. if(ctl==0){//free
  121. if(pttPressed==0 || micPttPressed==0 || maxPressed==0){
  122. sutApp.pttReq=0;
  123. pttPressed=0;micPttPressed=0;maxPressed=0;
  124. msgAtSend("AT+POC=0C0000\r\n");
  125. }
  126. }else{//press
  127. if(pttPressed || micPttPressed || maxPressed){
  128. if(sutApp.pttReq==0){
  129. sutApp.pttReq=1;
  130. msgAtSend("AT+POC=0B0000\r\n");
  131. }
  132. }
  133. }
  134. #else
  135. static char micPttPressed=0;
  136. static char pttPressed=0;
  137. char needSend=0;
  138. char mic_spk;
  139. if(type==0){//ptt
  140. if(ctl==0){//放开
  141. if(micPttPressed==0){
  142. needSend=1;mic_spk=0;
  143. }
  144. pttPressed=0;
  145. }else{//按下
  146. if(pttPressed==0 && micPttPressed==0){
  147. needSend=1;mic_spk=1;
  148. }
  149. pttPressed=1;
  150. }
  151. }else if(type==1){//mic ptt
  152. if(ctl==0){//放开
  153. if(pttPressed==0){
  154. needSend=1;mic_spk=0;
  155. }
  156. micPttPressed=0;
  157. }else{//按下
  158. if(pttPressed==0 && micPttPressed==0){
  159. needSend=1;mic_spk=1;
  160. }
  161. micPttPressed=1;
  162. }
  163. }
  164. if(needSend!=0){
  165. if(mic_spk==0) msgAtSend("AT+POC=0C0000\r\n");
  166. else msgAtSend("AT+POC=0B0000\r\n");
  167. }
  168. #endif
  169. }
  170. /*打印键信恿*/
  171. const char freeSeg[]="Free";
  172. const char pressSeg[]="Press";
  173. void showKeyMessage(unsigned short key,unsigned char status){
  174. char buf[50]="[Key_";
  175. switch(key){
  176. case MKEY_VALUE_F2: strcat(buf, "F2]");break;
  177. case MKEY_VALUE_F1: strcat(buf, "F1]");break;
  178. case MKEY_VALUE_PTT: strcat(buf, "PTT]");break;
  179. case MKEY_VALUE_MENU: strcat(buf, "MENU]");break;
  180. case MKEY_VALUE_UP: strcat(buf, "UP]");break;
  181. case MKEY_VALUE_DOWN: strcat(buf, "DOWN]");break;
  182. case MKEY_VALUE_ESC: strcat(buf, "ESC]");break;
  183. case MKEY_VALUE_CB_GT: strcat(buf, "CB_GT]");break;
  184. case MKEY_VALUE_CB_IP: strcat(buf, "CB_IP]");break;
  185. case MKEY_VALUE_MIC_PTT: strcat(buf, "MIC_PTT]");break;
  186. case MKEY_VALUE_CB_PTT: strcat(buf, "MAX_PTT]");break;
  187. default: return;
  188. }
  189. if(status==0) strcat(buf, freeSeg);
  190. else strcat(buf, pressSeg);
  191. MSG_INFO(1,buf);
  192. }
  193. /*
  194. 龙尚矩阵驱动有一个问题:先按A不放,检测到A按下,再按B不放,检测到B按下,同时放开,概率只检测到B放开,A没检测到
  195. 规避方式:键值发生变化时,如果上次的键值大于等于2,直接清掉键值。
  196. */
  197. void assistantCheck(unsigned short key){
  198. unsigned int i,j,w;
  199. static unsigned short lkey=0;
  200. if(lkey==key) return;
  201. j=0;
  202. for(i=0;i<16;i++){//上次键值置位的个数
  203. if(lkey & (1<<i)) j++;
  204. }
  205. w=0;
  206. for(i=0;i<16;i++){//本次键值置位的个数
  207. if(key & (1<<i)) w++;
  208. }
  209. if(j>=2 && j>w){//上一次至少两个键按下,现在发生变化,至少一个键放开了,全键清除
  210. lkey=0;
  211. clearKeyValue();
  212. }
  213. lkey=key;
  214. }
  215. unsigned char keyInArow=0;
  216. void keyCheck(unsigned short keyStatus){
  217. static unsigned short lkey=0;
  218. static unsigned char keyCtl=0,keyCnt=0;
  219. unsigned char keyType,needSendKey=0;
  220. assistantCheck(keyStatus);
  221. if(keyStatus==KS_ALL_IDLE){
  222. keyType=0;
  223. if(keyCtl==1){
  224. keyCtl=0;
  225. needSendKey=1;
  226. }
  227. }else{
  228. keyType=1;
  229. if(lkey != keyStatus) keyCtl=0;//值变匿
  230. if(keyCtl==0){
  231. lkey=keyStatus;
  232. keyCtl=1;
  233. keyCnt=0;
  234. needSendKey=1;
  235. }else if(keyInArow!=0){//是否输出持续倿
  236. if(++keyCnt>=(1000/KEY_TIMER_TICK)){//每秒产生持续倿
  237. keyCnt=0;
  238. needSendKey=1;
  239. }
  240. }
  241. }
  242. if(needSendKey){
  243. if(sutApp.enableKey!=0)//延时期间不检测按锿
  244. keySendEvent(lkey,keyType);
  245. }
  246. }
  247. bool lcdBackLightStatus=false;
  248. void pwrDetRead(char type){
  249. static char cnt=0;
  250. if(type==0){
  251. cnt++;
  252. if(cnt==3){
  253. sutApp.waitEscReleased=1;
  254. uISetNextStatus(UIS_MENU_SHUT_PWR);
  255. }
  256. }else{
  257. sutApp.waitEscReleased=0;
  258. cnt=0;
  259. }
  260. #if 0
  261. if(sutUIstatus.Status == UIS_MENU_SHUT_PWR) return;//关机界面不处理
  262. if(type==0) return;//放开时处理
  263. //处理按顶部键切换UI
  264. uiTimeOutToStandby(1,APP_SUB_DIV_TIME);
  265. //处理按顶部键切换背光
  266. if(sutUIstatus.Status != UIS_STANDBY) return;//待机页面时才反转背光
  267. if(lcdBackLightStatus==false) backLightReset();
  268. else lcdBackLightApi(0);
  269. #endif
  270. }
  271. void lcdBackLightApi(char value){
  272. CTL_LCD_BL(value);
  273. if(value==0) lcdBackLightStatus=false;
  274. else lcdBackLightStatus=true;
  275. }
  276. static void lockProcess(void){
  277. if(sutApp.keyLock==0){
  278. sutApp.keyLock=1;
  279. appSleepCtl(ASLEEP_GGROUP, 0);
  280. appSleepCtl(ASLEEP_GUSER, 0);
  281. uISetNextStatus(UIS_STANDBY);
  282. }else{
  283. sutApp.keyLock=0;
  284. sutApp.lockShow=0;
  285. }
  286. }
  287. void keyToneStart(void){
  288. if(newPara.KeySound==0) return;
  289. #ifdef ENABLE_PWM_BEEP
  290. beepStart(TONE_NORMAL);
  291. #else
  292. msgAtSend("AT+TONE\r\n");
  293. #endif
  294. }
  295. void quickUiSwitch(int uistatus){
  296. if(true==isUiSwitchReady()) return;
  297. uISetNextStatus(uistatus);
  298. getStackStruct()->FastUiChange=1;
  299. }
  300. /*进入GT模式*/
  301. static void enterGTMode(void){
  302. #ifndef ENABLE_PWM_BEEP
  303. msgAtSend("AT+TONES=1\r\n");
  304. #endif
  305. sutApp.gtMode=1;
  306. uioStatusSet(UIO_INDGT);
  307. paControl(true);//GT下常开喇叭
  308. #ifdef ENABLE_PWM_BEEP
  309. pwmBeepStart(868,50);
  310. LSAPI_OSI_ThreadSleep(100);
  311. pwmBeepStart(500,50);
  312. LSAPI_OSI_ThreadSleep(100);
  313. pwmBeepStart(868,50);
  314. #else
  315. msgAtSend("AT+TONE\r\n");
  316. LSAPI_OSI_ThreadSleep(200);
  317. msgAtSend("AT+TONE\r\n");
  318. #endif
  319. MSG_WARN(1, "Enter GT Mode");
  320. }
  321. void micPttHandler(char status){
  322. keySendEvent(MKEY_VALUE_MIC_PTT,status);
  323. }
  324. char beepStatus=0;//只tone一次,任何键放开后,有键按下可tone
  325. void keyHandler(unsigned short key,unsigned char status){//普通按键值处琿
  326. static unsigned char gtModeCnt=0;
  327. static unsigned char lockCnt=0;
  328. if(newPara.lockType!=0){
  329. if(sutApp.keyLock!=0 && MKEY_VALUE_MENU!=key){
  330. sutApp.lockShow=1;
  331. return;
  332. }
  333. }else{
  334. if(sutApp.keyLock!=0 && (MKEY_VALUE_DOWN==key || MKEY_VALUE_ESC==key)){
  335. sutApp.lockShow=1;
  336. return;
  337. }
  338. }
  339. //MSG_INFO(1, "KEY:%d,%d", key,status);
  340. showKeyMessage(key,status);
  341. if(status==0){//key free
  342. switch(key){
  343. case MKEY_VALUE_MIC_PTT:
  344. pttHandler(0,0);
  345. break;
  346. case MKEY_VALUE_PTT:
  347. pttHandler(1,0);
  348. break;
  349. case MKEY_VALUE_CB_PTT:
  350. pttHandler(2,0);
  351. break;
  352. case MKEY_VALUE_ESC:
  353. pwrDetRead(1);
  354. break;
  355. case MKEY_VALUE_F1:
  356. if(sutApp.key_f1_cnt==1 && sutUIstatus.Status!=UIS_MENU_SYS_SERVERPASS) sutApp.voluemUpdate=1;
  357. sutApp.key_f1_cnt=0;
  358. break;
  359. case MKEY_VALUE_F2:
  360. if(sutApp.key_f2_cnt==1 && sutUIstatus.Status!=UIS_MENU_SYS_SERVERPASS) sutApp.voluemUpdate=2;
  361. sutApp.key_f2_cnt=0;
  362. break;
  363. case MKEY_VALUE_CB_GT:
  364. gtModeCnt=0;
  365. break;
  366. case MKEY_VALUE_MENU:
  367. if(sutApp.keyLock != 0 && lockCnt==1)//实际无法实现锁短按一下,因为按下去键值就被使用了,不过锁键盘后,都是在待机界面,不影响
  368. sutApp.lockShow=1;
  369. lockCnt=0;
  370. break;
  371. default:
  372. break;
  373. }
  374. sutApp.timeOutCnt=0;
  375. keyInArow=0;
  376. appSleepCtl(ASLEEP_MKEY, 0);
  377. beepStatus=0;
  378. }else{//key press
  379. if(key!=MKEY_VALUE_PTT && key!=MKEY_VALUE_CB_GT && beepStatus==0) keyToneStart();
  380. beepStatus=1;
  381. backLightReset();//其它所有键都点亮(接口里面有调阻止休眠接口)
  382. appSleepCtl(ASLEEP_MKEY, 1);
  383. keyNum++;
  384. switch(key){
  385. case MKEY_VALUE_MIC_PTT:
  386. pttHandler(0,1);
  387. break;
  388. case MKEY_VALUE_PTT:
  389. pttHandler(1,1);
  390. break;
  391. case MKEY_VALUE_CB_PTT:
  392. pttHandler(2,1);
  393. break;
  394. case MKEY_VALUE_ESC:
  395. keyInArow=1;
  396. pwrDetRead(0);
  397. break;
  398. case MKEY_VALUE_F1:
  399. keyInArow=1;
  400. sutApp.key_f1_cnt++;
  401. if(sutApp.keyLock==0){
  402. if(sutApp.key_f1_cnt==3) quickUiSwitch(UIS_MENU_GROUP_SEL);
  403. }else if(sutApp.key_f1_cnt!=1) sutApp.lockShow=1;
  404. break;
  405. case MKEY_VALUE_F2:
  406. keyInArow=1;
  407. sutApp.key_f2_cnt++;
  408. if(sutApp.keyLock==0){
  409. if(sutApp.key_f2_cnt==3) quickUiSwitch(UIS_MENU_USER_SEL);
  410. }else if(sutApp.key_f2_cnt!=1) sutApp.lockShow=1;
  411. break;
  412. case MKEY_VALUE_CB_GT:
  413. keyInArow=1;
  414. gtModeCnt++;
  415. if(sutApp.keyLock==0){
  416. if(gtModeCnt==3){
  417. if(sutApp.gtMode==0){
  418. enterGTMode();
  419. }
  420. }
  421. }else sutApp.lockShow=1;
  422. break;
  423. case MKEY_VALUE_CB_IP:
  424. keyInArow=1;
  425. break;
  426. case MKEY_VALUE_MENU:
  427. keyInArow=1;
  428. if(++lockCnt==3) lockProcess();
  429. break;
  430. default:
  431. break;
  432. }
  433. }
  434. }
  435. /////////////////////////////事件发送接叿//////////////////////////
  436. void threadSendEvent(LSAPI_OSI_Thread_t *threadID, unsigned int id, unsigned int param1,unsigned int param2,unsigned int param3){
  437. LSAPI_OSI_Event_t pEventSend;
  438. pEventSend.id=id;
  439. pEventSend.param1=param1;
  440. pEventSend.param2=param2;
  441. pEventSend.param3=param3;
  442. osiEventTrySend(threadID,&pEventSend,0);
  443. }
  444. //////////////////////////////其它处理接口//////////////////////////
  445. static void adcRead(unsigned int interval){
  446. #if 1
  447. static unsigned char earStatus=0xff;
  448. unsigned char tmpEar;
  449. int32_t chargeVol;
  450. static unsigned short cnt=0,lcnt=0;
  451. static unsigned int laSiVbat;
  452. unsigned int adcValueTmp;
  453. if(++cnt<(1000/interval)) return;//1秒读一次ADC即可
  454. cnt=0;
  455. LSAPI_SYS_BattGetVol(&adcValueTmp);
  456. sutApp.g_iBAT=adcValueTmp/10;
  457. if(sutApp.g_iBAT == laSiVbat){
  458. laSiVbat=sutApp.g_iBAT;
  459. if(sutApp.g_iBAT<=MIN_PWR_LEVEL){
  460. MSG_WARN(1,"Low power:%d", lcnt++);
  461. if(lcnt>=10){
  462. MSG_INFO(1, "Low power ,shut");
  463. sutApp.lowPwrMsg=1;
  464. appSleepCtl(ASLEEP_PWR, 1);
  465. }
  466. }else lcnt=0;
  467. }
  468. //读取充电/耳机接入状态 //不知道为啥是LSAPI_Device_ADC_CHANNEL_3,而不是LSAPI_Device_ADC_CHANNEL_1
  469. chargeVol=LSAPI_Device_AdcGetChannelVolt(LSAPI_Device_ADC_CHANNEL_3, LSAPI_Device_ADC_SCALE_3V233);
  470. if(chargeVol<=800){//耳机插入,没在充电
  471. tmpEar=0;
  472. sutApp.chargeStatus=0;
  473. }else if(chargeVol<=1000){//耳机插入,正在充电
  474. tmpEar=0;
  475. sutApp.chargeStatus=1;
  476. }else if(chargeVol<=1400){//耳机拔出,没在充电
  477. tmpEar=1;
  478. sutApp.chargeStatus=0;
  479. }else{//耳机拔出,正在充电
  480. tmpEar=1;
  481. sutApp.chargeStatus=1;
  482. }
  483. if(tmpEar != earStatus){//耳机状态发生变化
  484. earStatus=tmpEar;
  485. tmpEar += 0x30;
  486. proHeadSet(&tmpEar);
  487. }
  488. #else//这里ADC太频繁调用ADC接口,有概率会影响poc播放tone音效果
  489. #define VBAT_READ_TIME 20
  490. unsigned int adcValueTmp;
  491. static unsigned int siVbat=0,laSiVbat;
  492. static unsigned char index=0;
  493. LSAPI_SYS_BattGetVol(&adcValueTmp);
  494. siVbat += adcValueTmp;
  495. if(++index>=VBAT_READ_TIME){
  496. sutApp.g_iBAT=siVbat / VBAT_READ_TIME / 10;
  497. if(laSiVbat!=sutApp.g_iBAT){
  498. //MSG_INFO(1, "bat:%d", sutApp.g_iBAT);
  499. laSiVbat=sutApp.g_iBAT;
  500. if(sutApp.g_iBAT<=MIN_PWR_LEVEL){
  501. MSG_INFO(1, "Low power ,shut");
  502. sutApp.lowPwrMsg=1;
  503. appSleepCtl(ASLEEP_PWR, 1);
  504. }
  505. }
  506. siVbat=0;
  507. index=0;
  508. }
  509. #endif
  510. }
  511. /*处理UI操作*/
  512. static void uiProcess(unsigned int exeInterval){
  513. static int cnt=0;
  514. if(getAppObjStatus(ASLEEP_PWR) != 0) return;//关机后,不切换菜单,只显示关机
  515. uiLoop(exeInterval);
  516. uiResponse(exeInterval);
  517. }
  518. /*触发关机操作*/
  519. static void pwrShutPro(void){
  520. static char shutFlag=0;
  521. if(getAppObjStatus(ASLEEP_PWR) == 0) return;
  522. lcdBackLightApi(1);
  523. msgAtSend("AT+POC=050000\r\n");
  524. msgAtSend("AT+CFUN=0\r\n");
  525. if(shutFlag==0){
  526. //显示关机界面
  527. if(sutApp.lowPwrMsg==0) guiShowMessageBox("正在关机");
  528. else guiShowMessageBox("低压关机");
  529. shutFlag=1;
  530. LSAPI_OSI_ThreadSleep(1000);
  531. guiShowBmp(0,0,"BYEBYE.bmp");
  532. LSAPI_OSI_ThreadSleep(1000);
  533. }
  534. MSG_INFO(1, "Normal PwrOff");
  535. //msgAtSend("AT+TRB=1\r\n");//normal power off 当前固件先不发模块关机指令,否则断电再上电有可能是起不来皿
  536. //LSAPI_OSI_ThreadSleep(1000);//一秒后释放电源锿防止软关机不成功
  537. lcdBackLightApi(0);
  538. MSG_INFO(1, "Release pwr");
  539. guiFillRect(0,0,GLCD_WIDTH-1,GLCD_HEIGHT-1,guiGetBackColor());//防止下次开机能看到残留
  540. msgAtSend("AT+CPOF\r\n");//软件关机模块
  541. LSAPI_OSI_ThreadSleep(100);
  542. CTL_POWER_HOLD(false);
  543. }
  544. static void NoteCheck(int interval){
  545. int dlyMs;
  546. if(sutApp.lowPwrWarn!=0){
  547. sutApp.lowPwrCnt += interval;
  548. if(sutPocStatus.spk==0 && sutPocStatus.mic==0){//对计状态下不播放请充电
  549. if(sutApp.lowPwrCnt>=WARN_TTS_INTERVAL){
  550. sutApp.lowPwrCnt=0;
  551. ttsPlay(ENCODE_USER_GBK, "C7EBB3E4B5E7");
  552. }
  553. }
  554. }
  555. }
  556. void AntModeRun(void){
  557. #ifdef ENABLE_ANT_MODE
  558. guiShowMessageBox("调天线模式");
  559. for(;;){
  560. LSAPI_OSI_ThreadSleep(2000);
  561. }
  562. #endif
  563. }
  564. static void paProCtl(void);
  565. static void subTimerCtl(unsigned char sleep_or_not);
  566. static void configureVoiceParam(void);
  567. void appRun(void){
  568. char cnt=0;
  569. LSAPI_OSI_Event_t event={0};
  570. //等待lcd初始化完房
  571. MSG_INFO(1, "wait lcd init");
  572. while(sutApp.guiStatus==0){LSAPI_OSI_ThreadSleep(50);}//是否检测超时?
  573. //newGuiClearMainPage();
  574. while(1){
  575. ClearGaucLcdBufF();
  576. LCDFlashPain();
  577. MSG_INFO(1, " lcd clear------------");
  578. LSAPI_OSI_ThreadSleep(5000);
  579. SetGaucLcdBufF();
  580. MSG_INFO(1, " lcd fill------------");
  581. LCDFlashPain();
  582. LSAPI_OSI_ThreadSleep(5000);
  583. }
  584. // AntModeRun();
  585. // localAuthNow();
  586. //等待poc启动完成
  587. MSG_INFO(1, "lcd init done, wait poc start");
  588. // while(sutApp.pocInitStatus==0){
  589. // msgAtSend("ATE0\r\n");
  590. // LSAPI_OSI_ThreadSleep(1000);
  591. // }//是否检测超时?
  592. MSG_INFO(1, "app loop start");
  593. msgAtSend("AT+AUDCH=0,0\r\n");//此机型只使用主通道
  594. //设置一下TTS语音速度
  595. msgAtSend("AT+LSHTTSPARAM=3000,106,100\r\n");//设置TTS参数
  596. //查询一下POC版本叿
  597. msgAtSend("AT+SIMCROSS?\r\n");
  598. // configureVoiceParam();
  599. // adcRead(APP_SUB_DIV_TIME);//在开机播放前设置下SPK
  600. // splVolumeSet(newPara.spkVol*10);//更新音量
  601. backLightReset();
  602. // if(newPara.ttsMessage[0]!=0){
  603. // if(newPara.ttsCodeType==0){
  604. //// ttsPlay(ENCODE_USER_UNICODE_BE, newPara.ttsMessage);
  605. // }else if(newPara.ttsCodeType==1) ttsPlay(ENCODE_USER_GBK, newPara.ttsMessage);
  606. // else MSG_INFO(1, "ttsCodeType:%d not support", newPara.ttsCodeType);
  607. // }else MSG_INFO(1, "tts null");
  608. // newGuiNoteBoot(1);
  609. // //检测卡是否存在
  610. // while(sutApp.cardStatus==0){
  611. // msgAtSend("AT+CCID\r\n");
  612. // LSAPI_OSI_ThreadSleep(500);
  613. // if(++cnt>=10){
  614. // MSG_INFO(1, "Check card timeout");
  615. // break;
  616. // }
  617. // }
  618. msgAtSend("AT+POC=030000\r\n");
  619. for(;;){
  620. ledsProCtl();
  621. adcRead(APP_SUB_DIV_TIME);
  622. uiProcess(APP_SUB_DIV_TIME);
  623. pocProCtl(APP_SUB_DIV_TIME);
  624. NoteCheck(APP_SUB_DIV_TIME);
  625. uiTimeOutToStandby(0, APP_SUB_DIV_TIME);
  626. HookGroupUserInfo();
  627. LogoutOutTimeCheck(APP_SUB_DIV_TIME);
  628. if(isSleepReady()==0) LSAPI_OSI_ThreadSleep(APP_TASK_SLEEP_TIME);
  629. else if(sutApp.gtMode==0){//正常模式下可以休眿
  630. MSG_WARN(1, "APP SLEEP");
  631. uiTimeOutToStandby(1, APP_SUB_DIV_TIME);
  632. stopKeyTimer();
  633. subTimerCtl(1);//切换为休眠状态定时器
  634. sutApp.appStatus=1;
  635. redLedCtl(false);//休眠后保证灯没亮,否则有可能灯亮10ms,按理10ms后灯能灭,然后10ms时休眠了,应用就短时间内不会灭灯
  636. greenLedCtl(false);//休眠后保证灯没亮
  637. sutApp.updateStatusBar=1;
  638. LSAPI_OSI_EventWait(LSAPI_OSI_ThreadCurrent(), &event);
  639. LSAPI_OSI_ThreadSleep(150);//添加这个后,休眠时按键或被呼叫或本机呼叫,tone音能是完整的
  640. lcdDrv_Init(1);//深度休眠唤醒后重新初始化SPI-LCD
  641. if(sutApp.lcdDlyLightUp){
  642. sutApp.lcdDlyLightUp=0;
  643. lcdBackLightApi(1);
  644. }
  645. sutApp.forceUiFlash=1;
  646. sutApp.appStatus=0;
  647. subTimerCtl(0);//切换为唤醒状态定时器
  648. MSG_WARN(1, "APP WAKEUP");
  649. }
  650. //检测是否关机,这里要放在唤醒后操作
  651. pwrShutPro();
  652. }
  653. }
  654. unsigned int subTimerInterval=100;//定时器定时的时间
  655. LSAPI_OSI_Timer_t *pSubtimer_t = NULL;
  656. /*
  657. 为了做低功耗,此定时器在休眠时,设置为长时间定旿
  658. 非休眠时,设置为短时间定旿
  659. sleep_or_not:0 未休眠, else 休眠
  660. */
  661. static void subTimerCtl(unsigned char sleep_or_not){
  662. if(NULL==pSubtimer_t){
  663. MSG_WARN(1, "subTimer null");
  664. return;
  665. }
  666. LSAPI_OSI_TimerStop(pSubtimer_t);
  667. //打开定时噿
  668. if(sleep_or_not==0) subTimerInterval=100;//未休眠时_00ms
  669. else subTimerInterval=5000;//休眠旿5000ms
  670. LSAPI_OSI_TimerStart(pSubtimer_t,subTimerInterval);
  671. }
  672. static void subTimeroutcallback(void *param){
  673. unsigned int *dlyTime=(unsigned int *)param;
  674. //处理灯的显示
  675. uioProctl(*dlyTime);
  676. //控制功放的关闿
  677. paProCtl();
  678. if(NULL!=pSubtimer_t) LSAPI_OSI_TimerStart(pSubtimer_t,subTimerInterval);
  679. }
  680. void subTask(void *param){
  681. LSAPI_OSI_Event_t event={0};
  682. if(NULL==pSubtimer_t) pSubtimer_t = LSAPI_OSI_TimerCreate(LSAPI_OSI_ThreadCurrent(), subTimeroutcallback, (void *)&subTimerInterval);
  683. if(NULL==pSubtimer_t) MSG_WARN(1,"sub timer init failed");
  684. else LSAPI_OSI_TimerStart(pSubtimer_t,subTimerInterval);
  685. for(;;){LSAPI_OSI_EventWait(LSAPI_OSI_ThreadCurrent(), &event);}
  686. }
  687. static void paProCtl(void){
  688. //会被定时调用
  689. if(sutPocStatus.TTS!=0) return;
  690. if(sutPocStatus.spk!=0) return;
  691. if(sutPocStatus.TONE!=0) return;
  692. if(sutPocStatus.beep!=0) return;
  693. if(sutApp.gtMode!=0) return;
  694. paControl(false);
  695. //MSG_INFO(1,"spk off");
  696. }
  697. void tryWakeupApp(void){
  698. if(sutApp.appStatus!=0){
  699. if(mainThreadPtr!=NULL){
  700. threadSendEvent(mainThreadPtr,OHPOC_EVENT_MAIN,NULL,NULL,NULL);
  701. }
  702. }
  703. }
  704. void ttsPlay(ENCODE_USER_ENUM type, char *tts){
  705. char buf[20];
  706. MSG_INFO(1, "tts Play:%d,%s",type,tts);
  707. paControl(true);
  708. snprintf(buf, sizeof(buf), "AT+LSHTTS=%d,\"", type);
  709. msgAtSend(buf);
  710. msgAtSend(tts);
  711. msgAtSend("\"\r\n");
  712. sutPocStatus.TTS=1;
  713. }
  714. /*背光时间到,熄灭*/
  715. void backLightCb(void *param){
  716. if(sutPocStatus.firstLogin==0) return;//未登录过,不灭屏
  717. if(newPara.lcdParaList[newPara.lcdParaDefaultIndex]==0) return;//常亮
  718. lcdBackLightApi(0);
  719. appSleepCtl(ASLEEP_LCD, 0);//可以休眠
  720. }
  721. /*点亮背光*/
  722. void backLightReset(void){
  723. unsigned short tmp;
  724. appSleepCtl(ASLEEP_LCD, 1);//不让休眠
  725. tmp=newPara.lcdParaList[newPara.lcdParaDefaultIndex];
  726. if(sutApp.appStatus==0) lcdBackLightApi(1);//未休眠时,直接点亮
  727. else sutApp.lcdDlyLightUp=1;//休眠时不马上亮亮,会在LCD初始化完后点亮
  728. startBackLightTimer(tmp*1000);
  729. }
  730. void sysPwrLock(void){
  731. sutApp.pwrLock=1;
  732. }
  733. void sysPwrRlease(void){
  734. sutApp.pwrLock=0;
  735. }
  736. //"3132" --> 0x31,0x32
  737. void StrAsciiToHex(char *src, unsigned char *des){
  738. unsigned char temp[2],i;
  739. if(strlen(src)%2) return;
  740. while(0!=*src)
  741. {
  742. for(i=0;i<2;i++)
  743. {
  744. temp[i] = *src++;
  745. if(temp[i] >= '0' && temp[i] <= '9') temp[i] -= 0x30;
  746. else if(temp[i] >= 'A' && temp[i] <= 'F') temp[i] -= 0x37;
  747. else temp[i] -= 0x57;
  748. }
  749. temp[0] <<= 4;
  750. temp[0] &= 0xf0;
  751. *des++=temp[0]|temp[1];
  752. }
  753. *des=0;
  754. }
  755. void splVolumeSet(unsigned char level){
  756. char info[30];
  757. snprintf(info, sizeof(info), "AT+CLVL=%d\r\nAT+CRSL=%d\r\n", level,level);
  758. msgAtSend(info);
  759. MSG_INFO(1,"SPK_VOL:%d",level);
  760. }
  761. const unsigned char spkGainTable[SPK_GAIN_NUM];
  762. /*调节音量,刷新音量进度条*/
  763. void volAdjAction(char direction,unsigned char UIStatus){
  764. unsigned char vol;
  765. if(sutApp.earLev==0){//不接耳机
  766. if(direction==0){
  767. if(newPara.spkVol<MAX_SPK_VOL) newPara.spkVol++;
  768. else goto FLASH;
  769. }else{
  770. if(newPara.spkVol>0) newPara.spkVol--;
  771. else goto FLASH;
  772. }
  773. vol=newPara.spkVol*10;
  774. splVolumeSet(vol);
  775. }else{//接了耳机
  776. if(direction==0){
  777. if(newPara.spkGain<SPK_GAIN_NUM) newPara.spkGain++;
  778. else goto FLASH;
  779. }else{
  780. if(newPara.spkGain>0) newPara.spkGain--;
  781. else goto FLASH;
  782. }
  783. if(newPara.spkGain==0) vol=0;
  784. else vol=spkGainTable[newPara.spkGain-1];
  785. splVolumeSet(vol);
  786. vol=newPara.spkGain;
  787. }
  788. sysIniSave();
  789. //刷新进度条
  790. FLASH:
  791. if(sutApp.earLev==0) vol=newPara.spkVol;
  792. else vol=newPara.spkGain;
  793. //if(UIS_STANDBY==UIStatus) volUiFlash(vol);
  794. }
  795. void volUpdateNeed(void){
  796. if(sutApp.voluemUpdate==0) return;
  797. if(sutApp.voluemUpdate==1) volAdjAction(0, sutUIstatus.Status);
  798. else if(sutApp.voluemUpdate==2) volAdjAction(1, sutUIstatus.Status);
  799. sutApp.voluemUpdate=0;
  800. }
  801. const unsigned char spkGainTable[SPK_GAIN_NUM]={
  802. 24,32,40,48,56,64,72,80
  803. };
  804. void VolSpkUpdate(void){
  805. char cmd[30];
  806. unsigned char volLev;
  807. if(sutApp.earLev==0){//耳机拔掉后,恢复正常的SPK增益
  808. volLev=newPara.spkVol*10;
  809. }else{//耳机接入,应用特定值
  810. if(newPara.spkGain>=SPK_GAIN_NUM) volLev=SPK_GAIN_DEFAULT;
  811. else volLev=newPara.spkGain;
  812. if(volLev>0) volLev=spkGainTable[newPara.spkGain-1];
  813. }
  814. splVolumeSet(volLev);
  815. }
  816. //对都使用主音频通道设计来说,耳机模式时,需要按比例降低输入输出增益
  817. const unsigned short micGainTable[MIC_GAIN_NUM][2]={
  818. {2,6},{2,10},{3,10},{4,10},{5,10},{6,10},{6,13}
  819. };
  820. void VolMicUpdate(void){
  821. #if 1
  822. char cmd[50];
  823. unsigned char hana,lana,hadc,ladc;
  824. if(sutApp.earLev==0){//耳机拔掉,恢复正常MIC增益
  825. hana=sutApp.mic_ana>>8;
  826. lana=sutApp.mic_ana;
  827. hadc=sutApp.mic_adc>>8;
  828. ladc=sutApp.mic_adc;
  829. }else{//耳机接入
  830. hana=micGainTable[newPara.micGain][0]>>8;
  831. lana=micGainTable[newPara.micGain][0];
  832. hadc=micGainTable[newPara.micGain][1]>>8;
  833. ladc=micGainTable[newPara.micGain][1];
  834. }
  835. snprintf(cmd, sizeof(cmd), "AT+CACCP=0,0,0,\"%02x%02x%02x%02x\"\r\n",lana,hana,ladc,hadc);
  836. msgAtSend(cmd);
  837. #else
  838. unsigned char tableIndex;
  839. char cmd[50];
  840. int vol=newPara.spkVol*10;
  841. splVolumeSet(vol);
  842. if(sutApp.earLev==0){//耳机拔掉,恢复正常MIC增益
  843. tableIndex=newPara.micGain_onspk;
  844. //msgAtSend("AT+CACCP=0,0,0,\"04000a00\"\r\n");
  845. }else{//耳机接入
  846. tableIndex=newPara.micGain_onear;
  847. //msgAtSend("AT+CACCP=0,0,0,\"02000f00\"\r\n");
  848. }
  849. if(tableIndex>=MIC_GAIN_NUM){
  850. MSG_WARN(1, "Index invalid:%d", tableIndex);
  851. return;
  852. }
  853. snprintf(cmd, sizeof(cmd), "AT+CACCP=0,0,0,\"%02x00%02x00\"\r\n", micGainTable[tableIndex][0],micGainTable[tableIndex][1]);
  854. msgAtSend(cmd);
  855. #endif
  856. }
  857. //开机配置设定好的模块音频参数文件
  858. #define READ_PER_SIZE 400 //每次从Bin文件读取最多400字节来发送,AT时长度翻倍
  859. static void configureVoiceParam(void){
  860. //const char *confiFile="ZT-MINI101HGS.bin";
  861. const char *confiFile="ZT-MINI201-202HGS-20210703.bin";
  862. unsigned char sendbuf[40+2*400];//AT+CAIET=0,0,9600,400,""
  863. unsigned char *dataPtr=sendbuf+sizeof(sendbuf)-READ_PER_SIZE;
  864. char buf[3];
  865. char status=0;
  866. int fd,offset,readsize,i;
  867. LSAPI_FS_Stat_info_t pBuf;
  868. MSG_INFO(1, "config audio file'%s'",confiFile);
  869. fd=LSAPI_FS_Open(confiFile, LSAPI_FS_O_RDONLY,0x0);
  870. if(fd>0){
  871. memset(&pBuf,0,sizeof(pBuf));
  872. LSAPI_FS_Fstat(fd,&pBuf);
  873. offset=0;
  874. LSAPI_FS_Seek(fd, offset, LSAPI_FS_SEEK_SET);
  875. while(offset<pBuf.st_size){
  876. readsize=pBuf.st_size-offset;
  877. if(readsize>400) readsize=400;
  878. readsize=LSAPI_FS_Read(fd, dataPtr, readsize);
  879. if(readsize==0) break;
  880. else if(readsize<0){
  881. status=1;
  882. break;
  883. }
  884. sprintf(sendbuf, "AT+CAIET=0,0,%d,%d,\"", offset, readsize);
  885. for(i=0;i<readsize;i++){
  886. sprintf(buf, "%02x", dataPtr[i]);
  887. strcat(sendbuf, buf);
  888. }
  889. strcat(sendbuf,"\"\r\n");
  890. msgAtSend(sendbuf);
  891. offset += readsize;
  892. LSAPI_OSI_ThreadSleep(10);
  893. }
  894. LSAPI_FS_Close(fd);
  895. if(status==0) MSG_INFO(1, "config audio file succ:%d",offset);
  896. else MSG_ERR(1, "config audio failed %d",status);
  897. }else MSG_ERR(1, "'%s' open failed",confiFile);
  898. if(status==0){//配置成功后,回读一下默认的Mic,这个值在不接耳机时是固定值
  899. LSAPI_OSI_ThreadSleep(50);
  900. msgAtSend("AT+CACCP=0,0,1,\"\"\r\n");
  901. LSAPI_OSI_ThreadSleep(50);
  902. }else{
  903. //如果配置失败了,直接使用默认值
  904. sutApp.mic_ana=4;
  905. sutApp.mic_adc=4;//12;
  906. }
  907. VolMicUpdate();
  908. }
  909. //+CACCP:
  910. //+CACCP: "04000C00" ana=0x0004 adc=0x000c
  911. void proCaccpMsg(char *msg){
  912. char tmp[10],*pName;
  913. char i=0,j=0;
  914. if(msg[0]=='"'){
  915. memcpy(tmp+j, msg+7,2);j += 2;
  916. memcpy(tmp+j, msg+5,2);j += 2;
  917. memcpy(tmp+j, msg+3,2);j += 2;
  918. memcpy(tmp+j, msg+1,2);j += 2;
  919. tmp[j]=0;//000C0004
  920. sutApp.mic_ana=strtol(tmp+4, &pName,16);
  921. tmp[4]=0;
  922. sutApp.mic_adc=strtol(tmp, &pName,16);
  923. }
  924. }