rtctime.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Module for RTC time keeping
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "rtc/rtctime_internal.h"
  5. #include "rtc/rtctime.h"
  6. // ******* C API functions *************
  7. void rtctime_early_startup (void)
  8. {
  9. Cache_Read_Enable (0, 0, 1);
  10. rtc_time_register_bootup ();
  11. rtc_time_switch_clocks ();
  12. Cache_Read_Disable ();
  13. }
  14. void rtctime_late_startup (void)
  15. {
  16. rtc_time_switch_system ();
  17. }
  18. void rtctime_gettimeofday (struct rtc_timeval *tv)
  19. {
  20. rtc_time_gettimeofday (tv);
  21. }
  22. void rtctime_settimeofday (const struct rtc_timeval *tv)
  23. {
  24. if (!rtc_time_check_magic ())
  25. rtc_time_prepare ();
  26. rtc_time_settimeofday (tv);
  27. }
  28. bool rtctime_have_time (void)
  29. {
  30. return rtc_time_have_time ();
  31. }
  32. void rtctime_deep_sleep_us (uint32_t us)
  33. {
  34. rtc_time_deep_sleep_us (us);
  35. }
  36. void rtctime_deep_sleep_until_aligned_us (uint32_t align_us, uint32_t min_us)
  37. {
  38. rtc_time_deep_sleep_until_aligned (align_us, min_us);
  39. }
  40. // ******* Lua API functions *************
  41. // rtctime.set (sec, usec)
  42. static int rtctime_set (lua_State *L)
  43. {
  44. if (!rtc_time_check_magic ())
  45. rtc_time_prepare ();
  46. uint32_t sec = luaL_checknumber (L, 1);
  47. uint32_t usec = 0;
  48. if (lua_isnumber (L, 2))
  49. usec = lua_tonumber (L, 2);
  50. struct rtc_timeval tv = { sec, usec };
  51. rtctime_settimeofday (&tv);
  52. return 0;
  53. }
  54. // sec, usec = rtctime.get ()
  55. static int rtctime_get (lua_State *L)
  56. {
  57. struct rtc_timeval tv;
  58. rtctime_gettimeofday (&tv);
  59. lua_pushnumber (L, tv.tv_sec);
  60. lua_pushnumber (L, tv.tv_usec);
  61. return 2;
  62. }
  63. static void do_sleep_opt (lua_State *L, int idx)
  64. {
  65. if (lua_isnumber (L, idx))
  66. {
  67. uint32_t opt = lua_tonumber (L, idx);
  68. if (opt < 0 || opt > 4)
  69. luaL_error (L, "unknown sleep option");
  70. system_deep_sleep_set_option (opt);
  71. }
  72. }
  73. // rtctime.dsleep (usec, option)
  74. static int rtctime_dsleep (lua_State *L)
  75. {
  76. uint32_t us = luaL_checknumber (L, 1);
  77. do_sleep_opt (L, 2);
  78. rtctime_deep_sleep_us (us); // does not return
  79. return 0;
  80. }
  81. // rtctime.dsleep_aligned (aligned_usec, min_usec, option)
  82. static int rtctime_dsleep_aligned (lua_State *L)
  83. {
  84. if (!rtctime_have_time ())
  85. return luaL_error (L, "time not available, unable to align");
  86. uint32_t align_us = luaL_checknumber (L, 1);
  87. uint32_t min_us = luaL_checknumber (L, 2);
  88. do_sleep_opt (L, 3);
  89. rtctime_deep_sleep_until_aligned_us (align_us, min_us); // does not return
  90. return 0;
  91. }
  92. // Module function map
  93. static const LUA_REG_TYPE rtctime_map[] = {
  94. { LSTRKEY("set"), LFUNCVAL(rtctime_set) },
  95. { LSTRKEY("get"), LFUNCVAL(rtctime_get) },
  96. { LSTRKEY("dsleep"), LFUNCVAL(rtctime_dsleep) },
  97. { LSTRKEY("dsleep_aligned"), LFUNCVAL(rtctime_dsleep_aligned) },
  98. { LNILKEY, LNILVAL }
  99. };
  100. NODEMCU_MODULE(RTCTIME, "rtctime", rtctime_map, NULL);