This commit is contained in:
huxi
2025-12-03 11:12:34 +08:00
parent c23ae4f24c
commit bc195654bf
8163 changed files with 3799544 additions and 92 deletions
+552
View File
@@ -0,0 +1,552 @@
#include "asm/mcpwm.h"
#include "clock.h"
#include "gpio.h"
#include "spinlock.h"
#define MCPWM_DEBUG_ENABLE 0 //MCPWM打印使能
#if MCPWM_DEBUG_ENABLE
#define mcpwm_debug(fmt, ...) printf("[MCPWM] "fmt, ##__VA_ARGS__)
#else
#define mcpwm_debug(...)
#endif
#define log_error(fmt, ...) printf("[MCPWM](err): "fmt, ##__VA_ARGS__)
#define MCPWM_CLK clk_get("mcpwm")
DEFINE_SPINLOCK(mcpwm_lock);
static struct mcpwm_info_t *mcpwm_info[MCPWM_NUM_MAX] = {NULL};
static MCPWM_TIMERx_REG *mcpwm_get_timerx_reg(mcpwm_ch_type ch)
{
ASSERT((u32)ch < MCPWM_CH_MAX, "func:%s(), line:%d\n", __func__, __LINE__);
MCPWM_TIMERx_REG *reg = NULL;
reg = (MCPWM_TIMERx_REG *)(MCPWM_TMR_BASE_ADDR + ch * MCPWM_TMR_OFFSET);
return reg;
}
static MCPWM_CHx_REG *mcpwm_get_chx_reg(mcpwm_ch_type ch)
{
ASSERT((u32)ch < MCPWM_CH_MAX, "func:%s(), line:%d\n", __func__, __LINE__);
MCPWM_CHx_REG *reg = NULL;
reg = (MCPWM_CHx_REG *)(MCPWM_CH_BASE_ADDR + ch * MCPWM_CH_OFFSET);
return reg;
}
static int mcpwm_get_cfg_id(u32 ch)
{
for (u8 id = 0; id < MCPWM_NUM_MAX; id++) {
if (mcpwm_info[id] != NULL) {
if ((u32)mcpwm_info[id]->cfg.ch == ch) {
return (int)id;
}
}
}
return -1;
}
static u32 old_mcpwm_clk = 0;
static void clock_critical_enter(void)
{
old_mcpwm_clk = MCPWM_CLK;
}
static void clock_critical_exit(void)
{
u32 new_mcpwm_clk = MCPWM_CLK;
if (new_mcpwm_clk == old_mcpwm_clk) {
return;
}
MCPWM_CHx_REG *ch_reg = NULL;
for (u8 ch = 0; ch < MCPWM_CH_MAX; ch++) {
ch_reg = mcpwm_get_chx_reg(ch);
if (ch_reg->ch_con0 & (BIT(MCPWM_CH_H_EN) | BIT(MCPWM_CH_L_EN))) {
int id = mcpwm_get_cfg_id(ch);
if (id != -1) {
mcpwm_set_frequency(id, mcpwm_info[id]->cfg.aligned_mode, mcpwm_info[id]->cfg.frequency);
}
}
}
}
LSB_CRITICAL_HANDLE_REG(mcpwm, clock_critical_enter, clock_critical_exit)
static void mcpwm_reg_log_info(int mcpwm_cfg_id)
{
int id = mcpwm_cfg_id;
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
//cppcheck-suppress unreadVariable
MCPWM_CHx_REG *ch_reg = mcpwm_get_chx_reg(ch);
//cppcheck-suppress unreadVariable
MCPWM_TIMERx_REG *timer_reg = mcpwm_get_timerx_reg(ch);
mcpwm_debug("tmr%d con = 0x%x", ch, timer_reg->tmr_con);
mcpwm_debug("tmr%d pr = 0x%x", ch, timer_reg->tmr_pr);
mcpwm_debug("pwm ch%d_con0 = 0x%x", ch, ch_reg->ch_con0);
mcpwm_debug("pwm ch%d_con1 = 0x%x", ch, ch_reg->ch_con1);
mcpwm_debug("pwm ch%d_cmph = 0x%x, pwm ch%d_cmpl = 0x%x", ch, ch_reg->ch_cmph, ch, ch_reg->ch_cmpl);
mcpwm_debug("pwm ch%d_fpin = 0x%x", ch, JL_MCPWM->FPIN_CON);
mcpwm_debug("MCPWM_CON0 = 0x%x", JL_MCPWM->MCPWM_CON0);
mcpwm_debug("mcpwm clk = %d", MCPWM_CLK);
}
static void (*mcpwm_cb_table[MCPWM_CH_MAX])(u32 ch);
static void mcpwm_cb(u32 ch)
{
if (mcpwm_cb_table[ch]) {
mcpwm_cb_table[ch](ch);
}
asm("csync");
}
___interrupt
static void mcpwm_fpin_cb()
{
MCPWM_CHx_REG *ch_reg = NULL;
for (u8 ch = 0; ch < MCPWM_CH_MAX; ch++) {
ch_reg = mcpwm_get_chx_reg(ch);
if (ch_reg->ch_con1 & BIT(MCPWM_CH_FPND)) {
JL_MCPWM->MCPWM_CON0 &= ~BIT(ch + MCPWM_CON_PWM_EN);
JL_MCPWM->MCPWM_CON0 &= ~BIT(ch + MCPWM_CON_TMR_EN);
if (ch_reg->ch_con1 & BIT(MCPWM_CH_INTEN)) {
ch_reg->ch_con1 &= ~BIT(MCPWM_CH_INTEN); //关闭故障保护输入IE使能
mcpwm_cb(ch);
}
}
}
}
static void mcpwm_cfg_info_load(int mcpwm_cfg_id)
{
if (!mcpwm_info[mcpwm_cfg_id]) {
log_error("[%s]mcpwm_cfg_id:%d not init", __func__, mcpwm_cfg_id);
return;
}
/* ASSERT(mcpwm_info[mcpwm_cfg_id] != NULL, "func:%s(), line:%d\n", __func__, __LINE__); */
int id = mcpwm_cfg_id;
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
MCPWM_CHx_REG *ch_reg = mcpwm_get_chx_reg(ch);
mcpwm_set_frequency(id, mcpwm_info[id]->cfg.aligned_mode, mcpwm_info[id]->cfg.frequency);
mcpwm_set_duty(id, mcpwm_info[id]->cfg.duty);
u16 ch_con0 = 0;
u16 ch_con1 = 0;
if (mcpwm_info[id]->cfg.complementary_en) { //是否互补
ch_con0 &= ~(BIT(MCPWM_CH_L_INV) | BIT(MCPWM_CH_H_INV));
ch_con0 |= BIT(MCPWM_CH_L_INV); //L_INV
} else {
ch_con0 &= ~(BIT(MCPWM_CH_L_INV) | BIT(MCPWM_CH_H_INV));
}
ch_con1 &= ~(0b111 << MCPWM_CH_TMRSEL);
ch_con1 |= (ch << MCPWM_CH_TMRSEL); //sel mctmr
//H:
if (mcpwm_info[id]->cfg.h_pin < IO_MAX_NUM) { //任意引脚
ch_con0 |= BIT(MCPWM_CH_H_EN); //H_EN
gpio_set_mode(IO_PORT_SPILT(mcpwm_info[id]->cfg.h_pin), PORT_OUTPUT_LOW);
gpio_set_function(IO_PORT_SPILT(mcpwm_info[id]->cfg.h_pin), PORT_FUNC_MCPWM0_H + 2 * ch);
#ifdef IO_LCD_PG
} else if (mcpwm_info[id]->cfg.h_pin == IO_LCD_PG) {
ch_con0 |= BIT(MCPWM_CH_H_EN); //H_EN
SFR(JL_IOMC->LCDPG_CON, 2, 6, (FO_MCPWM0_H >> 2) + ch);
JL_IOMC->LCDPG_CON |= BIT(0);
#endif
#ifdef IO_MT_PG
} else if (mcpwm_info[id]->cfg.h_pin == IO_MT_PG) {
ch_con0 |= BIT(MCPWM_CH_H_EN); //H_EN
SFR(JL_IOMC->MTPG_CON, 2, 6, (FO_MCPWM0_H >> 2) + ch);
JL_IOMC->MTPG_CON |= BIT(0);
#endif
}
//L:
if (mcpwm_info[id]->cfg.l_pin < IO_MAX_NUM) { //任意引脚
ch_con0 |= BIT(MCPWM_CH_L_EN); //L_EN
gpio_set_mode(IO_PORT_SPILT(mcpwm_info[id]->cfg.l_pin), PORT_OUTPUT_LOW);
gpio_set_function(IO_PORT_SPILT(mcpwm_info[id]->cfg.l_pin), PORT_FUNC_MCPWM0_L + 2 * ch);
}
if (mcpwm_info[id]->cfg.detect_port < IO_MAX_NUM) { //需要开启故障保护功能
ASSERT(mcpwm_info[id]->cfg.edge != MCPWM_EDGE_DEFAULT, "func:%s(), line:%d\n", __func__, __LINE__);
u32 fpin_con = JL_MCPWM->FPIN_CON;
asm("csync");
if (mcpwm_info[id]->cfg.edge) { //上升沿
gpio_set_mode(IO_PORT_SPILT(mcpwm_info[id]->cfg.detect_port), PORT_INPUT_PULLDOWN_10K);
fpin_con |= BIT(MCPWM_FPIN_EDGE + ch);//上升沿触发
} else {
gpio_set_mode(IO_PORT_SPILT(mcpwm_info[id]->cfg.detect_port), PORT_INPUT_PULLUP_10K);
fpin_con &= ~BIT(MCPWM_FPIN_EDGE + ch);//下升沿触发
}
fpin_con |= BIT(MCPWM_FPIN_FLT_EN + ch);//开启滤波
fpin_con |= (0b111111 << MCPWM_FPIN_FLT_PR); //滤波时间 = 16 * 64 / lsb_clk (单位:s)
gpio_set_function(IO_PORT_SPILT(mcpwm_info[id]->cfg.detect_port), PORT_FUNC_MCPWM0_FP + ch);
mcpwm_cb_table[ch] = mcpwm_info[id]->cfg.irq_cb;
request_irq(IRQ_MCPWM_CHX_IDX, mcpwm_info[id]->cfg.irq_priority, mcpwm_fpin_cb, 0);
ch_con1 |= BIT(MCPWM_CH_FCLR) | BIT(MCPWM_CH_INTEN) | BIT(MCPWM_CH_FPINEN) | BIT(MCPWM_CH_FPINAUTO) | (ch << MCPWM_CH_FPINSEL);
spin_lock(&mcpwm_lock);
JL_MCPWM->FPIN_CON = fpin_con;
spin_unlock(&mcpwm_lock);
}
spin_lock(&mcpwm_lock);
ch_reg->ch_con0 = ch_con0;
ch_reg->ch_con1 = ch_con1;
spin_unlock(&mcpwm_lock);
}
int mcpwm_init(struct mcpwm_config *mcpwm_cfg)
{
MCPWM_CHx_REG *ch_reg = mcpwm_get_chx_reg(mcpwm_cfg->ch);
MCPWM_TIMERx_REG *timer_reg = mcpwm_get_timerx_reg(mcpwm_cfg->ch);
int cfg_id = -1;
for (u32 i = 0; i < MCPWM_NUM_MAX; i++) {
if (mcpwm_info[i]) {
continue;
}
if (mcpwm_info[i] == NULL) {
mcpwm_info[i] = (struct mcpwm_info_t *)malloc(sizeof(struct mcpwm_info_t));
ASSERT(mcpwm_info[i] != NULL, "func:%s(), line:%d\n", __func__, __LINE__);
cfg_id = i;
break;
}
}
if (cfg_id == -1) {
mcpwm_debug("mcpwm_config_id is null!!!\n");
return cfg_id;
}
mcpwm_info[cfg_id]->ch_reg = ch_reg;
mcpwm_info[cfg_id]->timer_reg = timer_reg;
memcpy(&mcpwm_info[cfg_id]->cfg, mcpwm_cfg, sizeof(struct mcpwm_config));
mcpwm_debug("mcpwm_info[%d]->ch_reg = 0x%x\n", cfg_id, (u32)mcpwm_info[cfg_id]->ch_reg);
mcpwm_debug("mcpwm_info[%d]->timer_reg = 0x%x\n", cfg_id, (u32)mcpwm_info[cfg_id]->timer_reg);
mcpwm_debug("mcpwm_info[%d]->cfg.ch = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.ch);
mcpwm_debug("mcpwm_info[%d]->cfg.alifned_mode = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.aligned_mode);
mcpwm_debug("mcpwm_info[%d]->cfg.frequency = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.frequency);
mcpwm_debug("mcpwm_info[%d]->cfg.duty = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.duty);
mcpwm_debug("mcpwm_info[%d]->cfg.h_pin = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.h_pin);
mcpwm_debug("mcpwm_info[%d]->cfg.l_pin = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.l_pin);
mcpwm_debug("mcpwm_info[%d]->cfg.complementary_en = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.complementary_en);
mcpwm_debug("mcpwm_info[%d]->cfg.detect_port = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.detect_port);
mcpwm_debug("mcpwm_info[%d]->cfg.irq_cb = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.irq_cb);
mcpwm_debug("mcpwm_info[%d]->cfg.irq_priority = %d\n", cfg_id, (u32)mcpwm_info[cfg_id]->cfg.irq_priority);
return cfg_id;
}
void mcpwm_deinit(int mcpwm_cfg_id)
{
if (!mcpwm_info[mcpwm_cfg_id]) {
log_error("[%s]mcpwm_cfg_id:%d not init", __func__, mcpwm_cfg_id);
return;
}
/* ASSERT(mcpwm_info[mcpwm_cfg_id] != NULL, "func:%s(), line:%d\n", __func__, __LINE__); */
int id = mcpwm_cfg_id;
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
MCPWM_TIMERx_REG *timer_reg = mcpwm_get_timerx_reg(ch);
MCPWM_CHx_REG *ch_reg = mcpwm_get_chx_reg(ch);
u32 mcpwm_con = JL_MCPWM->MCPWM_CON0;
asm("csync");
mcpwm_con &= ~BIT(ch + MCPWM_CON_PWM_EN);
mcpwm_con &= ~BIT(ch + MCPWM_CON_TMR_EN);
if ((JL_MCPWM->MCPWM_CON0 & 0xff) == 0) {
mcpwm_con &= ~BIT(MCPWM_CON_CLK_EN);
}
spin_lock(&mcpwm_lock);
JL_MCPWM->MCPWM_CON0 = mcpwm_con;
spin_unlock(&mcpwm_lock);
if (mcpwm_info[id]->cfg.h_pin < IO_MAX_NUM) {
gpio_disable_function(IO_PORT_SPILT(mcpwm_info[mcpwm_cfg_id]->cfg.h_pin), PORT_FUNC_MCPWM0_H + 2 * ch);
gpio_set_mode(IO_PORT_SPILT(mcpwm_info[mcpwm_cfg_id]->cfg.h_pin), PORT_HIGHZ);
#ifdef IO_LCD_PG
} else if (mcpwm_info[id]->cfg.h_pin == IO_LCD_PG) {
JL_IOMC->LCDPG_CON = 0;
#endif
#ifdef IO_MT_PG
} else if (mcpwm_info[id]->cfg.h_pin == IO_MT_PG) {
JL_IOMC->MTPG_CON = 0;
#endif
}
if (mcpwm_info[id]->cfg.l_pin < IO_MAX_NUM) {
gpio_disable_function(IO_PORT_SPILT(mcpwm_info[mcpwm_cfg_id]->cfg.l_pin), PORT_FUNC_MCPWM0_L + 2 * ch);
gpio_set_mode(IO_PORT_SPILT(mcpwm_info[mcpwm_cfg_id]->cfg.l_pin), PORT_HIGHZ);
}
if (mcpwm_info[id]->cfg.detect_port < IO_MAX_NUM) { //需要开启故障保护功能
gpio_disable_function(IO_PORT_SPILT(mcpwm_info[mcpwm_cfg_id]->cfg.detect_port), PORT_FUNC_MCPWM0_FP + ch);
gpio_set_mode(IO_PORT_SPILT(mcpwm_info[mcpwm_cfg_id]->cfg.detect_port), PORT_HIGHZ);
spin_lock(&mcpwm_lock);
ch_reg->ch_con1 = BIT(MCPWM_CH_FCLR);
spin_unlock(&mcpwm_lock);
}
free(mcpwm_info[mcpwm_cfg_id]);
memset(mcpwm_info[mcpwm_cfg_id], 0, sizeof(struct mcpwm_info_t));
}
void mcpwm_start(int mcpwm_cfg_id)
{
if (!mcpwm_info[mcpwm_cfg_id]) {
log_error("[%s]mcpwm_cfg_id:%d not init", __func__, mcpwm_cfg_id);
return;
}
/* ASSERT(mcpwm_info[mcpwm_cfg_id] != NULL, "func:%s(), line:%d\n", __func__, __LINE__); */
int id = mcpwm_cfg_id;
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
mcpwm_cfg_info_load(id);
u32 mcpwm_con = JL_MCPWM->MCPWM_CON0;
asm("csync");
mcpwm_con |= BIT(MCPWM_CON_CLK_EN);
mcpwm_con |= BIT(ch + MCPWM_CON_TMR_EN);
mcpwm_con |= BIT(ch + MCPWM_CON_PWM_EN);
spin_lock(&mcpwm_lock);
JL_MCPWM->MCPWM_CON0 = mcpwm_con;
spin_unlock(&mcpwm_lock);
mcpwm_reg_log_info(id);
}
void mcpwm_pause(int mcpwm_cfg_id)
{
if (!mcpwm_info[mcpwm_cfg_id]) {
log_error("[%s]mcpwm_cfg_id:%d not init", __func__, mcpwm_cfg_id);
return;
}
int id = mcpwm_cfg_id;
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
u32 mcpwm_con = JL_MCPWM->MCPWM_CON0;
asm("csync");
mcpwm_con &= ~BIT(ch + MCPWM_CON_PWM_EN);
mcpwm_con &= ~BIT(ch + MCPWM_CON_TMR_EN);
if ((JL_MCPWM->MCPWM_CON0 & 0xff) == 0) {
mcpwm_con &= ~BIT(MCPWM_CON_CLK_EN);
}
spin_lock(&mcpwm_lock);
JL_MCPWM->MCPWM_CON0 = mcpwm_con;
spin_unlock(&mcpwm_lock);
}
void mcpwm_resume(int mcpwm_cfg_id)
{
mcpwm_start(mcpwm_cfg_id);
}
void mcpwm_set_frequency(int mcpwm_cfg_id, mcpwm_aligned_mode_type align, u32 frequency)
{
if (!mcpwm_info[mcpwm_cfg_id]) {
log_error("[%s]mcpwm_cfg_id:%d not init", __func__, mcpwm_cfg_id);
return;
}
/* ASSERT(mcpwm_info[mcpwm_cfg_id] != NULL, "func:%s(), line:%d\n", __func__, __LINE__); */
int id = mcpwm_cfg_id;
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
MCPWM_TIMERx_REG *timer_reg = mcpwm_get_timerx_reg(ch);
u32 tmr_con = timer_reg->tmr_con;
u16 tmr_pr = 0;
asm("csync");
u32 i = 0;
u32 mcpwm_div_clk = 0;
u32 mcpwm_tmr_pr = 0;
u32 mcpwm_fre_min;
u32 clk = MCPWM_CLK;
for (i = 0; i < 16; i++) {
mcpwm_fre_min = clk / (65536u << i);
if ((frequency >= mcpwm_fre_min) || (i == 15)) {
break;
}
}
tmr_con |= (i << MCPWM_TMR_CKPS); //div 2^i
mcpwm_div_clk = clk / (1 << i);
if (frequency == 0) {
mcpwm_tmr_pr = 0;
} else {
if (align == MCPWM_CENTER_ALIGNED) { //中心对齐
mcpwm_tmr_pr = mcpwm_div_clk / (frequency * 2) - 1;
} else {
mcpwm_tmr_pr = mcpwm_div_clk / frequency - 1;
}
}
tmr_pr = mcpwm_tmr_pr;
//timer mode
if (align == MCPWM_CENTER_ALIGNED) { //中心对齐
tmr_con |= 0b10; //递增-递降循环模式,中心对齐
} else {
tmr_con |= 0b01; //递增模式,边沿对齐
}
spin_lock(&mcpwm_lock);
timer_reg->tmr_con = tmr_con;
timer_reg->tmr_pr = tmr_pr;
spin_unlock(&mcpwm_lock);
}
void mcpwm_set_duty(int mcpwm_cfg_id, u16 duty)
{
if (!mcpwm_info[mcpwm_cfg_id]) {
log_error("[%s]mcpwm_cfg_id:%d not init", __func__, mcpwm_cfg_id);
return;
}
/* ASSERT(mcpwm_info[mcpwm_cfg_id] != NULL, "func:%s(), line:%d\n", __func__, __LINE__); */
int id = mcpwm_cfg_id;
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
MCPWM_TIMERx_REG *timer_reg = mcpwm_get_timerx_reg(ch);
MCPWM_CHx_REG *ch_reg = mcpwm_get_chx_reg(ch);
u16 ch_cmph = 0;
u16 ch_cmpl = 0;
u16 tmr_cnt = 0;
u16 tmr_con = timer_reg->tmr_con;
u16 tmr_pr = timer_reg->tmr_pr;
asm("csync");
ch_cmpl = tmr_pr * duty / 10000;
/* printf("---%d---%d---%d\n", ch_cmpl, tmr_pr, duty); */
ch_cmph = ch_cmpl;
tmr_cnt = 0;
/* tmr_con |= 0b01; */
/* if (duty == 10000) { */
/* tmr_cnt = 0; */
/* tmr_con &= ~(0b11); */
/* } else if (duty == 0) { */
/* tmr_cnt = ch_cmpl; */
/* tmr_con &= ~(0b11); */
/* } */
spin_lock(&mcpwm_lock);
ch_reg->ch_cmph = ch_cmph;
ch_reg->ch_cmpl = ch_cmpl;
u32 mcpwm_con = JL_MCPWM->MCPWM_CON0;
JL_MCPWM->MCPWM_CON0 |= BIT(MCPWM_CON_CLK_EN);
timer_reg->tmr_cnt = tmr_cnt;
timer_reg->tmr_con = tmr_con;
JL_MCPWM->MCPWM_CON0 = mcpwm_con;
spin_unlock(&mcpwm_lock);
}
void mcpwm_fpnd_clr(u32 ch)
{
MCPWM_CHx_REG *ch_reg = mcpwm_get_chx_reg(ch);
u32 mcpwm_con = JL_MCPWM->MCPWM_CON0;
u16 ch_con1 = ch_reg->ch_con1;
asm("csync");
mcpwm_con |= BIT(MCPWM_CON_CLK_EN);
mcpwm_con |= BIT(ch + MCPWM_CON_TMR_EN);
mcpwm_con |= BIT(ch + MCPWM_CON_PWM_EN);
ch_con1 |= BIT(MCPWM_CH_FCLR) | BIT(MCPWM_CH_INTEN);
spin_lock(&mcpwm_lock);
JL_MCPWM->MCPWM_CON0 = mcpwm_con;
ch_reg->ch_con1 = ch_con1;
spin_unlock(&mcpwm_lock);
}
#include "asm/power_interface.h"
static u16 mcpwm_con_en AT_VOLATILE_RAM_BSS_LOWPOWER;
static void mcpwm_enter_deepsleep(void)
{
mcpwm_con_en = 0;
for (u8 id = 0; id < MCPWM_NUM_MAX; id++) {
if (mcpwm_info[id] != NULL) {
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
if (JL_MCPWM->MCPWM_CON0 & BIT(ch + MCPWM_CON_TMR_EN)) {
mcpwm_con_en |= BIT(ch + MCPWM_CON_TMR_EN);
}
if (JL_MCPWM->MCPWM_CON0 & BIT(ch + MCPWM_CON_PWM_EN)) {
mcpwm_con_en |= BIT(ch + MCPWM_CON_PWM_EN);
}
}
}
}
static void mcpwm_post_deepsleep(void)
{
for (u8 id = 0; id < MCPWM_NUM_MAX; id++) {
if (mcpwm_info[id] != NULL) {
u32 ch = (u32)mcpwm_info[id]->cfg.ch;
if ((mcpwm_con_en & BIT(ch + MCPWM_CON_TMR_EN)) && (mcpwm_con_en & BIT(ch + MCPWM_CON_PWM_EN))) {
mcpwm_start(id);
}
}
}
}
DEEPSLEEP_TARGET_REGISTER(mcpwm) = {
.name = "mcpwm",
.enter = (void *)mcpwm_enter_deepsleep,
.post = (void *)mcpwm_post_deepsleep,
};
#if 0
static void usr_mcpwm_detect_test_func(u32 ch)
{
mcpwm_debug("usr ch %d\n", ch);
mcpwm_fpnd_clr(ch); //检测到故障,手动清PND恢复
}
void mcpwm_test(void)
{
#define PWM_CH0_ENABLE 1
#define PWM_CH1_ENABLE 0
struct mcpwm_config usr_mcpwm_cfg;
#if PWM_CH0_ENABLE
usr_mcpwm_cfg.ch = MCPWM_CH0; //通道号
usr_mcpwm_cfg.aligned_mode = MCPWM_EDGE_ALIGNED; //边沿对齐
usr_mcpwm_cfg.frequency = 1000; //1KHz
usr_mcpwm_cfg.duty = 0; //占空比50%
usr_mcpwm_cfg.h_pin = IO_PORTC_08; //任意引脚
usr_mcpwm_cfg.l_pin = IO_PORTC_09; //任意引脚,不需要就填-1
usr_mcpwm_cfg.complementary_en = 0; //两个引脚的波形, 0: 同步, 1: 互补,互补波形的占空比体现在H引脚上
usr_mcpwm_cfg.detect_port = IO_PORTC_02; //任意引脚,不需要就填-1
usr_mcpwm_cfg.edge = MCPWM_EDGE_FAILL;
usr_mcpwm_cfg.irq_cb = usr_mcpwm_detect_test_func;
usr_mcpwm_cfg.irq_priority = 1; //优先级默认为1
int ch0_id0 = mcpwm_init(&usr_mcpwm_cfg);
usr_mcpwm_cfg.ch = MCPWM_CH0; //通道号
usr_mcpwm_cfg.aligned_mode = MCPWM_EDGE_ALIGNED; //边沿对齐
usr_mcpwm_cfg.frequency = 1000; //1KHz
usr_mcpwm_cfg.duty = 5000; //占空比50%
usr_mcpwm_cfg.h_pin = IO_PORTC_00; //任意引脚
usr_mcpwm_cfg.l_pin = IO_PORTC_01; //任意引脚,不需要就填-1
usr_mcpwm_cfg.complementary_en = 1; //两个引脚的波形, 0: 同步, 1: 互补,互补波形的占空比体现在H引脚上
usr_mcpwm_cfg.detect_port = IO_PORTC_02; //任意引脚,不需要就填-1
usr_mcpwm_cfg.irq_cb = NULL;
usr_mcpwm_cfg.irq_priority = 1; //优先级默认为1
int ch0_id1 = mcpwm_init(&usr_mcpwm_cfg);
#endif
#if PWM_CH1_ENABLE
usr_mcpwm_cfg.ch = MCPWM_CH1; //通道号
usr_mcpwm_cfg.aligned_mode = MCPWM_EDGE_ALIGNED; //边沿对齐
usr_mcpwm_cfg.frequency = 2000; //1KHz
usr_mcpwm_cfg.duty = 5000; //占空比50%
usr_mcpwm_cfg.h_pin = IO_PORTC_03; //任意引脚
usr_mcpwm_cfg.l_pin = IO_PORTC_04; //任意引脚,不需要就填-1
usr_mcpwm_cfg.complementary_en = 1; //两个引脚的波形, 0: 同步, 1: 互补,互补波形的占空比体现在H引脚上
usr_mcpwm_cfg.detect_port = IO_PORTC_05; //任意引脚,不需要就填-1
usr_mcpwm_cfg.edge = MCPWM_EDGE_FAILL;
usr_mcpwm_cfg.irq_cb = usr_mcpwm_detect_test_func;
usr_mcpwm_cfg.irq_priority = 1; //优先级默认为1
int ch1_id0 = mcpwm_init(&usr_mcpwm_cfg);
#endif
mcpwm_start(ch0_id0);
mcpwm_start(ch1_id0);
/* mcpwm_start(ch1_id0); */
/* extern void wdt_clear(); */
u32 duty = 0;
JL_PORTC->DIR &= ~BIT(7);
while (1) {
mdelay(1000);
JL_PORTC->OUT ^= BIT(7);
mcpwm_set_duty(ch0_id0, duty);
if (duty == 0) {
duty = 10000;
} else {
duty = 0;
}
wdt_clear();
}
}
#endif