luat_lib_statem.c 4.2 KB

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