app(6660).c 26 KB

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