1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openLuat-luatos-soc-air101

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
luat_pwm_air101.c 15 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Wendal Chen Отправлено год назад b26de8a
#include "luat_base.h"
#include "luat_pwm.h"
#define LUAT_LOG_TAG "luat.pwm"
#include "luat_log.h"
#include "wm_type_def.h"
#include "wm_cpu.h"
#include "wm_regs.h"
#include "wm_dma.h"
#include "wm_pwm.h"
#include "wm_io.h"
#include "luat_msgbus.h"
#include "wm_gpio_afsel.h"
uint32_t pwmDmaCap0[10]={0};
uint32_t pwmDmaCap4[10]={0};
static luat_pwm_conf_t pwm_confs[5];
static uint8_t dmaCh;
int l_pwm_dma_capture(lua_State *L, void* ptr) {
int pwmH = 0,pwmL = 0,pulse = 0;
// 给 sys.publish方法发送数据
rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
int channel = msg->arg1;
if (channel ==0){
pwmH = (int)(pwmDmaCap0[5]>>16);
pwmL = (int)(pwmDmaCap0[5]&0x0000ffff);
pulse = pwmH*100/(pwmH+pwmL);
}else if(channel ==4){
pwmH = (int)(pwmDmaCap4[5]>>16);
pwmL = (int)(pwmDmaCap4[5]&0x0000ffff);
pulse = pwmH*100/(pwmH+pwmL);
}
lua_getglobal(L, "sys_pub");
if (lua_isnil(L, -1)) {
lua_pushinteger(L, 0);
return 1;
}
lua_pushstring(L, "PWM_CAPTURE");
lua_pushinteger(L, channel);
lua_pushinteger(L, pulse);
lua_pushinteger(L, pwmH);
lua_pushinteger(L, pwmL);
lua_call(L, 5, 0);
return 0;
}
static void pwm_dma_callback(void * channel)
{
u8 ch = (u8)(channel);
tls_pwm_stop(ch);
tls_dma_free(dmaCh);
dmaCh = 0;
rtos_msg_t msg={0};
msg.handler = l_pwm_dma_capture;
msg.arg1 = ch;
luat_msgbus_put(&msg, 0);
}
int luat_pwm_setup(luat_pwm_conf_t* conf) {
int channel = conf->channel;
size_t period = conf->period;
size_t pulse = conf->pulse;
size_t pnum = conf->pnum;
size_t precision = conf->precision;
tls_sys_clk sysclk;
if (period == 0) {
LLOGW("period can't be 0");
return -1;
}
if (precision != 100 && precision != 256) {
LLOGW("only 100 or 256 PWM precision supported");
return -1;
}
if (pulse >= precision)
pulse = precision;
if (precision == 100)
pulse = pulse * 2.56;
int ret = -1;
switch (channel)
{
case 00:
wm_pwm0_config(WM_IO_PB_00);
break;
case 10:
wm_pwm0_config(WM_IO_PA_10);
break;
case 20:
wm_pwm0_config(WM_IO_PB_12);
break;
case 30:
wm_pwm0_config(WM_IO_PA_02);
break;
case 40:
wm_pwm0_config(WM_IO_PB_19);
break;
case 01:
wm_pwm1_config(WM_IO_PB_01);
break;
case 11:
wm_pwm1_config(WM_IO_PA_11);
break;
case 21:
wm_pwm1_config(WM_IO_PB_13);
break;
case 31:
wm_pwm1_config(WM_IO_PA_03);
break;
case 02:
wm_pwm2_config(WM_IO_PB_02);
break;
case 12:
wm_pwm2_config(WM_IO_PA_12);
break;
case 22:
wm_pwm2_config(WM_IO_PB_14);
break;
case 32:
wm_pwm2_config(WM_IO_PB_24);
break;
case 03:
wm_pwm3_config(WM_IO_PB_03);
break;
case 13:
wm_pwm3_config(WM_IO_PA_13);
break;
case 23:
wm_pwm3_config(WM_IO_PB_15);
break;
case 33:
wm_pwm3_config(WM_IO_PB_25);
break;
case 04:
wm_pwm4_config(WM_IO_PA_07);
break;
case 14:
wm_pwm4_config(WM_IO_PA_14);
break;
case 24:
wm_pwm4_config(WM_IO_PB_16);
break;
case 34:
wm_pwm4_config(WM_IO_PB_26);
break;
case 44:
wm_pwm4_config(WM_IO_PA_04);
break;
// #endif
// TODO 再选一组PWM0~PWM4
default:
LLOGW("unkown pwm channel %d", channel);
return -1;
}
channel = channel%10;
if (channel < 0 || channel > 4)
return -1;
if (conf->pulse == 0) {
return luat_pwm_close(conf->channel);
}
tls_sys_clk_get(&sysclk);
if (pnum != 0){
// 按次输出的时候, 总是重置pwm配置
}else if(memcmp(&pwm_confs[channel], conf, sizeof(luat_pwm_conf_t))) {// 判断一下是否只修改了占空比
while (1) {
if (pwm_confs[channel].period != conf->period) {
break;
// TODO 支持只修改频率
//tls_pwm_freq_config(channel, sysclk.apbclk*UNIT_MHZ/256/period, period);
}
if (pwm_confs[channel].pnum != conf->pnum) {
break;
}
if (pwm_confs[channel].precision != conf->precision) {
break;
}
if (pwm_confs[channel].pulse != conf->pulse) {
// 仅占空比不同,修改即可, V0006
tls_pwm_duty_config(channel, pulse);
pwm_confs[channel].pulse = conf->pulse;
return 0;
}
break;
}
}
else {
// 完全相同, 那不需要重新配置了
return 0;
}
// 属于全新配置
tls_pwm_stop(channel);
ret = tls_pwm_init(channel, period, pulse, pnum);
if(ret != WM_SUCCESS)
return ret;
tls_pwm_start(channel);
memcpy(&pwm_confs[channel], conf, sizeof(luat_pwm_conf_t));
return 0;
}
int luat_pwm_capture(int channel,int freq) {
struct tls_dma_descriptor DmaDesc;
tls_sys_clk sysclk;
tls_sys_clk_get(&sysclk);
if (dmaCh) {
tls_dma_free(dmaCh);
dmaCh = 0;
}
switch (channel){
// #ifdef AIR101
// case 0:
// memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
// wm_pwm0_config(WM_IO_PB_00);
// tls_pwm_stop(channel);
// dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
// DmaDesc.src_addr = HR_PWM_CAPDAT;
// DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
// DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
// DmaDesc.valid = TLS_DMA_DESC_VALID;
// DmaDesc.next = NULL;
// tls_dma_start(dmaCh, &DmaDesc, 0);
// tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
// tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
// tls_pwm_start(channel);
// return 0;
// case 4:
// memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
// wm_pwm4_config(WM_IO_PA_07);
// tls_pwm_stop(channel);
// dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
// DmaDesc.src_addr = HR_PWM_CAPDAT;
// DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
// DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
// DmaDesc.valid = TLS_DMA_DESC_VALID;
// DmaDesc.next = NULL;
// tls_dma_start(dmaCh, &DmaDesc, 0);
// tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
// tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
// tls_pwm_start(channel);
// return 0;
// #else
case 00:
channel = channel%10;
memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
wm_pwm0_config(WM_IO_PB_00);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 10:
channel = channel%10;
memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
wm_pwm0_config(WM_IO_PA_10);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 20:
memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
wm_pwm0_config(WM_IO_PB_12);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 30:
channel = channel%10;
memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
wm_pwm0_config(WM_IO_PA_02);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 40:
channel = channel%10;
memset(pwmDmaCap0, 0, sizeof(pwmDmaCap0)/sizeof(char));
wm_pwm0_config(WM_IO_PB_19);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap0;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 04:
channel = channel%10;
memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
wm_pwm4_config(WM_IO_PA_07);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 14:
channel = channel%10;
memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
wm_pwm4_config(WM_IO_PA_14);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 24:
channel = channel%10;
memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
wm_pwm4_config(WM_IO_PB_16);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 34:
channel = channel%10;
memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
wm_pwm4_config(WM_IO_PB_26);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
case 44:
channel = channel%10;
memset(pwmDmaCap4, 0, sizeof(pwmDmaCap4)/sizeof(char));
wm_pwm4_config(WM_IO_PA_04);
tls_pwm_stop(channel);
dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
DmaDesc.src_addr = HR_PWM_CAPDAT;
DmaDesc.dest_addr = (unsigned int)pwmDmaCap4;
DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
DmaDesc.valid = TLS_DMA_DESC_VALID;
DmaDesc.next = NULL;
tls_dma_start(dmaCh, &DmaDesc, 0);
tls_dma_irq_register(dmaCh, pwm_dma_callback, (void*)channel, TLS_DMA_IRQ_TRANSFER_DONE);
tls_pwm_cap_init(channel, sysclk.apbclk*UNIT_MHZ/256/freq, DISABLE, WM_PWM_CAP_DMA_INT);
tls_pwm_start(channel);
return 0;
// #endif
// TODO 再选一组PWM0~PWM4
default:
break;
}
return -1;
}
// @return -1 关闭失败。 0 关闭成功
int luat_pwm_close(int channel) {
int ret = -1;
channel = channel%10;
if (channel < 0 || channel > 4)
return 0;
ret = tls_pwm_stop(channel);
pwm_confs[channel].period = 0;
if(ret != WM_SUCCESS)
return ret;
return 0;
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/openLuat-luatos-soc-air101.git
git@gitlife.ru:oschina-mirror/openLuat-luatos-soc-air101.git
oschina-mirror
openLuat-luatos-soc-air101
openLuat-luatos-soc-air101
master