blob: 64b8d57ed508c7da3a2d961ae16bc59c37fd5038 [file] [log] [blame]
/******************************************************************************
* @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
}
}