| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /*
- @module pwm
- @summary PWM模块
- @version 1.0
- @date 2020.07.03
- @demo pwm
- @tag LUAT_USE_PWM
- @usage
- -- 本库支持2套API风格
- -- 1. 传统API, open和close
- -- 2. 新的API(推荐使用), setup,start,stop,setDuty,setFreq
- -- 传统API
- pwm.open(1, 1000, 50) -- 打开PWM1, 频率1kHz, 占空比50%
- sys.wait(5000) -- 等待5秒
- pwm.close(1) -- 关闭PWM1
- -- 新API
- pwm.setup(1, 1000, 50) -- 设置PWM1, 频率1kHz, 占空比50%
- pwm.start(1) -- 启动PWM1
- sys.wait(5000) -- 等待5秒
- pwm.setFreq(1, 2000) -- 设置PWM1频率2kHz
- sys.wait(5000) -- 等待5秒
- pwm.setDuty(1, 25) -- 设置PWM1占空比25%
- sys.wait(5000) -- 等待5秒
- pwm.stop(1) -- 关闭PWM1
- -- 提醒: pwm.setFreq和pwm.setDuty的, 仅在start/open状态下立即生效, stop/close状态是不会生效的
- */
- #include "luat_base.h"
- #include "luat_pwm.h"
- #include "luat_mem.h"
- #define LUAT_LOG_TAG "pwm"
- #include "luat_log.h"
- static uint32_t s_state = 0;
- static luat_pwm_conf_t* confs[12];
- /**
- 开启指定的PWM通道
- @api pwm.open(channel, period, pulse, pnum, precision)
- @int PWM通道
- @int 频率, 1-N,单位Hz. N受限于具体硬件能力
- @int 占空比 0-分频精度
- @int 输出周期 0为持续输出, 1为单次输出, 其他为指定脉冲数输出
- @int 分频精度, 100/256/1000, 默认为100, 若设备不支持会有日志提示
- @return boolean 处理结果,成功返回true,失败返回false
- @usage
- -- 打开PWM5, 频率1kHz, 占空比50%
- pwm.open(5, 1000, 50)
- -- 打开PWM5, 频率10kHz, 分频为 31/256
- pwm.open(5, 10000, 31, 0, 256)
- */
- static int l_pwm_open(lua_State *L) {
- luat_pwm_conf_t conf = {
- .pnum = 0,
- .precision = 100
- };
- conf.channel = luaL_checkinteger(L, 1);
- conf.period = luaL_checkinteger(L, 2);
- conf.pulse = luaL_optnumber(L, 3,0);
- if (lua_isnumber(L, 4) || lua_isinteger(L, 4)){
- conf.pnum = luaL_checkinteger(L, 4);
- }
- if (lua_isnumber(L, 5) || lua_isinteger(L, 5)){
- conf.precision = luaL_checkinteger(L, 5);
- }
- int ret = luat_pwm_setup(&conf);
- if (ret == 0) {
- s_state |= (1 << conf.channel);
- }
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- return 1;
- }
- /**
- 关闭指定的PWM通道
- @api pwm.close(channel)
- @int PWM通道
- @return nil 无处理结果
- @usage
- -- 关闭PWM5
- pwm.close(5)
- */
- static int l_pwm_close(lua_State *L) {
- int channel = luaL_checkinteger(L, 1);
- luat_pwm_close(channel);
- s_state &= ~(1 << channel);
- return 0;
- }
- /**
- PWM捕获
- @api pwm.capture(channel)
- @int PWM通道
- @int 捕获频率
- @return boolean 处理结果,成功返回true,失败返回false
- @usage
- -- PWM0捕获
- while 1 do
- pwm.capture(0,1000)
- local ret,channel,pulse,pwmH,pwmL = sys.waitUntil("PWM_CAPTURE", 2000)
- if ret then
- log.info("PWM_CAPTURE","channel"..channel,"pulse"..pulse,"pwmH"..pwmH,"pwmL"..pwmL)
- end
- end
- */
- static int l_pwm_capture(lua_State *L) {
- int ret = luat_pwm_capture(luaL_checkinteger(L, 1),luaL_checkinteger(L, 2));
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- return 1;
- }
- // 新的API系列, 封装老的版本, bsp层暂时不改
- /*
- 初始化指定的PWM通道
- @api pwm.setup(channel, period, pulse, pnum, precision)
- @int PWM通道
- @int 频率, 1-N,单位Hz. N受限于具体硬件能力
- @int 占空比 0-分频精度
- @int 输出周期 0为持续输出, 1为单次输出, 其他为指定脉冲数输出
- @int 分频精度, 100/256/1000, 默认为100, 若设备不支持会有日志提示
- @return boolean 处理结果,成功返回true,失败返回false
- @usage
- -- 设置PWM5, 频率1kHz, 占空比50%
- pwm.setup(5, 1000, 50)
- */
- static int l_pwm_setup(lua_State *L) {
- luat_pwm_conf_t conf = {
- .pnum = 0,
- .precision = 100
- };
- conf.channel = luaL_checkinteger(L, 1);
- conf.period = luaL_checkinteger(L, 2);
- conf.pulse = luaL_optnumber(L, 3,0);
- if (lua_isnumber(L, 4) || lua_isinteger(L, 4)){
- conf.pnum = luaL_checkinteger(L, 4);
- }
- if (lua_isnumber(L, 5) || lua_isinteger(L, 5)){
- conf.precision = luaL_checkinteger(L, 5);
- }
- if (conf.channel > 5 || conf.channel < 0) {
- return 0;
- }
- if (confs[conf.channel] == NULL) {
- confs[conf.channel] = luat_heap_malloc(sizeof(luat_pwm_conf_t));
- if (confs[conf.channel] == NULL) {
- LLOGE("pwm_setup malloc fail");
- return 0;
- }
- }
- memcpy(confs[conf.channel], &conf, sizeof(luat_pwm_conf_t));
- lua_pushboolean(L, 1);
- return 1;
- }
- static int check_channel(lua_State *L) {
- int channel = luaL_checkinteger(L, 1);
- if (channel >= 12 || channel < 0) {
- return -1;
- }
- if (confs[channel] == NULL) {
- LLOGE("请先调用pwm.setup!! %d", channel);
- return -1;
- }
- return channel;
- }
- /*
- 启动指定的PWM通道
- @api pwm.start(channel)
- @int PWM通道
- @return boolean 处理结果,成功返回true,失败返回false
- @usage
- -- 启动PWM1
- pwm.start(1)
- */
- static int l_pwm_start(lua_State *L) {
- int channel = check_channel(L);
- if (channel < 0) {
- return 0;
- }
- int ret = luat_pwm_setup(confs[channel]);
- if (ret == 0) {
- s_state |= (1 << channel);
- }
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- return 1;
- }
- /*
- 停止指定的PWM通道
- @api pwm.stop(channel)
- @int PWM通道
- @return boolean 处理结果,成功返回true,失败返回false
- @usage
- -- 停止PWM1
- pwm.stop(1)
- */
- static int l_pwm_stop(lua_State *L) {
- int channel = check_channel(L);
- if (channel < 0) {
- return 0;
- }
- luat_pwm_close(channel);
- luat_heap_free(confs[channel]);
- confs[channel] = NULL;
- s_state &= ~(1 << channel);
- lua_pushboolean(L, 1);
- return 1;
- }
- /*
- 设置指定PWM通道的占空比
- @api pwm.setDuty(channel, duty)
- @int PWM通道
- @int 占空比
- @return boolean 处理结果,成功返回true,失败返回false
- @usage
- -- 设置PWM1占空比25%
- pwm.setDuty(1, 25)
- */
- static int l_pwm_set_duty(lua_State *L) {
- int channel = check_channel(L);
- if (channel < 0) {
- return 0;
- }
- confs[channel]->pulse = luaL_checkinteger(L, 2);
- luat_pwm_conf_t conf = *confs[channel];
- // 如果已经是打开状态, 需要重新setup一下
- if (s_state & (1 << channel)) {
- int ret = luat_pwm_setup(&conf);
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- }
- else {
- lua_pushboolean(L, 1);
- }
- return 1;
- }
- /*
- 设置指定PWM通道的频率
- @api pwm.setFreq(channel, freq)
- @int PWM通道
- @int 频率, 1-N,单位Hz. N受限于具体硬件能力
- @return boolean 处理结果,成功返回true,失败返回false
- @usage
- -- 设置PWM5频率2kHz
- pwm.setFreq(5, 2000)
- */
- static int l_pwm_set_freq(lua_State *L) {
- int channel = check_channel(L);
- if (channel < 0) {
- return 0;
- }
- confs[channel]->period = luaL_checkinteger(L, 2);
- luat_pwm_conf_t conf = *confs[channel];
- // 如果已经是打开状态, 需要重新setup一下
- if (s_state & (1 << channel)) {
- int ret = luat_pwm_setup(&conf);
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- }
- else {
- lua_pushboolean(L, 1);
- }
- return 1;
- }
- #include "rotable2.h"
- static const rotable_Reg_t reg_pwm[] =
- {
- { "open" , ROREG_FUNC(l_pwm_open )},
- { "close" , ROREG_FUNC(l_pwm_close)},
- { "capture" , ROREG_FUNC(l_pwm_capture)},
- // 新api, setup,start,stop
- { "setup" , ROREG_FUNC(l_pwm_setup )},
- { "start" , ROREG_FUNC(l_pwm_start )},
- { "stop" , ROREG_FUNC(l_pwm_stop )},
- { "setDuty" , ROREG_FUNC(l_pwm_set_duty )},
- { "setFreq" , ROREG_FUNC(l_pwm_set_freq )},
- { NULL, ROREG_INT(0) }
- };
- LUAMOD_API int luaopen_pwm( lua_State *L ) {
- luat_newlib2(L, reg_pwm);
- return 1;
- }
|