ledc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "system/includes.h"
  2. #include "system/debug.h"
  3. #include "generic/gpio.h"
  4. #include "asm/clock.h"
  5. #include "asm/ledc.h"
  6. static JL_LEDC_TypeDef *JL_LEDCx[2] = {
  7. JL_LEDC0,
  8. JL_LEDC1
  9. };
  10. static void (*ledc0_isr_cbfun)(void) = NULL;
  11. static void (*ledc1_isr_cbfun)(void) = NULL;
  12. static OS_SEM ledc0_sem;
  13. static OS_SEM ledc1_sem;
  14. ___interrupt
  15. void ledc_isr(void)
  16. {
  17. if (JL_LEDC0->CON & BIT(7)) {
  18. JL_LEDC0->CON |= BIT(6);
  19. os_sem_post(&ledc0_sem);
  20. if (ledc0_isr_cbfun) {
  21. ledc0_isr_cbfun();
  22. }
  23. }
  24. if (JL_LEDC1->CON & BIT(7)) {
  25. JL_LEDC1->CON |= BIT(6);
  26. os_sem_post(&ledc1_sem);
  27. if (ledc1_isr_cbfun) {
  28. ledc1_isr_cbfun();
  29. }
  30. }
  31. }
  32. static u8 t_div[9] = {1, 2, 3, 6, 12, 24, 48, 96, 192};
  33. void ledc_init(const struct ledc_platform_data *arg)
  34. {
  35. gpio_set_die(arg->port, 1);
  36. gpio_set_direction(arg->port, 0);
  37. gpio_set_pull_up(arg->port, 0);
  38. gpio_set_pull_down(arg->port, 0);
  39. gpio_set_fun_output_port(arg->port, FO_LEDC0_DO + arg->index, 0, 1);
  40. //std_48M
  41. JL_LEDCK->CLK &= ~(0b11 << 0);
  42. JL_LEDCK->CLK |= (0b11 << 0);
  43. //set div
  44. JL_LEDCK->CLK &= ~(0xff << 8);
  45. JL_LEDCK->CLK |= ((t_div[arg->t_unit] - 1) << 8);
  46. JL_LEDCx[arg->index]->CON = BIT(6);
  47. os_sem_create(&ledc0_sem, 1);
  48. os_sem_create(&ledc1_sem, 1);
  49. request_irq(16, 1, ledc_isr, 0);
  50. if (arg->cbfun) {
  51. if (arg->index == 0) {
  52. ledc0_isr_cbfun = arg->cbfun;
  53. } else {
  54. ledc1_isr_cbfun = arg->cbfun;
  55. }
  56. }
  57. if (arg->idle_level) {
  58. JL_LEDCx[arg->index]->CON |= BIT(4);
  59. }
  60. if (arg->out_inv) {
  61. JL_LEDCx[arg->index]->CON |= BIT(3);
  62. }
  63. JL_LEDCx[arg->index]->CON |= (arg->bit_inv << 1);
  64. JL_LEDCx[arg->index]->TIX = 0;
  65. JL_LEDCx[arg->index]->TIX |= ((arg->t1h_cnt - 1) << 24);
  66. JL_LEDCx[arg->index]->TIX |= ((arg->t1l_cnt - 1) << 16);
  67. JL_LEDCx[arg->index]->TIX |= ((arg->t0h_cnt - 1) << 8);
  68. JL_LEDCx[arg->index]->TIX |= ((arg->t0l_cnt - 1) << 0);
  69. JL_LEDCx[arg->index]->RSTX = 0;
  70. JL_LEDCx[arg->index]->RSTX |= (arg->t_rest_cnt << 8);
  71. printf("JL_LEDCK->CLK = 0x%x\n", JL_LEDCK->CLK);
  72. printf("JL_LEDCx[%d]->CON = 0x%x\n", arg->index, JL_LEDCx[arg->index]->CON);
  73. printf("JL_LEDCx[%d]->TIX = 0x%x\n", arg->index, JL_LEDCx[arg->index]->TIX);
  74. printf("JL_LEDCx[%d]->RSTX = 0x%x\n", arg->index, JL_LEDCx[arg->index]->RSTX);
  75. }
  76. void ledc_rgb_to_buf(u8 r, u8 g, u8 b, u8 *buf, int idx)
  77. {
  78. buf = buf + idx * 3;
  79. buf[2] = b;
  80. buf[1] = r;
  81. buf[0] = g;
  82. }
  83. void ledc_send_rgbbuf(u8 index, u8 *rgbbuf, u32 led_num, u16 again_cnt)
  84. {
  85. if (!led_num) {
  86. return;
  87. }
  88. JL_LEDCx[index]->ADR = (u32)rgbbuf;
  89. JL_LEDCx[index]->FD = led_num * 3 * 8;
  90. JL_LEDCx[index]->LP = again_cnt;
  91. JL_LEDCx[index]->CON |= BIT(0);//启动
  92. JL_LEDCx[index]->CON &= ~BIT(5);//关闭中断
  93. while (!(JL_LEDCx[index]->CON & BIT(7)));
  94. JL_LEDCx[index]->CON |= BIT(6);
  95. }
  96. void ledc_send_rgbbuf_isr(u8 index, u8 *rgbbuf, u32 led_num, u16 again_cnt)
  97. {
  98. if (!led_num) {
  99. return;
  100. }
  101. if (index == 0) {
  102. os_sem_pend(&ledc0_sem, 0);
  103. } else {
  104. os_sem_pend(&ledc1_sem, 0);
  105. }
  106. JL_LEDCx[index]->ADR = (u32)rgbbuf;
  107. JL_LEDCx[index]->FD = led_num * 3 * 8;
  108. JL_LEDCx[index]->LP = again_cnt;
  109. JL_LEDCx[index]->CON |= BIT(0);//启动
  110. JL_LEDCx[index]->CON |= BIT(5);//使能中断
  111. }
  112. // *INDENT-OFF*
  113. /******************************* 参考示例 ***********************************/
  114. LEDC_PLATFORM_DATA_BEGIN(ledc0_data)
  115. .index = 0,
  116. .port = IO_PORTA_04,
  117. .idle_level = 0,
  118. .out_inv = 0,
  119. .bit_inv = 1,
  120. .t_unit = t_42ns,
  121. .t1h_cnt = 24,
  122. .t1l_cnt = 7,
  123. .t0h_cnt = 7,
  124. .t0l_cnt = 24,
  125. .t_rest_cnt = 20000,
  126. .cbfun = NULL,
  127. LEDC_PLATFORM_DATA_END()
  128. #define LED_NUM_MAX 5
  129. static u8 ledc_test_buf[3 * LED_NUM_MAX] __attribute__((aligned(4)));
  130. void ledc_test(void)
  131. {
  132. printf("************* ledc test **************\n");
  133. ledc_init(&ledc0_data);
  134. u8 r_val = 0;
  135. u8 g_val = 85;
  136. u8 b_val = 175;
  137. u16 sec_num = 5;//循环发送的次数,用于一条大灯带又分为几条效果一样的小灯带
  138. extern void wdt_clear();
  139. while (1) {
  140. wdt_clear();
  141. os_time_dly(1);
  142. r_val += 1;
  143. g_val += 1;
  144. b_val += 1;
  145. ledc_rgb_to_buf(r_val, g_val, b_val, ledc_test_buf, 0);
  146. #if 0
  147. ledc_send_rgbbuf(0, ledc_test_buf, 1, sec_num - 1);
  148. #else
  149. ledc_send_rgbbuf_isr(0, ledc_test_buf, 1, sec_num - 1);
  150. #endif
  151. }
  152. }