123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #include "system/includes.h"
- #include "system/debug.h"
- #include "generic/gpio.h"
- #include "asm/clock.h"
- #include "asm/ledc.h"
- static JL_LEDC_TypeDef *JL_LEDCx[2] = {
- JL_LEDC0,
- JL_LEDC1
- };
- static void (*ledc0_isr_cbfun)(void) = NULL;
- static void (*ledc1_isr_cbfun)(void) = NULL;
- static OS_SEM ledc0_sem;
- static OS_SEM ledc1_sem;
- ___interrupt
- void ledc_isr(void)
- {
- if (JL_LEDC0->CON & BIT(7)) {
- JL_LEDC0->CON |= BIT(6);
- os_sem_post(&ledc0_sem);
- if (ledc0_isr_cbfun) {
- ledc0_isr_cbfun();
- }
- }
- if (JL_LEDC1->CON & BIT(7)) {
- JL_LEDC1->CON |= BIT(6);
- os_sem_post(&ledc1_sem);
- if (ledc1_isr_cbfun) {
- ledc1_isr_cbfun();
- }
- }
- }
- static u8 t_div[9] = {1, 2, 3, 6, 12, 24, 48, 96, 192};
- void ledc_init(const struct ledc_platform_data *arg)
- {
- gpio_set_die(arg->port, 1);
- gpio_set_direction(arg->port, 0);
- gpio_set_pull_up(arg->port, 0);
- gpio_set_pull_down(arg->port, 0);
- gpio_set_fun_output_port(arg->port, FO_LEDC0_DO + arg->index, 0, 1);
- //std_48M
- JL_LEDCK->CLK &= ~(0b11 << 0);
- JL_LEDCK->CLK |= (0b11 << 0);
- //set div
- JL_LEDCK->CLK &= ~(0xff << 8);
- JL_LEDCK->CLK |= ((t_div[arg->t_unit] - 1) << 8);
- JL_LEDCx[arg->index]->CON = BIT(6);
- os_sem_create(&ledc0_sem, 1);
- os_sem_create(&ledc1_sem, 1);
- request_irq(16, 1, ledc_isr, 0);
- if (arg->cbfun) {
- if (arg->index == 0) {
- ledc0_isr_cbfun = arg->cbfun;
- } else {
- ledc1_isr_cbfun = arg->cbfun;
- }
- }
- if (arg->idle_level) {
- JL_LEDCx[arg->index]->CON |= BIT(4);
- }
- if (arg->out_inv) {
- JL_LEDCx[arg->index]->CON |= BIT(3);
- }
- JL_LEDCx[arg->index]->CON |= (arg->bit_inv << 1);
- JL_LEDCx[arg->index]->TIX = 0;
- JL_LEDCx[arg->index]->TIX |= ((arg->t1h_cnt - 1) << 24);
- JL_LEDCx[arg->index]->TIX |= ((arg->t1l_cnt - 1) << 16);
- JL_LEDCx[arg->index]->TIX |= ((arg->t0h_cnt - 1) << 8);
- JL_LEDCx[arg->index]->TIX |= ((arg->t0l_cnt - 1) << 0);
- JL_LEDCx[arg->index]->RSTX = 0;
- JL_LEDCx[arg->index]->RSTX |= (arg->t_rest_cnt << 8);
- printf("JL_LEDCK->CLK = 0x%x\n", JL_LEDCK->CLK);
- printf("JL_LEDCx[%d]->CON = 0x%x\n", arg->index, JL_LEDCx[arg->index]->CON);
- printf("JL_LEDCx[%d]->TIX = 0x%x\n", arg->index, JL_LEDCx[arg->index]->TIX);
- printf("JL_LEDCx[%d]->RSTX = 0x%x\n", arg->index, JL_LEDCx[arg->index]->RSTX);
- }
- void ledc_rgb_to_buf(u8 r, u8 g, u8 b, u8 *buf, int idx)
- {
- buf = buf + idx * 3;
- buf[2] = b;
- buf[1] = r;
- buf[0] = g;
- }
- void ledc_send_rgbbuf(u8 index, u8 *rgbbuf, u32 led_num, u16 again_cnt)
- {
- if (!led_num) {
- return;
- }
- JL_LEDCx[index]->ADR = (u32)rgbbuf;
- JL_LEDCx[index]->FD = led_num * 3 * 8;
- JL_LEDCx[index]->LP = again_cnt;
- JL_LEDCx[index]->CON |= BIT(0);//启动
- JL_LEDCx[index]->CON &= ~BIT(5);//关闭中断
- while (!(JL_LEDCx[index]->CON & BIT(7)));
- JL_LEDCx[index]->CON |= BIT(6);
- }
- void ledc_send_rgbbuf_isr(u8 index, u8 *rgbbuf, u32 led_num, u16 again_cnt)
- {
- if (!led_num) {
- return;
- }
- if (index == 0) {
- os_sem_pend(&ledc0_sem, 0);
- } else {
- os_sem_pend(&ledc1_sem, 0);
- }
- JL_LEDCx[index]->ADR = (u32)rgbbuf;
- JL_LEDCx[index]->FD = led_num * 3 * 8;
- JL_LEDCx[index]->LP = again_cnt;
- JL_LEDCx[index]->CON |= BIT(0);//启动
- JL_LEDCx[index]->CON |= BIT(5);//使能中断
- }
- // *INDENT-OFF*
- /******************************* 参考示例 ***********************************/
- LEDC_PLATFORM_DATA_BEGIN(ledc0_data)
- .index = 0,
- .port = IO_PORTA_04,
- .idle_level = 0,
- .out_inv = 0,
- .bit_inv = 1,
- .t_unit = t_42ns,
- .t1h_cnt = 24,
- .t1l_cnt = 7,
- .t0h_cnt = 7,
- .t0l_cnt = 24,
- .t_rest_cnt = 20000,
- .cbfun = NULL,
- LEDC_PLATFORM_DATA_END()
- #define LED_NUM_MAX 5
- static u8 ledc_test_buf[3 * LED_NUM_MAX] __attribute__((aligned(4)));
- void ledc_test(void)
- {
- printf("************* ledc test **************\n");
- ledc_init(&ledc0_data);
- u8 r_val = 0;
- u8 g_val = 85;
- u8 b_val = 175;
- u16 sec_num = 5;//循环发送的次数,用于一条大灯带又分为几条效果一样的小灯带
- extern void wdt_clear();
- while (1) {
- wdt_clear();
- os_time_dly(1);
- r_val += 1;
- g_val += 1;
- b_val += 1;
- ledc_rgb_to_buf(r_val, g_val, b_val, ledc_test_buf, 0);
- #if 0
- ledc_send_rgbbuf(0, ledc_test_buf, 1, sec_num - 1);
- #else
- ledc_send_rgbbuf_isr(0, ledc_test_buf, 1, sec_num - 1);
- #endif
- }
- }
|