luat_lib_pm.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*
  2. @module pm
  3. @summary 电源管理
  4. @version 1.0
  5. @date 2020.07.02
  6. @demo pm
  7. @tag LUAT_USE_PM
  8. @usage
  9. --[[
  10. 休眠模式简介
  11. -- 全速模式
  12. -- PRO低功耗模式
  13. -- PSM+模式
  14. 以上模式均使用 pm.power(pm.WORK_MODE, mode) 来设置
  15. -- mode=0 正常运行,就是无休眠
  16. -- mode=1 轻度休眠, CPU停止, RAM保持, 可中断唤醒, 可定时器唤醒, 可网络唤醒. 支持从休眠处继续运行
  17. -- mode=3 彻底休眠, CPU停止, RAM掉电, 支持特殊唤醒管脚唤醒, 支持定时器唤醒. 唤醒后脚本从头开始执行
  18. ]]
  19. */
  20. #include "lua.h"
  21. #include "lauxlib.h"
  22. #include "luat_base.h"
  23. #include "luat_pm.h"
  24. #include "luat_msgbus.h"
  25. #include "luat_gpio.h"
  26. #ifdef LUAT_USE_HMETA
  27. #include "luat_hmeta.h"
  28. #endif
  29. #define LUAT_LOG_TAG "pm"
  30. #include "luat_log.h"
  31. #ifdef LUAT_USE_DRV_PM
  32. #include "luat_airlink.h"
  33. #include "luat/drv_pm.h"
  34. extern uint32_t g_airlink_pause;
  35. #endif
  36. #ifdef LUAT_USE_YHM27XX
  37. #include "luat_gpio.h"
  38. #include "luat_zbuff.h"
  39. #include "luat_msgbus.h"
  40. #include "luat_gpio.h"
  41. #ifdef LUAT_USE_DRV_GPIO
  42. #include "luat/drv_gpio.h"
  43. #endif
  44. static uint8_t yhm27xx_reg_infos[9] = {0};
  45. #endif
  46. // static int lua_event_cb = 0;
  47. /*
  48. @sys_pub pm
  49. deep sleep timer定时时间到回调
  50. DTIMER_WAKEUP
  51. @usage
  52. sys.subscribe("DTIMER_WAKEUP", function(timer_id)
  53. log.info("deep sleep timer", timer_id)
  54. end)
  55. */
  56. int luat_dtimer_cb(lua_State *L, void* ptr) {
  57. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  58. lua_getglobal(L, "sys_pub");
  59. if (lua_isfunction(L, -1)) {
  60. lua_pushstring(L, "DTIMER_WAKEUP");
  61. lua_pushinteger(L, msg->arg1);
  62. lua_call(L, 2, 0);
  63. }
  64. return 0;
  65. }
  66. /**
  67. 请求进入指定的休眠模式
  68. @api pm.request(mode, chip)
  69. @int 休眠模式,例如pm.IDLE/LIGHT/DEEP/HIB.
  70. @int 休眠芯片的ID, 默认是0, 大部分型号都只有0
  71. @return boolean 处理结果,即使返回成功,也不一定会进入, 也不会马上进入
  72. @usage
  73. -- 请求进入休眠模式
  74. --[[
  75. IDLE 正常运行,就是无休眠
  76. LIGHT 轻休眠, CPU停止, RAM保持, 外设保持, 可中断唤醒. 部分型号支持从休眠处继续运行
  77. DEEP 深休眠, CPU停止, RAM掉电, 仅特殊引脚保持的休眠前的电平, 大部分管脚不能唤醒设备.
  78. HIB 彻底休眠, CPU停止, RAM掉电, 仅复位/特殊唤醒管脚可唤醒设备.
  79. ]]
  80. pm.request(pm.HIB)
  81. */
  82. static int l_pm_request(lua_State *L) {
  83. int mode = luaL_checkinteger(L, 1);
  84. int ret = 0;
  85. #ifdef LUAT_USE_DRV_PM
  86. int chip = 0;
  87. if (lua_isinteger(L, 2)) {
  88. chip = luaL_checkinteger(L, 2);
  89. if (chip > 0) {
  90. luat_airlink_set_pause(1); // wifi进入休眠自动暂停airlink工作
  91. }
  92. }
  93. ret = luat_drv_pm_request(chip, mode);
  94. #else
  95. ret = luat_pm_request(mode);
  96. #endif
  97. lua_pushboolean(L, ret == 0 ? 1 : 0);
  98. return 1;
  99. }
  100. /**
  101. 启动底层定时器,在休眠模式下依然生效. 只触发一次,关机状态下无效
  102. @api pm.dtimerStart(id, timeout)
  103. @int 定时器id,通常是0-5
  104. @int 定时时长,单位毫秒
  105. @return boolean 处理结果
  106. @usage
  107. -- 添加底层定时器
  108. pm.dtimerStart(0, 300 * 1000) -- 5分钟后唤醒
  109. -- 针对Air780EXXX有如下限制
  110. -- id = 0 或者 id = 1 是, 最大休眠时长是2.5小时
  111. -- id >= 2是, 最大休眠时长是740小时
  112. */
  113. static int l_pm_dtimer_start(lua_State *L) {
  114. int dtimer_id = luaL_checkinteger(L, 1);
  115. int timeout = luaL_checkinteger(L, 2);
  116. if (luat_pm_dtimer_start(dtimer_id, timeout)) {
  117. lua_pushboolean(L, 0);
  118. }
  119. else {
  120. lua_pushboolean(L, 1);
  121. }
  122. return 1;
  123. }
  124. /**
  125. 关闭底层定时器
  126. @api pm.dtimerStop(id)
  127. @int 定时器id
  128. @usage
  129. -- 关闭底层定时器
  130. pm.dtimerStop(0) -- 关闭id=0的底层定时器
  131. */
  132. static int l_pm_dtimer_stop(lua_State *L) {
  133. int dtimer_id = luaL_checkinteger(L, 1);
  134. luat_pm_dtimer_stop(dtimer_id);
  135. return 0;
  136. }
  137. #ifndef LUAT_COMPILER_NOWEAK
  138. LUAT_WEAK uint32_t luat_pm_dtimer_remain(int id){
  139. return -1;
  140. }
  141. LUAT_WEAK int luat_pm_get_last_req_mode(void){
  142. return -1;
  143. }
  144. #endif
  145. /**
  146. 检查底层定时器是不是在运行
  147. @api pm.dtimerCheck(id)
  148. @int 定时器id
  149. @return boolean 处理结果,true还在运行,false不在运行
  150. @return number 如果运行,运行剩余时间,单位毫秒(需bsp支持)
  151. @usage
  152. -- 检查底层定时器是不是在运行
  153. pm.dtimerCheck(0) -- 检查id=0的底层定时器
  154. */
  155. static int l_pm_dtimer_check(lua_State *L) {
  156. int dtimer_id = luaL_checkinteger(L, 1);
  157. if (luat_pm_dtimer_check(dtimer_id)){
  158. uint32_t remain = luat_pm_dtimer_remain(dtimer_id);
  159. lua_pushboolean(L, 1);
  160. lua_pushinteger(L, remain);
  161. return 2;
  162. }else{
  163. lua_pushboolean(L, 0);
  164. return 1;
  165. }
  166. }
  167. static int l_pm_dtimer_list(lua_State *L) {
  168. size_t c = 0;
  169. size_t dlist[24];
  170. luat_pm_dtimer_list(&c, dlist);
  171. lua_createtable(L, c, 0);
  172. for (size_t i = 0; i < c; i++)
  173. {
  174. if (dlist[i] > 0) {
  175. lua_pushinteger(L, dlist[i]);
  176. lua_seti(L, -3, i+1);
  177. }
  178. }
  179. return 1;
  180. }
  181. /**
  182. 检查定时唤醒是哪一个定时器,如果不是定时唤醒的,返回-1
  183. @api pm.dtimerWkId()
  184. @return int 处理结果 >=0 是本次定时唤醒的定时器ID,其他错误,说明不是定时唤醒的
  185. @usage
  186. local timer_id = pm.dtimerWkId()
  187. */
  188. static int l_pm_dtimer_wakeup_id(lua_State *L) {
  189. int dtimer_id = 0xFF;
  190. luat_pm_dtimer_wakeup_id(&dtimer_id);
  191. if (dtimer_id != 0xFF) {
  192. lua_pushinteger(L, dtimer_id);
  193. }
  194. else {
  195. lua_pushinteger(L, -1);
  196. }
  197. return 1;
  198. }
  199. /**
  200. 开机原因,用于判断是从休眠模块开机,还是电源/复位开机
  201. @api pm.lastReson()
  202. @return int 0-上电/复位开机, 1-RTC开机, 2-WakeupIn/Pad/IO开机, 3-未知原因(Wakeup/RTC皆有可能)开机,目前只有air101,air103会有这个返回值
  203. @return int 0-普通开机(上电/复位),3-深睡眠开机,4-休眠开机
  204. @return int 复位开机详细原因:0-powerkey或者上电开机 1-充电或者AT指令下载完成后开机 2-闹钟开机 3-软件重启 4-未知原因 5-RESET键 6-异常重启 7-工具控制重启 8-内部看门狗重启 9-外部重启 10-充电开机
  205. @usage
  206. -- 是哪种方式开机呢
  207. log.info("pm", "last power reson", pm.lastReson())
  208. */
  209. static int l_pm_last_reson(lua_State *L) {
  210. int lastState = 0;
  211. int rtcOrPad = 0;
  212. luat_pm_last_state(&lastState, &rtcOrPad);
  213. lua_pushinteger(L, rtcOrPad);
  214. lua_pushinteger(L, lastState);
  215. lua_pushinteger(L, luat_pm_get_poweron_reason());
  216. return 3;
  217. }
  218. /**
  219. 强制进入指定的休眠模式,忽略某些外设的影响,比如USB
  220. @api pm.force(mode)
  221. @int 休眠模式
  222. @return boolean 处理结果,若返回成功,大概率会马上进入该休眠模式
  223. @usage
  224. -- 请求进入休眠模式
  225. pm.force(pm.HIB)
  226. -- 针对Air780EXXX, 该操作会关闭USB通信
  227. -- 唤醒后如需开启USB, 请打开USB电压
  228. --pm.power(pm.USB, true)
  229. */
  230. static int l_pm_force(lua_State *L) {
  231. lua_pushinteger(L, luat_pm_force(luaL_checkinteger(L, 1)));
  232. return 1;
  233. }
  234. /**
  235. 检查休眠状态
  236. @api pm.check()
  237. @return boolean 处理结果,如果能顺利进入休眠,返回true,否则返回false
  238. @return int 底层返回值,0代表能进入最底层休眠,其他值代表最低可休眠级别
  239. @usage
  240. -- 请求进入休眠模式,然后检查是否能真的休眠
  241. pm.request(pm.HIB)
  242. if pm.check() then
  243. log.info("pm", "it is ok to hib")
  244. else
  245. -- 针对Air780EXXX, 该操作会关闭USB通信
  246. pm.force(pm.HIB) -- 强制休眠
  247. -- 唤醒后如需开启USB, 请打开USB电压
  248. --sys.wait(100)
  249. --pm.power(pm.USB, true)
  250. end
  251. */
  252. static int l_pm_check(lua_State *L) {
  253. int ret = luat_pm_check();
  254. lua_pushboolean(L, luat_pm_check() == 0 ? 1 : 0);
  255. lua_pushinteger(L, ret);
  256. return 2;
  257. }
  258. #ifndef LUAT_COMPILER_NOWEAK
  259. LUAT_WEAK int luat_pm_poweroff(void) {
  260. LLOGW("powerOff is not supported");
  261. return -1;
  262. }
  263. #else
  264. extern int luat_pm_poweroff(void);
  265. #endif
  266. /**
  267. 关机
  268. @api pm.shutdown()
  269. @return nil 无返回值
  270. @usage
  271. -- 当前支持移芯CAT1平台系列(Air780E/Air700E/Air780EP等等)
  272. -- 需要2022-12-22之后编译的固件
  273. pm.shutdown()
  274. */
  275. static int l_pm_power_off(lua_State *L) {
  276. (void)L;
  277. luat_pm_poweroff();
  278. return 0;
  279. }
  280. /**
  281. 重启
  282. @api pm.reboot()
  283. @return nil 无返回值
  284. -- 立即重启设备, 本函数的行为与rtos.reboot()完全一致,只是在pm库做个别名
  285. pm.reboot()
  286. */
  287. int l_rtos_reboot(lua_State *L);
  288. int l_rtos_standby(lua_State *L);
  289. /**
  290. 开启内部的电源控制,注意不是所有的平台都支持,可能部分平台支持部分选项,看硬件
  291. @api pm.power(id, onoff, chip)
  292. @int 电源控制id, 包括开关型pm.USB(USB电源) pm.GPS(GPS电源) pm.PWK_MODE(powerkey模式)和 数值型pm.WORK_MODE(功耗模式)
  293. @boolean/int 开关型控制:true/1打开供电,false/0关闭供电,默认关。pm.WORK_MODE 0~3,0完全关闭,1~2普通低功耗,3超低功耗,深度休眠
  294. @int 休眠芯片的ID, 默认是0, 大部分型号都只有0。1是协处理器,如air8000内的wifi芯片
  295. @return boolean 处理结果true成功,false失败
  296. @usage
  297. -- 关闭USB电源, 反之开启就是传true
  298. pm.power(pm.USB, false)
  299. -- Air780EG,为内置的GPS芯片上电. 注意, Air780EG的GPS和GPS_ANT是一起控制的,所以合并了.
  300. pm.power(pm.GPS, true)
  301. -- Air780EXXX开启pwrkey开机防抖
  302. -- 注意: 开启后, 复位键就变成关机了!!! pwrkey要长按2秒才能开机
  303. -- pm.power(pm.PWK_MODE, true)
  304. -- Air780EXXX PSM+低功耗设置
  305. -- Air780EXXX节能模式,0~3,0完全关闭,1~2普通低功耗,3超低功耗,深度休眠
  306. -- 详情访问: https://airpsm.cn
  307. -- pm.power(pm.WORK_MODE, 1)
  308. */
  309. static int l_pm_power_ctrl(lua_State *L) {
  310. uint8_t onoff = 0;
  311. int id = luaL_checkinteger(L, 1);
  312. int ret = 0;
  313. if (lua_isboolean(L, 2)) {
  314. onoff = lua_toboolean(L, 2);
  315. }
  316. else
  317. {
  318. onoff = lua_tointeger(L, 2);
  319. }
  320. if (id == LUAT_PM_POWER_WIFI) {
  321. #ifdef LUAT_MODEL_AIR8000
  322. luat_gpio_set(23, onoff ? Luat_GPIO_HIGH : Luat_GPIO_LOW);
  323. #endif
  324. }
  325. #ifdef LUAT_USE_DRV_PM
  326. int chip = 0;
  327. if (lua_isinteger(L, 3)) {
  328. chip = luaL_checkinteger(L, 3);
  329. }
  330. ret = luat_drv_pm_power_ctrl(chip, id, onoff);
  331. #else
  332. ret = luat_pm_power_ctrl(id, onoff);
  333. #endif
  334. lua_pushboolean(L, !ret);
  335. return 1;
  336. }
  337. /**
  338. IO高电平和对外输出LDO的电压控制
  339. @api pm.ioVol(id, val)
  340. @int 电平id,目前只有pm.IOVOL_ALL_GPIO
  341. @int 电平值,单位毫伏
  342. @return boolean 处理结果true成功,false失败
  343. @usage
  344. -- Air780EXXX设置IO电平, 范围 1650 ~ 2000,2650~3400 , 单位毫伏, 步进50mv
  345. -- 注意, 这里的设置优先级会高于硬件IOSEL脚的配置
  346. -- 但开机时依然先使用硬件配置,直至调用本API进行配置, 所以io电平会变化
  347. -- pm.ioVol(pm.IOVOL_ALL_GPIO, 3300) -- 所有GPIO高电平输出3.3V
  348. -- pm.ioVol(pm.IOVOL_ALL_GPIO, 1800) -- 所有GPIO高电平输出1.8V
  349. */
  350. static int l_pm_iovolt_ctrl(lua_State *L) {
  351. int val = 3300;
  352. int id = luaL_optinteger(L, 1, LUAT_PM_ALL_GPIO);
  353. if (lua_isboolean(L, 2)) {
  354. val = lua_toboolean(L, 2);
  355. }
  356. else if (lua_isinteger(L, 2)) {
  357. val = luaL_checkinteger(L, 2);
  358. }
  359. lua_pushboolean(L, !luat_pm_iovolt_ctrl(id, val));
  360. return 1;
  361. }
  362. #ifndef LUAT_COMPILER_NOWEAK
  363. LUAT_WEAK int luat_pm_iovolt_ctrl(int id, int val) {
  364. return -1;
  365. }
  366. #endif
  367. /**
  368. 配置唤醒引脚
  369. @api pm.wakeupPin(pin,level)
  370. @int gpio引脚
  371. @int 唤醒方式, 例如gpio.RISING (上升沿), gpio.FALLING (下降沿)
  372. @int 芯片的ID, 默认是0, 大部分型号都只有0
  373. @return boolean 处理结果
  374. @usage
  375. -- 本函数仅Air8101有效
  376. pm.wakeupPin(8, gpio.RISING)
  377. -- 对Air780xx系列, Air8000, Air72x系列均无效
  378. -- 对于这些系列,使用gpio.setup即可, 例如使用 WAKEUP0引脚实现唤醒操作
  379. gpio.setup(gpio.WAKEUP0, function() end, gpio.PULLUP, gpio.RISING)
  380. -- 注意, 对于PSM+休眠, 唤醒相当于重启, 回调函数是不会执行的
  381. -- 对于PRO休眠, 回调函数会执行
  382. -- 唤醒原因, 可以通过 pm.lastReson()获取
  383. */
  384. static int l_pm_wakeup_pin(lua_State *L) {
  385. int level = luaL_optinteger(L, 2,0);
  386. if (lua_istable(L, 1)) {
  387. size_t count = lua_rawlen(L, 1);
  388. for (size_t i = 1; i <= count; i++){
  389. lua_geti(L, 1, i);
  390. luat_pm_wakeup_pin(luaL_checkinteger(L, -1), level);
  391. lua_pop(L, 1);
  392. }
  393. }else if(lua_isnumber(L, 1)){
  394. #ifdef LUAT_USE_DRV_PM
  395. int chip = 0;
  396. if (lua_isinteger(L, 3)) {
  397. chip = luaL_checkinteger(L, 3);
  398. }
  399. luat_drv_pm_wakeup_pin(chip, luaL_checkinteger(L, 1), level);
  400. #else
  401. luat_pm_wakeup_pin(luaL_checkinteger(L, 1), level);
  402. #endif
  403. }
  404. lua_pushboolean(L, 1);
  405. return 1;
  406. }
  407. // yhm27xx
  408. #ifdef LUAT_USE_YHM27XX
  409. /*
  410. @sys_pub pm
  411. YHM27XX芯片寄存器信息更新回调
  412. YHM27XX_REG
  413. @usage
  414. sys.subscribe("YHM27XX_REG", function(data)
  415. -- 注意, 会一次性读出0-9,总共8个寄存器值
  416. log.info("yhm27xx", data and data:toHex())
  417. end)
  418. */
  419. static int l_yhm_27xx_cb(lua_State *L, void *ptr)
  420. {
  421. lua_getglobal(L, "sys_pub");
  422. if (lua_isfunction(L, -1))
  423. {
  424. lua_pushstring(L, "YHM27XX_REG");
  425. lua_pushlstring(L, (const char *)yhm27xx_reg_infos, 9);
  426. lua_call(L, 2, 0);
  427. }
  428. return 0;
  429. }
  430. static void luat_gpio_driver_yhm27xx_reqinfo(uint8_t pin, uint8_t chip_id)
  431. {
  432. for (uint8_t i = 0; i < 9; i++)
  433. {
  434. luat_gpio_driver_yhm27xx(pin, chip_id, i, 1, &(yhm27xx_reg_infos[i]));
  435. }
  436. rtos_msg_t msg = {0};
  437. msg.handler = l_yhm_27xx_cb;
  438. luat_msgbus_put(&msg, 0);
  439. }
  440. // 根据模组型号匹配YHM27XX引脚
  441. static uint8_t get_default_yhm27xx_pin(void)
  442. {
  443. char model[32] = {0};
  444. luat_hmeta_model_name(model);
  445. if (memcmp("Air8000\0", model, 8) == 0 ||
  446. memcmp("Air8000XB\0", model, 10) == 0 ||
  447. memcmp("Air8000AB\0", model, 10) == 0 ||
  448. memcmp("Air8000U\0", model, 9) == 0 ||
  449. memcmp("Air8000N\0", model, 9) == 0
  450. ) {
  451. return 152;
  452. }
  453. if (memcmp("Air8000G\0", model, 9) == 0) {
  454. return 22;
  455. }
  456. return 0;
  457. }
  458. /**
  459. 单总线命令读写YHM27XX
  460. @api pm.chgcmd(pin, chip_id, reg, data)
  461. @int yhm27xx_CMD引脚(可选,若传入nil则根据模组型号自动选择)
  462. @int 芯片ID
  463. @int 读写寄存器地址
  464. @int 要写入的数据,如果没填,则表示从寄存器读取数据
  465. @return boolean 成功返回true,失败返回false
  466. @return int 读取成功返回寄存器值,写入成功无返回
  467. @usage
  468. -- 读取寄存器0x01的值
  469. local ret = pm.chgcmd(pin, chip_id, 0x01)
  470. -- 写入寄存器0x01的值为0x55
  471. local ret = pm.chgcmd(pin, chip_id, 0x01, 0x55)
  472. */
  473. int l_pm_chgcmd(lua_State *L)
  474. {
  475. uint8_t pin = 0;
  476. // 第一个参数可选,若传入nil则根据模组型号自动选择
  477. if (!lua_isnoneornil(L, 1))
  478. {
  479. pin = luaL_checkinteger(L, 1);
  480. }
  481. else
  482. {
  483. // 根据模组型号设置默认值
  484. pin = get_default_yhm27xx_pin();
  485. }
  486. uint8_t chip_id = luaL_checkinteger(L, 2);
  487. uint8_t reg = luaL_checkinteger(L, 3);
  488. uint8_t data = 0;
  489. uint8_t is_read = 1;
  490. int ret = 0;
  491. if (!lua_isnone(L, 4))
  492. {
  493. is_read = 0;
  494. data = luaL_checkinteger(L, 4);
  495. }
  496. #ifdef LUAT_USE_DRV_GPIO
  497. ret = luat_drv_gpio_driver_yhm27xx(pin, chip_id, reg, is_read, &data);
  498. #else
  499. ret = luat_gpio_driver_yhm27xx(pin, chip_id, reg, is_read, &data);
  500. #endif
  501. if (ret != 0)
  502. {
  503. lua_pushboolean(L, 0);
  504. return 1;
  505. }
  506. lua_pushboolean(L, 1);
  507. if (is_read)
  508. {
  509. lua_pushinteger(L, data);
  510. return 2;
  511. }
  512. return 1;
  513. }
  514. /*
  515. 获取最新的寄存器信息(异步)
  516. @api pm.chginfo(pin, chip_id)
  517. @int yhm27xx_CMD引脚(可选,若传入nil则根据模组型号自动选择)
  518. @int 芯片ID
  519. @return nil 无返回值
  520. @usage
  521. sys.subscribe("YHM27XX_REG", function(data)
  522. -- 注意, 会一次性读出0-9,总共8个寄存器值
  523. log.info("yhm27xx", data and data:toHex())
  524. end)
  525. pm.chginfo(nil, 0x04)
  526. */
  527. int l_pm_chginfo(lua_State *L)
  528. {
  529. uint8_t pin = 0;
  530. // 第一个参数可选,若传入nil则根据模组型号自动选择
  531. if (!lua_isnoneornil(L, 1))
  532. {
  533. pin = luaL_checkinteger(L, 1);
  534. }
  535. else
  536. {
  537. // 根据模组型号设置默认值
  538. pin = get_default_yhm27xx_pin();
  539. }
  540. uint8_t chip_id = luaL_checkinteger(L, 2);
  541. #ifdef LUAT_USE_DRV_GPIO
  542. if (pin >= 128)
  543. {
  544. luat_drv_gpio_driver_yhm27xx_reqinfo(pin, chip_id);
  545. return 0;
  546. }
  547. #endif
  548. luat_gpio_driver_yhm27xx_reqinfo(pin, chip_id);
  549. return 0;
  550. }
  551. #endif
  552. #include "rotable2.h"
  553. static const rotable_Reg_t reg_pm[] =
  554. {
  555. { "request" , ROREG_FUNC(l_pm_request )},
  556. // { "release" , ROREG_FUNC( l_pm_release)},
  557. { "dtimerStart", ROREG_FUNC(l_pm_dtimer_start)},
  558. { "dtimerStop" , ROREG_FUNC(l_pm_dtimer_stop)},
  559. { "dtimerCheck" , ROREG_FUNC(l_pm_dtimer_check)},
  560. { "dtimerList", ROREG_FUNC(l_pm_dtimer_list)},
  561. { "dtimerWkId", ROREG_FUNC(l_pm_dtimer_wakeup_id)},
  562. //{ "on", ROREG_FUNC(l_pm_on)},
  563. { "force", ROREG_FUNC(l_pm_force)},
  564. { "check", ROREG_FUNC(l_pm_check)},
  565. { "lastReson", ROREG_FUNC(l_pm_last_reson)},
  566. { "shutdown", ROREG_FUNC(l_pm_power_off)},
  567. { "reboot", ROREG_FUNC(l_rtos_reboot)},
  568. { "power", ROREG_FUNC(l_pm_power_ctrl)},
  569. { "ioVol", ROREG_FUNC(l_pm_iovolt_ctrl)},
  570. { "wakeupPin", ROREG_FUNC(l_pm_wakeup_pin)},
  571. // yhm27xx
  572. #ifdef LUAT_USE_YHM27XX
  573. { "chgcmd", ROREG_FUNC(l_pm_chgcmd)},
  574. { "chginfo", ROREG_FUNC(l_pm_chginfo)},
  575. #endif
  576. //@const NONE number 不休眠模式
  577. { "NONE", ROREG_INT(LUAT_PM_SLEEP_MODE_NONE)},
  578. //@const IDLE number IDLE模式
  579. { "IDLE", ROREG_INT(LUAT_PM_SLEEP_MODE_IDLE)},
  580. //@const LIGHT number LIGHT模式
  581. { "LIGHT", ROREG_INT(LUAT_PM_SLEEP_MODE_LIGHT)},
  582. //@const DEEP number DEEP模式
  583. { "DEEP", ROREG_INT(LUAT_PM_SLEEP_MODE_DEEP)},
  584. //@const HIB number HIB模式
  585. { "HIB", ROREG_INT(LUAT_PM_SLEEP_MODE_STANDBY)},
  586. //@const USB number USB电源
  587. { "USB", ROREG_INT(LUAT_PM_POWER_USB)},
  588. //@const GPS number GPS电源
  589. { "GPS", ROREG_INT(LUAT_PM_POWER_GPS)},
  590. //@const GPS_ANT number GPS的天线电源,有源天线才需要
  591. { "GPS_ANT", ROREG_INT(LUAT_PM_POWER_GPS_ANT)},
  592. //@const CAMERA number camera电源,CAM_VCC输出
  593. { "CAMERA", ROREG_INT(LUAT_PM_POWER_CAMERA)},
  594. //@const DAC_EN number Air780EXXX的DAC_EN(新版硬件手册的LDO_CTL,同一个PIN,命名变更),注意audio的默认配置会自动使用这个脚来控制CODEC的使能
  595. { "DAC_EN", ROREG_INT(LUAT_PM_POWER_DAC_EN_PIN)},
  596. //@const LDO_CTL number Air780EXXX的LDO_CTL(老版硬件手册的DAC_EN,同一个PIN,命名变更),Air780EXXX的LDO_CTL, 注意audio的默认配置会自动使用这个脚来控制CODEC的使能
  597. { "LDO_CTL", ROREG_INT(LUAT_PM_POWER_LDO_CTL_PIN)},
  598. //@const PWK_MODE number 是否Air780EXXX的powerkey滤波模式,true开,注意滤波模式下reset变成直接关机
  599. { "PWK_MODE", ROREG_INT(LUAT_PM_POWER_POWERKEY_MODE)},
  600. //@const WORK_MODE number Air780EXXX的节能模式,0~3,0完全关闭,1~2普通低功耗,3超低功耗,深度休眠
  601. { "WORK_MODE", ROREG_INT(LUAT_PM_POWER_WORK_MODE)},
  602. //@const IOVOL_ALL_GPIO number 所有GPIO高电平电压控制,当前仅Air780EXXX可用
  603. { "IOVOL_ALL_GPIO", ROREG_INT(LUAT_PM_ALL_GPIO)},
  604. //@const IOVOL_SDIO number VMMC电压域IO
  605. { "IOVOL_SDIO", ROREG_INT(LUAT_PM_LDO_TYPE_VMMC)},
  606. //@const IOVOL_LCD number VLCD电压域IO
  607. { "IOVOL_LCD", ROREG_INT(LUAT_PM_LDO_TYPE_VLCD)},
  608. //@const IOVOL_CAMA number camera模拟电压
  609. { "IOVOL_CAMA", ROREG_INT(LUAT_PM_LDO_TYPE_CAMA)},
  610. //@const IOVOL_CAMD number camera数字电压
  611. { "IOVOL_CAMD", ROREG_INT(LUAT_PM_LDO_TYPE_CAMD)},
  612. //@const ID_NATIVE number PM控制的ID, 主芯片, 任意芯片的默认值就是它
  613. { "ID_NATIVE", ROREG_INT(0)},
  614. //@const ID_WIFI number PM控制的ID, WIFI芯片, 仅Air8000可用
  615. { "ID_WIFI", ROREG_INT(1)},
  616. { "WIFI", ROREG_INT(LUAT_PM_POWER_WIFI)},
  617. //@const WIFI_STA_DTIM number wifi芯片控制STA模式下的DTIM间隔,单位100ms,默认值是1
  618. { "WIFI_STA_DTIM", ROREG_INT(LUAT_PM_POWER_WIFI_STA_DTIM)},
  619. { "WIFI_AP_DTIM", ROREG_INT(LUAT_PM_POWER_WIFI_AP_DTIM)},
  620. { NULL, ROREG_INT(0) }
  621. };
  622. LUAMOD_API int luaopen_pm( lua_State *L ) {
  623. luat_newlib2(L, reg_pm);
  624. return 1;
  625. }