泰凌微芯片输出PWM期间不能进入suspend
我的灯是低亮 所以代码中是 rgb_pwm_io_t[index].duty = APP_PWM_MAX_VALUE - duty;
头文件
#ifndef APP_RGB_PWM_H_
#define APP_RGB_PWM_H_#define PWM_ID_R PWM3_ID // zxk 20230426
#define PWM_ID_G PWM2_ID
#define PWM_ID_B PWM1_ID//PWW口定义
#define IO_LED_PWM_R GPIO_PB7
#define IO_LED_PWM_G GPIO_PB6
#define IO_LED_PWM_B GPIO_PB5#define PWM_CLOCK_HZ (CLOCK_SYS_CLOCK_HZ/4)
//定义PWM的最大值
#define APP_PWM_MAX_VALUE 255void app_pwm_init(void);u8 is_rgb_led_busy(void);
void rgb_flash_led_task(void);void set_dpi_rgb_led_evt(u8 dpi);
void set_low_bat_led_evt(void);void test_app_pwm(void);
#endif
c文件
#include "AAA_public_config.h"#define RED_LED_INDEX 0
#define GREEN_LED_INDEX 1
#define BLUE_LED_INDEX 2
#define MAX_RGB_LED_IND 2#define RGB_PWM_LED_OFF 0
#define RGB_PWM_LED_ON 1static void red_pwm_ctrl(u8 on_off);
static void green_pwm_ctrl(u8 on_off);
static void blue_pwm_ctrl(u8 on_off);enum rgb_io_mode{rgb_pwm_mode,rgb_gpio_mode = AS_GPIO,
};struct rgb_io_pwm_map_t {const char ind;enum rgb_io_mode mode;unsigned char duty;const pwm_id pwm_ind;const GPIO_PinTypeDef pin;const gpio_func_e fun;
};static struct rgb_io_pwm_map_t rgb_pwm_io_t[3] = {{.ind = RED_LED_INDEX,.mode = rgb_gpio_mode,.duty = APP_PWM_MAX_VALUE,.pwm_ind = PWM_ID_R,.pin = IO_LED_PWM_R,.fun = PIN_PWM_R_FUNC,},{.ind = GREEN_LED_INDEX,.mode = rgb_gpio_mode,.duty = APP_PWM_MAX_VALUE,.pwm_ind = PWM_ID_G,.pin = IO_LED_PWM_G,.fun = PIN_PWM_G_FUNC,},{.ind = BLUE_LED_INDEX,.mode = rgb_gpio_mode,.duty = APP_PWM_MAX_VALUE,.pwm_ind = PWM_ID_B,.pin = IO_LED_PWM_B,.fun = PIN_PWM_B_FUNC,}
};
static MY_FLASH_LED_T s_rgbLed[3] = {{ .ctrl_led = red_pwm_ctrl, .duty = APP_PWM_MAX_VALUE,},{ .ctrl_led = green_pwm_ctrl, .duty = APP_PWM_MAX_VALUE,},{ .ctrl_led = blue_pwm_ctrl, .duty = APP_PWM_MAX_VALUE,},
};
// ==========================================================================================
static void set_rgb_io_mode(unsigned char ind, unsigned char io_mode)
{pwm_id pwm_ind = rgb_pwm_io_t[ind].pwm_ind;GPIO_PinTypeDef pin = rgb_pwm_io_t[ind].pin;gpio_func_e func = rgb_pwm_io_t[ind].fun;if(ind > BLUE_LED_INDEX){return;}switch(io_mode){case rgb_gpio_mode:pwm_set_cmp(pwm_ind,APP_PWM_MAX_VALUE);pwm_stop(pwm_ind);gpio_set_func(pin,AS_GPIO);gpio_set_input_en(pin,0);gpio_set_output_en(pin,1);gpio_setup_up_down_resistor(pin,PM_PIN_UP_DOWN_FLOAT);rgb_pwm_io_t[ind].mode = rgb_gpio_mode;gpio_write(pin, RGB_LED_OFF_LEVEL);printf("set gpio [%d] pin:0x%02x, pwm_ind:%d.\n",ind,pin,pwm_ind);break;default:gpio_write(pin, RGB_LED_ON_LEVEL);gpio_set_func(pin, func);pwm_set_mode(pwm_ind, PWM_NORMAL_MODE);pwm_set_phase(pwm_ind, 0); //no phase at pwm beginningpwm_set_cycle_and_duty(pwm_ind, (u16)APP_PWM_MAX_VALUE,(u16)rgb_pwm_io_t[ind].duty);rgb_pwm_io_t[ind].mode = rgb_pwm_mode;pwm_start(pwm_ind);pwm_set_cmp(PWM_ID_G,rgb_pwm_io_t[ind].duty);printf("set pwm [%d] pin:0x%02x, duty:%d, pwm_ind:%d, fun:%d.\n",ind,pin,rgb_pwm_io_t[ind].duty,pwm_ind,func);break;}
}
static void red_pwm_ctrl(u8 on_off)
{if((RGB_PWM_LED_ON == on_off) && rgb_pwm_io_t[RED_LED_INDEX].mode == rgb_pwm_mode){pwm_set_cmp(PWM_ID_R,rgb_pwm_io_t[RED_LED_INDEX].duty);return;}if((RGB_PWM_LED_OFF == on_off) && (rgb_pwm_io_t[RED_LED_INDEX].mode == rgb_gpio_mode)){gpio_write(rgb_pwm_io_t[RED_LED_INDEX].pin, RGB_LED_OFF_LEVEL);return;}rgb_pwm_io_t[RED_LED_INDEX].duty = s_rgbLed[RED_LED_INDEX].duty;set_rgb_io_mode(RED_LED_INDEX, (on_off==RGB_PWM_LED_ON)?rgb_pwm_mode:rgb_gpio_mode);
}static void green_pwm_ctrl(u8 on_off)
{if((RGB_PWM_LED_ON == on_off) && rgb_pwm_io_t[GREEN_LED_INDEX].mode == rgb_pwm_mode){pwm_set_cmp(PWM_ID_G,rgb_pwm_io_t[GREEN_LED_INDEX].duty);return;}if((RGB_PWM_LED_OFF == on_off) && (rgb_pwm_io_t[GREEN_LED_INDEX].mode == rgb_gpio_mode)){gpio_write(rgb_pwm_io_t[GREEN_LED_INDEX].pin, RGB_LED_OFF_LEVEL);return;}rgb_pwm_io_t[GREEN_LED_INDEX].duty = s_rgbLed[GREEN_LED_INDEX].duty;set_rgb_io_mode(GREEN_LED_INDEX, (on_off==RGB_PWM_LED_ON)?rgb_pwm_mode:rgb_gpio_mode);
}static void blue_pwm_ctrl(u8 on_off)
{if((RGB_PWM_LED_ON == on_off) && rgb_pwm_io_t[BLUE_LED_INDEX].mode == rgb_pwm_mode){pwm_set_cmp(PWM_ID_B,rgb_pwm_io_t[BLUE_LED_INDEX].duty);return;}if((RGB_PWM_LED_OFF == on_off) && (rgb_pwm_io_t[BLUE_LED_INDEX].mode == rgb_gpio_mode)){gpio_write(rgb_pwm_io_t[BLUE_LED_INDEX].pin, RGB_LED_OFF_LEVEL);return;}rgb_pwm_io_t[BLUE_LED_INDEX].duty = s_rgbLed[BLUE_LED_INDEX].duty;set_rgb_io_mode(BLUE_LED_INDEX, (on_off==RGB_PWM_LED_ON)?rgb_pwm_mode:rgb_gpio_mode);
}//初始化PWM用于LED的RGB驱动
void app_pwm_init(void)
{//设置PWM的时钟源pwm_set_clk(CLOCK_SYS_CLOCK_HZ,PWM_CLOCK_HZ);set_rgb_io_mode(RED_LED_INDEX, rgb_gpio_mode);set_rgb_io_mode(GREEN_LED_INDEX, rgb_gpio_mode);set_rgb_io_mode(BLUE_LED_INDEX, rgb_gpio_mode);
}
// ==========================================================================================// 设置指定颜色灯用pwm模式闪灯
static void set_rgb_pwm_flash(u8 index, u16 cnt, u16 on_time, u16 off_time, u8 duty)
{if((s_rgbLed[index].ctrl_led == NULL) || (index > MAX_RGB_LED_IND))return;if((!on_time) || (!cnt) || (!duty)){cnt = 0;duty = 0;on_time = 0;printf("Close ind: ...... %d.\n",index);}rgb_pwm_io_t[index].duty = APP_PWM_MAX_VALUE - duty;s_rgbLed[index].duty = APP_PWM_MAX_VALUE - duty;s_rgbLed[index].cycle = cnt;s_rgbLed[index].on_time = on_time;s_rgbLed[index].off_time = off_time;s_rgbLed[index].start_tick = clock_time();s_rgbLed[index].ctrl_led(cnt?RGB_PWM_LED_ON:RGB_PWM_LED_OFF);printf("--> Set rgb_%d cnt:%d, on:%d, off:%d.\n",index,s_rgbLed[index].cycle,s_rgbLed[index].on_time,s_rgbLed[index].off_time);
}
// RGB灯的闪灯任务
void rgb_flash_led_task(void)
{u8 index = 0;do{if(s_rgbLed[index].ctrl_led == NULL)continue;if(s_rgbLed[index].cycle){ // 先亮后灭if(clock_time_exceed(s_rgbLed[index].start_tick, (s_rgbLed[index].on_time + s_rgbLed[index].off_time)*1000)){//s_rgbLed[index].ctrl_led(RGB_LED_OFF_LEVEL); // 一个周期结束s_rgbLed[index].start_tick = clock_time();s_rgbLed[index].cycle--;}else if(clock_time_exceed(s_rgbLed[index].start_tick, s_rgbLed[index].on_time*1000)){s_rgbLed[index].ctrl_led(RGB_PWM_LED_OFF); // 在一个周期中灭的时间内}else{s_rgbLed[index].ctrl_led(RGB_PWM_LED_ON); // 在一个周期中亮的时间内}}else{s_rgbLed[index].ctrl_led(RGB_PWM_LED_OFF);}}while(++index < 3);if(is_rgb_led_busy()){reset_idle_status();}
}
// 判断现在是否有RGB灯任务在忙碌
u8 is_rgb_led_busy(void)
{return (s_rgbLed[RED_LED_INDEX].cycle||s_rgbLed[GREEN_LED_INDEX].cycle||s_rgbLed[BLUE_LED_INDEX].cycle)?1:0;
}
void set_dpi_rgb_led_evt(u8 dpi)
{const u8 dpi_rgb_duty[7][3] = {// reg green blue{ APP_PWM_MAX_VALUE, 0, 0}, /* 0 */{ APP_PWM_MAX_VALUE, APP_PWM_MAX_VALUE/8, 0}, /* 1 */{ APP_PWM_MAX_VALUE/2,APP_PWM_MAX_VALUE/2, 0}, /* 2 */{ 0, APP_PWM_MAX_VALUE, 0}, /* 3 */{ 0, APP_PWM_MAX_VALUE/2, APP_PWM_MAX_VALUE/2}, /* 4 */{ 0, 0, APP_PWM_MAX_VALUE}, /* 5 */{ APP_PWM_MAX_VALUE/2,0, APP_PWM_MAX_VALUE/2}, /* 6 */};if(dpi >= 7){return;}printf("\nset dpi:......%d.\n");set_rgb_pwm_flash(RED_LED_INDEX, dpi_rgb_duty[dpi][RED_LED_INDEX]?5:0, 200, 300,dpi_rgb_duty[dpi][RED_LED_INDEX]);set_rgb_pwm_flash(GREEN_LED_INDEX, dpi_rgb_duty[dpi][GREEN_LED_INDEX]?5:0, 200, 300,dpi_rgb_duty[dpi][GREEN_LED_INDEX]);set_rgb_pwm_flash(BLUE_LED_INDEX, dpi_rgb_duty[dpi][BLUE_LED_INDEX]?5:0, 200, 300,dpi_rgb_duty[dpi][BLUE_LED_INDEX]);
}
/*** Data 23/12/28* Brief test rgb pwm ok.*/
void test_app_pwm(void)
{
#if 1static u32 tick_loop = 0;static u8 select = 0;//while(1){#if (MODULE_32K_WATCHDOG_ENABLE)wd_32k_clear();#endif#if (MODULE_32K_WATCHDOG_ENABLE)wd_32k_clear();#endifif(clock_time_exceed(tick_loop,500*1000)){tick_loop = clock_time();set_dpi_rgb_led_evt(select);select = (select+1)%7;}rgb_flash_led_task();}
#endif
}