blob: 84975dba630ff8a6756eb0888824a926f5250be3 [file] [log] [blame]
/******************************************************************************
* @file rc_ir.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"
#include "rc_ir.h"
#include "app_ir.h"
#if (REMOTE_IR_ENABLE)
#define ADD_REPEAT_ONE_BY_ONE 1
///////////// NEC protocol /////////////////////////////////////////////
//start
#define IR_INTRO_CARR_TIME_NEC 9000
#define IR_INTRO_NO_CARR_TIME_NEC 4500
//stop
#define IR_END_TRANS_TIME_NEC 563 // user define
//repeat
#define IR_REPEAT_CARR_TIME_NEC 9000
#define IR_REPEAT_NO_CARR_TIME_NEC 2250
#define IR_REPEAT_LOW_CARR_TIME_NEC 560
//data "1"
#define IR_HIGH_CARR_TIME_NEC 560
#define IR_HIGH_NO_CARR_TIME_NEC 1690
//data "0"
#define IR_LOW_CARR_TIME_NEC 560
#define IR_LOW_NO_CARR_TIME_NEC 560
pwm_dma_data_t T_dmaData_buf;
u16 waveform_start_bit_1st;
u16 waveform_start_bit_2nd;
u16 waveform_stop_bit_1st;
u16 waveform_stop_bit_2nd;
u16 waveform_logic_0_1st;
u16 waveform_logic_0_2nd;
u16 waveform_logic_1_1st;
u16 waveform_logic_1_2nd;
u16 waveform_repeat_1st;
u16 waveform_repeat_2nd;
u16 waveform_repeat_3rd;
u16 waveform_repeat_4th;
u16 waveform_wait_to_repeat;
int ir_sending_check(void);
void ir_nec_send(u8 addr1, u8 addr2, u8 cmd)
{
if(ir_send_ctrl.last_cmd != cmd)
{
if(ir_sending_check())
{
return;
}
ir_send_ctrl.last_cmd = cmd;
//// set waveform input in sequence //////
T_dmaData_buf.data_num = 0;
//waveform for start bit
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_start_bit_1st;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_start_bit_2nd;
//add data
u32 data = (~cmd)<<24 | cmd<<16 | addr2<<8 | addr1;
for(int i=0;i<32;i++){
if(data & BIT(i)){
//waveform for logic_1
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_logic_1_1st;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_logic_1_2nd;
}
else{
//waveform for logic_0
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_logic_0_1st;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_logic_0_2nd;
}
}
//waveform for stop bit
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_stop_bit_1st;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_stop_bit_2nd;
T_dmaData_buf.dma_len = T_dmaData_buf.data_num * 2;
if(1){ //need repeat
ir_send_ctrl.repeat_enable = 1; //need repeat signal
}
else{ //no need repeat
ir_send_ctrl.repeat_enable = 0; //no need repeat signal
}
reg_pwm_irq_sta = FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //clear dma fifo mode done irq status
reg_pwm_irq_mask |= FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //enable dma fifo mode done irq mask
ir_send_ctrl.is_sending = IR_SENDING_DATA;
ir_send_ctrl.sending_start_time = clock_time();
// gpio_set_func(GPIO_PB3, AS_PWM0_N);
pwm_start_dma_ir_sending();
}
}
int ir_is_sending()
{
if(ir_send_ctrl.is_sending && clock_time_exceed(ir_send_ctrl.sending_start_time, 300*1000))
{
ir_send_ctrl.is_sending = IR_SENDING_NONE;
pwm_stop_dma_ir_sending();
}
return ir_send_ctrl.is_sending;
}
int ir_sending_check(void)
{
u8 r = irq_disable();
if(ir_is_sending()){
irq_restore(r);
return 1;
}
irq_restore(r);
return 0;
}
#if 0
void ir_send_release(void)
{
u8 r = irq_disable();
ir_send_ctrl.last_cmd = 0xff;
#if(!ADD_REPEAT_ONE_BY_ONE)
if(ir_send_ctrl.is_sending != IR_SENDING_NONE){
pwm_stop_dma_ir_sending();
}
#endif
ir_send_ctrl.is_sending = IR_SENDING_NONE;
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; //disable irq mask
irq_restore(r);
}
#else
void ir_send_release(void)
{
printf("ir_send_release\r\n");
ir_send_ctrl.last_cmd = 0xff;
ir_send_ctrl.is_sending = IR_SENDING_STOP;
}
#endif
//int AA_pwm_irq_cnt = 0;
#if (ADD_REPEAT_ONE_BY_ONE)
#if (REMOTE_IR_ENABLE)
_attribute_ram_code_
#endif
void rc_ir_irq_prc(void)
{
// printf("rc_ir_irq_prc\r\n");
if(reg_pwm_irq_sta & FLD_IRQ_PWM0_IR_DMA_FIFO_DONE){
reg_pwm_irq_sta = FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //clear irq status
if(is_programming_key_send() == 0)
{
if(ir_send_ctrl.repeat_enable){
if(ir_send_ctrl.is_sending == IR_SENDING_DATA){
ir_send_ctrl.is_sending = IR_SENDING_REPEAT;
T_dmaData_buf.data_num = 0;
u32 tick_2_repeat_sysClockTimer16M = 110*CLOCK_16M_SYS_TIMER_CLK_1MS - (clock_time() - ir_send_ctrl.sending_start_time);
u32 tick_2_repeat_sysTimer = (tick_2_repeat_sysClockTimer16M*CLOCK_SYS_CLOCK_1US>>4);
waveform_wait_to_repeat = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, tick_2_repeat_sysTimer/PWM_CARRIER_CYCLE_TICK);
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_wait_to_repeat;
T_dmaData_buf.dma_len = T_dmaData_buf.data_num * 2;
//printf("IR_SENDING_DATA\r\n");
pwm_start_dma_ir_sending();
}
else if(ir_send_ctrl.is_sending == IR_SENDING_REPEAT){
//printf("IR_SENDING_REPEAT\r\n");
T_dmaData_buf.data_num = 0;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_1st;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_2nd;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_3rd;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_4th;
T_dmaData_buf.dma_len = T_dmaData_buf.data_num * 2;
pwm_start_dma_ir_sending();
}
else
{
printf("ir irq release\r\n");
reg_pwm_irq_mask &= ~FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //disable irq mask
ir_send_ctrl.is_sending = IR_SENDING_NONE;
}
}
else{
printf("ir irq release\r\n");
reg_pwm_irq_mask &= ~FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //disable irq mask
ir_send_ctrl.is_sending = IR_SENDING_NONE;
}
}
else
{
if(ir_type_read())
{
pwm_start_dma_ir_sending();
}
}
}
}
#else
#if (REMOTE_IR_ENABLE)
_attribute_ram_code_
#endif
void rc_ir_irq_prc(void)
{
if(reg_pwm_irq_sta & FLD_IRQ_PWM0_IR_DMA_FIFO_DONE){
reg_pwm_irq_sta = FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //clear irq status
if(is_programming_key_send() == 0)
{
if(ir_send_ctrl.repeat_enable){
if(ir_send_ctrl.is_sending == IR_SENDING_DATA){
ir_send_ctrl.is_sending = IR_SENDING_REPEAT;
T_dmaData_buf.data_num = 0;
u32 tick_2_repeat_sysClockTimer16M = 110*CLOCK_16M_SYS_TIMER_CLK_1MS - (clock_time() - ir_send_ctrl.sending_start_time);
u32 tick_2_repeat_sysTimer = (tick_2_repeat_sysClockTimer16M*CLOCK_SYS_CLOCK_1US>>4);
waveform_wait_to_repeat = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, tick_2_repeat_sysTimer/PWM_CARRIER_CYCLE_TICK);
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_wait_to_repeat;
for(int i=0;i<5;i++){
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_1st;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_2nd;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_3rd;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_4th;
}
T_dmaData_buf.dma_len = T_dmaData_buf.data_num * 2;
pwm_start_dma_ir_sending();
}
else if(ir_send_ctrl.is_sending == IR_SENDING_REPEAT){
T_dmaData_buf.data_num = 0;
for(int i=0;i<5;i++){
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_1st;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_2nd;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_3rd;
T_dmaData_buf.data[T_dmaData_buf.data_num ++] = waveform_repeat_4th;
}
T_dmaData_buf.dma_len = T_dmaData_buf.data_num * 2;
pwm_start_dma_ir_sending();
}
else
{
printf("ir irq release\r\n");
reg_pwm_irq_mask &= ~FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //disable irq mask
ir_send_ctrl.is_sending = IR_SENDING_NONE;
}
}
else{
//ir_send_release();
printf("ir irq release\r\n");
reg_pwm_irq_mask &= ~FLD_IRQ_PWM0_IR_DMA_FIFO_DONE; //disable irq mask
ir_send_ctrl.is_sending = IR_SENDING_NONE;
}
}
else
{
if(ir_type_read())
{
pwm_start_dma_ir_sending();
}
}
}
}
#endif
void rc_ir_init(void)
{
//only pwm0 support fifo mode
pwm_n_revert(PWM0_ID); //if use PWMx_N, user must set "pwm_n_revert" before gpio_set_func(pwmx_N).
gpio_set_func(GPIO_PB3, AS_PWM0_N);
pwm_set_mode(PWM0_ID, PWM_IR_DMA_FIFO_MODE);
pwm_set_phase(PWM0_ID, 0); //no phase at pwm beginning
pwm_set_cycle_and_duty(PWM0_ID, PWM_CARRIER_CYCLE_TICK, PWM_CARRIER_HIGH_TICK ); //config carrier: 38k, 1/3 duty
pwm_set_dma_address(&T_dmaData_buf);
//logic_0, 560 us carrier, 560 us low
waveform_logic_0_1st = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
waveform_logic_0_2nd = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
//logic_1, 560 us carrier, 1690 us low
waveform_logic_1_1st = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
waveform_logic_1_2nd = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 1690 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
//start bit, 9000 us carrier, 4500 us low
waveform_start_bit_1st = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 9000 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
waveform_start_bit_2nd = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 4500 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
//stop bit, 560 us carrier, 500 us low
waveform_stop_bit_1st = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
waveform_stop_bit_2nd = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 500 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
//repeat signal first part, 9000 us carrier, 2250 us low
waveform_repeat_1st = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 9000 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
waveform_repeat_2nd = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 2250 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
//repeat signal second part, 560 us carrier, 99190 us low(110 ms - 9000us - 2250us - 560us = 99190 us)
waveform_repeat_3rd = pwm_config_dma_fifo_waveform(1, PWM0_PULSE_NORMAL, 560 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
waveform_repeat_4th = pwm_config_dma_fifo_waveform(0, PWM0_PULSE_NORMAL, 99190 * CLOCK_SYS_CLOCK_1US/PWM_CARRIER_CYCLE_TICK);
//add fifo stop irq, when all waveform send over, this irq will triggers
//enable system irq PWM
reg_irq_mask |= FLD_IRQ_SW_PWM_EN;
//enable pwm0 fifo stop 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;
ir_send_ctrl.last_cmd = 0xff; //must
}
void ir_send_specil (u16 freq, u8 cycle)
{
u32 max_tick,cmp_tick;
u8 length;
printf("ir_send_specil\r\n");
printf("cycle=%x\r\n",cycle);
printf("freq=%x\r\n",freq);
max_tick = CLOCK_SYS_CLOCK_HZ/freq;
cmp_tick = cycle*max_tick/100;
pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ);
pwm_n_revert(PWM0_ID); //if use PWMx_N, user must set "pwm_n_revert" before gpio_set_func(pwmx_N).
gpio_set_func(GPIO_PB3,AS_PWM0_N );
pwm_set_mode(PWM0_ID, PWM_IR_DMA_FIFO_MODE);
pwm_set_cycle_and_duty(PWM0_ID, max_tick, cmp_tick);
length = T_dmaData_buf.data_num*2;
printf("length=%x\r\n",length);
unsigned char* buff = (unsigned char *)&T_dmaData_buf;
buff[0]= length&0xff;
buff[1]= (length>>8)&0xff;
buff[2]= (length>>16)&0xff;
buff[3]= (length>>24)&0xff;
printf("T_dmaData_buf=\r\n");
for(u8 i=0;i<T_dmaData_buf.data_num;i++)
printf(" %x",T_dmaData_buf.data[i]);
pwm_set_dma_address(&T_dmaData_buf);
//enable pwm0 ir dma fifo done irq
reg_pwm_irq_mask |= FLD_IRQ_PWM0_IR_DMA_FIFO_DONE;
reg_irq_mask |= FLD_IRQ_SW_PWM_EN;
//irq_enable();
ir_send_ctrl.is_sending = IR_SENDING_DATA;
pwm_start_dma_ir_sending();
ir_send_ctrl.last_cmd = 0xff; //must
}
#endif