luat_lib_statem.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. @module statem
  3. @summary SM状态机
  4. @version 1.0
  5. @date 2021.09.26
  6. @demo statem
  7. @tag LUAT_USE_STATEM
  8. */
  9. #include "luat_base.h"
  10. #include "luat_statem.h"
  11. /*
  12. 创建一个新的状态机.
  13. @api statem.create(count, repeat)
  14. @int 指令条数,默认32条
  15. @int 重复执行的次数, 0 代表不重复, 正整数代表具体重复执行的次数. 暂不支持永续执行
  16. @return some 若成功,返回状态机指针,否则返回nil
  17. @usage
  18. gpio.setup(7, 0, gpio.PULLUP)
  19. gpio.setup(12, 0, gpio.PULLUP)
  20. gpio.setup(13, 0, gpio.PULLUP)
  21. gpio.setup(14, 0, gpio.PULLUP)
  22. local sm = statem.create()
  23. :gpio_set(7, 0) -- gpio设置为低电平
  24. :usleep(10) -- 休眠10us
  25. :gpio_set(7, 1) -- gpio设置为高电平
  26. :usleep(40) -- 休眠40us
  27. :gpio_set(12, 1) -- gpio设置为高电平
  28. :gpio_set(13, 1) -- gpio设置为高电平
  29. :gpio_set(14, 1) -- gpio设置为高电平
  30. :usleep(40) -- 休眠40us
  31. :gpio_set(7, 0) -- gpio设置为低电平
  32. :finish()
  33. -- 执行之,后续会支持后台执行
  34. sm:exec()
  35. */
  36. static int l_statem_create(lua_State *L) {
  37. int count = luaL_optinteger(L, 1, 32);
  38. if (count < 1)
  39. return 0;
  40. int repeat = luaL_optinteger(L, 2, 0);
  41. if (repeat < 0)
  42. return 0;
  43. luat_statem_t* sm = (luat_statem_t*)lua_newuserdata(L, sizeof(luat_statem_t) + sizeof(luat_statm_op_t)*count);
  44. if (sm == NULL) {
  45. return 0;
  46. }
  47. memset(sm, 0, sizeof(luat_statem_t) + sizeof(luat_statm_op_t) * count);
  48. sm->op_count = count;
  49. luaL_setmetatable(L, "SM*");
  50. return 1;
  51. }
  52. static int _statem_gpio_set(lua_State *L) {
  53. luat_statem_t* sm = luaL_checkudata(L, 1, "SM*");
  54. int gpio_pin = luaL_checkinteger(L, 2);
  55. int gpio_val = luaL_checkinteger(L, 3);
  56. luat_statem_addop(sm, LUAT_SM_OP_GPIO_SET, (uint8_t)gpio_pin, (uint8_t)gpio_val, (uint8_t)0);
  57. lua_settop(L, 1);
  58. return 1;
  59. }
  60. static int _statem_gpio_get(lua_State *L) {
  61. luat_statem_t* sm = luaL_checkudata(L, 1, "SM*");
  62. int gpio_pin = luaL_checkinteger(L, 2);
  63. luat_statem_addop(sm, LUAT_SM_OP_GPIO_GET, (uint8_t)gpio_pin, (uint8_t)0, (uint8_t)0);
  64. lua_settop(L, 1);
  65. return 1;
  66. }
  67. static int _statem_usleep(lua_State *L) {
  68. luat_statem_t* sm = luaL_checkudata(L, 1, "SM*");
  69. int usleep = luaL_checkinteger(L, 2);
  70. luat_statem_addop(sm, LUAT_SM_OP_USLEEP, (uint8_t)usleep, (uint8_t)0, (uint8_t)0);
  71. lua_settop(L, 1);
  72. return 1;
  73. }
  74. static int _finish_end(lua_State *L) {
  75. luat_statem_t* sm = luaL_checkudata(L, 1, "SM*");
  76. luat_statem_addop(sm, LUAT_SM_OP_END, (uint8_t)0, (uint8_t)0, (uint8_t)0);
  77. lua_settop(L, 1);
  78. return 1;
  79. }
  80. static int _statem_exec(lua_State *L) {
  81. luat_statem_t* sm = luaL_checkudata(L, 1, "SM*");
  82. int backgroud = luaL_optinteger(L, 2, 0);
  83. if (backgroud) {
  84. return 0;
  85. }
  86. else {
  87. luat_statem_exec(sm);
  88. }
  89. return 1;
  90. }
  91. static int _statem_clear(lua_State *L) {
  92. luat_statem_t* sm = luaL_checkudata(L, 1, "SM*");
  93. memset(sm, 0, sizeof(luat_statem_t) + sm->op_count*4);
  94. lua_settop(L, 1);
  95. return 1;
  96. }
  97. static int _statem_result(lua_State *L) {
  98. luat_statem_t* sm = luaL_checkudata(L, 1, "SM*");
  99. lua_createtable(L, 8, 0);
  100. for (size_t i = 0; i < 8; i++)
  101. {
  102. lua_pushinteger(L, sm->gpio_inputs[i]);
  103. lua_seti(L, -2, i+1);
  104. }
  105. return 1;
  106. }
  107. static int _statem_struct_newindex(lua_State *L) {
  108. const char* key = luaL_checkstring(L, 2);
  109. if (!strcmp("gpio_set", key)) {
  110. lua_pushcfunction(L, _statem_gpio_set);
  111. return 1;
  112. }
  113. else if (!strcmp("gpio_get", key)) {
  114. lua_pushcfunction(L, _statem_gpio_get);
  115. return 1;
  116. }
  117. else if (!strcmp("finish", key)) {
  118. lua_pushcfunction(L, _finish_end);
  119. return 1;
  120. }
  121. else if (!strcmp("usleep", key)) {
  122. lua_pushcfunction(L, _statem_usleep);
  123. return 1;
  124. }
  125. else if (!strcmp("exec", key)) {
  126. lua_pushcfunction(L, _statem_exec);
  127. return 1;
  128. }
  129. else if (!strcmp("clear", key)) {
  130. lua_pushcfunction(L, _statem_clear);
  131. return 1;
  132. }
  133. else if (!strcmp("result", key)) {
  134. lua_pushcfunction(L, _statem_result);
  135. return 1;
  136. }
  137. return 0;
  138. }
  139. #include "rotable2.h"
  140. static const rotable_Reg_t reg_statem[] =
  141. {
  142. { "create", ROREG_FUNC(l_statem_create)},
  143. { NULL, ROREG_INT(0)}
  144. };
  145. static void luat_statem_struct_init(lua_State *L) {
  146. luaL_newmetatable(L, "SM*");
  147. lua_pushcfunction(L, _statem_struct_newindex);
  148. lua_setfield( L, -2, "__index" );
  149. lua_pop(L, 1);
  150. }
  151. LUAMOD_API int luaopen_statem( lua_State *L ) {
  152. luat_newlib2(L, reg_statem);
  153. luat_statem_struct_init(L);
  154. return 1;
  155. }