luat_lib_pwm.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. @module pwm
  3. @summary PWM模块
  4. @version 1.0
  5. @date 2020.07.03
  6. @demo pwm
  7. @tag LUAT_USE_PWM
  8. */
  9. #include "luat_base.h"
  10. #include "luat_pwm.h"
  11. #include "luat_mem.h"
  12. #define LUAT_LOG_TAG "pwm"
  13. #include "luat_log.h"
  14. /**
  15. 开启指定的PWM通道
  16. @api pwm.open(channel, period, pulse, pnum, precision)
  17. @int PWM通道
  18. @int 频率, 1-1000000hz
  19. @int 占空比 0-分频精度
  20. @int 输出周期 0为持续输出, 1为单次输出, 其他为指定脉冲数输出
  21. @int 分频精度, 100/256/1000, 默认为100, 若设备不支持会有日志提示
  22. @return boolean 处理结果,成功返回true,失败返回false
  23. @usage
  24. -- 打开PWM5, 频率1kHz, 占空比50%
  25. pwm.open(5, 1000, 50)
  26. -- 打开PWM5, 频率10kHz, 分频为 31/256
  27. pwm.open(5, 10000, 31, 0, 256)
  28. */
  29. static int l_pwm_open(lua_State *L) {
  30. luat_pwm_conf_t conf = {
  31. .pnum = 0,
  32. .precision = 100
  33. };
  34. conf.channel = luaL_checkinteger(L, 1);
  35. conf.period = luaL_checkinteger(L, 2);
  36. conf.pulse = luaL_optnumber(L, 3,0);
  37. if (lua_isnumber(L, 4) || lua_isinteger(L, 4)){
  38. conf.pnum = luaL_checkinteger(L, 4);
  39. }
  40. if (lua_isnumber(L, 5) || lua_isinteger(L, 5)){
  41. conf.precision = luaL_checkinteger(L, 5);
  42. }
  43. int ret = luat_pwm_setup(&conf);
  44. lua_pushboolean(L, ret == 0 ? 1 : 0);
  45. return 1;
  46. }
  47. /**
  48. 关闭指定的PWM通道
  49. @api pwm.close(channel)
  50. @int PWM通道
  51. @return nil 无处理结果
  52. @usage
  53. -- 关闭PWM5
  54. pwm.close(5)
  55. */
  56. static int l_pwm_close(lua_State *L) {
  57. luat_pwm_close(luaL_checkinteger(L, 1));
  58. return 0;
  59. }
  60. /**
  61. PWM捕获
  62. @api pwm.capture(channel)
  63. @int PWM通道
  64. @int 捕获频率
  65. @return boolean 处理结果,成功返回true,失败返回false
  66. @usage
  67. -- PWM0捕获
  68. while 1 do
  69. pwm.capture(0,1000)
  70. local ret,channel,pulse,pwmH,pwmL = sys.waitUntil("PWM_CAPTURE", 2000)
  71. if ret then
  72. log.info("PWM_CAPTURE","channel"..channel,"pulse"..pulse,"pwmH"..pwmH,"pwmL"..pwmL)
  73. end
  74. end
  75. */
  76. static int l_pwm_capture(lua_State *L) {
  77. int ret = luat_pwm_capture(luaL_checkinteger(L, 1),luaL_checkinteger(L, 2));
  78. lua_pushboolean(L, ret == 0 ? 1 : 0);
  79. return 1;
  80. }
  81. // 新的API系列, 封装老的版本, bsp层暂时不改
  82. static luat_pwm_conf_t* confs[6];
  83. static int l_pwm_setup(lua_State *L) {
  84. luat_pwm_conf_t conf = {
  85. .pnum = 0,
  86. .precision = 100
  87. };
  88. conf.channel = luaL_checkinteger(L, 1);
  89. conf.period = luaL_checkinteger(L, 2);
  90. conf.pulse = luaL_optnumber(L, 3,0);
  91. if (lua_isnumber(L, 4) || lua_isinteger(L, 4)){
  92. conf.pnum = luaL_checkinteger(L, 4);
  93. }
  94. if (lua_isnumber(L, 5) || lua_isinteger(L, 5)){
  95. conf.precision = luaL_checkinteger(L, 5);
  96. }
  97. if (conf.channel > 5 || conf.channel < 0) {
  98. return 0;
  99. }
  100. if (confs[conf.channel] == NULL) {
  101. confs[conf.channel] = luat_heap_malloc(sizeof(luat_pwm_conf_t));
  102. if (confs[conf.channel] == NULL) {
  103. LLOGE("pwm_setup malloc fail");
  104. return 0;
  105. }
  106. }
  107. memcpy(confs[conf.channel], &conf, sizeof(luat_pwm_conf_t));
  108. lua_pushboolean(L, 1);
  109. return 1;
  110. }
  111. static int check_channel(lua_State *L) {
  112. int channel = luaL_checkinteger(L, 1);
  113. if (channel > 5 || channel < 0) {
  114. return -1;
  115. }
  116. if (confs[channel] == NULL) {
  117. LLOGE("请先调用pwm.setup!! %d", channel);
  118. return -1;
  119. }
  120. return channel;
  121. }
  122. static int l_pwm_start(lua_State *L) {
  123. int channel = check_channel(L);
  124. if (channel < 0) {
  125. return 0;
  126. }
  127. int ret = luat_pwm_setup(confs[channel]);
  128. lua_pushboolean(L, ret == 0 ? 1 : 0);
  129. return 1;
  130. }
  131. static int l_pwm_stop(lua_State *L) {
  132. int channel = check_channel(L);
  133. if (channel < 0) {
  134. return 0;
  135. }
  136. luat_pwm_close(channel);
  137. luat_heap_free(confs[channel]);
  138. confs[channel] = NULL;
  139. lua_pushboolean(L, 1);
  140. return 1;
  141. }
  142. static int l_pwm_set_duty(lua_State *L) {
  143. int channel = check_channel(L);
  144. if (channel < 0) {
  145. return 0;
  146. }
  147. confs[channel]->pulse = luaL_checkinteger(L, 2);
  148. int ret = luat_pwm_setup(confs[channel]);
  149. lua_pushboolean(L, ret == 0 ? 1 : 0);
  150. return 1;
  151. }
  152. static int l_pwm_set_freq(lua_State *L) {
  153. int channel = check_channel(L);
  154. if (channel < 0) {
  155. return 0;
  156. }
  157. confs[channel]->period = luaL_checkinteger(L, 2);
  158. int ret = luat_pwm_setup(confs[channel]);
  159. lua_pushboolean(L, ret == 0 ? 1 : 0);
  160. return 1;
  161. }
  162. #include "rotable2.h"
  163. static const rotable_Reg_t reg_pwm[] =
  164. {
  165. { "open" , ROREG_FUNC(l_pwm_open )},
  166. { "close" , ROREG_FUNC(l_pwm_close)},
  167. { "capture" , ROREG_FUNC(l_pwm_capture)},
  168. // 新api, setup,start,stop
  169. { "setup" , ROREG_FUNC(l_pwm_setup )},
  170. { "start" , ROREG_FUNC(l_pwm_start )},
  171. { "stop" , ROREG_FUNC(l_pwm_stop )},
  172. { "setDuty" , ROREG_FUNC(l_pwm_set_duty )},
  173. { "setFreq" , ROREG_FUNC(l_pwm_set_freq )},
  174. { NULL, ROREG_INT(0) }
  175. };
  176. LUAMOD_API int luaopen_pwm( lua_State *L ) {
  177. luat_newlib2(L, reg_pwm);
  178. return 1;
  179. }