rtcfifo.c 4.3 KB

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