📄 msir.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// File name: msIR.c
// Version: 1.0
// Date: 2006/8/24
//
// Author: Antony
// Company: MStarSemi Inc.
//
// Description: MStar IR device control functions
//
///////////////////////////////////////////////////////////////////////////////
#define MS_IR_C
/******************************************************************************/
/* Header Files */
/* ****************************************************************************/
#include "datatype.h"
#include "hwreg.h"
#include "sysinfo.h"
#include "drvGlobal.h"
#include "drvuart.h"
#include "drvtimer.h"
#include <stdio.h>
#include <string.h>
#include "mreg51.h"
#include "MsIR.h"
#if (IR_MODE_SEL == IR_TYPE_FULLDECODE_MODE)
#define IR_NEC_INTERVAL 108 // shjang_070108
#define IR_NEC_TIMEOUT 120 // shjang_070111
static U8 u8RepeatCount;
static U32 gIRTimeCount = 0; // shjang_070106
U32 gIRTimeOutCount = 0; // shjang_070112
U8 u8IRTimerBlockstatus; // shjang_070106
#elif (IR_MODE_SEL == IR_TYPE_RAWDATA_MODE)
static U8 u8IRRawModeDone;
static U8 u8IRRawModeCount;
static U8 u8IRRawModeBuf[IR_RAW_DATA_NUM];
#elif (IR_MODE_SEL == IR_TYPE_SWDECODE_MODE)
#if 1
#define IRPRINT(a) //a
#define IRCHAR(a) //putchar(a)
//#define HEADER_UPPER_BOND 0x1400
//#define HEADER_LOWER_BOND 0x1300
#define IR_SW_REPEAT_TIMEOUT 110//110ms
#define IR_REPEAT_SKIP_COUNT 1
#define IR_CODE (g_ucIrCode[2])
#define IS_TV_LNK_LOADER_START() (g_ucIrCode[0] == 0x7F && g_ucIrCode[1] == 0x5F && g_ucIrCode[2] == 0x3F && g_ucIrCode[3] == 0x1F)
U8 data g_ucIrPulseCntIndex = 0;
//U8 g_bIrHold = 0;
U32 data g_wIrPulseCounter = 0;
U8 data g_ucIrRepeatTimer = 0;
U8 data g_ucIrByteIndex = 0;
U8 data g_ucIrCode[10];
U8 data g_bIrTVLinkLoader = FALSE;
U8 data g_bIrStartReceived = FALSE;
U8 data g_ucIrRepeatSkipCnt = IR_REPEAT_SKIP_COUNT;
U8 data g_bIrDetect = FALSE;//!<IR command detect flag
U8 data g_bIrRepeat = FALSE;//!<IR Repeat code 荐脚 flag
//U8 g_bIrKeypadMenuHold = FALSE; //test
//U8 g_bIrRcMenuHold = FALSE; // test
#else
U32 data gIRKey;
U8 data gIRCount;
#endif
#endif
#define IR_DEBUG(x) //x
//*************************************************************************
//Function name: msIR_ReadByte
//Passing parameter: U16 u16RegIndex: register address
//Return parameter: U8 u8Value: value
//Description: read register value
//*************************************************************************
#if (ROBUST_TEST_ENABLE)
extern U8 RobustBuf[8], RobustIndex;
U8 msIR_ReadByte( U16 u16RegIndex )
{
U8 RetVal, i;
if (u16RegIndex == IR_RPT_FIFOEMPTY)
{
if(RobustIndex == 0)
{
RetVal = 0x02;
}
else
RetVal = 0x00;
}
else if (u16RegIndex == IR_KEY)
{
if(RobustIndex == 0)
{
RetVal = 0xFF;
}
else
{
RetVal = RobustBuf[0];
for(i=0; i<RobustIndex; i++)
{
RobustBuf[i] = RobustBuf[i+1];
}
RobustBuf[RobustIndex--] = 0;
}
}
else
RetVal = XBYTE[u16RegIndex];
return RetVal;
}
#else
U8 msIR_ReadByte( U16 u16RegIndex )
{
return XBYTE[u16RegIndex];
}
#endif
U8 msIR_GetIrKeyData( void )
{
U8 IrKeyData;
IrKeyData=XBYTE[IR_KEY];
XBYTE[IR_FIFO_READ_PULSE]=0x01;
return(IrKeyData);
}
//*************************************************************************
//Function name: msIR_WriteByte
//Passing parameter: U16 u16RegIndex: register address
// U8 u8Value: value
//Return parameter: none
//Description: write 2 register values
//*************************************************************************
void msIR_WriteByte(U16 u16RegIndex, U8 u8Value)
{
XBYTE[u16RegIndex] = u8Value;
}
//*************************************************************************
//Function name: msIR_Write2Byte
//Passing parameter: U16 u16RegIndex: register address
// U16 u16Value: value
//Return parameter: none
//Description: write 2 register values
//*************************************************************************
void msIR_Write2Byte( U16 u16RegIndex, U16 u16Value )
{
XBYTE[u16RegIndex] = LOWBYTE(u16Value);
XBYTE[u16RegIndex + 1] = HIGHBYTE(u16Value);
}
//*************************************************************************
//Function name: msIR_Write3Byte
//Passing parameter: U16 u16Regndex: register address
// U32 u32Value: value
//Return parameter: none
//Description: write 3 register values
//*************************************************************************
void msIR_Write3Byte( U16 u16Regndex, U32 u32Value )
{
XBYTE[u16Regndex] = VARBYTE(u32Value, 3);
XBYTE[u16Regndex + 1] = VARBYTE(u32Value, 2);
XBYTE[u16Regndex + 2] = VARBYTE(u32Value, 1);
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
void msIR_Set_HighSpeed_Parameter(void)
{
IR_DEBUG(printf("IR High Speed Init\n"));
// header code upper bound
msIR_Write2Byte(IR_HDC_UPB_L, IR_HDC_UPB);
// header code lower bound
msIR_Write2Byte(IR_HDC_LOB_L, IR_HDC_LOB);
// off code upper bound
msIR_Write2Byte(IR_OFC_UPB_L, IR_OFC_UPB);
// off code lower bound
msIR_Write2Byte(IR_OFC_LOB_L, IR_OFC_LOB);
// off code repeat upper bound
msIR_Write2Byte(IR_OFC_RP_UPB_L, IR_OFC_RP_UPB);
// off code repeat lower bound
msIR_Write2Byte(IR_OFC_RP_LOB_L, IR_OFC_RP_LOB);
// logical 0/1 high upper bound
msIR_Write2Byte(IR_LG01H_UPB_L, IR_LG01H_UPB);
// logical 0/1 high lower bound
msIR_Write2Byte(IR_LG01H_LOB_L, IR_LG01H_LOB);
// logical 0 upper bound
msIR_Write2Byte(IR_LG0_UPB_L, IR_LG0_UPB);
// logical 0 lower bound
msIR_Write2Byte(IR_LG0_LOB_L, IR_LG0_LOB);
// logical 1 upper bound
msIR_Write2Byte(IR_LG1_UPB_L, IR_LG1_UPB);
// logical 1 lower bound
msIR_Write2Byte(IR_LG1_LOB_L, IR_LG1_LOB);
// Ir timerout counter
msIR_Write3Byte(IR_TIMEOUT_CYC_0, IR_RP_TIMEOUT);
msIR_WriteByte(IR_CKDIV_NUM_REG, IR_CKDIV_NUM);
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
void msIR_Set_LowSpeed_Parameter(void)
{
IR_DEBUG(printf("IR low Speed Init\n"));
// header code upper bound
msIR_Write2Byte(IR_HDC_UPB_L, IR_HDC_UPB_BOOT);
// header code lower bound
msIR_Write2Byte(IR_HDC_LOB_L, IR_HDC_LOB_BOOT);
// off code upper bound
msIR_Write2Byte(IR_OFC_UPB_L, IR_OFC_UPB_BOOT);
// off code lower bound
msIR_Write2Byte(IR_OFC_LOB_L, IR_OFC_LOB_BOOT);
// off code repeat upper bound
msIR_Write2Byte(IR_OFC_RP_UPB_L, IR_OFC_RP_UPB_BOOT);
// off code repeat lower bound
msIR_Write2Byte(IR_OFC_RP_LOB_L, IR_OFC_RP_LOB_BOOT);
// logical 0/1 high upper bound
msIR_Write2Byte(IR_LG01H_UPB_L, IR_LG01H_UPB_BOOT);
// logical 0/1 high lower bound
msIR_Write2Byte(IR_LG01H_LOB_L, IR_LG01H_LOB_BOOT);
// logical 0 upper bound
msIR_Write2Byte(IR_LG0_UPB_L, IR_LG0_UPB_BOOT);
// logical 0 lower bound
msIR_Write2Byte(IR_LG0_LOB_L, IR_LG0_LOB_BOOT);
// logical 1 upper bound
msIR_Write2Byte(IR_LG1_UPB_L, IR_LG1_UPB_BOOT);
// logical 1 lower bound
msIR_Write2Byte(IR_LG1_LOB_L, IR_LG1_LOB_BOOT);
// Ir timerout counter
msIR_Write3Byte(IR_TIMEOUT_CYC_0, IR_RP_TIMEOUT_BOOT);
msIR_WriteByte(IR_CKDIV_NUM_REG, IR_CKDIV_NUM_BOOT);
}
void msIR_Clear_FIFO(void)
{
#if((IR_MODE_SEL==IR_TYPE_RAWDATA_MODE) || (IR_MODE_SEL==IR_TYPE_FULLDECODE_MODE))
U8 i;
for(i=0; i<8; i++)
{
U8 garbage;
if(XBYTE[IR_RPT_FIFOEMPTY] & 0x2)
break;
garbage = msIR_GetIrKeyData();
garbage = XBYTE[IR_RPT_FIFOEMPTY];
}
#endif
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
void msIR_Initialize(U8 irclk_mhz)
{
//add by Jason071031 for RC5
#if(IR_MODE_SEL == IR_TYPE_RC5_MODE)
// initialize variables
irclk_mhz = irclk_mhz;
g_wIRCounter = 0;
g_ucIRCountSkip = 0;
g_ucLongFlag = 0;
g_RC5Data = _BIT0;
g_ucIRBitsCnt = _BIT13;
g_bIRSWDone = 0;
g_ReadyForRepeat = 1;
g_RC5RepeatTimer = 0;
//setup IR RC5 register
msIR_WriteByte(IR_ENABLE, 0x80); // enable control
msIR_WriteByte(IR_CTRL, 0x80); // invert ir signal
msIR_WriteByte(IR_CHECK, 0X01); // enable timerout
msIR_WriteByte(IR_FIFO_CTRL, 0x30); // both PSHOT and NSHOT edge detect for counter
msIR_WriteByte(IR_GLHRM_NUM_H, 0x1D); // SW mode and enable Glitch remove set the
msIR_WriteByte(IR_GLHRM_NUM_L, 0x97); // xtal=14.318Mhz. 100000ns/(1/14.318Mhz)=100000ns/69.84ns=1431=H597 =>set IR_GLHRM_NUM_H[2:0]=5, IR_GLHRM_NUM_L[7:0]=97
msIR_WriteByte(IR_CKDIV_NUM_REG, 0x0D);
#else
// initialize variables
#if (IR_MODE_SEL == IR_TYPE_FULLDECODE_MODE)
u8RepeatCount = 0;
u8IRTimerBlockstatus = 0; // shjang_070106
gIRTimeOutCount = 0;
#elif(IR_MODE_SEL == IR_TYPE_RAWDATA_MODE)
u8IRRawModeDone = 0;
u8IRRawModeCount = 0;
#elif(IR_MODE_SEL == IR_TYPE_SWDECODE_MODE)
#endif
#if (ROBUST_TEST_ENABLE)
memset(RobustBuf, 0x00, sizeof(RobustBuf));
RobustIndex = 0;
ES = 1;
#endif
msIR_WriteByte(IR_ENABLE, 0x80); // enable control
msIR_WriteByte(IR_CTRL, IR_LEADER_CODE_CHECKING_OPTION); // enable control
msIR_WriteByte(IR_CHECK, 0X01); // enable timerout
#define msIR_GetCnt(time, tolerance) \
((time) * (100UL + (tolerance)) * (irclk_mhz) / ((irclk_mhz) + 1) / 100)
#if(IR_MODE_SEL==IR_TYPE_FULLDECODE_MODE)
// header code upper bound
msIR_Write2Byte(IR_HDC_UPB_L, msIR_GetCnt(IR_HEADER_CODE_TIME, IR_HEADER_CODE_TIME_UB));
// header code lower bound
msIR_Write2Byte(IR_HDC_LOB_L, msIR_GetCnt(IR_HEADER_CODE_TIME, IR_HEADER_CODE_TIME_LB));
// off code upper bound
msIR_Write2Byte(IR_OFC_UPB_L, msIR_GetCnt(IR_OFF_CODE_TIME, IR_OFF_CODE_TIME_UB));
// off code lower bound
msIR_Write2Byte(IR_OFC_LOB_L, msIR_GetCnt(IR_OFF_CODE_TIME, IR_OFF_CODE_TIME_LB));
// off code repeat upper bound
msIR_Write2Byte(IR_OFC_RP_UPB_L, msIR_GetCnt(IR_OFF_CODE_RP_TIME, IR_OFF_CODE_RP_TIME_UB));
// off code repeat lower bound
msIR_Write2Byte(IR_OFC_RP_LOB_L, msIR_GetCnt(IR_OFF_CODE_RP_TIME, IR_OFF_CODE_RP_TIME_LB));
// logical 0/1 high upper bound
msIR_Write2Byte(IR_LG01H_UPB_L, msIR_GetCnt(IR_LOGI_01H_TIME, IR_LOGI_01H_TIME_UB));
// logical 0/1 high lower bound
msIR_Write2Byte(IR_LG01H_LOB_L, msIR_GetCnt(IR_LOGI_01H_TIME, IR_LOGI_01H_TIME_LB));
// logical 0 upper bound
msIR_Write2Byte(IR_LG0_UPB_L, msIR_GetCnt(IR_LOGI_0_TIME, IR_LOGI_0_TIME_UB));
// logical 0 lower bound
msIR_Write2Byte(IR_LG0_LOB_L, msIR_GetCnt(IR_LOGI_0_TIME, IR_LOGI_0_TIME_LB));
// logical 1 upper bound
msIR_Write2Byte(IR_LG1_UPB_L, msIR_GetCnt(IR_LOGI_1_TIME, IR_LOGI_1_TIME_UB));
// logical 1 lower bound
msIR_Write2Byte(IR_LG1_LOB_L, msIR_GetCnt(IR_LOGI_1_TIME, IR_LOGI_1_TIME_LB));
// Ir timerout counter
msIR_Write3Byte(IR_TIMEOUT_CYC_0, msIR_GetCnt(IR_TIMEOUT_CYC, 0) + 0x300000UL);
msIR_WriteByte(IR_CKDIV_NUM_REG, irclk_mhz);
#endif
msIR_WriteByte(IR_CCODE_L, IR_HEADER_CODE0);
msIR_WriteByte(IR_CCODE_H, IR_HEADER_CODE1);
msIR_WriteByte(IR_CODEBYTE, 0x14); //ir cc code byte enable,ir_code byte = 4
msIR_WriteByte(IR_GLHRM_NUM_L, 0x04); // GLHRM number[7:0]
#if(IR_MODE_SEL == IR_TYPE_FULLDECODE_MODE)
msIR_WriteByte(IR_FIFO_CTRL, 0x0F); // {2'b0,IR_SHOT_SEL[1:0],IR_FIFO_FULL_EN,FIFO_DEPTH[2:0]}
msIR_WriteByte(IR_GLHRM_NUM_H, 0x38); // {IR_DECOMODE[1:0], GLHRM_EN,GLHRM_NUM[10:8]}
#elif(IR_MODE_SEL == IR_TYPE_RAWDATA_MODE)
msIR_WriteByte(IR_FIFO_CTRL, 0x0F); // {2'b0,IR_SHOT_SEL[1:0],IR_FIFO_FULL_EN,FIFO_DEPTH[2:0]}
msIR_WriteByte(IR_GLHRM_NUM_H, 0x28); // {IR_DECOMODE[1:0], GLHRM_EN,GLHRM_NUM[10:8]}
#elif(IR_MODE_SEL == IR_TYPE_SWDECODE_MODE)
msIR_WriteByte(IR_FIFO_CTRL, 0x2F); // Only NSHOT edge detect for counter
msIR_WriteByte(IR_GLHRM_NUM_H, 0x18);
#endif
printf("\r\n *** Init IR done ***\r\n"); // kevin test
#endif//add by Jason071031 end of (IR_MODE_SEL == IR_TYPE_RC5_MODE)
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
void msIR_PowerDown_Init(void)
{
//add by Jason071031 for RC5
#if(IR_MODE_SEL == IR_TYPE_RC5_MODE)
msIR_Initialize(MST_XTAL_CLOCK_MHZ);
#else
IR_DEBUG(printf("IR Power down Init\n"));
msIR_Initialize(MST_XTAL_CLOCK_MHZ);
// header code upper bound
msIR_Write2Byte(IR_HDC_UPB_L, PM_IR_HDC_UPB_BOOT);
// header code lower bound
msIR_Write2Byte(IR_HDC_LOB_L, PM_IR_HDC_LOB_BOOT);
#endif//add by Jason071031 end of (IR_MODE_SEL == IR_TYPE_RC5_MODE)
}
/******************************************************************************/
/// IR get key value and repeat flag
/// @param pkey \b IN return the key value
/// @param pu8flag \b IN return the repeat flag(1:Repeat)
/******************************************************************************/
BOOLEAN msIR_GetIRKeyCode(U8 *pkey, U8 *pu8flag)
{
//add by Jason071031 for RC5
#if (IR_MODE_SEL == IR_TYPE_RC5_MODE )
if(g_RC5RepeatTimer!=0)
if((--g_RC5RepeatTimer)==0)
g_ReadyForRepeat = 1;
#endif
//printf("g_RC5RepeatTimer:%bx\n", g_RC5RepeatTimer);
#if (IR_MODE_SEL == IR_TYPE_RC5_MODE)
if(g_bIRSWDone)
{
*pu8flag=0;
*pkey =0xff;
*pkey = (BYTE)(g_RC5Data & 0x003F);
/*
if((BYTE)((g_RC5Data & 0x07C0)>>6) == IR_RC5_ADDR1 || (BYTE)((g_RC5Data & 0x07C0)>>6) == IR_RC5_ADDR2)
{
if((BYTE)((g_RC5Data & 0x07C0)>>6) == IR_RC5_ADDR1)
*pkey |= _BIT7;
g_bIrDetect = 1;
}
*/
g_RC5RepeatTimer = RC5_REPEAT_DELAY;
RC5Reset();
return MSRET_OK;
}
return MSRET_ERROR;
//end by Jason071031
#elif (IR_MODE_SEL == IR_TYPE_FULLDECODE_MODE)
U8 i, j;
// shjang_070106 ================================================
*pkey = 0xff;
*pu8flag = 0;
//printf("IR KEY: %bd\n", msIR_GetIrKeyData());
// shjang_070112 ===========================================
// 付瘤阜 ir 涝仿阑 罐篮饶 IR_NEC_TIMEOUT 悼救 虐 涝仿捞 绝栏搁 IR BUFFER甫 檬扁拳 矫糯.
if ((MDrv_Timer_TimeDifference(MDrv_Timer_GetTime0(), gIRTimeOutCount) >= IR_NEC_TIMEOUT) &&
(gIRTimeOutCount != 0xffffffff))
{
gIRTimeOutCount = 0xffffffff;
msIR_Clear_FIFO();
return MSRET_ERROR;
}
//===========================================================
if (MDrv_Timer_TimeDifference(MDrv_Timer_GetTime0(), gIRTimeCount) >= IR_NEC_INTERVAL)
{
u8IRTimerBlockstatus = 0;
gIRTimeCount = MDrv_Timer_GetTime0();
}
else
{
u8IRTimerBlockstatus = 0xff;
return MSRET_ERROR;
}
//================================================================
for(j=0; j<IR_FILTER_REPEAT_NUM; j++)
{
if((msIR_ReadByte(IR_RPT_FIFOEMPTY) & 0x2))
{
return MSRET_ERROR;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -