ledc_test.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. #if 0
  2. #include "system/includes.h"
  3. #include "asm/ledc.h"
  4. #define LED_NUM_MAX (18 * 6)
  5. static u8 led_rgb_val_buf[3 * LED_NUM_MAX] __attribute__((aligned(4)));
  6. const struct ledc_platform_data my_ledc0_data = {
  7. .index = 0,
  8. .port = IO_PORTA_01,
  9. .idle_level = 0,
  10. .out_inv = 0,
  11. .bit_inv = 1,
  12. .t_unit = t_42ns,
  13. .t1h_cnt = 24,
  14. .t1l_cnt = 7,
  15. .t0h_cnt = 7,
  16. .t0l_cnt = 24,
  17. .t_rest_cnt = 20000,
  18. .cbfun = NULL,
  19. };
  20. void ledc_init(const struct ledc_platform_data *arg);
  21. void ledc_rgb_to_buf(u8 r, u8 g, u8 b, u8 *buf, int idx);
  22. void ledc_send_rgbbuf_isr(u8 index, u8 *rgbbuf, u32 led_num, u16 again_cnt);
  23. /***********************************************************************************************
  24. * 接口替换区
  25. ***********************************************************************************************/
  26. #define led_init() ledc_init(&my_ledc0_data)
  27. #define led_rgb_to_buf(r,g,b,buf,idx) ledc_rgb_to_buf(r,g,b,buf,idx)
  28. #define led_send_rgbbuf(buf,num) ledc_send_rgbbuf_isr(0,buf,num,1)
  29. /***********************************************************************************************
  30. ******** **
  31. r: * * *
  32. * * *
  33. ******* ********
  34. ** ********
  35. g: * * *
  36. * * *
  37. ******* ********
  38. ****** ********
  39. b: * * *
  40. * * *
  41. ******* ****
  42. * 流水灯控制驱动原理:
  43. *1. 每个模式都会一个周期 ***********
  44. *2. 以一个灯为例,一个模式周期内,又分三个颜色,即每个颜色各有各的周期。 * *
  45. *3. 最核心的思维是:一个灯的三个颜色的地位是相等的,灯与灯之间,每个灯的地位是相等。 * *
  46. *4. 每个颜色在一个周期里分为几个阶段:最暗到最亮,最亮维持,最亮到最暗,最暗维持 ******** *******
  47. *5. 颜色之间可以存在相位差,
  48. *6. 灯与灯之间的计数值可以存在相位差
  49. ***********************************************************************************************/
  50. struct led_rgb_t {
  51. u8 mode_idx; //灯亮的模式号
  52. u8 div_sec_num; //一条灯带分几段
  53. u8 sec_led_num; //每段灯带几个灯
  54. u8 cnt_freq; //CNT多久加一次,单位10ms,这个值越大,灯变化越慢
  55. u8 rgb_val_max[3]; //可配置某颜色值的最大值,一般是255
  56. u8 rgb_val_min[3]; //可配置某颜色值的最大值,一般是0
  57. int cnt[3]; //单个灯,颜色的变化计数值,cnt的初值,就是三个颜色的相位差。
  58. int next_cnt_dir[3]; //同个颜色灯与灯之间的传递方向和传递间隔, 下一个灯的cnt是上一个灯的cnt+next_cnt_dir
  59. int next_sec_cnt_phase[3]; //同个颜色段与段之间的相位差,即下一段灯带的颜色cnt初始值是上一段灯带的cnt+next_sec_cnt_phase
  60. int cnt_unit[3]; //CNT加一次加多少,这个值越大,灯变化越快,CNT加到最大周期值后,又从0开始加
  61. int cnt_max_prd[3]; //一个颜色的整个模式的周期, 不管CNT怎么加,都映射在这个周期里,即cnt %= cnt_max_prd
  62. int pu_cnt_start[3]; //一个周期内,颜色值上升开始的时间,即这个颜色开始亮了
  63. int pu_cnt_end[3]; //一个周期内,颜色值上升结束的时间,即颜色值达到最大值
  64. int keep_cnt_start[3]; //一个周期内,颜色值维持最大的开始时间,一般为颜色值上升结束的时间
  65. int keep_cnt_end[3]; //一个周期内,颜色值维持最大的结束时间
  66. int pd_cnt_start[3]; //一个周期内,颜色值下降开始的时间,一般为颜色值维持最大的结束时间
  67. int pd_cnt_end[3]; //一个周期内,颜色值下降结束的时间,即颜色值没有为0了
  68. };
  69. static struct led_rgb_t mode0_led_rgb = {
  70. .mode_idx = 0,
  71. .div_sec_num = 6,
  72. .sec_led_num = 18,
  73. .cnt_freq = 1,
  74. //r:
  75. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
  76. .cnt[ 0] = 0, .next_cnt_dir[ 0] = -10,
  77. .cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 90,
  78. .pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 30,
  79. .keep_cnt_start[0] = 30, .keep_cnt_end[ 0] = 30,
  80. .pd_cnt_start[ 0] = 30, .pd_cnt_end[ 0] = 60,
  81. //g:
  82. .rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
  83. .cnt[ 1] = 30, .next_cnt_dir[ 1] = -10,
  84. .cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 90,
  85. .pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 30,
  86. .keep_cnt_start[1] = 30, .keep_cnt_end[ 1] = 30,
  87. .pd_cnt_start[ 1] = 30, .pd_cnt_end[ 1] = 60,
  88. //b:
  89. .rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
  90. .cnt[ 2] = 60, .next_cnt_dir[ 2] = -10,
  91. .cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 90,
  92. .pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 30,
  93. .keep_cnt_start[2] = 30, .keep_cnt_end[ 2] = 30,
  94. .pd_cnt_start[ 2] = 30, .pd_cnt_end[ 2] = 60,
  95. };
  96. static struct led_rgb_t mode1_led_rgb = {
  97. .mode_idx = 1,
  98. .div_sec_num = 6,
  99. .sec_led_num = 18,
  100. .cnt_freq = 1,
  101. //r:
  102. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
  103. .cnt[ 0] = 0, .next_cnt_dir[ 0] = 6,
  104. .cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
  105. .pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
  106. .keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 54,
  107. .pd_cnt_start[ 0] = 54, .pd_cnt_end[ 0] = 54,
  108. //g:
  109. .rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
  110. .cnt[ 1] = 36, .next_cnt_dir[ 1] = 6,
  111. .cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
  112. .pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
  113. .keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 54,
  114. .pd_cnt_start[ 1] = 54, .pd_cnt_end[ 1] = 54,
  115. //b:
  116. .rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
  117. .cnt[ 2] = 72, .next_cnt_dir[ 2] = 6,
  118. .cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
  119. .pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
  120. .keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 54,
  121. .pd_cnt_start[ 2] = 54, .pd_cnt_end[ 2] = 54,
  122. };
  123. static struct led_rgb_t mode2_led_rgb = {
  124. .mode_idx = 2,
  125. .div_sec_num = 6,
  126. .sec_led_num = 18,
  127. .cnt_freq = 1,
  128. //r:
  129. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
  130. .cnt[ 0] = 0, .next_cnt_dir[ 0] = -5,
  131. .cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 90,
  132. .pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
  133. .keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 30,
  134. .pd_cnt_start[ 0] = 30, .pd_cnt_end[ 0] = 30,
  135. //g:
  136. .rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
  137. .cnt[ 1] = 30, .next_cnt_dir[ 1] = -5,
  138. .cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 90,
  139. .pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
  140. .keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 30,
  141. .pd_cnt_start[ 1] = 30, .pd_cnt_end[ 1] = 30,
  142. //b:
  143. .rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
  144. .cnt[ 2] = 60, .next_cnt_dir[ 2] = -5,
  145. .cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 90,
  146. .pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
  147. .keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 30,
  148. .pd_cnt_start[ 2] = 30, .pd_cnt_end[ 2] = 30,
  149. };
  150. static struct led_rgb_t mode3_led_rgb = {
  151. .mode_idx = 3,
  152. .div_sec_num = 6,
  153. .sec_led_num = 18,
  154. .cnt_freq = 1,
  155. //r:
  156. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
  157. .cnt[ 0] = 0, .next_cnt_dir[ 0] = 2,
  158. .cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
  159. .pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
  160. .keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 36,
  161. .pd_cnt_start[ 0] = 36, .pd_cnt_end[ 0] = 36,
  162. //g:
  163. .rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
  164. .cnt[ 1] = 36, .next_cnt_dir[ 1] = 2,
  165. .cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
  166. .pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
  167. .keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 36,
  168. .pd_cnt_start[ 1] = 36, .pd_cnt_end[ 1] = 36,
  169. //b:
  170. .rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
  171. .cnt[ 2] = 72, .next_cnt_dir[ 2] = 2,
  172. .cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
  173. .pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
  174. .keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 36,
  175. .pd_cnt_start[ 2] = 36, .pd_cnt_end[ 2] = 36,
  176. };
  177. static struct led_rgb_t mode4_led_rgb = {
  178. .mode_idx = 4,
  179. .div_sec_num = 6,
  180. .sec_led_num = 18,
  181. .cnt_freq = 1,
  182. //r:
  183. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
  184. .cnt[ 0] = 0, .next_cnt_dir[ 0] = -12,
  185. .cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
  186. .pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 12,
  187. .keep_cnt_start[0] = 12, .keep_cnt_end[ 0] = 24,
  188. .pd_cnt_start[ 0] = 24, .pd_cnt_end[ 0] = 36,
  189. //g:
  190. .rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
  191. .cnt[ 1] = 36, .next_cnt_dir[ 1] = -12,
  192. .cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
  193. .pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 12,
  194. .keep_cnt_start[1] = 12, .keep_cnt_end[ 1] = 24,
  195. .pd_cnt_start[ 1] = 24, .pd_cnt_end[ 1] = 36,
  196. //b:
  197. .rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
  198. .cnt[ 2] = 72, .next_cnt_dir[ 2] = -12,
  199. .cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
  200. .pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 12,
  201. .keep_cnt_start[2] = 12, .keep_cnt_end[ 2] = 24,
  202. .pd_cnt_start[ 2] = 24, .pd_cnt_end[ 2] = 36,
  203. };
  204. static struct led_rgb_t mode5_led_rgb = {
  205. .mode_idx = 5,
  206. .div_sec_num = 6,
  207. .sec_led_num = 18,
  208. .cnt_freq = 1,
  209. //r:
  210. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 0,
  211. .cnt[ 0] = 0, .next_cnt_dir[ 0] = 2,
  212. .cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 108,
  213. .pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
  214. .keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 2,
  215. .pd_cnt_start[ 0] = 2, .pd_cnt_end[ 0] = 2,
  216. //g:
  217. .rgb_val_max[ 1] = 255, .rgb_val_min[ 1] = 0,
  218. .cnt[ 1] = 36, .next_cnt_dir[ 1] = 2,
  219. .cnt_unit[ 1] = 1, .cnt_max_prd[ 1] = 108,
  220. .pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
  221. .keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 2,
  222. .pd_cnt_start[ 1] = 2, .pd_cnt_end[ 1] = 2,
  223. //b:
  224. .rgb_val_max[ 2] = 255, .rgb_val_min[ 2] = 0,
  225. .cnt[ 2] = 72, .next_cnt_dir[ 2] = 2,
  226. .cnt_unit[ 2] = 1, .cnt_max_prd[ 2] = 108,
  227. .pu_cnt_start[ 2] = 0, .pu_cnt_end[ 2] = 0,
  228. .keep_cnt_start[2] = 0, .keep_cnt_end[ 2] = 2,
  229. .pd_cnt_start[ 2] = 2, .pd_cnt_end[ 2] = 2,
  230. };
  231. static struct led_rgb_t mode6_led_rgb = {
  232. .mode_idx = 6,
  233. .div_sec_num = 4,
  234. .sec_led_num = 6,
  235. .cnt_freq = 1,
  236. //r:
  237. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 200,
  238. .cnt[ 0] = 0, .next_cnt_dir[ 0] = -18,
  239. .cnt_unit[ 0] = 1, .cnt_max_prd[ 0] = 48,
  240. .pu_cnt_start[ 0] = 0, .pu_cnt_end[ 0] = 0,
  241. .keep_cnt_start[0] = 0, .keep_cnt_end[ 0] = 24,
  242. .pd_cnt_start[ 0] = 24, .pd_cnt_end[ 0] = 24,
  243. .next_sec_cnt_phase[0] = 18,
  244. //g:
  245. .rgb_val_max[ 1] = 128, .rgb_val_min[ 1] = 32,
  246. .cnt[ 1] = 0, .next_cnt_dir[ 1] = 18,
  247. .cnt_unit[ 1] = 0, .cnt_max_prd[ 1] = 108,
  248. .pu_cnt_start[ 1] = 0, .pu_cnt_end[ 1] = 0,
  249. .keep_cnt_start[1] = 0, .keep_cnt_end[ 1] = 1,
  250. .pd_cnt_start[ 1] = 1, .pd_cnt_end[ 1] = 108,
  251. };
  252. static struct led_rgb_t mode7_led_rgb = {
  253. .mode_idx = 7,
  254. .div_sec_num = 6,
  255. .sec_led_num = 18,
  256. .cnt_freq = 1,
  257. //r:
  258. .rgb_val_max[ 0] = 255, .rgb_val_min[ 0] = 255,
  259. };
  260. struct led_rgb_t *led_rgb_table[] = {
  261. &mode0_led_rgb,//流水灯
  262. &mode1_led_rgb,//流水灯
  263. &mode2_led_rgb,//流水灯
  264. &mode3_led_rgb,//流水灯
  265. &mode4_led_rgb,//流水灯
  266. &mode5_led_rgb,//流水灯
  267. &mode6_led_rgb,//用于4X6火焰效果
  268. &mode7_led_rgb,//用于显示播歌的频点能量
  269. };
  270. #if AUDIO_SPECTRUM_CONFIG
  271. #include "audio_spectrum.h"
  272. extern spectrum_fft_hdl *spec_hdl;
  273. static short db_data_old[32];
  274. static short led_on_table[32];
  275. /*
  276. * @brief 获取频谱能量,板级头文件要定义音频的宏#define AUDIO_SPECTRUM_CONFIG 1 //频响能量值获取接口
  277. * @param p 音频接口的结构体参数
  278. */
  279. void led_get_spectrum(void *p)
  280. {
  281. spectrum_fft_hdl *hdl = p;
  282. if (hdl) {
  283. u8 db_num = audio_spectrum_fft_get_num(hdl);//获取频谱个数
  284. short *db_data = audio_spectrum_fft_get_val(hdl);//获取存储频谱值得地址
  285. if (!db_data) {
  286. return;
  287. }
  288. for (int i = 0; i < db_num; i++) {
  289. if (i < 32) {
  290. led_on_table[i] = db_data[i] - db_data_old[i];
  291. db_data_old[i] = db_data[i];
  292. }
  293. }
  294. }
  295. }
  296. #endif
  297. /*
  298. * @brief 一段灯带亮灯的数量
  299. * @param led_rgb 该模式结构体参数
  300. * @param sec_num 第几段灯带
  301. * @return 可以亮灯的数量
  302. */
  303. int get_led_sec_on_num(struct led_rgb_t *led_rgb, int sec_num)
  304. {
  305. int on_num = led_rgb->sec_led_num;
  306. switch (led_rgb->mode_idx) {
  307. case 0:
  308. break;
  309. case 1:
  310. break;
  311. case 2:
  312. break;
  313. case 3:
  314. break;
  315. case 4:
  316. break;
  317. case 5:
  318. break;
  319. case 6:
  320. break;
  321. case 7:
  322. #if AUDIO_SPECTRUM_CONFIG
  323. if (spec_hdl) {
  324. short sum0 = 0;
  325. short sum1 = 0;
  326. int tmp = 32 / led_rgb->div_sec_num;
  327. for (short i = 0; i < tmp; i ++) {
  328. sum0 += led_on_table[i + sec_num * tmp];
  329. sum1 += db_data_old[i + sec_num * tmp];
  330. }
  331. sum0 /= 5;
  332. sum1 /= 5;
  333. short num = ((sum1 * led_rgb->sec_led_num / 90) + sum0);
  334. if (num < 0) {
  335. num = 0;
  336. }
  337. on_num = num % led_rgb->sec_led_num;
  338. }
  339. #endif
  340. break;
  341. }
  342. return on_num;
  343. }
  344. /*
  345. * @brief 约束CNT值在周期值内
  346. * @param led_rgb 该模式结构体参数
  347. * @param colour 颜色号:0,红色 1,绿色 2,蓝色
  348. * @param cnt 颜色对应的计数值
  349. * @return 映射后的值
  350. */
  351. int get_map_cnt(struct led_rgb_t *led_rgb, int colour, int cnt)
  352. {
  353. if (led_rgb->cnt_max_prd[colour] == 0) {
  354. return 0;
  355. }
  356. while (cnt < 0) {
  357. cnt += led_rgb->cnt_max_prd[colour];
  358. }
  359. cnt %= led_rgb->cnt_max_prd[colour];
  360. return cnt;
  361. }
  362. /*
  363. * @brief 将CNT值转换为RGB值
  364. * @param led_rgb 该模式结构体参数
  365. * @param colour 颜色号:0,红色 1,绿色 2,蓝色
  366. * @param cnt 颜色对应的计数值
  367. * @return 对应的颜色亮度值
  368. */
  369. u8 led_cnt_to_rgb_val(struct led_rgb_t *led_rgb, int colour, int cnt)
  370. {
  371. u8 rgb_val = led_rgb->rgb_val_min[colour];
  372. int tmp_cnt = 0;
  373. int i = colour;
  374. int rgb_val_delta = led_rgb->rgb_val_max[i] - led_rgb->rgb_val_min[i];
  375. if ((led_rgb->pu_cnt_start[i] <= cnt) && (cnt < led_rgb->pu_cnt_end[i])) { //递增区间
  376. tmp_cnt = cnt - led_rgb->pu_cnt_start[i] + 1;
  377. 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]));
  378. } else if ((led_rgb->keep_cnt_start[i] <= cnt) && (cnt < led_rgb->keep_cnt_end[i])) { //高维持区间
  379. rgb_val = led_rgb->rgb_val_max[i];
  380. } else if ((led_rgb->pd_cnt_start[i] <= cnt) && (cnt < led_rgb->pd_cnt_end[i])) { //递减区间
  381. tmp_cnt = led_rgb->pd_cnt_end[i] - cnt - 1;
  382. 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]));
  383. }
  384. return rgb_val;
  385. }
  386. /*
  387. * @brief 更新RGB的DMA buf数据,并发送出去,更新灯带
  388. * @param led_rgb 该模式结构体参数
  389. * @param cnt 基础节拍计数值
  390. */
  391. void led_rgb_upgrade(struct led_rgb_t *led_rgb, int cnt)
  392. {
  393. u8 r_val = 0;
  394. u8 g_val = 0;
  395. u8 b_val = 0;
  396. if ((cnt % led_rgb->cnt_freq) == 0) {
  397. led_rgb->cnt[0] = get_map_cnt(led_rgb, 0, led_rgb->cnt[0] + led_rgb->cnt_unit[0]);
  398. led_rgb->cnt[1] = get_map_cnt(led_rgb, 1, led_rgb->cnt[1] + led_rgb->cnt_unit[1]);
  399. led_rgb->cnt[2] = get_map_cnt(led_rgb, 2, led_rgb->cnt[2] + led_rgb->cnt_unit[2]);
  400. for (int i = 0; i < led_rgb->div_sec_num; i ++) {
  401. int led_on_num = get_led_sec_on_num(led_rgb, i);
  402. for (int j = 0; j < led_rgb->sec_led_num; j ++) {
  403. 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]));
  404. 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]));
  405. 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]));
  406. if (j >= led_on_num) {
  407. r_val = 0;
  408. g_val = 0;
  409. b_val = 0;
  410. }
  411. led_rgb_to_buf(r_val, g_val, b_val, led_rgb_val_buf, i * led_rgb->sec_led_num + j);
  412. }
  413. }
  414. led_send_rgbbuf(led_rgb_val_buf, led_rgb->div_sec_num * led_rgb->sec_led_num);
  415. }
  416. }
  417. /*
  418. * @brief 定时轮询各模式
  419. */
  420. void led_rgb_scan(void *priv)
  421. {
  422. static u32 step_cnt = 0;
  423. static u32 mode_idx = 0;
  424. static struct led_rgb_t *led_rgb = NULL;
  425. if ((step_cnt % 800) == 0) { //8s
  426. step_cnt = 0;
  427. led_rgb = led_rgb_table[mode_idx];
  428. mode_idx ++;
  429. if (mode_idx >= (sizeof(led_rgb_table) / 4)) {
  430. mode_idx = 0;
  431. }
  432. }
  433. led_rgb_upgrade(led_rgb, step_cnt);
  434. step_cnt ++;
  435. }
  436. void my_led_test(void)
  437. {
  438. printf("****************** led test *******************\n");
  439. led_init();
  440. sys_timer_add(NULL, led_rgb_scan, 10);
  441. #if AUDIO_SPECTRUM_CONFIG
  442. sys_timer_add(spec_hdl, led_get_spectrum, 100);//定期获取能量值
  443. #endif
  444. }
  445. #endif