123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- #include "system/includes.h"
- #include "app_config.h"
- #include "app_action.h"
- #include "app_main.h"
- #include "gpio.h"
- #include "asm/power/p11.h"
- // 可配参数
- #define AUDIO_PWM_SOURCE (1) // 0:timer 1:mcpwm
- #define AUDIO_PWM_MODE (3) // 0:single mode 1:diff mode 0 2:diff mode 1 3:diff mode 2
- #define FADE_STEP (100) // PWM开始和结尾的淡入淡出步进,每 FADE_STEP 个点更新一次占空比单位
- #if (AUDIO_PWM_SOURCE == 0)
- #define PWM_DEAD_AREA (50) // PWM死区时钟数 因为占空比在中断更新,这个时间要大于中断的整个处理时间,但要小于PWM周期
- #elif (AUDIO_PWM_SOURCE == 1)
- #define PWM_DEAD_AREA (0) // PWM死区时钟数 MCPWM 模块有占空比更新时机控制机制,不需要死区
- #endif
- #define BUF_SIZE (1024 * 4) // AUDIO PWM 缓冲buf大小
- u32 pwm_io_P = IO_PORTB_08; // PWM 输出 P 端 IO 选择,单端只关注 P 端即可
- u32 pwm_io_N = IO_PORTB_09; // PWM 输出 N 端 IO 选择,差分需要配置 N 端
- // PWM cbuf 缓冲区相关参数
- volatile s16 audio_pwm_cbuf[BUF_SIZE] = {0};
- volatile u32 rptr = 0;
- volatile u32 wptr = 0;
- static u8 pwm_is_closed = 1;
- // PWM 状态及占空比控制参数
- #define STATE_STOP (0)
- #define STATE_FADE_IN (1)
- #define STATE_START (2)
- #define STATE_FADE_OUT (3)
- volatile u8 audio_pwm_state = 0;
- volatile u32 audio_pwm_target = 0;
- volatile u32 audio_pwm_cur = 0;
- volatile u32 audio_pwm_prd = 0; // 周期时钟数,也是占空比的分辨率
- u16 pcm_to_pwm_scale = 0; // 16bit pcm数据 转成 占空比分辨率范围 的比例值
- u32 audio_pwm_zero = 0; // PCM 数据 0 的时候对应的 PWM 值
- u32 half_wave_limit = 0;
- volatile u8 pwm_need_resume = 0;
- static OS_SEM pwm_need_resume_sem ;
- static void (*pwm_resume_handler)(void *) = NULL;
- static u8 drop_flag = 0;
- void state_printf(void)
- {
- printf("state :%d, pwm_h:%d, pwm_l:%d", audio_pwm_state, JL_MCPWM->CH3_CMPH, JL_MCPWM->CH3_CMPL);
- }
- void set_state(u8 state)
- {
- if (state == STATE_STOP) { //要设置pwm 停止需要等cbuffer 里面的数据播完
- u8 err_cnt = 0;
- while (abs(wptr - rptr) > 1) {
- delay(3000);
- err_cnt++;
- if (err_cnt > 500) {
- printf("wptr:%x,rptr:%x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", wptr, rptr);
- break;
- }
- }
- audio_pwm_state = state;
- pwm_is_closed = 1;
- } else {
- audio_pwm_state = state;
- pwm_is_closed = 0;
- }
- }
- #if (AUDIO_PWM_SOURCE == 0) // timer
- ___interrupt
- void usr_pwm_timer_isr(void) __attribute__((section(".audio_pwm_code")))
- {
- s32 pcm = 0;
- s32 pcm1 = 0;
- JL_TIMER3->CON |= BIT(14);
- /* JL_PORTA->DIR &= ~BIT(5); */
- /* JL_PORTA->OUT &= ~BIT(5); */
- if (drop_flag == 0) {
- drop_flag = 1;
- return;
- } else {
- drop_flag = 0;
- }
- if (audio_pwm_state == STATE_START) {
- if (rptr != wptr) {
- pcm = (s32)(audio_pwm_cbuf[rptr]);
- #if (AUDIO_PWM_MODE == 0)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- } else {
- pcm -= pcm_to_pwm_scale / 2;
- }
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- } else if (pcm < -half_wave_limit) {
- pcm = -half_wave_limit;
- }
- JL_TIMER3->PWM = (u32)(pcm + audio_pwm_zero); // P
- #elif (AUDIO_PWM_MODE == 1)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- } else {
- pcm -= pcm_to_pwm_scale / 2;
- }
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- } else if (pcm < -half_wave_limit) {
- pcm = -half_wave_limit;
- }
- JL_TIMER3->PWM = (u32)(pcm + audio_pwm_zero); // P
- JL_TIMER2->PWM = (u32)(pcm + audio_pwm_zero); // N
- #elif (AUDIO_PWM_MODE == 2)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- } else {
- pcm -= pcm_to_pwm_scale / 2;
- }
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- } else if (pcm < -half_wave_limit) {
- pcm = -half_wave_limit;
- }
- JL_TIMER3->PWM = (u32)(pcm + audio_pwm_zero); // P
- JL_TIMER2->PWM = (u32)(-pcm + audio_pwm_zero); // N
- #elif (AUDIO_PWM_MODE == 3)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- }
- JL_TIMER3->PWM = (u32)(PWM_DEAD_AREA + pcm); // P
- JL_TIMER2->PWM = (u32)(PWM_DEAD_AREA); // N
- } else {
- pcm = -pcm;
- pcm -= pcm_to_pwm_scale / 2;
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- }
- JL_TIMER3->PWM = (u32)(PWM_DEAD_AREA); // P
- JL_TIMER2->PWM = (u32)(PWM_DEAD_AREA + pcm); // N
- }
- #endif
- rptr++;
- if (rptr >= BUF_SIZE) {
- rptr = 0;
- }
- } else {
- /* putchar('e'); */
- }
- } else if ((audio_pwm_state == STATE_FADE_IN) || (audio_pwm_state == STATE_FADE_OUT)) {
- if (audio_pwm_cur > audio_pwm_target) {
- audio_pwm_cur--;
- /* printf("{%d", audio_pwm_cur); */
- } else if (audio_pwm_cur < audio_pwm_target) {
- audio_pwm_cur++;
- /* printf("}%d", audio_pwm_cur); */
- } else {
- if (audio_pwm_state == STATE_FADE_IN) {
- audio_pwm_state = STATE_START;
- } else {
- audio_pwm_state = STATE_STOP;
- }
- }
- #if (AUDIO_PWM_MODE == 0)
- JL_TIMER3->PWM = audio_pwm_cur / FADE_STEP;
- #elif ((AUDIO_PWM_MODE == 1) || (AUDIO_PWM_MODE == 2))
- JL_TIMER3->PWM = audio_pwm_cur / FADE_STEP;
- JL_TIMER2->PWM = audio_pwm_cur / FADE_STEP;
- #elif (AUDIO_PWM_MODE == 3) // 这种调制方式不需要淡入淡出
- if (audio_pwm_state == STATE_FADE_IN) {
- audio_pwm_state = STATE_START;
- } else {
- audio_pwm_state = STATE_STOP;
- }
- #endif
- } else {
- // do no thing
- }
- /* JL_PORTA->DIR &= ~BIT(5); */
- /* JL_PORTA->OUT |= BIT(5); */
- }
- void usr_pwm_timer_init(void)
- {
- printf("############ usr_pwm_timer_init ########## \n");
- bit_clr_ie(IRQ_TIME3_IDX);
- request_irq(IRQ_TIME3_IDX, 3, usr_pwm_timer_isr, 0);
- irq_unmask_set(IRQ_TIME3_IDX, 0);
- JL_TIMER3->CON = BIT(14);
- JL_TIMER3->CON |= (6 << 10); //时钟源选择稳定的STD_24M
- JL_TIMER3->CON |= (0b0000 << 4); //时钟源再1分频
- JL_TIMER3->CON &= ~BIT(9); // PWM_INV 信号反相
- JL_TIMER3->CON |= BIT(8); // PWM IO OUT
- JL_TIMER3->CNT = 0;
- JL_TIMER3->PRD = 750; // 频率 32kHz
- JL_TIMER3->PWM = 0;
- JL_TIMER3->CON |= BIT(14) | BIT(0);
- audio_pwm_prd = JL_TIMER3->PRD;
- #if (AUDIO_PWM_MODE == 3)
- pcm_to_pwm_scale = 32767 / audio_pwm_prd;
- audio_pwm_zero = 0;
- half_wave_limit = audio_pwm_prd;
- #else
- pcm_to_pwm_scale = 65536 / (audio_pwm_prd - PWM_DEAD_AREA);
- audio_pwm_zero = PWM_DEAD_AREA + (audio_pwm_prd - PWM_DEAD_AREA) / 2;
- half_wave_limit = (audio_pwm_prd - PWM_DEAD_AREA) / 2;
- #endif
- gpio_set_fun_output_port(pwm_io_P, FO_TMR3_PWM, 0, 1);
- //设置引脚状态
- gpio_set_die(pwm_io_P, 1);
- gpio_set_pull_up(pwm_io_P, 0);
- gpio_set_pull_down(pwm_io_P, 0);
- gpio_set_direction(pwm_io_P, 0);
- #if ((AUDIO_PWM_MODE == 1) || (AUDIO_PWM_MODE == 2) || (AUDIO_PWM_MODE == 3))
- JL_TIMER2->CON = 0;
- JL_TIMER2->CON |= (6 << 10); //时钟源选择稳定的STD_24M
- JL_TIMER2->CON |= (0b0000 << 4); //时钟源再1分频
- #if (AUDIO_PWM_MODE == 1)
- JL_TIMER2->CON |= BIT(9); // PWM_INV 信号反相
- #elif ((AUDIO_PWM_MODE == 2) || (AUDIO_PWM_MODE == 3))
- JL_TIMER2->CON &= ~BIT(9); // PWM_INV 信号反相
- #endif
- JL_TIMER2->CON |= BIT(8); // PWM IO OUT
- JL_TIMER2->PRD = 750; // 频率 32kHz
- JL_TIMER2->PWM = 0;
- JL_TIMER2->CON |= BIT(0);
- JL_TIMER2->CNT = 0;
- JL_TIMER3->CNT = 0; // sync
- gpio_set_fun_output_port(pwm_io_N, FO_TMR2_PWM, 0, 1);
- //设置引脚状态
- gpio_set_die(pwm_io_N, 1);
- gpio_set_pull_up(pwm_io_N, 0);
- gpio_set_pull_down(pwm_io_N, 0);
- gpio_set_direction(pwm_io_N, 0);
- /* gpio_set_hd(pwm_io_N, 1); */
- /* gpio_set_hd0(pwm_io_N, 1); */
- #endif
- audio_pwm_state = STATE_START;
- }
- void usr_pwm_timer_uninit(void)
- {
- JL_TIMER3->CON = 0;
- #if ((AUDIO_PWM_MODE == 1) || (AUDIO_PWM_MODE == 2) || (AUDIO_PWM_MODE == 3))
- JL_TIMER2->CON = 0;
- #endif
- }
- #elif (AUDIO_PWM_SOURCE == 1) // mcpwm
- ___interrupt
- void usr_mcpwm_isr(void) __attribute__((section(".audio_pwm_code")))
- {
- s32 pcm = 0;
- s32 pcm1 = 0;
- if (JL_MCPWM->TMR3_CON & BIT(12)) {
- JL_MCPWM->TMR3_CON |= BIT(10);//清中断标志
- }
- if (drop_flag == 0) {
- drop_flag = 1;
- return;
- } else {
- drop_flag = 0;
- }
- /* JL_PORTA->DIR &= ~BIT(5); */
- /* JL_PORTA->OUT &= ~BIT(5); */
- if (audio_pwm_state == STATE_START) {
- if (rptr != wptr) {
- pcm = (s32)(audio_pwm_cbuf[rptr]);
- #if (AUDIO_PWM_MODE == 0)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- } else {
- pcm -= pcm_to_pwm_scale / 2;
- }
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- } else if (pcm < -half_wave_limit) {
- pcm = -half_wave_limit;
- }
- JL_MCPWM->CH3_CMPH = (u32)(pcm + audio_pwm_zero); // P
- #elif (AUDIO_PWM_MODE == 1)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- } else {
- pcm -= pcm_to_pwm_scale / 2;
- }
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- } else if (pcm < -half_wave_limit) {
- pcm = -half_wave_limit;
- }
- JL_MCPWM->CH3_CMPH = (u32)(pcm + audio_pwm_zero); // P
- JL_MCPWM->CH3_CMPL = (u32)(pcm + audio_pwm_zero); // N
- #elif (AUDIO_PWM_MODE == 2)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- } else {
- pcm -= pcm_to_pwm_scale / 2;
- }
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- } else if (pcm < -half_wave_limit) {
- pcm = -half_wave_limit;
- }
- JL_MCPWM->CH3_CMPH = (u32)(pcm + audio_pwm_zero); // P
- pcm1 = pcm;
- JL_MCPWM->CH3_CMPL = (u32)(-pcm + audio_pwm_zero); // N
- #elif (AUDIO_PWM_MODE == 3)
- if (pcm >= 0) {
- pcm += pcm_to_pwm_scale / 2;
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- }
- JL_MCPWM->CH3_CMPH = (u32)(PWM_DEAD_AREA + pcm); // P
- JL_MCPWM->CH3_CMPL = PWM_DEAD_AREA; // N
- } else {
- pcm = -pcm;
- pcm -= pcm_to_pwm_scale / 2;
- pcm /= pcm_to_pwm_scale;
- if (pcm > half_wave_limit) {
- pcm = half_wave_limit;
- }
- JL_MCPWM->CH3_CMPH = PWM_DEAD_AREA; // P
- JL_MCPWM->CH3_CMPL = (u32)(PWM_DEAD_AREA + pcm); // N
- }
- #endif
- rptr++;
- if (rptr >= BUF_SIZE) {
- rptr = 0;
- }
- } else {
- /* putchar('e'); */
- }
- } else if ((audio_pwm_state == STATE_FADE_IN) || (audio_pwm_state == STATE_FADE_OUT)) {
- if (audio_pwm_cur > audio_pwm_target) {
- audio_pwm_cur--;
- /* printf("{%d", audio_pwm_cur); */
- } else if (audio_pwm_cur < audio_pwm_target) {
- audio_pwm_cur++;
- /* printf("}%d", audio_pwm_cur); */
- } else {
- if (audio_pwm_state == STATE_FADE_IN) {
- audio_pwm_state = STATE_START;
- /* putchar('s'); */
- } else {
- audio_pwm_state = STATE_STOP;
- /* putchar('p'); */
- }
- }
- JL_MCPWM->CH3_CMPH = audio_pwm_cur / FADE_STEP;
- #if ((AUDIO_PWM_MODE == 1) || (AUDIO_PWM_MODE == 2))
- JL_MCPWM->CH3_CMPL = audio_pwm_cur / FADE_STEP;
- #elif (AUDIO_PWM_MODE == 3) // 这种调制方式不需要淡入淡出
- if (audio_pwm_state == STATE_FADE_IN) {
- audio_pwm_state = STATE_START;
- } else if (audio_pwm_state == STATE_FADE_OUT) {
- audio_pwm_state = STATE_STOP;
- }
- #endif
- } else {
- JL_MCPWM->CH3_CMPH = PWM_DEAD_AREA; // P
- JL_MCPWM->CH3_CMPL = PWM_DEAD_AREA; // N
- // do no thing
- }
- /* JL_PORTA->DIR &= ~BIT(5); */
- /* JL_PORTA->OUT |= BIT(5); */
- }
- void usr_mcpwm_init(void)
- {
- printf("############ usr_mcpwm_init ########## \n");
- request_irq(IRQ_MCPWM_TIMER, 3, usr_mcpwm_isr, 0);
- irq_unmask_set(IRQ_MCPWM_TIMER, 0);
- JL_MCPWM->MCPWM_CON0 &= ~BIT(8 + 3);
- JL_MCPWM->TMR3_CNT = 0;
- JL_MCPWM->TMR3_PR = clk_get("lsb") / 32000;
- audio_pwm_prd = JL_MCPWM->TMR3_PR;
- #if (AUDIO_PWM_MODE == 3)
- pcm_to_pwm_scale = 32767 / audio_pwm_prd;
- audio_pwm_zero = 0;
- half_wave_limit = audio_pwm_prd;
- #else
- pcm_to_pwm_scale = 65536 / (audio_pwm_prd - PWM_DEAD_AREA);
- audio_pwm_zero = PWM_DEAD_AREA + (audio_pwm_prd - PWM_DEAD_AREA) / 2;
- half_wave_limit = (audio_pwm_prd - PWM_DEAD_AREA) / 2;
- #endif
- JL_MCPWM->TMR3_CON |= BIT(8); // IE
- JL_MCPWM->TMR3_CON |= BIT(10) | BIT(0);
- JL_MCPWM->MCPWM_CON0 |= BIT(8 + 3); // MCTIMER3 enable
- gpio_set_fun_output_port(pwm_io_P, FO_MCPWM_CH3H, 0, 1);
- gpio_set_die(pwm_io_P, 1);
- gpio_set_direction(pwm_io_P, 0);
- gpio_set_pull_up(pwm_io_P, 0);
- gpio_set_pull_down(pwm_io_P, 0);
- #if ((AUDIO_PWM_MODE == 1) || (AUDIO_PWM_MODE == 2) || (AUDIO_PWM_MODE == 3))
- gpio_set_fun_output_port(pwm_io_N, FO_MCPWM_CH3L, 0, 1);
- gpio_set_die(pwm_io_N, 1);
- gpio_set_direction(pwm_io_N, 0);
- gpio_set_pull_up(pwm_io_N, 0);
- gpio_set_pull_down(pwm_io_N, 0);
- #endif
- JL_MCPWM->CH3_CON0 = 0;
- JL_MCPWM->CH3_CON0 |= BIT(2); // PWM H enable
- JL_MCPWM->CH3_CON0 |= BIT(3); // PWM L enable
- JL_MCPWM->CH3_CON0 &= ~BIT(4); // PWM H 信号反相使能
- #if (AUDIO_PWM_MODE == 1)
- JL_MCPWM->CH3_CON0 |= BIT(5); // PWM L 信号反相使能
- #elif ((AUDIO_PWM_MODE == 2) || (AUDIO_PWM_MODE == 3))
- JL_MCPWM->CH3_CON0 &= ~BIT(5); // PWM L 信号反相使能
- #endif
- SFR(JL_MCPWM->CH3_CON0, 0, 2, 2); // duty update type select
- SFR(JL_MCPWM->CH3_CON1, 8, 3, 3); // MCPWM CH3 select MCTIMER3
- JL_MCPWM->MCPWM_CON0 |= BIT(0 + 3); // MCPWM CH3 enable
- audio_pwm_state = STATE_START;
- }
- void usr_mcpwm_uninit(void)
- {
- pwm_is_closed = 1;
- }
- #endif
- static void audio_pwm_task(void *param)
- {
- printf(">>>> audio_pwm_task\n");
- u32 buf_points = 0;
- while (1) {
- if (pwm_need_resume) {
- if (rptr < wptr) {
- buf_points = wptr - rptr;
- } else if (rptr == wptr) {
- buf_points = 0;
- } else {
- buf_points = BUF_SIZE - rptr + wptr;
- }
- if (buf_points < 1024) { //32 ms
- if (pwm_resume_handler != NULL) {
- pwm_resume_handler(NULL);
- }
- /* putchar('R'); */
- } else {
- /* putchar('N'); */
- }
- } else {
- /* printf("enter audio_pwm.c %d\n",__LINE__); */
- os_sem_pend(&pwm_need_resume_sem, 0); //在不需要跑任务的时候pend住,避免任务频繁起来
- /* printf("enter audio_pwm.c %d\n",__LINE__); */
- }
- os_time_dly(1);
- }
- }
- void audio_pwm_set_resume(void (*resume)(void *))
- {
- pwm_resume_handler = resume;
- }
- void audio_pwm_open(void)
- {
- printf("audio_pwm_open\n");
- clk_set("sys", 96 * 1000000L);
- os_sem_create(&pwm_need_resume_sem, 0);
- os_task_create(audio_pwm_task, NULL, 2, 1024, 128, "audio_pwm_task");
- #if (AUDIO_PWM_SOURCE == 0) // timer
- usr_pwm_timer_init();
- #elif (AUDIO_PWM_SOURCE == 1) // mcpwm
- usr_mcpwm_init();
- #endif // timer of mcpwm
- //开机进低功耗要把输出清0,不然有杂声
- JL_MCPWM->CH3_CMPH = PWM_DEAD_AREA; // P
- JL_MCPWM->CH3_CMPL = PWM_DEAD_AREA; // N
- /* pwm_is_closed = 0; */
- }
- void audio_pwm_close(void)
- {
- #if (AUDIO_PWM_SOURCE == 0) // timer
- usr_pwm_timer_uninit();
- #elif (AUDIO_PWM_SOURCE == 1) // mcpwm
- usr_mcpwm_uninit();
- #endif // timer of mcpwm
- }
- void audio_pwm_start(void)
- {
- audio_pwm_state = STATE_FADE_IN;
- #if (AUDIO_PWM_SOURCE == 0) // timer
- audio_pwm_cur = JL_TIMER3->PWM * FADE_STEP;
- #elif (AUDIO_PWM_SOURCE == 1) // mcpwm
- audio_pwm_cur = JL_MCPWM->CH3_CMPH;
- #endif // timer of mcpwm
- audio_pwm_target = audio_pwm_zero * FADE_STEP;
- }
- void audio_pwm_stop(void)
- {
- audio_pwm_state = STATE_FADE_OUT;
- #if (AUDIO_PWM_SOURCE == 0) // timer
- audio_pwm_cur = JL_TIMER3->PWM * FADE_STEP;
- #elif (AUDIO_PWM_SOURCE == 1) // mcpwm
- audio_pwm_cur = JL_MCPWM->CH3_CMPH;
- #endif // timer of mcpwm
- audio_pwm_target = 0;
- }
- static int __audio_pwm_write(s16 *data, u32 len)
- {
- u32 free_points = 0;
- u32 wpoints = len / 2;
- local_irq_disable();
- if (rptr <= wptr) {
- if (rptr == 0) { // 不能让 wptr 和 rptr 碰到一起
- free_points = BUF_SIZE - wptr - 1;
- } else {
- free_points = BUF_SIZE - wptr;
- }
- } else {
- free_points = rptr - wptr - 1;
- }
- if (free_points == 0) {
- local_irq_enable();
- return 0;
- }
- if (wpoints > free_points) {
- wpoints = free_points;
- }
- memcpy(&(audio_pwm_cbuf[wptr]), data, wpoints * 2);
- wptr += wpoints;
- if (wptr >= BUF_SIZE) {
- wptr = 0;
- }
- local_irq_enable();
- return wpoints * 2;
- }
- int audio_pwm_write(s16 *data, u32 len)
- {
- u32 wlen = 0;
- wlen = __audio_pwm_write(data, len);
- if (len != wlen) {
- data += wlen / 2;
- wlen += __audio_pwm_write(data, len - wlen);
- }
- if (wlen != len) {
- /* putchar('S'); */
- pwm_need_resume = 1;
- os_sem_post(&pwm_need_resume_sem);
- } else {
- /* putchar('W'); */
- pwm_need_resume = 0;
- os_sem_set(&pwm_need_resume_sem, 0);
- }
- return wlen;
- }
- static u8 pwm_demo_idle_query()
- {
- return pwm_is_closed;
- }
- REGISTER_LP_TARGET(pwm_demo_lp_target) = {
- .name = "pwm_demo",
- .is_idle = pwm_demo_idle_query,
- };
|