泰凌微芯片输出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 255
void 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 1
static 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 beginning
pwm_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 1
static 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();
#endif
if(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
}