luat_lib_statem.c 4.6 KB

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