Files
kunlun/dtest/dtest3/unit_test_pwm/unit_test_pwm.c
2024-09-28 14:24:04 +08:00

1400 lines
36 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* os shim includes */
#include "os_types.h"
#include "dbg_io.h"
#include "iot_io.h"
#include "gpio_mtx.h"
#include "pwm.h"
#include "cpu.h"
#include "watchdog.h"
#include "ahb.h"
#include "gp_timer.h"
#include "iot_clock.h"
#include "dtest_printf.h"
#include "iot_gpio_api.h"
void delay_sometime(uint32_t times)
{
uint32_t loop = 0;
while (loop++ < times) {
__asm volatile ("nop\n");
}
}
#include <stdlib.h>
#include <string.h>
char g_str_buf[64];
char * binary_format(char *str, char *dest, int destlen)
{
int srclen = strlen(str);
int d = destlen - 1;
int f = 0;
// printf("strlen=%d, d = %d\r\n", srclen, d);
dest[d--] = 0;
for(int i = srclen - 1; i >= 0; i--)
{
dest[d--] = str[i];
f ++;
if (f % 4 == 0) {
dest[d--] = '-';
}
}
d ++;
if('-' == dest[d]) {
d ++;
}
// printf("len=%d\r\n", (int)strlen(dest + d));
return dest + d;
}
void print_pos(int offset, int len)
{
int pos = 0;
if (len <= 5) {
pos = 0;
} else if(len <= 10) {
pos = 4;
} else if(len <= 15) {
pos = 8;
} else if(len <= 20) {
pos = 12;
} else if(len <= 25) {
pos = 16;
} else if(len <= 30) {
pos = 20;
} else if(len <= 35) {
pos = 24;
} else if(len <= 40) {
pos = 28;
}
for (int i = 0; i < offset; i++) {
iot_printf(" ");
}
for(int j = 0; j < len; j += 5)
{
iot_printf("% 5d", pos);
pos -= 4;
}
iot_printf("\r\n");
}
void register_print_by_addr(uint32_t addr, int num)
{
volatile uint32_t *p_addr = (volatile uint32_t *)addr;
int i;
char s[32];
char *p;
for (i = 0; i < num; i++) {
itoa(*p_addr, s, 2);
p = binary_format(s, g_str_buf, 64);
iot_printf("[%08p]=0x%08x,%s\r\n", p_addr, *p_addr, p);
print_pos(1, strlen(p));
p_addr ++;
}
iot_printf("\r\n");
}
void AQ_set(int ch, uint8_t mode)
{
if (TB_COUNT_UP == mode) {
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
} else if(TB_COUNT_DOWN == mode) {
pwm_aqctla_set(ch, AQ_CLEAR, AQ_NOTHING,
AQ_NOTHING, AQ_SET, AQ_NOTHING, AQ_NOTHING);
pwm_aqctlb_set(ch, AQ_CLEAR, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_NOTHING, AQ_SET);
} else if(TB_COUNT_UP_DOWN == mode) {
pwm_aqctla_set(ch, AQ_NOTHING, AQ_NOTHING,
AQ_SET, AQ_CLEAR, AQ_NOTHING, AQ_NOTHING);
pwm_aqctlb_set(ch, AQ_CLEAR, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_SET, AQ_CLEAR);
}
}
#include "gpio_hw.h"
extern iot_gpio_op_t hw_gpio_api_table;
#if 0
#define pwm_inter_cb_def(ch) \
uint32_t pwm_ch##ch##_intr_cb(void) \
{ \
static int times##ch = -1; \
times##ch ++; \
if (times##ch % 1000 == 0) { \
iot_printf("times%d=%d\r\n", ch, times##ch); \
} \
return 0; \
}
pwm_inter_cb_def(0)
#else
#define pwm_inter_cb_def(ch) \
uint32_t pwm_ch##ch##_intr_cb(void) \
{ \
return 0; \
}
uint32_t pwm_ch0_intr_cb(void)
{
static int v = 0;
hw_gpio_api_table.set_value(8, v);
v ^= 0x01;
return 0;
}
#endif
pwm_inter_cb_def(1)
pwm_inter_cb_def(2)
pwm_inter_cb_def(3)
pwm_inter_cb_def(4)
pwm_inter_cb_def(5)
uint32_t (*cb_table[4])(void) ={
pwm_ch0_intr_cb,
pwm_ch1_intr_cb,
pwm_ch2_intr_cb,
pwm_ch3_intr_cb,
};
extern void pwm_set_etps(uint8_t ch, uint8_t int_prd, uint8_t soca_prd, uint8_t socb_prd);
//该case测试多通道周期占空比同步加载中断及中断分频死区
void all_pwm_module_sync_test_with_intc(void)
{
uint8_t ch = PWM_CHANNEL_0;
uint32_t pwm_phase[4] = {1000, 2000, 3000, 4000};
uint32_t pwm_duty[4][2]={{5000,10000},
{5000,10000},
{5000,10000},
{5000,10000},
};
uint8_t pwm_gpio[4][2] = {
{58, 59},
{60, 61},
{62, 63},
{26, 36},//8},
};
bool_t test_inter = true; //是否测试中断
uint8_t counter_modes[4]={TB_COUNT_UP, TB_COUNT_UP, TB_COUNT_UP, TB_COUNT_UP};
//uint8_t counter_modes[4]={TB_COUNT_DOWN, TB_COUNT_DOWN, TB_COUNT_DOWN, TB_COUNT_DOWN};
//uint8_t counter_modes[4]={TB_COUNT_UP_DOWN, TB_COUNT_UP_DOWN, TB_COUNT_UP_DOWN, TB_COUNT_UP_DOWN};
uint32_t cpu_id = cpu_get_mhartid();
iot_interrupt_init(cpu_id);
//
int pin = 8;
hw_gpio_api_table.gpio_init();
gpio_pin_select(pin, 0);
hw_gpio_api_table.set_gpio_mode(pin, GPIO_OUTPUT);
//
pwm_tbclk_sync(ch, false);
for(ch = PWM_CHANNEL_0; ch <= PWM_CHANNEL_3; ch ++) {
pwm_synci_in_config(7);
if (test_inter) {
pwm_gpio_config_with_isr(ch, pwm_gpio[ch][0], pwm_gpio[ch][1], cb_table[ch]);
pwm_set_etps(ch, 50, 0, 0); //设置中断得分频
} else {
pwm_gpio_config(ch, pwm_gpio[ch][0], pwm_gpio[ch][1]);
}
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, pwm_phase[ch]);
pwm_tbctl_set(ch, TB_ENABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 99999);
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_SHADOW, CC_SHADOW);
AQ_set(ch, counter_modes[ch]);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, counter_modes[ch]);
pwm_db_inmode_set(ch, DB_INMODE_PWMA_RAW, DB_INMODE_PWMB_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL); //A不反相B不反相
pwm_db_outmode_set(ch, DB_OUTMODE_DELAYED, DB_OUTMODE_DELAYED ); //都产生死区
pwm_db_rising_delay_set(ch, 10);
pwm_db_falling_delay_set(ch, 20);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_SOC_SYNC);
}
pwm_cnt_soc_sync_load();
pwm_tbclk_sync(ch, true);
int prd = 9999;
int v = 0;
int v2 = 0;
while (1) {
//频率=10k
v2 = ~v2;
if (v2) { //改变周期
prd = 9999;
} else {
prd = 999;
}
memset(pwm_duty, 0, sizeof(pwm_duty));
for(int j = 0; j < 10; j++) { // //以prd为周期分10次改变占空比
for (ch = PWM_CHANNEL_0; ch <= PWM_CHANNEL_3; ch++) {
pwm_duty[ch][0] += prd / 10 + 1;
pwm_duty[ch][1] += prd / 10 + 1;
if (pwm_duty[ch][0] >= prd) {
pwm_duty[ch][0] = prd / 10;
}
if (pwm_duty[ch][1] >= prd) {
pwm_duty[ch][1] = prd / 10;
}
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
delay_sometime(100);
pwm_tb_period_set(ch, prd);
}
delay_sometime(100);
pwm_cnt_soc_sync_load();
//hw_gpio_api_table.set_value(pin, v);
v ^= 0x01;
delay_sometime(100000);
}
}
}
void counter_modes_test(void)
{
uint8_t ch = PWM_CHANNEL_0;
uint32_t pwm_phase[4] = {1000, 2000, 3000, 4000};
uint32_t pwm_duty[4][2]={{500,1000},
{1500,2000},
{2500,3000},
{3500,4000},
};
uint8_t counter_modes[4]={TB_COUNT_UP, TB_COUNT_DOWN, TB_COUNT_STOP_FREEZE, TB_COUNT_UP_DOWN};
pwm_tbclk_sync(ch, false);
// UART R1
pwm_synci_in_config(7);
// t1 t2
pwm_gpio_config(ch, 8, 36);
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, pwm_phase[0]);
pwm_tbctl_set(ch, TB_ENABLE, TB_SHADOW, TB_SYNC_DISABLE,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_NO_SHADOW, CC_NO_SHADOW);
//action when counter equals zero or CMPA register
AQ_set(ch, counter_modes[ch]);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, counter_modes[ch]);
pwm_db_inmode_set(ch, DB_INMODE_PWMA_RAW, DB_INMODE_PWMB_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL); //A不反相B反相
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS ); //都不产生死区
pwm_db_rising_delay_set(ch, 1000);
pwm_db_falling_delay_set(ch, 1000);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_SOC_SYNC);
//-----------------------------------------------------------------------------
ch = PWM_CHANNEL_1;
// j204 23 24
pwm_gpio_config(ch, 58, 59);
pwm_tbclk_ctrl(ch, true); // 使能PWM1 的时钟
pwm_tb_phase_set(ch, pwm_phase[1]);
pwm_tbctl_set(ch, TB_ENABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_NO_SHADOW, CC_NO_SHADOW);
//action when counter equals zero or CMPA register
AQ_set(ch, counter_modes[ch]);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, counter_modes[ch]);
pwm_db_inmode_set(ch, DB_INMODE_PWMA_RAW, DB_INMODE_PWMB_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL);
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS );
pwm_db_rising_delay_set(ch, 1000);
pwm_db_falling_delay_set(ch, 1000);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_SOC_SYNC);
//-------------------------------------------------------------------------
ch = PWM_CHANNEL_2;
// j204 25 26
pwm_gpio_config(ch, 60, 61);
pwm_tbclk_ctrl(ch, true); // 使能PWM2 的时钟
pwm_tb_phase_set(ch, pwm_phase[2]);
pwm_tbctl_set(ch, TB_ENABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_NO_SHADOW, CC_NO_SHADOW);
//action when counter equals zero or CMPA register
AQ_set(ch, counter_modes[ch]);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, counter_modes[ch]);
//选择延迟输入信号
pwm_db_inmode_set(ch, DB_INMODE_PWMB_RAW, DB_INMODE_PWMB_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL);
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS );
pwm_db_rising_delay_set(ch, 100);
pwm_db_falling_delay_set(ch, 200);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_SOC_SYNC);
//-------------------------------------------------------------------------
ch = PWM_CHANNEL_3;
// j207 8 7
pwm_gpio_config(ch, 62, 63);
pwm_tbclk_ctrl(ch, true); // 使能PWM3 的时钟
pwm_tb_phase_set(ch, pwm_phase[3]);
pwm_tbctl_set(ch, TB_ENABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_NO_SHADOW, CC_NO_SHADOW);
//action when counter equals zero or CMPA register
AQ_set(ch, counter_modes[ch]);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, counter_modes[ch]);
//选择延迟输入信号
pwm_db_inmode_set(ch, DB_INMODE_PWMB_RAW, DB_INMODE_PWMB_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL);
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS );
pwm_db_rising_delay_set(ch, 100);
pwm_db_falling_delay_set(ch, 200);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_SOC_SYNC);
//-------------------------------------------------------------------------
pwm_cnt_soc_sync_load();
pwm_tbclk_sync(ch, true);
while (0) {
delay_sometime(1000000);
delay_sometime(1000000);
delay_sometime(1000000);
delay_sometime(1000000);
delay_sometime(1000000);
}
}
extern void iot_delay_us(uint32_t us);
#define DELAY_mS 1000
#define DELAY_S 1000* DELAY_mS
void delay_us(uint32_t us)
{
gp_timer_set(0, 0xffffffff, 0);
gp_timer_start(0);
while (gp_timer_get_current_val(0) < us);
gp_timer_stop(0);
}
//单个通道同步加载
void pwm_prd_duty_inner_sync_load(void)
{
uint8_t ch = PWM_CHANNEL_0;
uint32_t pwm_phase[4] = {1000, 2000, 3000, 4000};
uint32_t pwm_duty[4][2]={{500,1000},
{500,1000},
{500,1000},
{500,1000},
};
pwm_tbclk_sync(ch, false);
// UART R1
// pwm_synci_in_config(7);
// j204 23 24
pwm_gpio_config(ch, 58, 59);
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, pwm_phase[0]);
pwm_tbctl_set(ch, TB_DISABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
pwm_db_inmode_set(ch, DB_INMODE_PWMA_RAW, DB_INMODE_PWMA_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL); //A不反相B反相
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS ); //都不产生死区
pwm_db_rising_delay_set(ch, 100);
pwm_db_falling_delay_set(ch, 100);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_INNER_SYNC);
pwm_tbclk_sync(ch, true);
int pin = 8;
hw_gpio_api_table.gpio_init();
gpio_pin_select(pin, 0);
hw_gpio_api_table.set_gpio_mode(pin, GPIO_OUTPUT);
while (1) {
pwm_tb_period_set(ch, 99); // 1M
delay_sometime(80000000);
pwm_cmpa_cmpb_set(ch, 50, 25);
delay_sometime(80000000);
pwm_cnt_inner_sync(ch);
hw_gpio_api_table.set_value(pin, 0);
delay_sometime(300000);
pwm_tb_period_set(ch, 999); // 100k
delay_sometime(30000000);
pwm_cmpa_cmpb_set(ch, 500, 250);
delay_sometime(30000000);
pwm_cnt_inner_sync(ch);
hw_gpio_api_table.set_value(pin, 1);
delay_sometime(400000);
pwm_tb_period_set(ch, 9999); // 10k
delay_sometime(40000000);
pwm_cmpa_cmpb_set(ch, 5000, 2500);
delay_sometime(40000000);
pwm_cnt_inner_sync(ch);
hw_gpio_api_table.set_value(pin, 0);
delay_sometime(500000);
pwm_tb_period_set(ch, 99999); // 1k
delay_sometime(50000000);
pwm_cmpa_cmpb_set(ch, 50000, 25000);
delay_sometime(50000000);
pwm_cnt_inner_sync(ch);
hw_gpio_api_table.set_value(pin, 1);
delay_sometime(600000);
pwm_tb_period_set(ch, 999999); // 100
delay_sometime(60000000);
pwm_cmpa_cmpb_set(ch, 500000, 250000);
delay_sometime(60000000);
pwm_cnt_inner_sync(ch);
hw_gpio_api_table.set_value(pin, 0);
delay_sometime(700000);
pwm_tb_period_set(ch, 9999999); // 10
delay_sometime(70000000);
pwm_cmpa_cmpb_set(ch, 5000000, 2500000);
delay_sometime(70000000);
pwm_cnt_inner_sync(ch);
hw_gpio_api_table.set_value(pin, 1);
delay_sometime(800000);
}
}
uint32_t tz_cb(uint32_t mask)
{
iot_printf("mask=%02x\r\n", mask);
if (mask & PWM_OSHT_INT) {
iot_printf("one shot\r\n");
}
return 0;
}
//单个通道同步加载
void pwm_chopping_test(void)
{
uint8_t ch = PWM_CHANNEL_0;
pwm_tbclk_sync(ch, false);
// UART R1
// pwm_synci_in_config(7);
// j208 8 7
pwm_gpio_config(PWM_CHANNEL_0, 58, 59);
pwm_gpio_config(PWM_CHANNEL_1, 60, 61);
for(ch = PWM_CHANNEL_0; ch <= PWM_CHANNEL_1; ch++) {
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, 0);
pwm_tbctl_set(ch, TB_DISABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_cmpa_cmpb_set(ch, 5000, 2500);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
pwm_db_inmode_set(ch, DB_INMODE_PWMA_RAW, DB_INMODE_PWMA_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL); //A不反相B反相
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS ); //都不产生死区
pwm_db_rising_delay_set(ch, 100);
pwm_db_falling_delay_set(ch, 100);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_INNER_SYNC);
pwm_cnt_inner_sync(ch);
}
pwm_tbclk_sync(ch, true);
uint8_t all_chopp_duty_percent[]= {
CHOPP_DUTY_PERCENT_12_5 ,
CHOPP_DUTY_PERCENT_25_0 ,
CHOPP_DUTY_PERCENT_37_0 ,
CHOPP_DUTY_PERCENT_50_0 ,
CHOPP_DUTY_PERCENT_62_5 ,
CHOPP_DUTY_PERCENT_75_0 ,
CHOPP_DUTY_PERCENT_87_5 };
uint8_t all_chopp_freq_div[]={
CHOPP_FREQ_DIV_1,
CHOPP_FREQ_DIV_2,
CHOPP_FREQ_DIV_3,
CHOPP_FREQ_DIV_4,
CHOPP_FREQ_DIV_5,
CHOPP_FREQ_DIV_6,
CHOPP_FREQ_DIV_7,
CHOPP_FREQ_DIV_8
};
uint8_t all_chopp_one_shot_width[]={
CHOPP_ONE_SHOT_WIDTH_0, // 1个分频后的周期
CHOPP_ONE_SHOT_WIDTH_1, // 2个分频后的周期
CHOPP_ONE_SHOT_WIDTH_2,
CHOPP_ONE_SHOT_WIDTH_3,
CHOPP_ONE_SHOT_WIDTH_4,
CHOPP_ONE_SHOT_WIDTH_5,
CHOPP_ONE_SHOT_WIDTH_6,
CHOPP_ONE_SHOT_WIDTH_7,
CHOPP_ONE_SHOT_WIDTH_8,
CHOPP_ONE_SHOT_WIDTH_9,
CHOPP_ONE_SHOT_WIDTH_10,
CHOPP_ONE_SHOT_WIDTH_11,
CHOPP_ONE_SHOT_WIDTH_12,
CHOPP_ONE_SHOT_WIDTH_13,
CHOPP_ONE_SHOT_WIDTH_14,
CHOPP_ONE_SHOT_WIDTH_15
};
#define TABLE_NUM(table) (sizeof(table)/sizeof(table[0]))
int pin = 8;
uint8_t v = 0;
hw_gpio_api_table.gpio_init();
gpio_pin_select(pin, 0);
hw_gpio_api_table.set_gpio_mode(pin, GPIO_OUTPUT);
for(int i = 0; i < TABLE_NUM(all_chopp_duty_percent); i++) {
for(int j = 0; j < TABLE_NUM(all_chopp_freq_div); j++) {
for(int k = 0; k < TABLE_NUM(all_chopp_one_shot_width); k++) {
//chopp
// 仅pwm0使用chopping以作对比
pwm_chopping_duty_sel(PWM_CHANNEL_0, all_chopp_duty_percent[i]);
pwm_chopping_div_sel(PWM_CHANNEL_0, all_chopp_freq_div[j]);
pwm_chopping_one_shot_width_sel(PWM_CHANNEL_0, all_chopp_one_shot_width[k]);
pwm_chopping_en(PWM_CHANNEL_0, true);
delay_sometime(80000);
hw_gpio_api_table.set_value(pin, v);
v ^= 0x01;
}
}
}
while(1) {
}
}
//
void pwm_tz_with_intr_test(void)
{
uint8_t ch = PWM_CHANNEL_0;
uint32_t pwm_phase[4] = {1000, 2000, 3000, 4000};
uint32_t pwm_duty[4][2]={{500,1000},
{500,1000},
{500,1000},
{500,1000},
};
pwm_tbclk_sync(ch, false);
// UART R1
// pwm_synci_in_config(7);
pwm_tz_pin_set(ch, 7);
pwm_tz_sel(ch, TZ_SEL_TZ1_CBC);
pwm_tz_acta_set(ch, TZ_ACTION_FORCE_HIGHT);
pwm_tz_actb_set(ch, TZ_ACTION_FORCE_LOW);
//
pwm_gpio_config(ch, 58, 59);
//pwm_interrupt_init(ch, PWM_OSHT_INT, tz_cb);
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, pwm_phase[0]);
pwm_tbctl_set(ch, TB_DISABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_ZERO, CC_CTR_ZERO, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
pwm_db_inmode_set(ch, DB_INMODE_PWMA_RAW, DB_INMODE_PWMA_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL); //A不反相B反相
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS ); //都不产生死区
pwm_db_rising_delay_set(ch, 100);
pwm_db_falling_delay_set(ch, 100);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_INNER_SYNC);
pwm_cnt_inner_sync(ch);// pwm_cnt_soc_sync_load();
pwm_tbclk_sync(ch, true);
//int duty_a = 250;
//int duty_b = 500;
//int prd = 5000;
int pin = 8;
hw_gpio_api_table.gpio_init();
gpio_pin_select(pin, 0);
hw_gpio_api_table.set_gpio_mode(pin, GPIO_OUTPUT);
while (1) {
}
}
//
void pwm_auto_modify_duty(void)
{
uint8_t ch = PWM_CHANNEL_0;
uint32_t pwm_phase[4] = {1000, 2000, 3000, 4000};
uint32_t pwm_duty[4][2]={{0,0},
{500,1000},
{500,1000},
{500,1000},
};
pwm_tbclk_sync(ch, false);
// UART R1
// pwm_synci_in_config(7);
//
pwm_gpio_config(ch, 58, 59);
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, pwm_phase[0]);
pwm_tbctl_set(ch, TB_DISABLE, TB_SHADOW, TB_SYNC_PWM,99);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
pwm_cmpctl_set(ch, CC_CTR_PRD, CC_CTR_PRD, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_cmpa_cmpb_set(ch, pwm_duty[ch][0], pwm_duty[ch][1]);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
pwm_db_inmode_set(ch, DB_INMODE_PWMA_RAW, DB_INMODE_PWMA_RAW);
pwm_db_polsel_set(ch, DB_POLSE_NORMAL, DB_POLSE_NORMAL); //A不反相B反相
pwm_db_outmode_set(ch, DB_OUTMODE_BYPASS, DB_OUTMODE_BYPASS ); //都不产生死区
pwm_db_rising_delay_set(ch, 100);
pwm_db_falling_delay_set(ch, 100);
pwm_tb_cnt_set(ch, 0);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_INNER_SYNC);
pwm_cmpctl_cmpa_end(ch, 10000);
pwm_cmpctl_cmpa_step( ch, 200);
pwm_cmpctl_cmpb_end( ch, 10000);
pwm_cmpctl_cmpb_step( ch, 100);
pwm_cmpctl_auto_duty( ch, true, true);
pwm_cnt_inner_sync(ch);// pwm_cnt_soc_sync_load();
pwm_cnt_start(ch, true);
pwm_tbclk_sync(ch, true);
}
extern void _start(void);
extern struct uart_ctrl uart_e_ctrl;
#define my_g_uart_ctrl uart_e_ctrl
#include "uart_e.h"
#include "uart.h"
#include "apb.h"
//#define __noinit__ __attribute__ ((section (".noinit"))) //变量不初始化
//__noinit__ unsigned int SystemRamTest;//RAM不初始化
uint32_t *p_data = (uint32_t *)0x10038004;
void wdt_cpu_reset_pwm_test(void)
{
uint32_t cur_cpu = cpu_get_mhartid();
ahb_core0_set_start((uint32_t) _start);
wdg_deinit(cur_cpu);
wdg_init(cur_cpu);
wdg_set_cmp(cur_cpu, 999);//SET_WDG_INTC_CMP);
wdg_set_timeout_cmp(cur_cpu, 50);//SET_WDG_TIMEOUT_CMP);
wdg_set_cpurst_cmp(cur_cpu, 31);//SET_WDG_CPURST_CMP );
wdg_set_fullrst_cmp(cur_cpu, 60);//SET_WDG_FULLRST_CMP);
#if 1
if (0xabcdaabb == (*p_data)) {
iot_printf("wdg cpu rst\r\n");
} else {
iot_printf("pow on rst\r\n");
(*p_data) = 0xabcdaabb;
pwm_auto_modify_duty();
}
#else
uint32_t flag = 0;
flag = ahb_scratch_reg_get(1);
if (0xabcdaabb == flag) {
iot_printf("wdg rst flag=0x%08x\r\n", flag);
} else {
iot_printf("pow on rst flag=0x%08x\r\n", flag);
counter_modes_test();
ahb_scratch_reg_set(1, 0xabcdaabb);
}
#endif
while(1){
//my_g_uart_ctrl.puts(port, (uint8_t*)"***\r\n", 5);
//iot_printf("^v^");
}
}
void wdt_full_reset_pwm_test(void)
{
uint32_t cur_cpu = cpu_get_mhartid();
ahb_core0_set_start((uint32_t) _start);
wdg_deinit(cur_cpu);
wdg_init(cur_cpu);
wdg_set_cmp(cur_cpu, 999);//SET_WDG_INTC_CMP);
wdg_set_timeout_cmp(cur_cpu, 50);//SET_WDG_TIMEOUT_CMP);
wdg_set_cpurst_cmp(cur_cpu, 60);//SET_WDG_CPURST_CMP );
wdg_set_fullrst_cmp(cur_cpu, 31);//SET_WDG_FULLRST_CMP);
if (0xabcdaabb == (*p_data)) {
iot_printf("wdg full rst\r\n");
} else {
iot_printf("pow on rst\r\n");
(*p_data) = 0xabcdaabb;
pwm_auto_modify_duty();
}
while(1){
//my_g_uart_ctrl.puts(port, (uint8_t*)"***\r\n", 5);
//iot_printf("^v^");
}
}
void soft_reset_pwm_test(void)
{
ahb_core0_set_start((uint32_t) _start);
gp_timer_init();
gp_timer_set(0, 0xffffffff, 0);
gp_timer_start(0);
pwm_auto_modify_duty();
iot_delay_us(500000);
iot_printf("soft_rst\r\n");
iot_delay_us(500000);
//sec_glb_chip_rst();
while(1){
//my_g_uart_ctrl.puts(port, (uint8_t*)"***\r\n", 5);
//iot_printf("^v^");
}
}
int g_duty_a = 100;
int g_duty_b = 200;
uint8_t g_ch = PWM_CHANNEL_3;
//每个周期都改变占空比
uint32_t interrupt_cb(void)
{
g_duty_a += 100;
if (g_duty_a > 10000) {
g_duty_a = 100;
}
g_duty_b += 100;
if (g_duty_b > 10000) {
g_duty_b = 200;
}
pwm_cmpa_cmpb_set(g_ch, g_duty_a, g_duty_b);
return 0;
}
// 中断测试
void pwm_main4(void)
{
uint32_t cpu_id = cpu_get_mhartid();
iot_interrupt_init(cpu_id);
pwm_tbclk_sync(g_ch, false);
// 8 7
pwm_gpio_config_with_isr(g_ch, 26, 27, interrupt_cb);
pwm_tbclk_ctrl(g_ch, true); // 使能PWM 的时钟
pwm_tb_phase_set(g_ch, 0);
pwm_tbctl_set(g_ch, TB_DISABLE, TB_SHADOW, TB_SYNC_CNT_ZERO,99);
//pwm waveform period
pwm_tb_period_set(g_ch, 9999);
//load from shadow select mode
//注意若A或B 的ld mode被配置为 CC_CTR_FREEZE 则B的占空比保持着不再变化,
//却决于原来的状态,若是上电第一次运行,则B保持全低或者全高
pwm_cmpctl_set(g_ch, CC_CTR_PRD, CC_CTR_PRD, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctlb_set(g_ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_aqctla_set(g_ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_cnt_mode_set(g_ch, TB_COUNT_UP);
pwm_interrupt_init(g_ch);
pwm_cmpa_cmpb_set(g_ch, g_duty_a, g_duty_b);
pwm_tbclk_sync(g_ch, true);
while (1);
}
extern void pwm_fault_config(uint8_t ch, uint8_t gpio, uint8_t h_state,
uint8_t l_state,pwm_isr cb);
int v = 0;
int pin = 8; //t1
uint32_t pwm_falut_cb(void)
{
hw_gpio_api_table.set_value(pin, v);
v ^= 0x01;
return 0;
}
//输出 h 和 l输出互补的pwm 波形
void pwm_main5(void)
{
uint8_t ch = PWM_CHANNEL_0;
uint32_t pwm_clk;
iot_printf("%s\r\n", __func__);
iot_pwm_gpio_config(ch, 58, 59);
iot_pwm_hw_init(ch);
iot_pwm_start(ch);
hw_gpio_api_table.gpio_init();
gpio_pin_select(pin, 0);
hw_gpio_api_table.set_gpio_mode(pin, GPIO_OUTPUT);
pwm_clk = pwm_get_ch_clk(ch);
iot_printf("clk_freq=%d\r\n", pwm_clk);
iot_pwm_set_period(ch, 1000000); // 10k
iot_pwm_set_duty(ch, 50000);
pwm_fault_config(ch, 60, 0, 0, pwm_falut_cb);
int duty = 0;
while (1) {
//hw_gpio_api_table.set_value(pin, v);
//v ^= 0x01;
delay_sometime(500000);
//iot_pwm_set_duty(ch, duty);
duty += 100;
if (duty > 10000) duty = 0;
}
}
//------------------------------------------------------------------------------
void pwm_src_clk_freq_test(void)
{
uint8_t ch = PWM_CHANNEL_0;
dcase_start("src_clk_freq_test\n");
pwm_tbclk_sync(ch, false);
// t1 t2
pwm_gpio_config(ch, 8, 36);
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, 0);
pwm_tbctl_set(ch, TB_DISABLE, TB_SHADOW, TB_SYNC_CNT_ZERO, 49);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
//注意这里必须都设为CC_CTR_PRD,如果为CC_CTR_ZERO 输出的波形不对,
//在B的占空比为0时,A会少一个脉冲
pwm_cmpctl_set(ch, CC_CTR_PRD, CC_CTR_PRD, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
// 独立输出PWM 0-100都可以给duty_a和duty_b初值分别赋
// 0 0 A B输出相同占空比的PWM波形
// 0 100 A 为0时B不为0
// 100 0 B 为0时A不为0
//
int duty_a = 5000;
int duty_b = 2500;
pwm_cmpa_cmpb_set(ch, duty_a, duty_b);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
//
pwm_cnt_start(ch, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_SOC_SYNC);
//pwm_cnt_soc_sync_load();
pwm_cnt_soc_sync_load();//pwm_cnt_inner_sync( ch);
//
pwm_tbclk_sync(ch, true);
delay_sometime(10000);
delay_sometime(10000);
delay_sometime(10000);
dcase_success();
}
void pwm_max_freq_test(void)
{
uint8_t ch = PWM_CHANNEL_0;
dcase_start("pwm_max_freq_test\n");
pwm_tbclk_sync(ch, false);
// 8 7
pwm_gpio_config(ch, 26, 27);
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, 0);
pwm_tbctl_set(ch, TB_DISABLE, TB_SHADOW, TB_SYNC_CNT_ZERO, 0);
//pwm waveform period
pwm_tb_period_set(ch, 1);
//load from shadow select mode
//注意这里必须都设为CC_CTR_PRD,如果为CC_CTR_ZERO 输出的波形不对,
//在B的占空比为0时,A会少一个脉冲
pwm_cmpctl_set(ch, CC_CTR_PRD, CC_CTR_PRD, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
// 独立输出PWM 0-100都可以给duty_a和duty_b初值分别赋
// 0 0 A B输出相同占空比的PWM波形
// 0 100 A 为0时B不为0
// 100 0 B 为0时A不为0
//
int duty_a = 0;
int duty_b = 0;
pwm_cmpa_cmpb_set(ch, duty_a, duty_b);
pwm_aqctlb_set(ch, AQ_NOTHING, AQ_TOGGLE,
AQ_NOTHING, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_aqctla_set(ch, AQ_NOTHING, AQ_TOGGLE,
AQ_NOTHING, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_tbclk_sync(ch, true);
delay_sometime(10000);
delay_sometime(10000);
delay_sometime(10000);
dcase_success();
}
//-------------------------
void pwm_sync_in_test(void)
{
uint8_t ch = PWM_CHANNEL_0;
dcase_start("pwm_sync_in_test\n");
pwm_tbclk_sync(ch, false);
// 8 7
pwm_gpio_config(ch, 26, 27);
// 10
pwm_synci_in_config(28);
pwm_tbclk_ctrl(ch, true); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, 0);
pwm_tbctl_set(ch, TB_ENABLE, TB_SHADOW, TB_SYNC_PWM, 0);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
//注意这里必须都设为CC_CTR_PRD,如果为CC_CTR_ZERO 输出的波形不对,
//在B的占空比为0时,A会少一个脉冲
pwm_cmpctl_set(ch, CC_CTR_PRD, CC_CTR_PRD, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
// 独立输出PWM 0-100都可以给duty_a和duty_b初值分别赋
// 0 0 A B输出相同占空比的PWM波形
// 0 100 A 为0时B不为0
// 100 0 B 为0时A不为0
//
int duty_a = 5000;
int duty_b = 2500;
pwm_cmpa_cmpb_set(ch, duty_a, duty_b);
//下面是PWM1的配置
ch = PWM_CHANNEL_1;
// j204 19 38
pwm_gpio_config(ch, 9, 12);
pwm_tbclk_ctrl(ch, false); // 使能PWM0 的时钟
pwm_tb_phase_set(ch, 0);
pwm_tbctl_set(ch, TB_ENABLE, TB_SHADOW, TB_SYNC_CNT_ZERO, 0);
//pwm waveform period
pwm_tb_period_set(ch, 9999);
//load from shadow select mode
//注意这里必须都设为CC_CTR_PRD,如果为CC_CTR_ZERO 输出的波形不对,
//在B的占空比为0时,A会少一个脉冲
pwm_cmpctl_set(ch, CC_CTR_PRD, CC_CTR_PRD, CC_SHADOW, CC_SHADOW);
//action when counter equals zero or CMPA register
pwm_aqctlb_set(ch, AQ_SET, AQ_NOTHING,
AQ_NOTHING, AQ_NOTHING, AQ_CLEAR, AQ_NOTHING);
pwm_aqctla_set(ch, AQ_SET, AQ_NOTHING,
AQ_CLEAR, AQ_NOTHING, AQ_NOTHING, AQ_NOTHING);
pwm_cnt_mode_set(ch, TB_COUNT_UP);
// 独立输出PWM 0-100都可以给duty_a和duty_b初值分别赋
// 0 0 A B输出相同占空比的PWM波形
// 0 100 A 为0时B不为0
// 100 0 B 为0时A不为0
//
pwm_cmpa_cmpb_set(ch, duty_a, duty_b);
pwm_cnt_start(0, true);
pwm_cnt_start(1, true);
pwm_cnt_load_mode(ch, TB_LOAD_MODE_SOC_SYNC);
//pwm_cnt_soc_sync_load();
pwm_tbclk_sync(ch, true);
delay_sometime(10000);
delay_sometime(10000);
delay_sometime(10000);
dcase_success();
}
#ifdef __GNUC__
int main(void)
{
dbg_uart_init();
pwm_main5();
void (*test_case_table[])(void) = {
all_pwm_module_sync_test_with_intc, // 0
counter_modes_test, // 1
pwm_prd_duty_inner_sync_load, // 2
pwm_chopping_test, // 3
pwm_auto_modify_duty, // 4
pwm_tz_with_intr_test, // 5
wdt_full_reset_pwm_test, // 6 注意测试678时需要屏蔽startup_init.c void pre_init()函数中的 wdg_deinit(cpu);
wdt_cpu_reset_pwm_test, // 7
soft_reset_pwm_test, // 8
pwm_main5 // 9
};
//dversion();
dstart();
//dend();
while(1) {
if (uart_e_ctrl.rx_fifo_cnt(UART_PT0) > 0) {
int c = uart_e_ctrl.getc(UART_PT0);
if ( (c >= 0) && (c < sizeof(test_case_table)/sizeof(test_case_table[0]))) {
iot_printf("test case %d\r\n", c);
test_case_table[c]();
} else {
iot_printf("test case invalid\r\n", c);
}
}
}
return 0;
}
#endif // __GCC__