ulp_riscv_adc_example_main.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. /* ULP riscv example
  7. This example code is in the Public Domain (or CC0 licensed, at your option.)
  8. Unless required by applicable law or agreed to in writing, this
  9. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  10. CONDITIONS OF ANY KIND, either express or implied.
  11. */
  12. #include <stdio.h>
  13. #include <inttypes.h>
  14. #include "esp_sleep.h"
  15. #include "ulp_riscv.h"
  16. #include "ulp_riscv_adc.h"
  17. #include "ulp_main.h"
  18. #include "ulp/example_config.h"
  19. #include "esp_err.h"
  20. #include "driver/adc.h"
  21. #include "esp_adc/adc_oneshot.h"
  22. #include "esp_adc/adc_cali.h"
  23. #include "esp_adc/adc_cali_scheme.h"
  24. #include "user_sleep.h"
  25. #include "freertos/FreeRTOS.h"
  26. #include "freertos/task.h"
  27. #include "driver/uart.h"
  28. #include "esp_sleep.h"
  29. #include "esp_log.h"
  30. #include "esp_timer.h"
  31. #include "SPIFFS.h"
  32. #include "LORA.h"
  33. #include "FONT_LIB.h"
  34. #include "driver/rtc_io.h"
  35. #include "user_time.h"
  36. #include "Decection.h"
  37. #include "yc_protocol.h"
  38. #include "esp_sleep.h"
  39. #include "soc/sens_reg.h"
  40. #include "driver/gpio.h"
  41. #include "ulp_riscv.h"
  42. #include "freertos/FreeRTOS.h"
  43. #include "freertos/task.h"
  44. #include "freertos/timers.h"
  45. #include "esp_sleep.h"
  46. #include "driver/uart.h"
  47. #include "iot_button.h"
  48. static const char *LOG_TAG = "ulp_riscv_adc";
  49. extern uint8_t _wakeup_reson; //内存上次唤醒的原因
  50. extern QueueHandle_t screen_queue;
  51. bool is_first_run = false; //当前时间片只执行一次标志
  52. bool is_first_charge = false; //当前充电发送只执行一次标志
  53. uint8_t charging_flag;
  54. extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
  55. extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
  56. static void init_ulp_program(void);
  57. extern void app_init();
  58. extern RTC_DATA_ATTR uint8_t wakeup_reson; //内存上次唤醒的原因
  59. extern int64_t sleep_before_us; //开始进入睡眠时间
  60. extern int64_t sleep_afterr_us; //唤醒时间
  61. volatile int charge_is_success;
  62. volatile int charge_is_running;
  63. bool read_charge_is_success()
  64. {
  65. return true;
  66. }
  67. bool read_charge_is_running()
  68. {
  69. return true;
  70. }
  71. static void light_sleep_task(void *args)
  72. {
  73. // if(Machine_info.eflagID != 0xff) //如果未分配ID
  74. // {
  75. // esp_light_sleep_start(); //进入休眠
  76. // }
  77. extern bool is_adv;
  78. int bat_times = 0;
  79. int lev_2 = 0;
  80. while (true)
  81. {
  82. extern bool is_sleep;
  83. if(is_sleep == true)
  84. {
  85. //printf("system is ready sleep\r\n");
  86. #if LORA_SLEEP_ENABLE
  87. //rtc_gpio_hold_dis(LORA_POWER_PIN);
  88. lora_set_power_level(0);
  89. //rtc_gpio_hold_en(LORA_POWER_PIN);
  90. #endif
  91. #if USER_LIGHT_SLEEP_ENABLE
  92. is_first_run = false;
  93. printf("start light_sleep ,is_first_run = %d\r\n",is_first_run);
  94. if(Machine_info.power_status == 0) //关机状态
  95. {
  96. //#if LORA_SLEEP_ENABLE
  97. //rtc_gpio_hold_dis(LORA_POWER_PIN);
  98. //lora_set_power_level(0);
  99. // rtc_gpio_hold_en(LORA_POWER_PIN);
  100. //#endif
  101. #if 1
  102. font_into_sleep();
  103. #include "EPD.h"
  104. epd_sleep(SCREEN_LEFT);
  105. epd_sleep(SCREEN_RIGHT);
  106. //gpio_hold_en(PIN_L_CS);
  107. //gpio_hold_en(PIN_R_CS);
  108. // gpio_set_level(PIN_L_CS,1);
  109. // gpio_set_level(PIN_R_CS,1);
  110. //gpio_reset_pin(46);
  111. //uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM);
  112. //ESP_ERROR_CHECK(uart_wait_tx_done(UART_NUM_1,portMAX_DELAY));
  113. esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
  114. // gpio_set_level(LORA_TXD_PIN, 0);
  115. // gpio_set_level(LORA_RXD_PIN, 0);
  116. #if 0
  117. //uart_sleep_in_config();
  118. uart_driver_delete(UART_NUM_1);
  119. gpio_reset_pin(LORA_TXD_PIN);
  120. gpio_reset_pin(LORA_RXD_PIN);
  121. gpio_config_t io_conf = {};
  122. io_conf.pin_bit_mask = (1<<LORA_TXD_PIN);
  123. io_conf.mode = GPIO_MODE_OUTPUT;
  124. io_conf.pull_up_en = false;
  125. gpio_config(&io_conf);
  126. io_conf.pin_bit_mask = (1<<LORA_RXD_PIN);
  127. io_conf.mode = GPIO_MODE_OUTPUT;
  128. io_conf.pull_up_en = false;
  129. gpio_config(&io_conf);
  130. gpio_set_level(LORA_TXD_PIN, 0);
  131. gpio_set_level(LORA_RXD_PIN, 0);
  132. gpio_hold_en(LORA_TXD_PIN);
  133. gpio_hold_en(LORA_RXD_PIN);
  134. #endif
  135. //uart_sleep_out_config();
  136. //uart_driver_delete(UART_NUM_1);
  137. //esp_deep_sleep_start();
  138. #endif
  139. printf("=>deep sleep\r\n");
  140. uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM);
  141. //vTaskDelay(100/ portTICK_PERIOD_MS);
  142. #if 1 //电源按键
  143. adc_oneshot_del_unit(adc1_handle);
  144. gpio_reset_pin(4);
  145. int ext_wakeup_pin_0 = 4;
  146. printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0);
  147. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 0));
  148. // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
  149. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
  150. // No need to keep that power domain explicitly, unlike EXT1.
  151. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_0));
  152. ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_0));
  153. #endif
  154. //充电按键
  155. #if 0
  156. // adc_oneshot_del_unit(adc1_handle);
  157. gpio_reset_pin(2);
  158. int ext_wakeup_pin_1 = 2;
  159. //printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0);
  160. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_1, 0));
  161. // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
  162. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
  163. // No need to keep that power domain explicitly, unlike EXT1.
  164. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_1));
  165. ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_1));
  166. //gpio_hold_en(4);
  167. #else
  168. gpio_reset_pin(2);
  169. const int ext_wakeup_pin_1 = 2;
  170. const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1;
  171. printf("Enabling EXT1 wakeup on pins GPIO %d\r\n", ext_wakeup_pin_1);
  172. ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ALL_LOW));
  173. #endif
  174. adc_oneshot_del_unit(adc1_handle);
  175. esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
  176. ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup());
  177. esp_deep_sleep_start();
  178. //esp_light_sleep_start();
  179. }else if((Machine_info.power_status == 1) && Machine_info.paired == 1) //开机状态且配对
  180. {
  181. //重新配置休眠唤醒时间
  182. //printf("esp_sleep_enable_timer_wakeup ret = %d\n",esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US));//配置当前休眠的唤醒时间
  183. font_into_sleep();
  184. #include "EPD.h"
  185. epd_sleep(SCREEN_LEFT);
  186. epd_sleep(SCREEN_RIGHT);
  187. // uart_driver_delete(UART_NUM_1);
  188. // gpio_reset_pin(LORA_TXD_PIN);
  189. // gpio_reset_pin(LORA_RXD_PIN);
  190. // gpio_config_t io_conf = {};
  191. // io_conf.pin_bit_mask = (1<<LORA_TXD_PIN);
  192. // io_conf.mode = GPIO_MODE_OUTPUT;
  193. // io_conf.pull_up_en = false;
  194. // gpio_config(&io_conf);
  195. // io_conf.pin_bit_mask = (1<<LORA_RXD_PIN);
  196. // io_conf.mode = GPIO_MODE_OUTPUT;
  197. // io_conf.pull_up_en = false;
  198. // gpio_config(&io_conf);
  199. // gpio_set_level(LORA_TXD_PIN, 0);
  200. // gpio_set_level(LORA_RXD_PIN, 0);
  201. // gpio_hold_en(LORA_TXD_PIN);
  202. // gpio_hold_en(LORA_RXD_PIN);
  203. #if 0
  204. adc_oneshot_del_unit(adc1_handle);
  205. gpio_reset_pin(8);
  206. int ext_wakeup_pin_0 = 8;
  207. printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0);
  208. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 0));
  209. // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
  210. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
  211. // No need to keep that power domain explicitly, unlike EXT1.
  212. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_0));
  213. ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_0));
  214. #else
  215. iot_button_stop();
  216. #if 1 //电源按键
  217. // adc_oneshot_del_unit(adc1_handle);
  218. gpio_reset_pin(4);
  219. int ext_wakeup_pin_0 = 4;
  220. printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0);
  221. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 0));
  222. // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
  223. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
  224. // No need to keep that power domain explicitly, unlike EXT1.
  225. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_0));
  226. ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_0));
  227. esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
  228. ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup());
  229. #endif
  230. #if 0
  231. //充电按键
  232. gpio_reset_pin(2);
  233. const int ext_wakeup_pin_1 = 2;
  234. const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1;
  235. printf("Enabling EXT1 wakeup on pins GPIO %d\r\n", ext_wakeup_pin_1);
  236. ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ALL_LOW));
  237. #endif
  238. #endif
  239. esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间
  240. //adc_oneshot_del_unit(adc1_handle);
  241. ESP_LOGW(LOG_TAG,"-> sleep\r\n");
  242. uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM);
  243. uart_wait_tx_idle_polling(1);
  244. extern bool left_refresh_complete;
  245. extern bool right_refresh_complete;
  246. #if 0
  247. while(1)
  248. {
  249. if((left_refresh_timer_isActive() == false) &&(right_refresh_timer_isActive() == false) )
  250. {
  251. break;
  252. }
  253. printf("1left refresh complete %s,right refresh complete %s\n",left_refresh_timer_isActive()?"true":"false",right_refresh_timer_isActive()?"true":"false");
  254. #if 0
  255. if(
  256. (left_refresh_complete == true) || (right_refresh_complete == true)
  257. )
  258. {
  259. printf("left refresh complete %s,right refresh complete %s,",left_refresh_complete?"true":"false",right_refresh_complete?"true":"false");
  260. break;
  261. }
  262. printf("left refresh complete %s,right refresh complete %s,",left_refresh_complete?"true":"false",right_refresh_complete?"true":"false");
  263. #endif
  264. vTaskDelay(100/ portTICK_PERIOD_MS);
  265. }
  266. #endif
  267. //gpio_hold_en(4);
  268. //vTaskDelay(100/ portTICK_PERIOD_MS);
  269. //OTA 不休眠
  270. if(!is_adv){
  271. esp_light_sleep_start();
  272. }else{
  273. iot_button_stop();
  274. ESP_LOGW(LOG_TAG,"OTA not sleep");
  275. }
  276. }
  277. is_sleep = false;
  278. #endif
  279. // #if USER_DEEP_SLEEP_ENABLE
  280. // printf("start deep sleep\r\n");
  281. // uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM);
  282. // //重新配置休眠唤醒时间
  283. // esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间
  284. // // enter deep sleep
  285. // esp_deep_sleep_start();
  286. // #endif
  287. }
  288. //char *wakeup_reason = malloc(20*sizeof(uint8_t));
  289. int reson = esp_sleep_get_wakeup_cause();
  290. if(is_btn_timeout())
  291. {
  292. terminal_send_data(); //添加数据队列
  293. }
  294. // printf("reson = %d\r\n",reson);
  295. switch (reson) {
  296. case ESP_SLEEP_WAKEUP_TIMER:
  297. iot_button_resume();
  298. //wakeup_reason = "timer";
  299. #if LORA_SLEEP_ENABLE
  300. //rtc_gpio_pullup_dis(LORA_POWER_PIN);
  301. //rtc_gpio_deinit(LORA_POWER_PIN);
  302. //rtc_gpio_init(LORA_POWER_PIN);
  303. //rtc_gpio_set_direction(LORA_POWER_PIN, RTC_GPIO_MODE_OUTPUT_ONLY);
  304. //rtc_gpio_pullup_en(LORA_POWER_PIN);
  305. //rtc_gpio_set_level(LORA_POWER_PIN, 1);
  306. lora_set_power_level(1); //打开lora电源
  307. //rtc_gpio_hold_en(LORA_POWER_PIN);
  308. #endif
  309. #if FONT_SLEEP_ENABLE //字库唤醒恢复供电
  310. font_exit_sleep(); //退出睡眠
  311. #endif
  312. #if LCD_SLEEP_ENABLE
  313. #endif
  314. if(is_first_run == false)
  315. {
  316. gpio_hold_dis(LORA_TXD_PIN);
  317. gpio_hold_dis(LORA_RXD_PIN);
  318. //恢复串口i功能
  319. uart_sleep_out_config();
  320. getRtcTime(&Machine_info);
  321. Machine_info.batt_precent = read_battery_voltage();
  322. Machine_info.wait_send_rssi_bat++;
  323. printf("唤醒: bat %d wait_send_rssi_bat = %d,\r\n",Machine_info.batt_precent,Machine_info.wait_send_rssi_bat);
  324. // if(Machine_info.wait_send_rssi_bat>(30*60/TIMER_WAKEUP_TIME_S))//30分钟发一次lora
  325. if(Machine_info.wait_send_rssi_bat>60)
  326. {
  327. ESP_LOGW(LOG_TAG,"30分钟发送数据");
  328. Machine_info.wait_send_rssi_bat = 0;
  329. f_send_get_chart_data();
  330. f_send_lora_rssi(Machine_info.rssi);
  331. f_send_battary_vaule(Machine_info.batt_precent);
  332. }
  333. if((Machine_info.last_button.Minute != Machine_info.min) /*||(Machine_info.last_button.Hour != Machine_info.Hour)*/ ) //
  334. {
  335. if(is_sync_time(&Machine_info)) //同步到时间
  336. {
  337. ESP_LOGW(LOG_TAG,"update left value min %d,last min %d\r\n",Machine_info.min,Machine_info.last_button.Minute);
  338. Machine_info.last_button.time_min += (Machine_info.min - Machine_info.last_button.Minute);
  339. }else
  340. {
  341. printf("time not sync\r\n");
  342. }
  343. }
  344. // printf("wake reason: %s, slept for %lld ms\n",
  345. // wakeup_reason,(sleep_afterr_us - sleep_before_us) / 1000);
  346. printf("start timer id = %d,%d\r\n",Machine_info.eflagID,Machine_info.eflagID * TIMER_CAN_SEND_TIME);
  347. // Machine_info.eflagID = 0x01;
  348. //Already_send_timer_stop();
  349. Already_send_timer_start(LORA_POWER_TIME + (Machine_info.eflagID * TIMER_CAN_SEND_TIME));
  350. //sleep_timer_start(700); //进入睡眠
  351. is_first_run = true;
  352. }
  353. break;
  354. case ESP_SLEEP_WAKEUP_GPIO:
  355. bool is_left = false;
  356. printf("ULP ESP_SLEEP_WAKEUP_GPIO WAKE UP\r\n");
  357. lev_2 = gpio_get_level(2);
  358. {
  359. if(Machine_info.power_status == 0) //关机的情况
  360. {
  361. if(!lev_2) //充电
  362. {
  363. if(is_first_charge == false)
  364. {
  365. Machine_info.is_charge = true; //充电中标志
  366. is_first_charge = true;
  367. gpio_hold_dis(PIN_R_CS);
  368. is_left = false;
  369. if(xQueueSend(screen_queue,&is_left,portMAX_DELAY) != true)
  370. {
  371. ESP_LOGE(LOG_TAG,"queue:screen_queue");
  372. }
  373. // extern void dis_right_instructions();
  374. // dis_right_instructions();
  375. //dis_instructions();
  376. //right_screen_send();
  377. printf("charge in\r\n");
  378. }
  379. }else //未充电
  380. {
  381. if( is_first_charge == true)
  382. {
  383. Machine_info.is_charge = false; //拔掉充电
  384. is_first_charge = false;
  385. //right_screen_send();
  386. gpio_hold_dis(PIN_R_CS);
  387. // extern void dis_right_instructions();
  388. // dis_right_instructions();
  389. is_left = false;
  390. if(xQueueSend(screen_queue,&is_left,portMAX_DELAY) != true)
  391. {
  392. ESP_LOGE(LOG_TAG,"queue:screen_queue");
  393. }
  394. sleep_timer_start(1000);
  395. //user_compare(last_batt_precent,Machine_info.batt_precent);//刷完左屏,比较一次电量。电量图标不同则刷一次右屏
  396. printf("not charge in or charge out\r\n");
  397. }
  398. }
  399. }else if(Machine_info.power_status == 1) //开机的情况
  400. {
  401. if(!lev_2) //充电
  402. {
  403. if(is_first_charge == false)
  404. {
  405. Machine_info.is_charge = true; //充电中标志
  406. is_first_charge = true;
  407. right_screen_send();
  408. printf("charge in\r\n");
  409. }
  410. }else
  411. {
  412. if( is_first_charge == true)
  413. {
  414. Machine_info.is_charge = false; //拔掉充电
  415. is_first_charge = false;
  416. right_screen_send();
  417. //user_compare(last_batt_precent,Machine_info.batt_precent);//刷完左屏,比较一次电量。电量图标不同则刷一次右屏
  418. printf("not charge in or charge out\r\n");
  419. }
  420. }
  421. }
  422. }
  423. break;
  424. case ESP_SLEEP_WAKEUP_UART:
  425. printf("ESP_SLEEP_WAKEUP_UART\r\n");
  426. //wakeup_reason = "uart";
  427. /* Hang-up for a while to switch and execuse the uart task
  428. * Otherwise the chip may fall sleep again before running uart task */
  429. vTaskDelay(1);
  430. break;
  431. case ESP_SLEEP_WAKEUP_ULP:
  432. //wakeup_reason = "ulp";
  433. iot_button_resume();
  434. printf("ULP SLEEP WAKE UP\r\n");
  435. // is_sleep = true;//常按会进休眠,然后ulp唤醒,设置is_sleep = true,再次进入休眠
  436. if(Machine_info.paired && Machine_info.power_status )
  437. {
  438. printf("is_sleep = true\r\n");
  439. vTaskDelay(2000/ portTICK_PERIOD_MS);
  440. is_sleep = true;//配对且开机,进入休眠
  441. }
  442. break;
  443. case ESP_SLEEP_WAKEUP_EXT0:
  444. if(!is_adv)
  445. {
  446. iot_button_resume();
  447. }
  448. if(Machine_info.paired && Machine_info.power_status )
  449. {
  450. vTaskDelay(2000/ portTICK_PERIOD_MS);
  451. is_sleep = true;//配对且开机,进入休眠
  452. }
  453. printf("ESP_SLEEP_WAKEUP_EXT0 \r\n");
  454. break;
  455. default:
  456. //printf("other = %d\r\n",reson);
  457. //esp_light_sleep_start();
  458. //wakeup_reason = "other";
  459. break;
  460. }
  461. //free(wakeup_reason);
  462. /* extern bool is_adv;
  463. if(is_adv)//OTA 模式不检测电量
  464. {
  465. printf("is_adv\r\n");
  466. }
  467. else */if(Machine_info.power_status == 0) //关机的情况
  468. {
  469. user_compare_power_off(Machine_info.last_batt_precent,Machine_info.batt_precent);
  470. }else if(Machine_info.power_status == 1) //开机的情况
  471. {
  472. if(read_battery_voltage() == 0)
  473. {
  474. printf("-->low batt , power off\r\n");
  475. Machine_info.power_status = 0;
  476. // dis_instructions(); //进入关机界面
  477. bool is_left = true;
  478. if(xQueueSend(screen_queue,&is_left,portMAX_DELAY) != true)
  479. {
  480. ESP_LOGE(LOG_TAG,"queue:screen_queue");
  481. }
  482. is_left = false;
  483. if(xQueueSend(screen_queue,&is_left,portMAX_DELAY) != true)
  484. {
  485. ESP_LOGE(LOG_TAG,"queue:screen_queue");
  486. }
  487. sleep_timer_start(1000);
  488. }
  489. lev_2 = gpio_get_level(2);
  490. {
  491. #if 0
  492. if(Machine_info.power_status == 0) //关机的情况
  493. {
  494. if(!lev_2) //充电
  495. {
  496. if(is_first_charge == false)
  497. {
  498. Machine_info.is_charge = true; //充电中标志
  499. is_first_charge = true;
  500. gpio_hold_dis(PIN_R_CS);
  501. is_left = false
  502. if(xQueueSend(screen_queue,&is_left,portMAX_DELAY) != true)
  503. {
  504. ESP_LOGE(LOG_TAG,"queue:screen_queue");
  505. }
  506. // extern void dis_right_instructions();
  507. // dis_right_instructions();
  508. printf("charge in\r\n");
  509. }
  510. }else //未充电
  511. {
  512. if( is_first_charge == true)
  513. {
  514. Machine_info.is_charge = false; //拔掉充电
  515. is_first_charge = false;
  516. gpio_hold_dis(PIN_R_CS);
  517. // extern void dis_right_instructions();
  518. // dis_right_instructions();
  519. is_left = false
  520. if(xQueueSend(screen_queue,&is_left,portMAX_DELAY) != true)
  521. {
  522. ESP_LOGE(LOG_TAG,"queue:screen_queue");
  523. }
  524. sleep_timer_start(1000);
  525. //right_screen_send();
  526. //user_compare(last_batt_precent,Machine_info.batt_precent);//刷完左屏,比较一次电量。电量图标不同则刷一次右屏
  527. printf("not charge in or charge out\r\n");
  528. }
  529. }
  530. }else
  531. #endif
  532. if(Machine_info.power_status == 1) //开机的情况
  533. {
  534. if(!lev_2) //充电
  535. {
  536. if(is_first_charge == false)
  537. {
  538. Machine_info.is_charge = true; //充电中标志
  539. is_first_charge = true;
  540. right_screen_send();
  541. printf("charge in\r\n");
  542. }
  543. }else
  544. {
  545. if( is_first_charge == true)
  546. {
  547. Machine_info.is_charge = false; //拔掉充电
  548. is_first_charge = false;
  549. right_screen_send();
  550. //user_compare(last_batt_precent,Machine_info.batt_precent);//刷完左屏,比较一次电量。电量图标不同则刷一次右屏
  551. printf("not charge in or charge out\r\n");
  552. }
  553. }
  554. }
  555. }
  556. bat_times++;
  557. if(bat_times>30)
  558. {
  559. bat_times = 0;
  560. Machine_info.batt_precent = read_battery_voltage();
  561. printf("compare current bat and last bat refresh display,current = %d,last =%d\r\n",Machine_info.batt_precent,Machine_info.last_batt_precent);
  562. user_compare(Machine_info.last_batt_precent,Machine_info.batt_precent);//刷完左屏,比较一次电量。电量值不同则刷一次右屏
  563. Machine_info.last_batt_precent = Machine_info.batt_precent;
  564. }
  565. }
  566. vTaskDelay(1000/ portTICK_PERIOD_MS);
  567. }
  568. vTaskDelete(NULL);
  569. }
  570. /*********************************************************************************
  571. * function : app_main
  572. * Description : 初始化任务相关
  573. * Input :
  574. * Output :
  575. * Author : Data : 2023 11.08
  576. **********************************************************************************/
  577. void app_main(void)
  578. {
  579. app_init(); //用户任务相关
  580. sleep_init(); //使能协处理器相关
  581. //创建休眠任务
  582. xTaskCreate(light_sleep_task, "light_sleep_task", 4096*5, NULL, 1, NULL);
  583. printf("Machine_info.power_status = %d\r\n",Machine_info.power_status);
  584. #if 1
  585. if(Machine_info.power_status == 0) //关机状态
  586. {
  587. sleep_timer_start(5000);
  588. }
  589. #else
  590. if(Machine_info.power_status == 0) //关机状态
  591. {
  592. Machine_info.power_status = 1;
  593. //sleep_timer_start(5000);
  594. }
  595. #endif
  596. #if 0
  597. int reson = is_wake_up_reson(); //返回唤醒的原因
  598. if ((reson != ESP_SLEEP_WAKEUP_ULP) && (reson != ESP_SLEEP_WAKEUP_TIMER))
  599. {
  600. printf("sleep time = %d ms\r\n",(TIMER_WAKEUP_TIME_US)/1000);
  601. esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间
  602. sleep_timer_start(5000);
  603. }
  604. #endif
  605. }
  606. /*********************************************************************************
  607. * function : init_ulp_program
  608. * Description : 初始化ulp处理器相关
  609. * Input :
  610. * Output :
  611. * Author : Data : 2023 11.08
  612. **********************************************************************************/
  613. static void init_ulp_program(void)
  614. {
  615. ulp_riscv_adc_cfg_t cfg = {
  616. .adc_n = EXAMPLE_ADC_UNIT,
  617. .channel = EXAMPLE_ADC_CHANNEL,
  618. .width = EXAMPLE_ADC_WIDTH,
  619. .atten = EXAMPLE_ADC_ATTEN,
  620. };
  621. extern adc_oneshot_unit_handle_t adc1_handle;
  622. ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle));
  623. #if 0
  624. // #include "user_button.h"
  625. // power_button_deinit();
  626. // power_button_init(adc1_handle);
  627. #endif
  628. ESP_ERROR_CHECK(ulp_riscv_adc_init(&cfg));
  629. esp_err_t err = ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start));
  630. ESP_ERROR_CHECK(err);
  631. /* The first argument is the period index, which is not used by the ULP-RISC-V timer
  632. * The second argument is the period in microseconds, which gives a wakeup time period of: 20ms
  633. */
  634. #if 0
  635. ulp_set_wakeup_period(0, 20000);
  636. #else
  637. ulp_set_wakeup_period(0, 50000);
  638. #endif
  639. /* Start the program */
  640. /* Start the program */
  641. // ulp_riscv_cfg_t cfg1 = {
  642. // .wakeup_source = ULP_RISCV_WAKEUP_SOURCE_GPIO,
  643. // };
  644. // err = ulp_riscv_config_and_run(&cfg1);
  645. err = ulp_riscv_run();
  646. ESP_ERROR_CHECK(err);
  647. }
  648. void sleep_init()
  649. {
  650. #if 1
  651. //设置协处理器配置相关adc唤醒相关
  652. esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
  653. /* not a wakeup from ULP, load the firmware */
  654. if (((cause != ESP_SLEEP_WAKEUP_ULP) && (cause != ESP_SLEEP_WAKEUP_TIMER)) && (cause != ESP_SLEEP_WAKEUP_EXT0) ) {
  655. printf("Not a ULP-RISC-V wakeup (cause = %d), initializing it! \n", cause);
  656. init_ulp_program();
  657. }
  658. /* ULP Risc-V read and detected a temperature above the limit */
  659. if (cause == ESP_SLEEP_WAKEUP_ULP) {
  660. printf("ULP-RISC-V woke up the main CPU\n");
  661. printf("Threshold: high = %"PRIu32"\n", ulp_adc_threshold);
  662. printf("Value = %"PRIu32" was above threshold\n", ulp_wakeup_result);
  663. }
  664. /* Go back to sleep, only the ULP Risc-V will run */
  665. //printf("Entering in sleep\n\n");
  666. /* RTC peripheral power domain needs to be kept on to keep SAR ADC related configs during sleep */
  667. esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
  668. ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup());
  669. #endif
  670. #if 0
  671. /* Initialize GPIO */
  672. gpio_config_t config =
  673. {
  674. .pin_bit_mask = (1ULL << 4),
  675. .mode = GPIO_MODE_INPUT,
  676. .pull_down_en = false,
  677. .pull_up_en = true,
  678. .intr_type = GPIO_INTR_NEGEDGE
  679. };
  680. gpio_config_t charge_config =
  681. {
  682. .pin_bit_mask = (1ULL<<2),
  683. .mode = GPIO_MODE_INPUT,
  684. .pull_down_en = false,
  685. .pull_up_en = true,
  686. .intr_type = GPIO_INTR_LOW_LEVEL
  687. };
  688. if(gpio_config(&config)!=ESP_OK)
  689. {
  690. printf("gpio_config fail\r\n");
  691. }
  692. if(gpio_config(&charge_config)!=ESP_OK)
  693. {
  694. printf("gpio_config fail\r\n");
  695. }
  696. // gpio_hold_en(2);
  697. // gpio_hold_en(38);
  698. //配置下降沿触发
  699. if(gpio_wakeup_enable(4,GPIO_INTR_LOW_LEVEL)!=ESP_OK)
  700. {
  701. printf("gpio_wakeup_enable fail\r\n");
  702. }
  703. if(gpio_wakeup_enable(2,GPIO_INTR_LOW_LEVEL)!=ESP_OK)
  704. {
  705. printf("gpio_wakeup_enable fail\r\n");
  706. }
  707. // if(gpio_wakeup_enable(38,GPIO_INTR_LOW_LEVEL)!=ESP_OK)
  708. // {
  709. // printf("gpio_wakeup_enable fail\r\n");
  710. // }
  711. if(esp_sleep_enable_gpio_wakeup()!=ESP_OK) //使能GPIO唤醒
  712. {
  713. printf("esp_sleep_enable_gpio_wakeup fail\r\n");
  714. }
  715. #else
  716. // rtc_gpio_init(4);
  717. // rtc_gpio_set_direction(4, RTC_GPIO_MODE_INPUT_ONLY);
  718. // rtc_gpio_pullup_en(4);
  719. // rtc_gpio_pulldown_dis(4);
  720. // //配置下降沿触发
  721. // if(gpio_wakeup_enable(4,GPIO_INTR_LOW_LEVEL)!=ESP_OK)
  722. // {
  723. // printf("gpio_wakeup_enable fail\r\n");
  724. // }
  725. // if(esp_sleep_enable_gpio_wakeup()!=ESP_OK) //使能GPIO唤醒
  726. // {
  727. // printf("esp_sleep_enable_gpio_wakeup fail\r\n");
  728. // }
  729. #endif
  730. }