📄 irframer.c
字号:
{
#ifdef __PRODUCTION_RELEASE__
ASSERT(0);
#else
irda_drop_frame++;
IR_Freebuf(rx_lap_frame);
rx_lap_frame=0;
#endif
}
}
/*************************************************************************
* FUNCTION
* IRDA_SetBof
*
* DESCRIPTION
* This function is used to set # of bof
*
* PARAMETERS
* kal_uint8 frame_index
*
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
void IRDA_SetBof(kal_uint8 num_of_bof)
{
set_bof_flag=1;
/*only 7 bits, maximum=127*/
if(num_of_bof>127)
num_of_bof=127;
irda_addtional_bof=num_of_bof&IR_BOFS_MASK;
}
/*************************************************************************
* FUNCTION
* IRDA_SetBof
*
* DESCRIPTION
* This function is used to set irda baudrate
*
* PARAMETERS
* kal_uint32 baudrate
*
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
void IR_SetBaudRate(kal_uint32 baudrate)
{
kal_uint32 tmp_div;
kal_uint16 divisor;
kal_uint32 remainder;
kal_uint16 data=0;
/* Set BaudRate */
tmp_div = (IrClock)/(16*baudrate);
divisor = (kal_uint16)tmp_div;
remainder = (IrClock)%(16*baudrate);
if (remainder >= (8*baudrate))
{
divisor = (kal_uint16)(tmp_div+1);
}
else
{
divisor = (kal_uint16)tmp_div;
}
DRV_WriteReg(IR_DIV,divisor);
#if defined(MT6228)||defined(MT6229) || defined(MT6230)
/*reset as SIR*/
if(baudrate==4000000)
{
Ir_switch_to_fir();
DRV_WriteReg(IR_MODE,2);/*0=SIR, 1=MIR, 2=FIR*/
/*HW 6228/6229 ECO to cover Vishay transicver*/
data=DRV_Reg(IR_RATE_FIX);
data&=~(IR_TX_MIR576_ENABLE);
DRV_WriteReg(IR_RATE_FIX,data);/*0=SIR, 1=MIR, 2=FIR*/
}
else if(baudrate==1152000)
{
Ir_switch_to_mir();
DRV_WriteReg(IR_MODE,5);/*0=SIR, 1=MIR, 2=FIR*/
/*HW 6228/6229 ECO to cover Vishay transicver*/
data=DRV_Reg(IR_RATE_FIX);
data&=~(IR_TX_MIR576_ENABLE);
DRV_WriteReg(IR_RATE_FIX,data);/*0=SIR, 1=MIR, 2=FIR*/
}
else if(baudrate==576000)
{
Ir_switch_to_mir();
DRV_WriteReg(IR_MODE,1);/*0=SIR, 1=MIR, 2=FIR*/
/*HW 6228/6229 ECO to cover Vishay transicver*/
data=DRV_Reg(IR_RATE_FIX);
data|=IR_TX_MIR576_ENABLE;
DRV_WriteReg(IR_RATE_FIX,data);/*0=SIR, 1=MIR, 2=FIR*/
}
else
{
DRV_WriteReg(IR_MODE,0);/*0=SIR, 1=MIR, 2=FIR*/
DRV_WriteReg(IR_RX_EN,IR_RX_EN_DISABLE);
DRV_WriteReg(IR_BUF_CLEAR,IR_BUF_CLEAR_BIT);
Ir_switch_to_sir();
IR_RxEnable();
DRV_WriteReg(IR_BOFS,IR_BOFS_INIVALUE);
if(irda_fir==1||irda_mir==1)
{
irda_fir=0;
irda_mir=0;
}
}
#endif
}
/*************************************************************************
* FUNCTION
* IR_ioctl
*
* DESCRIPTION
* This function is used to set irda baudrate control. To change baudrate when
* finish a frame
*
* PARAMETERS
* kal_uint8 param
* kal_uint32 value
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
void IR_ioctl(kal_uint8 param, kal_uint32 value)
{
if(param == IOCTL_BAUD)
{
set_baudrate = 1;
IrPort.baud = value;
}
}
/*************************************************************************
* FUNCTION
* IR_Write
*
* DESCRIPTION
* This function is used to ask DMA to TX frames
* finish a frame
*
* PARAMETERS
* FBUF *frame
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint32 fir_wait_count=7000;
kal_uint8 irda_test_flag=1;
#ifdef IRDA_DEBUG
kal_uint32 irda_debug=0;
kal_uint32 debug_wait_count=0;
#endif
void IR_wait_min(void);
void IR_Write(FBUF *frame)
{
kal_uint8 * tmpptr;
IRQMask(IRQ_IrDA_CODE);
/*configure addtional bof setting*/
if (set_bof_flag==1)
{
DRV_WriteReg(IR_BOFS, irda_addtional_bof);
set_bof_flag=0;
}
if(irda_fir==1)
{
if(irda_test_flag)
ir_delay(fir_wait_count);
else
//IR_StartMaxTime();
IR_wait_min();
}
#ifdef IRDA_DEBUG
/*debug*/
if(irda_debug==1)
ir_delay(debug_wait_count);
#endif
if(DRV_Reg(IR_TX_EN))/*check if tx is busy*/
{
IrBuf_Push(&(IrPort.Tx_Buffer),frame);
}
else
{
/*Run DMA channel functions*/
PreBuffer = (FBUF *)frame;
tmpptr=(kal_uint8*)frame+FBUF_HEAD;
Ir_DMA_TxInit((kal_uint32)tmpptr,frame->size);
}
IRQUnmask(IRQ_IrDA_CODE);
}
/*************************************************************************
* FUNCTION
* IR_SW_Init
*
* DESCRIPTION
* This function is used to intialize global variable
*
*
* PARAMETERS
* None
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
void IR_SW_Init(void)
{
set_baudrate=0;
set_bof_flag=0;
irda_addtional_bof=0;
PreBuffer=NULL;
rx_lap_frame=NULL;
IR_timer_owner=0xff;
irda_fir=0;
irda_mir=0;
irda_frame1_error=KAL_FALSE;
ir_crc_detect=KAL_FALSE;
}
/*************************************************************************
* FUNCTION
* IR_Init
*
* DESCRIPTION
* This function is used to intialize IRDA HW
*
*
* PARAMETERS
* kal_uint32 baud
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
void IR_Init(kal_uint32 baud)
{
extern kal_uint8 irda_get_mode_gpio(void);
extern const irda_customize_function_struct *irda_GetFunc(void);
#if (defined(MT6219))||defined(MT6226M)||defined(MT6228)||defined(MT6229) || defined(MT6230)||defined(MT6226)||defined(MT6227)
DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_IRDA,PDN_IRDA);
#endif
irda_custom_ptr=( irda_customize_function_struct *)irda_GetFunc();
IrPort.baud = baud;
/*Clear HW FIFO*/
/*tricky, make sure SIR mode*/
#if defined(MT6228)||defined(MT6229) || defined(MT6230)
if((DRV_Reg(IR_MODE)&0x7)==0)
#endif
IR_ClearFIFO();
/*set up IrFramer in Rx state*/
IR_RxEnable();
/*Set up maxmum data size*/
DRV_WriteReg(IR_RX_FRAME_MAX,IRMAXDATASIZE);
/*Set up baud rate*/
IR_SetBaudRate(baud);
/*Set up the no. of BOFS*/
DRV_WriteReg(IR_BOFS,IR_BOFS_INIVALUE);
/*DMA mode*/
/*DMA initialize*/
Ir_DMA_Initialize();
/*Initialize the Interrupt*/
DRV_WriteReg(IR_IRQ_ENABLE,IR_IRQ_ENABLE_DMANORMAL);
DRV_WriteReg(IR_INTTRIGGER,IR_INTTRIGGER_NORMAL);
if(IrClock==52000000)
{
#if defined(MT6219)||defined(MT6226M)||defined(MT6218B)||defined(MT6217)||defined(MT6226)||defined(MT6227)
DRV_WriteReg(IR_RATE,1);//0=26MHZ, 1=52MHZ, 2=13MHZ
#else/*6228, 6229*/
DRV_WriteReg(IR_RATE,5);//0=26MHZ, 1=52MHZ, 2=13MHZ
#endif
}
else if (IrClock==26000000)
DRV_WriteReg(IR_RATE,0);//0=26MHZ, 1=52MHZ, 2=13MHZ
else if (IrClock==13000000)
DRV_WriteReg(IR_RATE,2);//0=26MHZ, 1=52MHZ, 2=13MHZ
IrBuf_init(&(IrPort.Tx_Buffer),(kal_uint32 *)(IrPort.trxptr),(kal_uint16)IrRingBufferLength);
if (IrPort.hisr == NULL)
{
IrPort.hisr = kal_create_hisr("IRDA_HISR",1,1024,IR_HISR,NULL);
//IrPort.hisr=(void*)0x1234;
//DRV_Register_HISR(DRV_IRDA_HISR_ID, IR_HISR);
}
IRQ_Register_LISR(IRQ_IrDA_CODE, IR_LISR, "IRDA");
IRQSensitivity(IRQ_IrDA_CODE,LEVEL_SENSITIVE);
IRQUnmask(IRQ_IrDA_CODE);
/*make sure IRDA is power off*/
DRV_WriteReg(IR_TRANSCEIVER_PDN,IR_POWER_OFF);
#if defined(MT6219)||defined(MT6226M)||defined(MT6228)||defined(MT6229) || defined(MT6230)||defined(MT6226)||defined(MT6227)
DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_IRDA,PDN_IRDA);
#endif
irda_mode_gpio=irda_get_mode_gpio();
#ifdef DCM_ENABLE
irda_dcm_handle=DCM_GetHandle();
#endif
/*for debug*/
#if 0
/* under construction !*/
/* under construction !*/
#endif
}
void IR_Receive(void)
{
while(1);
}
void IR_Transmit(void)
{
while(1);
}
/*tricky: use Dma size = real_size+1*/
/*************************************************************************
* FUNCTION
* IR_FrameTxDone
*
* DESCRIPTION
* This function is called when finishing transmit a frame
*
*
* PARAMETERS
* None
* RETURNS
* None
* GLOBALS AFFECTED
*
*************************************************************************/
void IR_FrameTxDone(void)
{
kal_uint32 frame_addr;
FBUF *frame;
kal_uint8 *tmpptr;
if (set_baudrate == 1)
{
IR_SetBaudRate(IrPort.baud);
set_baudrate = 0;
if(IrPort.baud==4000000&&irda_fir==0)
{
irda_fir=1;
DRV_WriteReg(IR_BOFS, 0);
}
if((IrPort.baud==1152000||IrPort.baud==576000)&&irda_mir==0)
{
irda_mir=1;
DRV_WriteReg(IR_BOFS, 0x7f);
}
}
if (PreBuffer != NULL)
{
tmpptr=(kal_uint8*)PreBuffer+FBUF_HEAD;
if((tmpptr[1]&0x01)!=0)/*I field*/
{
if(PreBuffer->stat==B_ALLOC)/*if disconnect happened, the buf had*/
IR_Freebuf(PreBuffer); /*been freed */
}
}
if (IrPort.Tx_Buffer.Read != IrPort.Tx_Buffer.Write)
{
if(!DMA_CheckRunStat(irda_tx_dmaport))
{
IrBuf_Pop(&(IrPort.Tx_Buffer),frame_addr);
PreBuffer = (FBUF *)frame_addr;
frame = (FBUF *)frame_addr;
tmpptr=(kal_uint8*)frame+FBUF_HEAD;
/*Run DMA channel functions*/
Ir_DMA_TxInit((kal_uint32)tmpptr,frame->size);
}
}
else
{
PreBuffer = NULL;
Ir_DMA_RxInit((kal_uint32)IrPort.rxdata_buffer[IrPort.rxdata_index],IRMAXDATASIZE);
}
}
/*************************************************************************
* FUNCTION
* Reset_Baudrate
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -