charge_box.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. #include "include.h"
  2. #if CHARGE_BOX_EN
  3. #define TRACE_EN 0
  4. #if TRACE_EN
  5. #define TRACE(...) printf(__VA_ARGS__)
  6. #else
  7. #define TRACE(...)
  8. #endif
  9. int btstack_get_link_key(uint8_t *bd_addr, uint8_t *link_key, uint8_t *type, bool ext);
  10. ch_box_cb_t chbox_cb;
  11. inbox_cb_t inbox_cb;
  12. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  13. vhouse_cb_t vhouse_cb;
  14. #endif
  15. ///设置leakage状态, 返回值 0:disable, 1: enable
  16. AT(.com_text.charge_box)
  17. void charge_box_leakage_set(u8 sta, u8 val)
  18. {
  19. u32 level = (val) ? val : xcfg_cb.ch_leakage_sel;
  20. chbox_cb.leakage_sta = sta & 0xfc;
  21. charge_set_leakage(sta, level);
  22. }
  23. ///使能出仓唤醒功能
  24. AT(.text.charge_box)
  25. void charge_box_inbox_wakeup_enable(void)
  26. {
  27. RTCCON3 |= BIT(12); //RTCCON3[12], INBOX Wakeup enable
  28. if ((xcfg_cb.ch_box_type_sel == 2) || (xcfg_cb.ch_box_type_sel == 0)) { //有维持电压的充电仓关闭leakage漏电
  29. charge_box_leakage_set(0, 0); //leakage disable
  30. }
  31. }
  32. ///检测INBOX状态 返回值 0: 正在检测, 1:检测完成,INBOX不在线, 2:检测完成,INBOX在线
  33. AT(.com_text.charge_box)
  34. u8 charge_box_inbox_check(void)
  35. {
  36. inbox_cb_t *s = &inbox_cb;
  37. if (CHARGE_INBOX()) {
  38. #if CHARGE_BOX_OUTBOX_FLIT
  39. s->on_cnt_filt = 0;
  40. #endif
  41. s->off_cnt = 0;
  42. if (s->on_cnt < s->on_delay) { //等待VUSB放电,确认INBOX是否在线
  43. s->on_cnt++;
  44. return 0;
  45. }
  46. if (s->on_cnt == s->on_delay) {
  47. s->on_cnt = s->on_delay + 5;
  48. return 2; //inbox在线
  49. }
  50. return 0x82;
  51. } else {
  52. #if CHARGE_BOX_OUTBOX_FLIT
  53. s->on_cnt_filt ++;
  54. if (s->on_cnt_filt >= 8) {
  55. s->on_cnt_filt = 0;
  56. s->on_cnt = 0;
  57. }
  58. #else
  59. s->on_cnt = 0;
  60. #endif
  61. if (s->off_cnt < s->off_delay) {
  62. s->off_cnt++;
  63. if ((s->off_cnt == 4) && (chbox_cb.leakage_sta & BIT(7))) {
  64. charge_box_leakage_set(0, 0);
  65. }
  66. return 0;
  67. }
  68. if (s->off_cnt == s->off_delay) {
  69. s->off_cnt = s->off_delay + 5;
  70. return 1; //inbox不在线
  71. }
  72. return 0x81;
  73. }
  74. }
  75. ///用于兼容短暂掉0V充电仓(充满后 5V -> 0V -> 2.xV)
  76. AT(.text.bsp.charge)
  77. int charge_box_outbox_stable_check(void)
  78. {
  79. int i;
  80. u8 inbox_sta = 0;
  81. if (xcfg_cb.ch_box_type_sel) {
  82. return 1; //非此类型仓, 直接返回出仓开机
  83. }
  84. charge_box_leakage_set(0, 0); //disable leakage
  85. delay_5ms(60); //delay 300ms
  86. charge_box_inbox_chk_init(12+(u16)xcfg_cb.chbox_out_delay*10, 20);
  87. for (i = 0; i < 200; i++) {
  88. delay_5ms(2);
  89. WDT_CLR();
  90. inbox_sta = charge_box_inbox_check(); //检测INBOX状态判断是否为充满状态
  91. if (inbox_sta) {
  92. break;
  93. }
  94. }
  95. if (inbox_sta == 2) { //inbox stable online
  96. if (CHARGE_DC_IN()) {
  97. charge_box_leakage_set(1, 0); //enable leakage
  98. return 0; //5V online, 继续充电
  99. }
  100. charge_box_inbox_wakeup_enable(); //INBOX Wakeup enable
  101. bsp_saradc_exit();
  102. sfunc_pwrdown(1); //开VUSB复位,且并机
  103. }
  104. charge_box_leakage_set(1, 0); //enable leakage
  105. return 1; //出仓开机
  106. }
  107. ///兼容某些维持电压的仓: 耳机入仓, 电池仓的电压不会自动升到5V, 需要手动按仓的按键。
  108. AT(.com_text.charge_box)
  109. void charge_box_inbox_process(void)
  110. {
  111. static u32 inbox_tick = 0;
  112. u8 sta;
  113. if ((chbox_cb.inbox_rtt_check) && (!CHARGE_DC_IN())) {
  114. if (!tick_check_expire(inbox_tick, 10)) {
  115. return;
  116. }
  117. inbox_tick = tick_get();
  118. sta = charge_box_inbox_check();
  119. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  120. charge_box_inbox_sta(sta);
  121. #endif
  122. if ((2 == sta) && (xcfg_cb.chg_inbox_pwrdwn_en)) {
  123. msg_enqueue(EVT_CHARGE_INBOX);
  124. }
  125. }
  126. }
  127. ///5ms调用一次
  128. AT(.text.charge_box)
  129. u8 charge_box_charge_on_process(void)
  130. {
  131. u8 inbox_sta, chbox_sta = 0;
  132. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  133. chbox_sta = charge_box_ssw_process(1);
  134. #endif
  135. if ((charge_box_sta() == 2) || (chbox_sta == 2)) { //是否充满
  136. charge_exit();
  137. unlock_code_charge();
  138. charge_box_inbox_wakeup_enable(); //INBOX Wakeup enable
  139. bsp_saradc_exit();
  140. sfunc_pwrdown(0);
  141. }
  142. if (!CHARGE_DC_IN()) { //DC IN online?
  143. // if ((chbox_cb.dc_in == 3) && CHARGE_INBOX()) {
  144. // charge_box_leakage_set(0x81, 6); //用大电流leakage加速VUSB掉电, 在检测到低于INBOX电压后关闭leakage(防止VUSB电容导致掉电慢)
  145. // }
  146. // if (chbox_cb.dc_in < 10) {
  147. // chbox_cb.dc_in++;
  148. // }
  149. charge_box_leakage_set(0, 0);
  150. inbox_sta = charge_box_inbox_check() & 0x3; //检查inbox online状态
  151. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  152. if (chbox_sta) { //智能充电仓已开盖, 需要退出充电流程
  153. charge_box_leakage_set(1, 0);
  154. if (inbox_sta == 1) { //dc_in = 0, 且inbox = 0
  155. sys_cb.outbox_pwron_flag = 1;
  156. }
  157. return 2;
  158. }
  159. #endif
  160. if (inbox_sta == 1) { //dc_in = 0, 且inbox = 0
  161. charge_box_leakage_set(1, 0);
  162. if ((chbox_cb.out2pwr_en) || (chbox_sta)) { //拿起开机
  163. sys_cb.outbox_pwron_flag = 1;
  164. return 2;
  165. }
  166. return 1;
  167. } else if (inbox_sta == 2) { //dc_in = 0, inbox = 1, 需要关机
  168. #if UART0_PRINTF_SEL != PRINTF_VUSB //vusb打印不关机
  169. charge_exit();
  170. unlock_code_charge();
  171. charge_box_inbox_wakeup_enable(); //INBOX Wakeup enable
  172. bsp_saradc_exit();
  173. sfunc_pwrdown(1);
  174. #endif
  175. }
  176. } else {
  177. chbox_cb.dc_in = 1;
  178. chbox_cb.out2pwr_en = xcfg_cb.ch_out_auto_pwron_en;
  179. inbox_cb.off_cnt = 0;
  180. inbox_cb.on_cnt = 0;
  181. charge_box_leakage_set(1, 0);
  182. }
  183. return 0;
  184. }
  185. AT(.text.charge_box.process)
  186. void charge_box_process(void)
  187. {
  188. charge_box_inbox_process();
  189. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  190. charge_box_ssw_process(0);
  191. #endif
  192. }
  193. ///耳机在充电仓充满自动关机,拿起自动开机处理。
  194. AT(.text.bsp.charge)
  195. u8 charge_box_sta(void)
  196. {
  197. if ((sys_cb.charge_sta == 2) && (!sys_cb.charge_bled_flag)) {
  198. //充满且蓝灯灭时进入关机
  199. if (xcfg_cb.ch_full_auto_pwrdwn_en) {
  200. //printf("charge full auto pwrdwn\n");
  201. charge_box_inbox_wakeup_enable();
  202. return 2; //充满关机
  203. }
  204. }
  205. return 0;
  206. }
  207. AT(.text.charge_box)
  208. void charge_box_inbox_chk_init(u16 off_delay, u16 on_delay)
  209. {
  210. inbox_cb.off_cnt = 0;
  211. inbox_cb.on_cnt = 0;
  212. inbox_cb.off_delay = off_delay;
  213. inbox_cb.on_delay = on_delay;
  214. }
  215. AT(.text.charge_box)
  216. void charge_box_enter(u8 out_auto_pwron)
  217. {
  218. memset(&chbox_cb, 0, sizeof(chbox_cb));
  219. chbox_cb.out2pwr_en = out_auto_pwron;
  220. charge_box_inbox_chk_init(20, 120); //inbox online检测长点,等待VUSB电容放电
  221. if ((chbox_cb.out2pwr_en) && (!xcfg_cb.ch_box_type_sel)) { //短暂掉0V的仓
  222. inbox_cb.off_delay = 100+(u16)xcfg_cb.chbox_out_delay*20; //inbox offline check 500ms + n*100ms
  223. }
  224. }
  225. void charge_box_reinit(void)
  226. {
  227. sys_cb.inbox_wken_flag = 0;
  228. charge_box_inbox_chk_init(10, 20);
  229. chbox_cb.leakage_sta = 0;
  230. if ((xcfg_cb.ch_box_type_sel == 2) || (xcfg_cb.ch_box_type_sel == 0)) {
  231. chbox_cb.inbox_rtt_check = 1;
  232. }
  233. }
  234. void charge_box_init(void)
  235. {
  236. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  237. charge_box_ssw_init();
  238. #endif
  239. }
  240. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  241. AT(.com_text.charge_box)
  242. void charge_box_inbox_sta(u8 sta)
  243. {
  244. if (sta) {
  245. bool new_sta = vhouse_cb.inbox_sta;
  246. if (sta & BIT(1)) {
  247. new_sta = true;
  248. } else if (sta & BIT(0)) {
  249. new_sta = false;
  250. }
  251. if(new_sta != vhouse_cb.inbox_sta) {
  252. vhouse_cb.inbox_sta = new_sta;
  253. vhouse_cb.update_ear_flag = true;
  254. }
  255. }
  256. }
  257. AT(.text.charge_box)
  258. void charge_box_update_sta(void)
  259. {
  260. vhouse_cb.update_ear_flag = true;
  261. }
  262. AT(.text.charge_box)
  263. static void charge_box_update_bat_adv(void)
  264. {
  265. if(vhouse_cb.update_ear_flag) {
  266. vhouse_cb.update_ear_flag = false;
  267. bool old_sta = (bool)(sys_cb.loc_bat & BIT(7));
  268. bool new_sta = vhouse_cb.inbox_sta;
  269. if(old_sta != new_sta) {
  270. if(new_sta) {
  271. sys_cb.loc_bat |= BIT(7);
  272. } else {
  273. sys_cb.loc_bat &= ~BIT(7);
  274. }
  275. }
  276. }
  277. }
  278. AT(.text.charge_box)
  279. static void charge_box_open_windows(void)
  280. {
  281. vhouse_cb.open_win_flag = 0;
  282. vhouse_cb.status = 1; //开窗,停止充电
  283. }
  284. u8 charge_box_popup_is_enable(void)
  285. {
  286. return sys_cb.popup_en;
  287. }
  288. AT(.text.charge_box)
  289. static void charge_box_popup_ctrl(vh_packet_t *packet)
  290. {
  291. u8 channel = packet->buf[0];
  292. u8 data = packet->buf[1];
  293. if (!bt_tws_channel_check(channel)) {
  294. return;
  295. }
  296. if ((data == 1) || (data == 2)) { //开或关广播功能
  297. param_vuart_popup_flag_write(data);
  298. sys_cb.popup_en = data - 1;
  299. ble_adv0_set_ctrl(0);
  300. } else { //翻转广播功能
  301. if (sys_cb.popup_en) {
  302. sys_cb.popup_en = 0;
  303. param_vuart_popup_flag_write(1); //disable
  304. ble_adv0_set_ctrl(0);
  305. } else {
  306. sys_cb.popup_en = 1;
  307. param_vuart_popup_flag_write(2); //enable
  308. ble_adv0_set_ctrl(2);
  309. }
  310. }
  311. }
  312. bool charge_box_bat_is_ready(void)
  313. {
  314. return vhouse_cb.rem_bat_ok;
  315. }
  316. u8 charge_box_get_charge_box_bat_level(void)
  317. {
  318. if(bt_tws_is_connected()){
  319. if((sys_cb.loc_bat & BIT(7)) == 0 && (sys_cb.rem_bat & BIT(7)) != 0) {
  320. return sys_cb.rem_house_bat & 0x7f;
  321. }
  322. }
  323. return sys_cb.loc_house_bat & 0x7f;
  324. }
  325. #if (CHARGE_BOX_INTF_SEL == INTF_UART1) || (CHARGE_BOX_INTF_SEL == INTF_UART2)
  326. //uart中断解析并匹配命令包
  327. AT(.com_text.charge_box)
  328. void charge_box_packet_recv(void)
  329. {
  330. #if QTEST_EN
  331. if(qtest_get_mode()){
  332. return ;
  333. }
  334. #endif
  335. vh_packet_t *p = &vh_packet;
  336. vhouse_cb.ticks = tick_get();
  337. if (p->cmd == VHOUSE_CMD_OPEN_WINDOW) {
  338. vhouse_cb.win_ticks = vhouse_cb.ticks;
  339. vhouse_cb.open_win_flag = 1;
  340. }
  341. if((!vhouse_cb.ack_dat_confirm)||(vhouse_cb.ack_dat == p->buf[0])){
  342. vhouse_cb.ack_dat = p->buf[0];
  343. if((p->cmd != VHOUSE_CMD_PAIR)&&(p->cmd != VHOUSE_CMD_GET_TWS_BTADDR)){
  344. vhouse_cb.need_ack = 1;
  345. }
  346. }
  347. }
  348. #elif (CHARGE_BOX_INTF_SEL == INTF_HUART)
  349. AT(.com_rodata.charge_box_tbl)
  350. const char charge_box_header[]={0x55,0xAA,0xFF};
  351. //uart中断解析并匹配命令包
  352. AT(.com_text.charge_box)
  353. void charge_box_packet_huart_recv(u8 *buf)
  354. {
  355. if(qtest_get_mode()) {
  356. return ;
  357. }
  358. if(!memcmp(buf,charge_box_header,3)) {
  359. if(buf[4] < VH_DATA_LEN){
  360. vh_packet_t *packet = &vhouse_cb.packet;
  361. vhouse_cb.ticks = tick_get();
  362. if (buf[3] == VHOUSE_CMD_OPEN_WINDOW) {
  363. vhouse_cb.win_ticks = vhouse_cb.ticks;
  364. vhouse_cb.open_win_flag = 1;
  365. }
  366. if((!vhouse_cb.ack_dat_confirm) || (vhouse_cb.ack_dat == buf[5])){
  367. vhouse_cb.ack_dat = buf[5];
  368. if((buf[3] != VHOUSE_CMD_PAIR) && (buf[3] != VHOUSE_CMD_GET_TWS_BTADDR)) {
  369. vhouse_cb.need_ack = 1;
  370. }
  371. }
  372. memcpy(packet, buf, buf[4]+5);
  373. packet->checksum = buf[packet->length+5];
  374. vhouse_cb.rx_flag=1;
  375. }
  376. }
  377. }
  378. #endif
  379. //接收心跳包后需要5~10ms回应1字节
  380. AT(.com_text.timer)
  381. void charge_box_heart_beat_ack(void)
  382. {
  383. if (vhouse_cb.need_ack == 1) {
  384. if (tick_check_expire(vhouse_cb.ticks, 6)) {
  385. #if (CHARGE_BOX_INTF_SEL == INTF_HUART)
  386. huart_tx((u8*)&vhouse_cb.ack_dat,1);
  387. #elif (CHARGE_BOX_INTF_SEL == INTF_UART1)
  388. UART1DATA = vhouse_cb.ack_dat;
  389. #elif (CHARGE_BOX_INTF_SEL == INTF_UART2)
  390. UART2DATA = vhouse_cb.ack_dat;
  391. #endif
  392. vhouse_cb.need_ack = 2;
  393. }
  394. }
  395. }
  396. AT(.text.charge_box)
  397. static void charge_box_send_data(u8 *buf,u8 len)
  398. {
  399. //超过5ms没有接收到VBUS程序才发送数据
  400. while (!tick_check_expire(vhouse_cb.ticks, 5)) {
  401. WDT_CLR();
  402. }
  403. if(vhouse_cb.need_ack == 2) {
  404. while (!(UART1CON & BIT(8)));
  405. }
  406. vhouse_cb.need_ack = 0;
  407. if(tick_check_expire(vhouse_cb.ticks, 80)){
  408. return;
  409. }
  410. #if (CHARGE_BOX_INTF_SEL == INTF_HUART)
  411. huart_tx(buf,len);
  412. #elif (CHARGE_BOX_INTF_SEL == INTF_UART1)
  413. for(u8 i = 0; i < len; i++){
  414. uart1_putchar(buf[i]);
  415. }
  416. #elif (CHARGE_BOX_INTF_SEL == INTF_UART2)
  417. for(u8 i = 0; i < len; i++){
  418. uart2_putchar(buf[i]);
  419. }
  420. #endif
  421. }
  422. AT(.text.charge_box)
  423. static void charge_box_cmd_ack(vh_packet_t *packet)
  424. {
  425. u8 *buf = (u8*)packet;
  426. u8 length = 5 + packet->length;
  427. buf[length] = crc8_maxim(buf, length);
  428. charge_box_send_data(buf, length + 1);
  429. }
  430. AT(.text.charge_box)
  431. static void charge_box_send_msg_suceess(void)
  432. {
  433. vh_packet_t *packet = &vhouse_cb.packet;
  434. packet->header = 0xAA55;
  435. packet->distinguish = VHOUSE_DISTINGUISH;
  436. packet->cmd = VHOUSE_CMD_SUCCESS;
  437. packet->length = 0;
  438. charge_box_cmd_ack(packet);
  439. }
  440. AT(.text.charge_box)
  441. static void charge_box_update_bat_value(vh_packet_t *packet)
  442. {
  443. bool update_flag = false;
  444. if ((packet->cmd == VHOUSE_CMD_OPEN_WINDOW) || (packet->cmd == VHOUSE_CMD_GET_VBAT)||packet->cmd == VHOUSE_CMD_CLOSE_WIN_GET_VBAT) {
  445. if(sys_cb.loc_house_bat != packet->buf[1]) {
  446. sys_cb.loc_house_bat = packet->buf[1];
  447. sys_cb.rem_house_bat = packet->buf[1];
  448. update_flag = true;
  449. }
  450. if(packet->cmd == VHOUSE_CMD_CLOSE_WIN_GET_VBAT) {
  451. return;
  452. }
  453. if(packet->buf[2] & BIT(7)) {
  454. if(sys_cb.rem_bat != packet->buf[2]) { //对方在仓内,且电量不为0时,用仓互传
  455. if((packet->buf[2]&0x7f) == 0) {
  456. sys_cb.rem_bat |= BIT(7);
  457. } else {
  458. sys_cb.rem_bat = packet->buf[2];
  459. vhouse_cb.rem_bat_ok = true;
  460. }
  461. update_flag = true;
  462. }
  463. } else {
  464. if(vhouse_cb.rem_bat_ok) {
  465. update_flag = true;
  466. }
  467. vhouse_cb.rem_bat_ok = false; //对方出仓后,电量通过TWS互传
  468. }
  469. if(!vhouse_cb.inbox_sta) {
  470. vhouse_cb.inbox_sta = true;
  471. update_flag = true;
  472. }
  473. }
  474. vhouse_cb.update_ear_flag = update_flag;
  475. }
  476. //分析电量接收包并回应相关电量数据
  477. AT(.text.charge_box)
  478. static void charge_box_vbat_ack(vh_packet_t *packet)
  479. {
  480. vhouse_cb.cmd3_rx_flag = 0;
  481. u8 channel = packet->buf[0];
  482. if (!bt_tws_channel_check(channel)) {
  483. // vhouse_send_message_err();
  484. return;
  485. }
  486. charge_box_update_bat_value(packet);
  487. //发送电量响应包
  488. packet->header = 0xAA55;
  489. packet->distinguish = VHOUSE_DISTINGUISH;
  490. packet->length = 0x04;
  491. packet->buf[0] = channel;
  492. packet->buf[2] = sys_cb.loc_bat;
  493. packet->buf[3] = sys_cb.charge_sta;
  494. charge_box_cmd_ack(packet);
  495. }
  496. AT(.text.charge_box)
  497. static void charge_box_pair_ack(vh_packet_t *packet)
  498. {
  499. u8 channel = packet->buf[0];
  500. if (!bt_tws_channel_check(channel)) {
  501. return;
  502. }
  503. if((channel != LEFT_CHANNEL_USER) || vhouse_cb.cmd3_rx_flag){
  504. //发送蓝牙地址包
  505. u8 bt_tws_addr[6];
  506. u8 feature = bt_tws_get_link_info(bt_tws_addr);
  507. memset(packet, 0, sizeof(vh_packet_t));
  508. packet->header = 0xAA55;
  509. packet->distinguish = VHOUSE_DISTINGUISH;
  510. packet->cmd = VHOUSE_CMD_GET_TWS_BTADDR;
  511. packet->length = 14;
  512. packet->buf[0] = (channel == RIGHT_CHANNEL_USER) ? LEFT_CHANNEL_USER : RIGHT_CHANNEL_USER; //发送对方声道
  513. memcpy(packet->buf+1, bt_tws_addr, 6); //TWS地址
  514. memcpy(packet->buf+7, xcfg_cb.bt_addr, 6); //本地的地址
  515. packet->buf[13] = feature; //TWS主从Feature
  516. charge_box_cmd_ack(packet);
  517. if (!bt_tws_is_slave()) {
  518. bt_nor_disconnect();
  519. ble_adv0_idx_update();
  520. }
  521. }else{
  522. vhouse_cb.cmd3_rx_flag = 1;
  523. }
  524. }
  525. AT(.text.charge_box)
  526. static void charge_box_clr_tws_link_info(void)
  527. {
  528. bt_clr_master_addr();
  529. bt_tws_delete_link_info_with_tag(BT_INFO_TAG_CHARGE_BOX, (uint32_t)__builtin_return_address(0));
  530. }
  531. AT(.text.iodm)
  532. static void charge_box_clr_bt_all_link_info(void)
  533. {
  534. bt_clr_master_addr();
  535. bt_nor_delete_link_info();
  536. bt_tws_delete_link_info_with_tag(BT_INFO_TAG_CHARGE_BOX, (uint32_t)__builtin_return_address(0));
  537. }
  538. AT(.text.charge_box)
  539. static void charge_box_get_tws_btaddr_ack(vh_packet_t *packet)
  540. {
  541. vhouse_cb.cmd3_rx_flag = 1;
  542. u8 tws_role = 0;
  543. u8 bt_tws_addr[6], new_addr[6];
  544. u8 channel = packet->buf[0];
  545. u8 pkt_feature = packet->buf[13];
  546. u8 feature = bt_tws_get_link_info(bt_tws_addr); //获取TWS地址及feature
  547. if (!bt_tws_channel_check(channel)) {
  548. return;
  549. }
  550. //TWS地址不匹配或Feature不对需要清除配对信息
  551. if ((memcmp(packet->buf+1, bt_tws_addr, 6) != 0) || (feature == pkt_feature) || (feature == 0) || (pkt_feature == 0)) {
  552. if(bt_tws_is_connected()){
  553. bt_tws_disconnect();
  554. }
  555. tws_role = bt_tws_get_tws_role();
  556. TRACE("BT_ADDDR_IS_DIFF: %d\n", tws_role);
  557. charge_box_clr_tws_link_info();
  558. if (tws_role) {
  559. memcpy(new_addr, packet->buf + 7, 6); //保存master
  560. } else {
  561. memcpy(new_addr, xcfg_cb.bt_addr, 6);
  562. }
  563. tws_update_local_addr(new_addr);
  564. u8 data[4];
  565. data[0] = new_addr[2];
  566. data[1] = new_addr[3];
  567. data[2] = new_addr[4];
  568. data[3] = new_addr[5];
  569. bt_tws_put_link_info_addr(new_addr,data);
  570. bt_tws_put_link_info_feature(new_addr, tws_role);
  571. }
  572. if (sys_cb.tws_force_channel == 1) {
  573. charge_box_send_msg_suceess();
  574. }
  575. if(tws_role){
  576. bt_tws_connect();
  577. }
  578. }
  579. AT(.text.charge_box)
  580. void bsp_vhouse_get_ear_addr(vh_packet_t *packet)
  581. {
  582. u8 channel = packet->buf[0];
  583. if (!bt_tws_channel_check(channel)) {
  584. return;
  585. }
  586. //发送蓝牙地址包
  587. u8 bt_tws_addr[6];
  588. u8 feature = bt_tws_get_link_info(bt_tws_addr);
  589. memset(packet, 0, sizeof(vh_packet_t));
  590. packet->header = 0xAA55;
  591. packet->distinguish = VHOUSE_DISTINGUISH;
  592. packet->cmd = VHOUSE_CMD_GET_EAR_ADDR;
  593. packet->length = 16;
  594. packet->buf[0] = channel;
  595. memcpy(packet->buf+1, bt_tws_addr, 6); //TWS地址
  596. memcpy(packet->buf+7, xcfg_cb.bt_addr, 6); //本地的地址
  597. packet->buf[13] = feature; //TWS主从Feature
  598. u16 link_key_sum = 0;
  599. u8 link_key[16];
  600. memset(link_key, 0, 16);
  601. btstack_get_link_key(bt_tws_addr, link_key, NULL, 1);
  602. for (u8 i = 0; i < 16; i++) {
  603. link_key_sum += link_key[i];
  604. }
  605. memcpy(packet->buf+14, (u8 *)&link_key_sum, 2);
  606. charge_box_cmd_ack(packet);
  607. }
  608. AT(.text.charge_box)
  609. static void charge_box_analysis_packet(vh_packet_t *packet)
  610. {
  611. u8 cmd = packet->cmd;
  612. switch (cmd) {
  613. case VHOUSE_CMD_GET_VBAT:
  614. // TRACE("VHOUSE_CMD_GET_VBAT\n");
  615. charge_box_vbat_ack(packet);
  616. break;
  617. case VHOUSE_CMD_PAIR:
  618. TRACE("VHOUSE_CMD_PAIR\n");
  619. charge_box_pair_ack(packet);
  620. break;
  621. case VHOUSE_CMD_GET_TWS_BTADDR:
  622. TRACE("VHOUSE_CMD_GET_TWS_BTADDR\n");
  623. charge_box_get_tws_btaddr_ack(packet);
  624. break;
  625. case VHOUSE_CMD_CLEAR_PAIR:
  626. TRACE("VHOUSE_CMD_CLEAR_PAIR\n");
  627. charge_box_clr_bt_all_link_info(); //删除所有配对信息
  628. break;
  629. case VHOUSE_CMD_PWROFF:
  630. TRACE("VHOUSE_CMD_PWROFF\n");
  631. vhouse_cb.status = 2; //充满电
  632. func_cb.sta = FUNC_PWROFF;
  633. break;
  634. case VHOUSE_CMD_CLOSE_WINDOW:
  635. TRACE("VHOUSE_CMD_CLOSE_WINDOW\n");
  636. vhouse_cb.open_win_flag = 0;
  637. vhouse_cb.status = 0; //关盖, 充电
  638. charge_box_vbat_ack(packet);
  639. break;
  640. case VHOUSE_CMD_OPEN_WINDOW:
  641. TRACE("VHOUSE_CMD_OPEN_WINDOW\n");
  642. charge_box_open_windows();
  643. charge_box_vbat_ack(packet);
  644. break;
  645. case VHOUSE_CMD_ENABLE_POPUP:
  646. TRACE("VHOUSE_CMD_ENABLE_POPUP\n");
  647. charge_box_popup_ctrl(packet);
  648. break;
  649. case VHOUSE_CMD_GET_EAR_ADDR:
  650. TRACE("VHOUSE_CMD_GET_EAR_ADDR\n");
  651. bsp_vhouse_get_ear_addr(packet);
  652. break;
  653. case VHOUSE_CMD_SYS_RST:
  654. sw_reset_kick(SW_RST_FLAG);
  655. break;
  656. default:
  657. break;
  658. }
  659. le_popup_vhouse_cmd_notice(cmd);
  660. }
  661. AT(.text.charge_box)
  662. static void charge_box_analysis_packet_for_charge(vh_packet_t *packet)
  663. {
  664. switch (packet->cmd) {
  665. //仓关盖后获取电量
  666. case VHOUSE_CMD_CLOSE_WIN_GET_VBAT:
  667. TRACE("VHOUSE_DISP_VBAT\n");
  668. charge_box_vbat_ack(packet);
  669. vhouse_cb.open_win_flag = 0;
  670. vhouse_cb.status = 0; //关盖, 充电
  671. break;
  672. //仓开盖后获取电量
  673. case VHOUSE_CMD_OPEN_WINDOW:
  674. TRACE("VHOUSE_CMD_OPEN_WINDOW\n");
  675. case VHOUSE_CMD_GET_VBAT:
  676. TRACE("VHOUSE_CMD_GET_VBAT\n");
  677. charge_box_vbat_ack(packet);
  678. vhouse_cb.status = 1; //开窗,停止充电
  679. break;
  680. case VHOUSE_CMD_PWROFF:
  681. TRACE("VHOUSE_CMD_PWROFF\n");
  682. vhouse_cb.status = 2; //充满电
  683. break;
  684. default:
  685. break;
  686. }
  687. }
  688. AT(.text.charge_box)
  689. u32 charge_box_ssw_process(u32 charge_sta)
  690. {
  691. #if QTEST_EN
  692. if(qtest_get_mode()){
  693. return 0;
  694. }
  695. #endif
  696. vh_packet_t *packet = &vhouse_cb.packet;
  697. if(vhouse_cb.open_win_flag && tick_check_expire(vhouse_cb.win_ticks, 180)) {
  698. charge_box_open_windows(); //防止开盖命令被堵而丢失的问题
  699. }
  700. if(tick_check_expire(vhouse_cb.loc_ticks, 500)) { //没必要一直检测,容易跳来跳去
  701. u8 loc_bat = bsp_get_bat_level();
  702. //修正会充不满电的问题
  703. if(charge_sta&&(loc_bat==100)) {
  704. loc_bat=99;
  705. }
  706. if((sys_cb.loc_bat & 0x7f) != loc_bat) {
  707. sys_cb.loc_bat = (sys_cb.loc_bat & 0x80) | loc_bat;
  708. vhouse_cb.update_ear_flag = true;
  709. }
  710. vhouse_cb.loc_ticks = tick_get();
  711. }
  712. #if (CHARGE_BOX_INTF_SEL == INTF_HUART)
  713. if(vhouse_cb.rx_flag) {
  714. if(packet->checksum == crc8_maxim((u8 *)packet, 5 + packet->length)) {
  715. // TRACE("cmd [%d], %d\n", packet->cmd, charge_sta);
  716. if (charge_sta) {
  717. charge_box_analysis_packet_for_charge(packet);
  718. } else {
  719. reset_sleep_delay(); //耳机在仓内不进休眠, 需要接收电量心跳包数据
  720. charge_box_analysis_packet(packet);
  721. charge_box_update_bat_adv();
  722. }
  723. }
  724. vhouse_cb.rx_flag=0;
  725. }
  726. #elif ((CHARGE_BOX_INTF_SEL == INTF_UART1) || (CHARGE_BOX_INTF_SEL == INTF_UART2))
  727. u8 parse_done;
  728. u8 ch;
  729. #if (CHARGE_BOX_INTF_SEL == INTF_UART1)
  730. while (bsp_uart1_get(&ch))
  731. #elif (CHARGE_BOX_INTF_SEL == INTF_UART2)
  732. while (bsp_uart2_get(&ch))
  733. #endif
  734. {
  735. WDT_CLR();
  736. parse_done = bsp_uart_packet_parse(packet, ch);
  737. if ((parse_done) && (packet->checksum == crc8_maxim((u8 *)packet, 5 + packet->length))) {
  738. TRACE("cmd [%d], %d\n", packet->cmd, charge_sta);
  739. if (charge_sta) {
  740. charge_box_analysis_packet_for_charge(packet);
  741. } else {
  742. reset_sleep_delay(); //耳机在仓内不进休眠, 需要接收电量心跳包数据
  743. charge_box_analysis_packet(packet);
  744. charge_box_update_bat_adv();
  745. }
  746. }
  747. }
  748. #endif
  749. if (charge_sta == 0) {
  750. charge_box_update_bat_adv();
  751. }
  752. return vhouse_cb.status;
  753. }
  754. void charge_box_channel_confirm(void)
  755. {
  756. u8 channel = bt_tws_get_tws_channel();
  757. if(!channel){
  758. return ;
  759. }
  760. vhouse_cb.ack_dat_confirm=1;
  761. if (channel == LEFT_CHANNEL) {
  762. vhouse_cb.ack_dat = LEFT_CHANNEL_USER;
  763. }else if(channel == RIGHT_CHANNEL){
  764. vhouse_cb.ack_dat = RIGHT_CHANNEL_USER;
  765. }
  766. }
  767. void charge_box_ssw_init(void)
  768. {
  769. printf("charge_box_ssw_init\n");
  770. memset(&vhouse_cb, 0, sizeof(vhouse_cb));
  771. tws_lr_xcfg_sel();
  772. charge_box_channel_confirm();
  773. bt_tws_channel_read();
  774. }
  775. #endif
  776. #endif