rtcfifo.c 4.0 KB

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