charge.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "include.h"
  2. #if CHARGE_EN
  3. #define TRACE_EN 0
  4. #if TRACE_EN
  5. #define TRACE(...) printf(__VA_ARGS__)
  6. #else
  7. #define TRACE(...)
  8. #endif
  9. #if CHARGE_LOW_POWER_EN
  10. u32 charge_pll0con0;
  11. #endif
  12. void unlock_code_charge(void);
  13. static charge_cfg_t charge_cfg;
  14. //充满电亮蓝灯时间table表
  15. AT(.rodata.charge)
  16. const u8 ch_bled_timeout_tbl[8] = {0, 10, 20, 30, 60, 120, 180, 255};
  17. //充满电亮蓝灯时间控制
  18. AT(.com_text.charge)
  19. void charge_bled_ctrl(void)
  20. {
  21. if (sys_cb.charge_bled_flag) {
  22. if (sys_cb.ch_bled_cnt) {
  23. if (sys_cb.ch_bled_cnt != 255) {
  24. sys_cb.ch_bled_cnt--;
  25. }
  26. } else {
  27. sys_cb.charge_bled_flag = 0;
  28. bled_set_off();
  29. }
  30. }
  31. }
  32. ///降低充电时主控耗电
  33. AT(.text.charge)
  34. static void charge_power_save(void)
  35. {
  36. sys_clk_free_all(); //释放其它模块sys_clk_req的系统时钟
  37. #if CHARGE_LOW_POWER_EN
  38. sys_clk_set(SYS_RC2M); //跑RC2M
  39. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  40. set_uart1_baud_rc2m_clk(9600);
  41. #endif
  42. sys_cb.charge_timr0_pr = TMR0PR;
  43. GLOBAL_INT_DISABLE();
  44. TMR0CON &= ~(7 << 1); //timer0 clk Select system clock
  45. // TMR0CON |= BIT(3); //timer0 CLK Select RC
  46. TMR0CNT = 0;
  47. TMR0PR = 2000000/1000 - 1; //2M Hz, 1ms_isr
  48. CLKCON1 &= ~(BIT(25)|BIT(26)); //saradc clk select RC
  49. GLOBAL_INT_RESTORE();
  50. clk_xosc_dis();
  51. #else
  52. sys_clk_set(SYS_24M);
  53. dac_clk_source_sel(2); //dac clk select xosc26m_clk
  54. #endif
  55. #if CHARGE_LOW_POWER_EN
  56. RSTCON0 &= ~BIT(4); //PLLSDM reset control
  57. charge_pll0con0 = PLL0CON0;
  58. PLL0CON0 = 0; //disable PLL
  59. #else
  60. clk_pll0_dis();
  61. #endif
  62. }
  63. AT(.text.charge)
  64. static void charge_power_recover(void)
  65. {
  66. #if CHARGE_LOW_POWER_EN
  67. clk_xosc_en();
  68. #endif
  69. #if CHARGE_LOW_POWER_EN
  70. PLL0CON0 = charge_pll0con0;
  71. adpll_init(DAC_OUT_SPR); //关了pll_ldo后需要重新init trim回频率
  72. #else
  73. clk_pll0_en();
  74. #endif
  75. sys_clk_set(SYS_CLK_SEL);
  76. #if !CHARGE_LOW_POWER_EN
  77. dac_clk_source_sel(1); //dac clk select adda_clk48
  78. #else
  79. GLOBAL_INT_DISABLE();
  80. CLKCON1 |= BIT(25); //saradc clk select x26m_clkdiv6
  81. TMR0CNT = 0;
  82. TMR0PR = sys_cb.charge_timr0_pr;
  83. TMR0CON &= ~(7 << 1); //timer0 clk
  84. TMR0CON |= 6 << 1; //tmr_inc select x26m_div_clk = 1M
  85. GLOBAL_INT_RESTORE();
  86. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  87. set_uart1_baud(9600);
  88. #endif
  89. #endif
  90. }
  91. #if TRACE_EN
  92. AT(.com_rodata.tkey)
  93. const char charge_on_str[] = "Charge on\n";
  94. AT(.com_rodata.tkey)
  95. const char charge_off_str[] = "Charge off: %d\n";
  96. #endif
  97. AT(.charge_text.det)
  98. void charge_status(u8 sta)
  99. {
  100. if (sta == 1) {
  101. //充电开启
  102. sys_cb.charge_sta = 1;
  103. sys_cb.charge_bled_flag = 0;
  104. #if !HLW_UI
  105. charge_led_on();
  106. #endif
  107. TRACE(charge_on_str);
  108. } else {
  109. //充电关闭
  110. TRACE(charge_off_str, sta);
  111. sys_cb.charge_sta = 0;
  112. sys_cb.charge_bled_flag = 0;
  113. #if !HLW_UI
  114. charge_led_off();
  115. #endif
  116. if (sta == 2) {
  117. sys_cb.charge_sta = 2;
  118. //充电满亮蓝灯
  119. if (BLED_CHARGE_FULL) {
  120. sys_cb.charge_bled_flag = 1;
  121. sys_cb.ch_bled_cnt = charge_cfg.bled_on_pr;
  122. #if !HLW_UI
  123. charge_bled_on();
  124. #endif
  125. }
  126. }
  127. }
  128. }
  129. AT(.text.charge)
  130. u8 charge_charge_on_process(void)
  131. {
  132. u8 charge_sta = 0;
  133. static u32 counter = 0;
  134. counter++;
  135. if ((counter % 20) == 0) {
  136. charge_detect(0);
  137. }
  138. if ((counter % 200) == 0) {
  139. #if HLW_UI
  140. vusb4s_reset_clr_cnt();
  141. #else
  142. vusb4s_reset_dis();
  143. #endif
  144. vusb_reset_clr();
  145. #if !HLW_UI
  146. charge_bled_ctrl();
  147. #endif
  148. }
  149. if (CHARGE_DC_IN()) {
  150. if ((counter % 1000) == 0) { //5秒
  151. bsp_charge_bcnt_calibration((CHARGE_BOX_EN) ? 100 : 500);
  152. }
  153. }
  154. #if CHARGE_BOX_EN
  155. charge_sta = charge_box_charge_on_process();
  156. #endif
  157. tkey_proc_calibration_in_charge();
  158. return charge_sta;
  159. }
  160. AT(.text.charge.process)
  161. void charge_process(void)
  162. {
  163. #if FUNC_USBDEV_EN
  164. if(func_cb.sta != FUNC_USBDEV)
  165. #endif // FUNC_USBDEV_EN
  166. {
  167. if (CHARGE_DC_IN() && (sys_cb.dc_in_filter == CHARGE_DC_IN_FILTER)) {
  168. sys_cb.dc_in_filter = CHARGE_DC_IN_FILTER + 1;
  169. if (func_bt_charge_dcin()) {
  170. sys_cb.pwrdwn_tone_en = 0;
  171. func_cb.sta = FUNC_CHARGE;
  172. }
  173. }
  174. charge_detect(1);
  175. #if CHARGE_BOX_EN
  176. charge_box_process();
  177. #endif
  178. }
  179. }
  180. AT(.text.charge)
  181. void charge_enter(u8 out_auto_pwron)
  182. {
  183. printf("charge_enter\n");
  184. #if CHARGE_BOX_EN
  185. charge_box_enter(out_auto_pwron);
  186. #endif
  187. charge_power_save();
  188. vusb4s_reset_dis();
  189. }
  190. AT(.text.charge)
  191. void charge_exit(void)
  192. {
  193. charge_power_recover();
  194. charge_off();
  195. #if CHARGE_BOX_EN
  196. charge_box_reinit();
  197. #endif
  198. tkey_stop_calibration_in_charge();
  199. printf("charge_exit\n");
  200. }
  201. bool charge_power_on_pre(u32 rtccon9)
  202. {
  203. int ch_dc_sw_rst = 0;
  204. if (sys_cb.sw_rst_flag == SW_RST_DC_IN) {
  205. ch_dc_sw_rst = 1;
  206. }
  207. u8 chbox_out2pwr_en = 0;
  208. #if CHARGE_BOX_EN
  209. if ((rtccon9 & BIT(4)) && (xcfg_cb.ch_out_auto_pwron_en) && (xcfg_cb.ch_box_type_sel != 3)) { //charge inbox wakeup直接开机(5V完全掉电无维持电压的仓不开机)
  210. if (charge_box_outbox_stable_check()) {
  211. sys_cb.outbox_pwron_flag = 1;
  212. printf("inbox wakeup\n");
  213. return true;
  214. }
  215. }
  216. //是否需要拿起开机
  217. if ((sys_cb.rst_reason & BIT(17)) || (rtccon9 & BIT(3)) || (ch_dc_sw_rst) || (sys_cb.inbox_wken_flag)) { //vusb reset or wakeup
  218. chbox_out2pwr_en = xcfg_cb.ch_out_auto_pwron_en;
  219. }
  220. #endif
  221. charge_enter(chbox_out2pwr_en);
  222. #if HLW_UI
  223. vusb4s_reset_en();
  224. #endif
  225. return false;
  226. }
  227. AT(.text.charge)
  228. void charge_off(void)
  229. {
  230. if (charge_cfg.chag_sta >= 3) {
  231. charge_stop(0);
  232. }
  233. }
  234. AT(.text.charge)
  235. void charge_set_stop_time(u16 stop_time)
  236. {
  237. charge_cfg.stop_time = stop_time;
  238. }
  239. void charge_init(void)
  240. {
  241. charge_cfg_t *p = &charge_cfg;
  242. memset(p, 0, sizeof(charge_cfg_t));
  243. p->trick_curr_en = CHARGE_TRICK_EN;
  244. p->const_curr = CHARGE_CONSTANT_CURR;
  245. if (p->const_curr > 15) {
  246. p->const_curr = (p->const_curr - 15) * 2 + 15;
  247. }
  248. p->const_curr = p->const_curr & 0x3f;
  249. p->trick_curr = CHARGE_TRICKLE_CURR & 0xf;
  250. p->stop_curr = CHARGE_STOP_CURR & 0x0f;
  251. p->stop_volt = CHARGE_STOP_VOLT & 0x03;
  252. p->leakage = xcfg_cb.ch_leakage_sel;
  253. p->inbox_voltage = xcfg_cb.ch_inbox_sel;
  254. p->dcin_reset = 0x01;
  255. p->trick_stop_volt = CHARGE_TRICK_STOP_VOLT;
  256. p->stop_time = 18000; //默认30分钟
  257. p->bled_on_pr = ch_bled_timeout_tbl[BLED_CHARGE_FULL];
  258. p->charge_sta_func = charge_status;
  259. p->ldo_en = 1; //默认普通充电使用LDO mode,
  260. p->volt_follow_en = CHARGE_VOLT_FOLLOW_EN;
  261. p->volt_follow_diff = CHARGE_VOLT_FOLLOW_DIFF & 0x03;
  262. if (CHARGE_VOLT_FOLLOW_EN) {
  263. p->ldo_en = 0; //开启电压跟随模式,强制不能开LD0 充电mode
  264. }
  265. if (RTCCON3 & BIT(12)) {
  266. sys_cb.inbox_wken_flag = 1; //修正触摸唤醒拿出不能开机问题
  267. }
  268. RTCCON3 &= ~BIT(12); //RTCCON3[12], INBOX Wakeup disable
  269. RTCCON11 &= ~BIT(6); //VUSB pull out filter
  270. charge_init_do(p);
  271. #if CHARGE_BOX_EN
  272. charge_box_init();
  273. #endif
  274. vusb4s_reset_en();
  275. }
  276. #endif // CHARGE_EN