/* 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 #include 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 注意测试6,7,8时需要屏蔽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__