KT24-1110_65E-HA-651B/cpu/br25/ledc_test.c

444 lines
19 KiB
C
Raw Permalink Normal View History

2024-11-10 10:44:17 +00:00
#if 0
#include "system/includes.h"
#include "audio_spectrum.h"
#define LED_NUM_MAX (18 * 6)
static u8 led_rgb_val_buf[24 * LED_NUM_MAX] __attribute__((aligned(4)));
void led_spi_init(void);
void led_spi_send_rgbbuf_isr(u8 *rgb_buf, u16 led_num);
void led_spi_rgb_to_24byte(u8 r, u8 g, u8 b, u8 *buf, int idx);
/***********************************************************************************************
*
***********************************************************************************************/
#define led_init() led_spi_init()
#define led_rgb_to_buf(r,g,b,buf,idx) led_spi_rgb_to_24byte(r,g,b,buf,idx)
#define led_send_rgbbuf(buf,num) led_spi_send_rgbbuf_isr(buf,num)
/***********************************************************************************************
******** **
r: * * *
* * *
******* ********
** ********
g: * * *
* * *
******* ********
****** ********
b: * * *
* * *
******* ****
*
*1. ***********
*2. * *
*3. * *
*4. ******** *******
*5.
*6.
***********************************************************************************************/
struct led_rgb_t {
u8 mode_idx; //灯亮的模式号
u8 div_sec_num; //一条灯带分几段
u8 sec_led_num; //每段灯带几个灯
u8 cnt_freq; //CNT多久加一次单位10ms这个值越大灯变化越慢
u8 rgb_val_max[3]; //可配置某颜色值的最大值一般是255
u8 rgb_val_min[3]; //可配置某颜色值的最大值一般是0
int cnt[3]; //单个灯颜色的变化计数值cnt的初值就是三个颜色的相位差。
int next_cnt_dir[3]; //同个颜色灯与灯之间的传递方向和传递间隔, 下一个灯的cnt是上一个灯的cnt+next_cnt_dir
int next_sec_cnt_phase[3]; //同个颜色段与段之间的相位差,即下一段灯带的颜色cnt初始值是上一段灯带的cnt+next_sec_cnt_phase
int cnt_unit[3]; //CNT加一次加多少这个值越大灯变化越快CNT加到最大周期值后又从0开始加
int cnt_max_prd[3]; //一个颜色的整个模式的周期, 不管CNT怎么加都映射在这个周期里即cnt %= cnt_max_prd
int pu_cnt_start[3]; //一个周期内,颜色值上升开始的时间,即这个颜色开始亮了
int pu_cnt_end[3]; //一个周期内,颜色值上升结束的时间,即颜色值达到最大值
int keep_cnt_start[3]; //一个周期内,颜色值维持最大的开始时间,一般为颜色值上升结束的时间
int keep_cnt_end[3]; //一个周期内,颜色值维持最大的结束时间
int pd_cnt_start[3]; //一个周期内,颜色值下降开始的时间,一般为颜色值维持最大的结束时间
int pd_cnt_end[3]; //一个周期内颜色值下降结束的时间即颜色值没有为0了
};
static struct led_rgb_t mode0_led_rgb = {
.mode_idx = 0,
.div_sec_num = 6,
.sec_led_num = 18,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
.cnt[ 0] = 0, .next_cnt_dir[ 0] = -10,
.cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 90,
.pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 30,
.keep_cnt_start[0] = 30, .keep_cnt_end[ 0] = 30,
.pd_cnt_start[ 0] = 30, .pd_cnt_end[ 0] = 60,
//g:
.rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
.cnt[ 1] = 30, .next_cnt_dir[ 1] = -10,
.cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 90,
.pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 30,
.keep_cnt_start[1] = 30, .keep_cnt_end[ 1] = 30,
.pd_cnt_start[ 1] = 30, .pd_cnt_end[ 1] = 60,
//b:
.rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
.cnt[ 2] = 60, .next_cnt_dir[ 2] = -10,
.cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 90,
.pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 30,
.keep_cnt_start[2] = 30, .keep_cnt_end[ 2] = 30,
.pd_cnt_start[ 2] = 30, .pd_cnt_end[ 2] = 60,
};
static struct led_rgb_t mode1_led_rgb = {
.mode_idx = 1,
.div_sec_num = 6,
.sec_led_num = 18,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
.cnt[ 0] = 0, .next_cnt_dir[ 0] = 6,
.cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
.pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
.keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 54,
.pd_cnt_start[ 0] = 54, .pd_cnt_end[ 0] = 54,
//g:
.rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
.cnt[ 1] = 36, .next_cnt_dir[ 1] = 6,
.cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
.pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
.keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 54,
.pd_cnt_start[ 1] = 54, .pd_cnt_end[ 1] = 54,
//b:
.rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
.cnt[ 2] = 72, .next_cnt_dir[ 2] = 6,
.cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
.pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
.keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 54,
.pd_cnt_start[ 2] = 54, .pd_cnt_end[ 2] = 54,
};
static struct led_rgb_t mode2_led_rgb = {
.mode_idx = 2,
.div_sec_num = 6,
.sec_led_num = 18,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
.cnt[ 0] = 0, .next_cnt_dir[ 0] = -5,
.cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 90,
.pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
.keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 30,
.pd_cnt_start[ 0] = 30, .pd_cnt_end[ 0] = 30,
//g:
.rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
.cnt[ 1] = 30, .next_cnt_dir[ 1] = -5,
.cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 90,
.pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
.keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 30,
.pd_cnt_start[ 1] = 30, .pd_cnt_end[ 1] = 30,
//b:
.rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
.cnt[ 2] = 60, .next_cnt_dir[ 2] = -5,
.cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 90,
.pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
.keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 30,
.pd_cnt_start[ 2] = 30, .pd_cnt_end[ 2] = 30,
};
static struct led_rgb_t mode3_led_rgb = {
.mode_idx = 3,
.div_sec_num = 6,
.sec_led_num = 18,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
.cnt[ 0] = 0, .next_cnt_dir[ 0] = 2,
.cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
.pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
.keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 36,
.pd_cnt_start[ 0] = 36, .pd_cnt_end[ 0] = 36,
//g:
.rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
.cnt[ 1] = 36, .next_cnt_dir[ 1] = 2,
.cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
.pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
.keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 36,
.pd_cnt_start[ 1] = 36, .pd_cnt_end[ 1] = 36,
//b:
.rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
.cnt[ 2] = 72, .next_cnt_dir[ 2] = 2,
.cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
.pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
.keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 36,
.pd_cnt_start[ 2] = 36, .pd_cnt_end[ 2] = 36,
};
static struct led_rgb_t mode4_led_rgb = {
.mode_idx = 4,
.div_sec_num = 6,
.sec_led_num = 18,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
.cnt[ 0] = 0, .next_cnt_dir[ 0] = -12,
.cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
.pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 12,
.keep_cnt_start[0] = 12, .keep_cnt_end[ 0] = 24,
.pd_cnt_start[ 0] = 24, .pd_cnt_end[ 0] = 36,
//g:
.rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
.cnt[ 1] = 36, .next_cnt_dir[ 1] = -12,
.cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
.pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 12,
.keep_cnt_start[1] = 12, .keep_cnt_end[ 1] = 24,
.pd_cnt_start[ 1] = 24, .pd_cnt_end[ 1] = 36,
//b:
.rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
.cnt[ 2] = 72, .next_cnt_dir[ 2] = -12,
.cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
.pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 12,
.keep_cnt_start[2] = 12, .keep_cnt_end[ 2] = 24,
.pd_cnt_start[ 2] = 24, .pd_cnt_end[ 2] = 36,
};
static struct led_rgb_t mode5_led_rgb = {
.mode_idx = 5,
.div_sec_num = 6,
.sec_led_num = 18,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
.cnt[ 0] = 0, .next_cnt_dir[ 0] = 2,
.cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
.pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
.keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 2,
.pd_cnt_start[ 0] = 2, .pd_cnt_end[ 0] = 2,
//g:
.rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
.cnt[ 1] = 36, .next_cnt_dir[ 1] = 2,
.cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
.pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
.keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 2,
.pd_cnt_start[ 1] = 2, .pd_cnt_end[ 1] = 2,
//b:
.rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
.cnt[ 2] = 72, .next_cnt_dir[ 2] = 2,
.cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
.pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
.keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 2,
.pd_cnt_start[ 2] = 2, .pd_cnt_end[ 2] = 2,
};
static struct led_rgb_t mode6_led_rgb = {
.mode_idx = 6,
.div_sec_num = 4,
.sec_led_num = 6,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 200,
.cnt[ 0] = 0, .next_cnt_dir[ 0] = -18,
.cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 48,
.pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
.keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 24,
.pd_cnt_start[ 0] = 24, .pd_cnt_end[ 0] = 24,
.next_sec_cnt_phase[0] = 18,
//g:
.rgb_val_max[ 1] = 128, .rgb_val_min[ 1] = 32,
.cnt[ 1] = 0, .next_cnt_dir[ 1] = 18,
.cnt_unit[ 1] = 0, .cnt_max_prd[ 1] = 108,
.pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
.keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 1,
.pd_cnt_start[ 1] = 1, .pd_cnt_end[ 1] = 108,
};
static struct led_rgb_t mode7_led_rgb = {
.mode_idx = 7,
.div_sec_num = 6,
.sec_led_num = 18,
.cnt_freq = 1,
//r:
.rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 255,
};
struct led_rgb_t *led_rgb_table[] = {
&mode0_led_rgb,//流水灯
&mode1_led_rgb,//流水灯
&mode2_led_rgb,//流水灯
&mode3_led_rgb,//流水灯
&mode4_led_rgb,//流水灯
&mode5_led_rgb,//流水灯
&mode6_led_rgb,//用于4X6火焰效果
&mode7_led_rgb,//用于显示播歌的频点能量
};
extern spectrum_fft_hdl *spec_hdl;
static short db_data_old[32];
static short led_on_table[32];
/*
* @brief ,#define AUDIO_SPECTRUM_CONFIG 1 //频响能量值获取接口
* @param p
*/
void led_get_spectrum(void *p)
{
spectrum_fft_hdl *hdl = p;
if (hdl) {
u8 db_num = audio_spectrum_fft_get_num(hdl);//获取频谱个数
short *db_data = audio_spectrum_fft_get_val(hdl);//获取存储频谱值得地址
if (!db_data) {
return;
}
for (int i = 0; i < db_num; i++) {
if (i < 32) {
led_on_table[i] = db_data[i] - db_data_old[i];
db_data_old[i] = db_data[i];
}
}
}
}
/*
* @brief
* @param led_rgb
* @param sec_num
* @return
*/
int get_led_sec_on_num(struct led_rgb_t *led_rgb, int sec_num)
{
int on_num = led_rgb->sec_led_num;
switch (led_rgb->mode_idx) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
if (spec_hdl) {
short sum0 = 0;
short sum1 = 0;
int tmp = 32 / led_rgb->div_sec_num;
for (short i = 0; i < tmp; i ++) {
sum0 += led_on_table[i + sec_num * tmp];
sum1 += db_data_old[i + sec_num * tmp];
}
sum0 /= 5;
sum1 /= 5;
short num = ((sum1 * led_rgb->sec_led_num / 90) + sum0);
if (num < 0) {
num = 0;
}
on_num = num % led_rgb->sec_led_num;
}
break;
}
return on_num;
}
/*
* @brief CNT值在周期值内
* @param led_rgb
* @param colour 0, 1,绿 2,
* @param cnt
* @return
*/
int get_map_cnt(struct led_rgb_t *led_rgb, int colour, int cnt)
{
if (led_rgb->cnt_max_prd[colour] == 0) {
return 0;
}
while (cnt < 0) {
cnt += led_rgb->cnt_max_prd[colour];
}
cnt %= led_rgb->cnt_max_prd[colour];
return cnt;
}
/*
* @brief CNT值转换为RGB值
* @param led_rgb
* @param colour 0, 1,绿 2,
* @param cnt
* @return
*/
u8 led_cnt_to_rgb_val(struct led_rgb_t *led_rgb, int colour, int cnt)
{
u8 rgb_val = led_rgb->rgb_val_min[colour];
int tmp_cnt = 0;
int i = colour;
int rgb_val_delta = led_rgb->rgb_val_max[i] - led_rgb->rgb_val_min[i];
if ((led_rgb->pu_cnt_start[i] <= cnt) && (cnt < led_rgb->pu_cnt_end[i])) { //递增区间
tmp_cnt = cnt - led_rgb->pu_cnt_start[i] + 1;
rgb_val = led_rgb->rgb_val_min[i] + (tmp_cnt * rgb_val_delta / (led_rgb->pu_cnt_end[i] - led_rgb->pu_cnt_start[i]));
} else if ((led_rgb->keep_cnt_start[i] <= cnt) && (cnt < led_rgb->keep_cnt_end[i])) { //高维持区间
rgb_val = led_rgb->rgb_val_max[i];
} else if ((led_rgb->pd_cnt_start[i] <= cnt) && (cnt < led_rgb->pd_cnt_end[i])) { //递减区间
tmp_cnt = led_rgb->pd_cnt_end[i] - cnt - 1;
rgb_val = led_rgb->rgb_val_min[i] + (tmp_cnt * rgb_val_delta / (led_rgb->pd_cnt_end[i] - led_rgb->pd_cnt_start[i]));
}
return rgb_val;
}
/*
* @brief RGB的DMA buf数据
* @param led_rgb
* @param cnt
*/
void led_rgb_upgrade(struct led_rgb_t *led_rgb, int cnt)
{
u8 r_val = 0;
u8 g_val = 0;
u8 b_val = 0;
if ((cnt % led_rgb->cnt_freq) == 0) {
led_rgb->cnt[0] = get_map_cnt(led_rgb, 0, led_rgb->cnt[0] + led_rgb->cnt_unit[0]);
led_rgb->cnt[1] = get_map_cnt(led_rgb, 1, led_rgb->cnt[1] + led_rgb->cnt_unit[1]);
led_rgb->cnt[2] = get_map_cnt(led_rgb, 2, led_rgb->cnt[2] + led_rgb->cnt_unit[2]);
for (int i = 0; i < led_rgb->div_sec_num; i ++) {
int led_on_num = get_led_sec_on_num(led_rgb, i);
for (int j = 0; j < led_rgb->sec_led_num; j ++) {
r_val = led_cnt_to_rgb_val(led_rgb, 0, get_map_cnt(led_rgb, 0, led_rgb->cnt[0] + (i * led_rgb->next_sec_cnt_phase[0] + j) * led_rgb->next_cnt_dir[0]));
g_val = led_cnt_to_rgb_val(led_rgb, 1, get_map_cnt(led_rgb, 1, led_rgb->cnt[1] + (i * led_rgb->next_sec_cnt_phase[1] + j) * led_rgb->next_cnt_dir[1]));
b_val = led_cnt_to_rgb_val(led_rgb, 2, get_map_cnt(led_rgb, 2, led_rgb->cnt[2] + (i * led_rgb->next_sec_cnt_phase[2] + j) * led_rgb->next_cnt_dir[2]));
if (j >= led_on_num) {
r_val = 0;
g_val = 0;
b_val = 0;
}
led_rgb_to_buf(r_val, g_val, b_val, led_rgb_val_buf, i * led_rgb->sec_led_num + j);
}
}
led_send_rgbbuf(led_rgb_val_buf, led_rgb->div_sec_num * led_rgb->sec_led_num);
}
}
/*
* @brief
*/
void led_rgb_scan(void *priv)
{
static u32 step_cnt = 0;
static u32 mode_idx = 0;
static struct led_rgb_t *led_rgb = NULL;
if ((step_cnt % 800) == 0) { //8s
step_cnt = 0;
led_rgb = led_rgb_table[mode_idx];
mode_idx ++;
if (mode_idx >= (sizeof(led_rgb_table) / 4)) {
mode_idx = 0;
}
}
led_rgb_upgrade(led_rgb, step_cnt);
step_cnt ++;
}
void my_led_test(void)
{
printf("****************** led test *******************\n");
led_init();
sys_timer_add(NULL, led_rgb_scan, 10);
sys_timer_add(spec_hdl, led_get_spectrum, 100);//定期获取能量值
}
#endif