luat_lib_pwm.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. @usage
  9. -- 本库支持2套API风格
  10. -- 1. 传统API, open和close
  11. -- 2. 新的API(推荐使用), setup,start,stop,setDuty,setFreq
  12. -- 传统API
  13. pwm.open(1, 1000, 50) -- 打开PWM1, 频率1kHz, 占空比50%
  14. sys.wait(5000) -- 等待5秒
  15. pwm.close(1) -- 关闭PWM1
  16. -- 新API
  17. pwm.setup(1, 1000, 50) -- 设置PWM1, 频率1kHz, 占空比50%
  18. pwm.start(1) -- 启动PWM1
  19. sys.wait(5000) -- 等待5秒
  20. pwm.setFreq(1, 2000) -- 设置PWM1频率2kHz
  21. sys.wait(5000) -- 等待5秒
  22. pwm.setDuty(1, 25) -- 设置PWM1占空比25%
  23. sys.wait(5000) -- 等待5秒
  24. pwm.stop(1) -- 关闭PWM1
  25. */
  26. #include "luat_base.h"
  27. #include "luat_pwm.h"
  28. #include "luat_mem.h"
  29. #define LUAT_LOG_TAG "pwm"
  30. #include "luat_log.h"
  31. /**
  32. 开启指定的PWM通道
  33. @api pwm.open(channel, period, pulse, pnum, precision)
  34. @int PWM通道
  35. @int 频率, 1-N,单位Hz. N受限于具体硬件能力
  36. @int 占空比 0-分频精度
  37. @int 输出周期 0为持续输出, 1为单次输出, 其他为指定脉冲数输出
  38. @int 分频精度, 100/256/1000, 默认为100, 若设备不支持会有日志提示
  39. @return boolean 处理结果,成功返回true,失败返回false
  40. @usage
  41. -- 打开PWM5, 频率1kHz, 占空比50%
  42. pwm.open(5, 1000, 50)
  43. -- 打开PWM5, 频率10kHz, 分频为 31/256
  44. pwm.open(5, 10000, 31, 0, 256)
  45. */
  46. static int l_pwm_open(lua_State *L) {
  47. luat_pwm_conf_t conf = {
  48. .pnum = 0,
  49. .precision = 100
  50. };
  51. conf.channel = luaL_checkinteger(L, 1);
  52. conf.period = luaL_checkinteger(L, 2);
  53. conf.pulse = luaL_optnumber(L, 3,0);
  54. if (lua_isnumber(L, 4) || lua_isinteger(L, 4)){
  55. conf.pnum = luaL_checkinteger(L, 4);
  56. }
  57. if (lua_isnumber(L, 5) || lua_isinteger(L, 5)){
  58. conf.precision = luaL_checkinteger(L, 5);
  59. }
  60. int ret = luat_pwm_setup(&conf);
  61. lua_pushboolean(L, ret == 0 ? 1 : 0);
  62. return 1;
  63. }
  64. /**
  65. 关闭指定的PWM通道
  66. @api pwm.close(channel)
  67. @int PWM通道
  68. @return nil 无处理结果
  69. @usage
  70. -- 关闭PWM5
  71. pwm.close(5)
  72. */
  73. static int l_pwm_close(lua_State *L) {
  74. luat_pwm_close(luaL_checkinteger(L, 1));
  75. return 0;
  76. }
  77. /**
  78. PWM捕获
  79. @api pwm.capture(channel)
  80. @int PWM通道
  81. @int 捕获频率
  82. @return boolean 处理结果,成功返回true,失败返回false
  83. @usage
  84. -- PWM0捕获
  85. while 1 do
  86. pwm.capture(0,1000)
  87. local ret,channel,pulse,pwmH,pwmL = sys.waitUntil("PWM_CAPTURE", 2000)
  88. if ret then
  89. log.info("PWM_CAPTURE","channel"..channel,"pulse"..pulse,"pwmH"..pwmH,"pwmL"..pwmL)
  90. end
  91. end
  92. */
  93. static int l_pwm_capture(lua_State *L) {
  94. int ret = luat_pwm_capture(luaL_checkinteger(L, 1),luaL_checkinteger(L, 2));
  95. lua_pushboolean(L, ret == 0 ? 1 : 0);
  96. return 1;
  97. }
  98. // 新的API系列, 封装老的版本, bsp层暂时不改
  99. static luat_pwm_conf_t* confs[6];
  100. /*
  101. 初始化指定的PWM通道
  102. @api pwm.setup(channel, period, pulse, pnum, precision)
  103. @int PWM通道
  104. @int 频率, 1-N,单位Hz. N受限于具体硬件能力
  105. @int 占空比 0-分频精度
  106. @int 输出周期 0为持续输出, 1为单次输出, 其他为指定脉冲数输出
  107. @int 分频精度, 100/256/1000, 默认为100, 若设备不支持会有日志提示
  108. @return boolean 处理结果,成功返回true,失败返回false
  109. @usage
  110. -- 设置PWM5, 频率1kHz, 占空比50%
  111. pwm.setup(5, 1000, 50)
  112. */
  113. static int l_pwm_setup(lua_State *L) {
  114. luat_pwm_conf_t conf = {
  115. .pnum = 0,
  116. .precision = 100
  117. };
  118. conf.channel = luaL_checkinteger(L, 1);
  119. conf.period = luaL_checkinteger(L, 2);
  120. conf.pulse = luaL_optnumber(L, 3,0);
  121. if (lua_isnumber(L, 4) || lua_isinteger(L, 4)){
  122. conf.pnum = luaL_checkinteger(L, 4);
  123. }
  124. if (lua_isnumber(L, 5) || lua_isinteger(L, 5)){
  125. conf.precision = luaL_checkinteger(L, 5);
  126. }
  127. if (conf.channel > 5 || conf.channel < 0) {
  128. return 0;
  129. }
  130. if (confs[conf.channel] == NULL) {
  131. confs[conf.channel] = luat_heap_malloc(sizeof(luat_pwm_conf_t));
  132. if (confs[conf.channel] == NULL) {
  133. LLOGE("pwm_setup malloc fail");
  134. return 0;
  135. }
  136. }
  137. memcpy(confs[conf.channel], &conf, sizeof(luat_pwm_conf_t));
  138. lua_pushboolean(L, 1);
  139. return 1;
  140. }
  141. static int check_channel(lua_State *L) {
  142. int channel = luaL_checkinteger(L, 1);
  143. if (channel > 5 || channel < 0) {
  144. return -1;
  145. }
  146. if (confs[channel] == NULL) {
  147. LLOGE("请先调用pwm.setup!! %d", channel);
  148. return -1;
  149. }
  150. return channel;
  151. }
  152. /*
  153. 启动指定的PWM通道
  154. @api pwm.start(channel)
  155. @int PWM通道
  156. @return boolean 处理结果,成功返回true,失败返回false
  157. @usage
  158. -- 启动PWM1
  159. pwm.start(1)
  160. */
  161. static int l_pwm_start(lua_State *L) {
  162. int channel = check_channel(L);
  163. if (channel < 0) {
  164. return 0;
  165. }
  166. int ret = luat_pwm_setup(confs[channel]);
  167. lua_pushboolean(L, ret == 0 ? 1 : 0);
  168. return 1;
  169. }
  170. /*
  171. 停止指定的PWM通道
  172. @api pwm.stop(channel)
  173. @int PWM通道
  174. @return boolean 处理结果,成功返回true,失败返回false
  175. @usage
  176. -- 停止PWM1
  177. pwm.stop(1)
  178. */
  179. static int l_pwm_stop(lua_State *L) {
  180. int channel = check_channel(L);
  181. if (channel < 0) {
  182. return 0;
  183. }
  184. luat_pwm_close(channel);
  185. luat_heap_free(confs[channel]);
  186. confs[channel] = NULL;
  187. lua_pushboolean(L, 1);
  188. return 1;
  189. }
  190. /*
  191. 设置指定PWM通道的占空比
  192. @api pwm.setDuty(channel, duty)
  193. @int PWM通道
  194. @int 占空比
  195. @return boolean 处理结果,成功返回true,失败返回false
  196. @usage
  197. -- 设置PWM1占空比25%
  198. pwm.setDuty(1, 25)
  199. */
  200. static int l_pwm_set_duty(lua_State *L) {
  201. int channel = check_channel(L);
  202. if (channel < 0) {
  203. return 0;
  204. }
  205. confs[channel]->pulse = luaL_checkinteger(L, 2);
  206. int ret = luat_pwm_setup(confs[channel]);
  207. lua_pushboolean(L, ret == 0 ? 1 : 0);
  208. return 1;
  209. }
  210. /*
  211. 设置指定PWM通道的频率
  212. @api pwm.setFreq(channel, freq)
  213. @int PWM通道
  214. @int 频率, 1-N,单位Hz. N受限于具体硬件能力
  215. @return boolean 处理结果,成功返回true,失败返回false
  216. @usage
  217. -- 设置PWM5频率2kHz
  218. pwm.setFreq(5, 2000)
  219. */
  220. static int l_pwm_set_freq(lua_State *L) {
  221. int channel = check_channel(L);
  222. if (channel < 0) {
  223. return 0;
  224. }
  225. confs[channel]->period = luaL_checkinteger(L, 2);
  226. int ret = luat_pwm_setup(confs[channel]);
  227. lua_pushboolean(L, ret == 0 ? 1 : 0);
  228. return 1;
  229. }
  230. #include "rotable2.h"
  231. static const rotable_Reg_t reg_pwm[] =
  232. {
  233. { "open" , ROREG_FUNC(l_pwm_open )},
  234. { "close" , ROREG_FUNC(l_pwm_close)},
  235. { "capture" , ROREG_FUNC(l_pwm_capture)},
  236. // 新api, setup,start,stop
  237. { "setup" , ROREG_FUNC(l_pwm_setup )},
  238. { "start" , ROREG_FUNC(l_pwm_start )},
  239. { "stop" , ROREG_FUNC(l_pwm_stop )},
  240. { "setDuty" , ROREG_FUNC(l_pwm_set_duty )},
  241. { "setFreq" , ROREG_FUNC(l_pwm_set_freq )},
  242. { NULL, ROREG_INT(0) }
  243. };
  244. LUAMOD_API int luaopen_pwm( lua_State *L ) {
  245. luat_newlib2(L, reg_pwm);
  246. return 1;
  247. }