rtcfifo.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Module for RTC sample FIFO storage
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "user_modules.h"
  5. #include "rtc/rtctime.h"
  6. #define RTCTIME_SLEEP_ALIGNED rtctime_deep_sleep_until_aligned_us
  7. #include "rtc/rtcfifo.h"
  8. // rtcfifo.prepare ([{sensor_count=n, interval_us=m, storage_begin=x, storage_end=y}])
  9. static int rtcfifo_prepare (lua_State *L)
  10. {
  11. uint32_t sensor_count = RTC_DEFAULT_TAGCOUNT;
  12. uint32_t interval_us = 0;
  13. int first = -1, last = -1;
  14. if (lua_istable (L, 1))
  15. {
  16. #ifdef LUA_USE_MODULES_RTCTIME
  17. lua_getfield (L, 1, "interval_us");
  18. if (lua_isnumber (L, -1))
  19. interval_us = lua_tonumber (L, -1);
  20. lua_pop (L, 1);
  21. #endif
  22. lua_getfield (L, 1, "sensor_count");
  23. if (lua_isnumber (L, -1))
  24. sensor_count = lua_tonumber (L, -1);
  25. lua_pop (L, 1);
  26. lua_getfield (L, 1, "storage_begin");
  27. if (lua_isnumber (L, -1))
  28. first = lua_tonumber (L, -1);
  29. lua_pop (L, 1);
  30. lua_getfield (L, 1, "storage_end");
  31. if (lua_isnumber (L, -1))
  32. last = lua_tonumber (L, -1);
  33. lua_pop (L, 1);
  34. }
  35. else if (!lua_isnone (L, 1))
  36. return luaL_error (L, "expected table as arg #1");
  37. rtc_fifo_prepare (0, interval_us, sensor_count);
  38. if (first != -1 && last != -1)
  39. rtc_fifo_put_loc (first, last, sensor_count);
  40. return 0;
  41. }
  42. // ready = rtcfifo.ready ()
  43. static int rtcfifo_ready (lua_State *L)
  44. {
  45. lua_pushnumber (L, rtc_fifo_check_magic ());
  46. return 1;
  47. }
  48. static void check_fifo_magic (lua_State *L)
  49. {
  50. if (!rtc_fifo_check_magic ())
  51. luaL_error (L, "rtcfifo not prepared!");
  52. }
  53. // rtcfifo.put (timestamp, value, decimals, sensor_name)
  54. static int rtcfifo_put (lua_State *L)
  55. {
  56. check_fifo_magic (L);
  57. sample_t s;
  58. s.timestamp = luaL_checknumber (L, 1);
  59. s.value = luaL_checknumber (L, 2);
  60. s.decimals = luaL_checknumber (L, 3);
  61. size_t len;
  62. const char *str = luaL_checklstring (L, 4, &len);
  63. union {
  64. uint32_t u;
  65. char s[4];
  66. } conv = { 0 };
  67. strncpy (conv.s, str, len > 4 ? 4 : len);
  68. s.tag = conv.u;
  69. rtc_fifo_store_sample (&s);
  70. return 0;
  71. }
  72. static int extract_sample (lua_State *L, const sample_t *s)
  73. {
  74. lua_pushnumber (L, s->timestamp);
  75. lua_pushnumber (L, s->value);
  76. lua_pushnumber (L, s->decimals);
  77. union {
  78. uint32_t u;
  79. char s[4];
  80. } conv = { s->tag };
  81. if (conv.s[3] == 0)
  82. lua_pushstring (L, conv.s);
  83. else
  84. lua_pushlstring (L, conv.s, 4);
  85. return 4;
  86. }
  87. // timestamp, value, decimals, sensor_name = rtcfifo.pop ()
  88. static int rtcfifo_pop (lua_State *L)
  89. {
  90. check_fifo_magic (L);
  91. sample_t s;
  92. if (!rtc_fifo_pop_sample (&s))
  93. return 0;
  94. else
  95. return extract_sample (L, &s);
  96. }
  97. // timestamp, value, decimals, sensor_name = rtcfifo.peek ([offset])
  98. static int rtcfifo_peek (lua_State *L)
  99. {
  100. check_fifo_magic (L);
  101. sample_t s;
  102. uint32_t offs = 0;
  103. if (lua_isnumber (L, 1))
  104. offs = lua_tonumber (L, 1);
  105. if (!rtc_fifo_peek_sample (&s, offs))
  106. return 0;
  107. else
  108. return extract_sample (L, &s);
  109. }
  110. // rtcfifo.drop (num)
  111. static int rtcfifo_drop (lua_State *L)
  112. {
  113. check_fifo_magic (L);
  114. rtc_fifo_drop_samples (luaL_checknumber (L, 1));
  115. return 0;
  116. }
  117. // num = rtcfifo.count ()
  118. static int rtcfifo_count (lua_State *L)
  119. {
  120. check_fifo_magic (L);
  121. lua_pushnumber (L, rtc_fifo_get_count ());
  122. return 1;
  123. }
  124. #ifdef LUA_USE_MODULES_RTCTIME
  125. // rtcfifo.dsleep_until_sample (min_sleep_us)
  126. static int rtcfifo_dsleep_until_sample (lua_State *L)
  127. {
  128. check_fifo_magic (L);
  129. uint32_t min_us = luaL_checknumber (L, 1);
  130. rtc_fifo_deep_sleep_until_sample (min_us); // no return
  131. return 0;
  132. }
  133. #endif
  134. // Module function map
  135. static const LUA_REG_TYPE rtcfifo_map[] = {
  136. { LSTRKEY("prepare"), LFUNCVAL(rtcfifo_prepare) },
  137. { LSTRKEY("ready"), LFUNCVAL(rtcfifo_ready) },
  138. { LSTRKEY("put"), LFUNCVAL(rtcfifo_put) },
  139. { LSTRKEY("pop"), LFUNCVAL(rtcfifo_pop) },
  140. { LSTRKEY("peek"), LFUNCVAL(rtcfifo_peek) },
  141. { LSTRKEY("drop"), LFUNCVAL(rtcfifo_drop) },
  142. { LSTRKEY("count"), LFUNCVAL(rtcfifo_count) },
  143. #ifdef LUA_USE_MODULES_RTCTIME
  144. { LSTRKEY("dsleep_until_sample"), LFUNCVAL(rtcfifo_dsleep_until_sample) },
  145. #endif
  146. { LNILKEY, LNILVAL }
  147. };
  148. NODEMCU_MODULE(RTCFIFO, "rtcfifo", rtcfifo_map, NULL);