| /****************************************************************************** |
| * @file app_pwm.c |
| * |
| * @brief for TLSR chips |
| * |
| * @author public@telink-semi.com; |
| * @date Sep. 30, 2010 |
| * |
| * @attention |
| * |
| * Copyright (C) 2019-2020 Telink Semiconductor (Shanghai) Co., Ltd. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *****************************************************************************/ |
| #include "tl_common.h" |
| #include "drivers.h" |
| |
| |
| |
| //normal mode |
| #define TEST_PWM_NORMAL_MODE_1 1 |
| #define TEST_PWM_NORMAL_MODE_2 2 |
| #define TEST_PWM_NORMAL_MODE_3 3 |
| #define TEST_PWM_NORMAL_MODE_4 4 |
| |
| //fifo mode |
| #define TEST_PWM0_FIFO_MODE 10 |
| #define TEST_PWM0_DMA_FIFO_MODE 11 |
| |
| |
| |
| |
| |
| #define TEST_PWM_SELECT TEST_PWM0_DMA_FIFO_MODE |
| |
| |
| |
| |
| |
| |
| |
| #define IR_CARRIER_FREQ 38000 // 1 frame -> 1/38k -> 1000/38 = 26 us |
| #define PWM_CARRIER_CYCLE_TICK ( CLOCK_SYS_CLOCK_HZ/IR_CARRIER_FREQ ) //16M: 421 tick, f = 16000000/421 = 38004,T = 421/16=26.3125 us |
| #define PWM_CARRIER_HIGH_TICK ( PWM_CARRIER_CYCLE_TICK/3 ) // 1/3 duty |
| |
| |
| |
| #define PWM_IR_MAX_NUM 64 //user can define this max number |
| typedef struct{ |
| unsigned int dma_len; // dma len |
| unsigned short data[PWM_IR_MAX_NUM]; |
| unsigned int data_num; |
| }pwm_dma_data_t; |
| |
| |
| pwm_dma_data_t T_dmaData_buf; |
| |
| /********************************************************************************* |
| PWM0 : PA2. PC1. PD5 |
| PWM1 : PA3. PC3. |
| PWM2 : PA4. PC4. |
| PWM3 : PB0. PD2. |
| PWM4 : PB1. PB4. |
| PWM5 : PB2. PB5. |
| PWM0_N : PA0. PB3. PC4 PD5 |
| PWM1_N : PC1. PD3. |
| PWM2_N : PD4. |
| PWM3_N : PC5. |
| PWM4_N : PC0. PC6. |
| PWM5_N : PC7. |
| *********************************************************************************/ |
| |
| void app_pwm_test(void) |
| { |
| pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ); |
| |
| |
| #if (TEST_PWM_SELECT == TEST_PWM_NORMAL_MODE_1) //test PWMx (0~5) normal mode |
| //PA2 PWM0 1ms cycle 1/2 duty |
| gpio_set_func(GPIO_PA2, AS_PWM0); |
| pwm_set_mode(PWM0_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM0_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (500 * CLOCK_SYS_CLOCK_1US) ); |
| pwm_start(PWM0_ID); |
| |
| |
| //PA3 PWM1 1ms cycle 1/3 duty |
| gpio_set_func(GPIO_PA3, AS_PWM1); |
| pwm_set_mode(PWM1_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM1_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (333 * CLOCK_SYS_CLOCK_1US) ); |
| pwm_start(PWM1_ID); |
| |
| |
| //PA4 PWM2 1ms cycle 1/4 duty |
| gpio_set_func(GPIO_PA4, AS_PWM2); |
| pwm_set_mode(PWM2_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM2_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM2_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (250 * CLOCK_SYS_CLOCK_1US) ); |
| pwm_start(PWM2_ID); |
| |
| |
| //PB0 PWM3 1ms cycle 1/5 duty |
| gpio_set_func(GPIO_PB0, AS_PWM3); |
| pwm_set_mode(PWM3_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM3_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM3_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (200 * CLOCK_SYS_CLOCK_1US) ); |
| pwm_start(PWM3_ID); |
| |
| //PB1 PWM4 1ms cycle 2/3 duty |
| gpio_set_func(GPIO_PB1, AS_PWM4); |
| pwm_set_mode(PWM4_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM4_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM4_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (667 * CLOCK_SYS_CLOCK_1US) ); |
| pwm_start(PWM4_ID); |
| |
| |
| //PB2 PWM5 1ms cycle 3/4 duty |
| gpio_set_func(GPIO_PB2, AS_PWM5); |
| pwm_set_mode(PWM5_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM5_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM5_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (750 * CLOCK_SYS_CLOCK_1US) ); |
| pwm_start(PWM5_ID); |
| |
| #elif (TEST_PWM_SELECT == TEST_PWM_NORMAL_MODE_2) //test PWMx and PWMx_N(0~2) normal mode |
| |
| //PC1 PWM0 1ms cycle 1/3 duty |
| //PA0 PWM0_N 1ms cycle 2/3 duty |
| gpio_set_func(GPIO_PC1, AS_PWM0); |
| gpio_set_func(GPIO_PA0, AS_PWM0_N); |
| pwm_set_mode(PWM0_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM0_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (333 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| //PC3 PWM1 1ms cycle 1/4 duty |
| //PD3 PWM1_N 1ms cycle 3/4 duty |
| gpio_set_func(GPIO_PC3, AS_PWM1); |
| gpio_set_func(GPIO_PD3, AS_PWM1_N); |
| pwm_set_mode(PWM1_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM1_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (250 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| //PC4 PWM2 1ms cycle 1/5 duty |
| //PD4 PWM2_N 1ms cycle 4/5 duty |
| gpio_set_func(GPIO_PC4, AS_PWM2); |
| gpio_set_func(GPIO_PD4, AS_PWM2_N); |
| pwm_set_mode(PWM2_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM2_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM2_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (200 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| pwm_start(PWM0_ID); |
| pwm_start(PWM1_ID); |
| pwm_start(PWM2_ID); |
| |
| |
| #elif (TEST_PWM_SELECT == TEST_PWM_NORMAL_MODE_3) //test PWMx and PWMx_N(3~5) normal mode |
| |
| //PD2 PWM3 1ms cycle 1/3 duty |
| //PC5 PWM3_N 1ms cycle 2/3 duty |
| gpio_set_func(GPIO_PD2, AS_PWM3); |
| gpio_set_func(GPIO_PC5, AS_PWM3_N); |
| pwm_set_mode(PWM3_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM3_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM3_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (333 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| //PB4 PWM4 1ms cycle 1/4 duty |
| //PC0 PWM4_N 1ms cycle 3/4 duty |
| gpio_set_func(GPIO_PB4, AS_PWM4); |
| gpio_set_func(GPIO_PC0, AS_PWM4_N); |
| pwm_set_mode(PWM4_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM4_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM4_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (250 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| //PB5 PWM5 1ms cycle 1/5 duty |
| //PC7 PWM5_N 1ms cycle 4/5 duty |
| gpio_set_func(GPIO_PB5, AS_PWM5); |
| gpio_set_func(GPIO_PC7, AS_PWM5_N); |
| pwm_set_mode(PWM5_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM5_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM5_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (200 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| pwm_start(PWM3_ID); |
| pwm_start(PWM4_ID); |
| pwm_start(PWM5_ID); |
| |
| #elif (TEST_PWM_SELECT == TEST_PWM_NORMAL_MODE_4) //test rest PWM gpio |
| |
| #if 1 |
| //PB3 PWM0_N 1ms cycle 2/3 duty |
| gpio_set_func(GPIO_PB3, AS_PWM0_N); |
| #elif 0 |
| //PD5 PWM0 1ms cycle 1/3 duty |
| //PC4 PWM0_N 1ms cycle 2/3 duty |
| gpio_set_func(GPIO_PD5, AS_PWM0); |
| gpio_set_func(GPIO_PC4, AS_PWM0_N); |
| #else |
| //PD5 PWM0_N 1ms cycle 2/3 duty |
| gpio_set_func(GPIO_PD5, AS_PWM0_N); |
| #endif |
| |
| pwm_set_mode(PWM0_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM0_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM0_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (333 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| |
| //PC1 PWM1_N 1ms cycle 3/4 duty |
| gpio_set_func(GPIO_PC1, AS_PWM1_N); |
| pwm_set_mode(PWM1_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM1_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (250 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| //PC6 PWM4_N 1ms cycle 4/5 duty |
| gpio_set_func(GPIO_PC6, AS_PWM4_N); |
| pwm_set_mode(PWM4_ID, PWM_NORMAL_MODE); |
| pwm_set_phase(PWM4_ID, 0); //no phase at pwm beginning |
| pwm_set_cycle_and_duty(PWM4_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (200 * CLOCK_SYS_CLOCK_1US) ); |
| |
| |
| |
| pwm_start(PWM0_ID); |
| pwm_start(PWM1_ID); |
| pwm_start(PWM4_ID); |
| |
| |
| #elif (TEST_PWM_SELECT == TEST_PWM0_DMA_FIFO_MODE) |
| sleep_us(1000000); |
| |
| |
| |
| //only pwm0 support fifo mode |
| gpio_set_func(GPIO_PA2, AS_PWM0); |
| pwm_set_mode(PWM0_ID, PWM_IR_DMA_FIFO_MODE); |
| pwm_set_phase(PWM0_ID, 0); //no phase at pwm beginning |
| |
| //config TMAX0 & TCMP0: 38k, 1/3 duty |
| pwm_set_cycle_and_duty(PWM0_ID, PWM_CARRIER_CYCLE_TICK, PWM_CARRIER_HIGH_TICK ); |
| |
| |
| |
| //config waveforms |
| T_dmaData_buf.data_num = 0; |
| |
| //preamble: 9 ms carrier, 4.5 ms low |
| T_dmaData_buf.data[T_dmaData_buf.data_num ++] = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 9000 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK); |
| T_dmaData_buf.data[T_dmaData_buf.data_num ++] = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 4500 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK); |
| |
| //data 1 : 560 us carrier, 560 us low |
| T_dmaData_buf.data[T_dmaData_buf.data_num ++] = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK); |
| T_dmaData_buf.data[T_dmaData_buf.data_num ++] = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK); |
| |
| |
| //data 0 : 560 us carrier, 1690 us low |
| T_dmaData_buf.data[T_dmaData_buf.data_num ++] = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK); |
| T_dmaData_buf.data[T_dmaData_buf.data_num ++]= pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 1690 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK); |
| |
| |
| //end: 560 us carrier |
| T_dmaData_buf.data[T_dmaData_buf.data_num ++] = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK); |
| |
| //calculate dma len |
| T_dmaData_buf.dma_len = T_dmaData_buf.data_num * 2; |
| |
| |
| |
| |
| pwm_set_dma_address(&T_dmaData_buf); |
| |
| |
| |
| //add pwm0 dma fifo done irq, when all waveform send over, this irq will triggers |
| //enable mcu global irq |
| irq_enable(); |
| |
| //enable system irq PWM |
| reg_irq_mask |= FLD_IRQ_SW_PWM_EN; |
| |
| //enable pwm0 ir dma fifo done irq |
| reg_pwm_irq_sta = FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //clear irq status |
| reg_pwm_irq_mask |= FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; |
| |
| |
| //PWM0 ir dma fifo mode begin |
| pwm_start_dma_ir_sending(); |
| |
| DBG_CHN0_HIGH; //debug |
| |
| |
| #else |
| |
| |
| #endif |
| |
| } |
| |
| |
| |
| |
| _attribute_ram_code_ void app_pwm_irq_test_proc(void) |
| { |
| |
| if(reg_pwm_irq_sta & FLD_IRQ_PWM0_IR_DMA_FIFO_DONE){ |
| reg_pwm_irq_sta = FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; |
| DBG_CHN0_LOW; //finish |
| } |
| } |
| |
| |
| |
| |
| |
| |