📄 saa7114.c
字号:
saa7114GetSaturationM(pboardVIDec_t pVD, UInt * val)
{
return iicReadReg(pVD->slaveAddr, ChromaSaturation, val);
}
extern tmLibdevErr_t
saa7114GetSaturation(UInt * val)
{
return saa7114GetSaturationM(&defaultVD[0], val);
}
/******************************************************************************/
extern tmLibdevErr_t
saa7114SetSaturationM(pboardVIDec_t pVD, UInt val)
{
if (val > 127)
return BOARD_ERR_VAL_OUT_OF_RANGE;
return iicWriteReg(pVD->slaveAddr, ChromaSaturation, val);
}
extern tmLibdevErr_t
saa7114SetSaturation(UInt val)
{
return saa7114SetSaturationM(&defaultVD[0], val);
}
/******************************************************************************/
extern tmLibdevErr_t
saa7114GetHueM(pboardVIDec_t pVD, UInt * val)
{
return iicReadReg(pVD->slaveAddr, ChromaHueControl, val);
}
extern tmLibdevErr_t
saa7114GetHue(UInt * val)
{
return saa7114GetHueM(&defaultVD[0], val);
}
/******************************************************************************/
extern tmLibdevErr_t
saa7114SetHueM(pboardVIDec_t pVD, UInt val)
{
if (val > 255)
return BOARD_ERR_VAL_OUT_OF_RANGE;
return iicWriteReg(pVD->slaveAddr, ChromaHueControl, val);
}
extern tmLibdevErr_t
saa7114SetHue(UInt val)
{
return saa7114SetHueM(&defaultVD[0], val);
}
/******************************************************************************/
/* Helper functions for video decoder HAL functionality */
static Bool /* Successful or not */
SetReg( /* Set a register value */
pboardVIDec_t pVD, /* Pointer to I2C access structure */
UInt8 bReg, /* Subaddress of the register */
UInt8 bData) /* Value to be written */
{
lastI2cError = 0;
return ((lastI2cError = iicWriteReg(pVD->slaveAddr, bReg, bData)) == TMLIBDEV_OK);
}
static Bool /* Successful or not */
GetReg( /* Get a register value */
pboardVIDec_t pVD, /* Pointer to I2C access structure */
UInt8 bReg, /* Subaddress of the register */
UInt8 * pbData) /* Pointer to variable to recieve value */
{
UInt data;
Bool retVal;
lastI2cError = 0;
if (retVal = ((lastI2cError = iicReadReg (pVD->slaveAddr, bReg, &data)) == TMLIBDEV_OK))
*pbData = data;
else
*pbData = 0;
return retVal;
}
/********************************************************************************************/
extern tmLibdevErr_t
saa7114GetVSyncFallingEdge(pboardVIDec_t pVD, UInt *lineNumber)
{
/* Equivalent to Video DecHAL VideoDecGetDefaultAcquisitionWnd */
switch (pVD->curVideoStandard)
{
case vasNTSC:
/* First line seen by TM */
*lineNumber = 20;
break;
case vasPAL:
*lineNumber = 23;
break;
default:
return BOARD_ERR_COLOR_STANDARD_NOT_DETECTED;
}
return TMLIBDEV_OK;
}
/* Get a byte number index from planar buffer */
static UInt8 GetDataByte(UInt8 *Y, UInt8 *U, UInt8 *V, UInt8 index)
{
if (index & 0x1)
return Y [index >> 1];
else if (index & 0x2)
return V [index >> 2];
else
return U [index >> 2];
}
extern tmLibdevErr_t
saa7114GetSlicedData(pboardVIDec_t pVD, UInt8 *Y, UInt8 *U, UInt8 *V, tmVideoDataService_t service,
UInt size, UInt8 *data, UInt8 *dataSize)
{
UInt index = 0;
UInt bytesToFind;
UInt byteNr;
/* - Search video buffer for sliced data */
/* - Extract and copy sliced data from planar buffers into output buffer */
/* - Code not optimized for performance */
/* Assume no data will be found */
*dataSize = 0;
/* First implementation does support Closed Caption, only */
switch (service)
{
case vdsUSClosedCaption:
case vdsEuroClosedCaption:
bytesToFind = 2;
break;
case vdsVPS:
case vdsJapFormatSwitch:
bytesToFind = 26;
break;
case vdsWSS:
bytesToFind = 14;
break;
case vdsTeleText:
case vdsEuroTeleText:
bytesToFind = 42;
break;
case vdsUSNABTS:
bytesToFind = 33;
break;
case vdsUSTeleText:
bytesToFind = 34;
break;
case vdsVITC_EBU:
case vdsVITC_SMPTE:
bytesToFind = 11;
break;
case vdsMoji:
bytesToFind = 35;
break;
default:
/* Not supported, yet */
return BOARD_ERR_VAL_OUT_OF_RANGE;
}
/* Search for data header 0x53 */
while (GetDataByte(Y, U, V, index++) != 0x53)
if (index > size)
return TMLIBDEV_OK;
/* Skip next three bytes */
index += 3;
/* Find up to maximum number of data bytes */
for (byteNr = 0; byteNr < bytesToFind; byteNr++)
{
UInt8 nibble1;
UInt8 nibble2;
/* Skip zeroes in data stream */
while ((nibble1 = GetDataByte(Y, U, V, index++)) == 0)
if (index > size)
return TMLIBDEV_OK;
while ((nibble2 = GetDataByte(Y, U, V, index++)) == 0)
if (index > size)
return TMLIBDEV_OK;
data [byteNr] = (nibble1 >> 2) & 0xF;
data [byteNr] |= ((nibble2 << 2) & 0xF0);
*dataSize = byteNr + 1;
}
return TMLIBDEV_OK;
}
extern tmLibdevErr_t
saa7114GetStatus(pboardVIDec_t pVD, tmVideoStatusType_t type, UInt *pState)
{
/* Equivalent to Video DecHAL VideoDecGetStatus */
UInt8 ucStatus;
UInt8 ucValue;
switch (type)
{
case vstLocked: /* HIGH unlocked, LOW locked */
if(!GetReg(pVD, CompatibilityControl, &ucValue)) /* Set OLDSB=1 */
return IIC_ERR_TIMEOUT;
SetReg(pVD, CompatibilityControl, ucValue & ~0x04 | 0x04);
GetReg(pVD, StatusByte, &ucStatus);
*pState = (ucStatus & 0x40) ? False : True;
break;
case vstReady: /* HIGH locked, LOW unlocked */
if(!GetReg(pVD, CompatibilityControl, &ucValue)) /* Set OLDSB=0 */
return IIC_ERR_TIMEOUT;
SetReg(pVD, CompatibilityControl, ucValue & ~0x04 | 0x00);
GetReg(pVD, StatusByte, &ucStatus);
*pState = (ucStatus & 0x01) ? True : False;
break;
case vstSyncLock: /* HIGH unlocked, LOW locked */
if(!GetReg(pVD, CompatibilityControl, &ucValue)) /* Set OLDSB=0 */
return IIC_ERR_TIMEOUT;
SetReg(pVD, CompatibilityControl, ucValue & ~0x04 | 0x00);
GetReg(pVD, StatusByte, &ucStatus);
*pState = (ucStatus & 0x40) ? False : True;
break;
case vstCopy: /* HIGH copy protected, */
/* LOW not copy protected */
if(!GetReg(pVD, CompatibilityControl, &ucValue)) /* Set OLDSB=0 */
return IIC_ERR_TIMEOUT;
SetReg(pVD, CompatibilityControl, ucValue & ~0x04 | 0x00);
GetReg(pVD, StatusByte, &ucStatus);
*pState = (ucStatus & 0x02) ? True : False;
break;
case vstColorSignal: /* HIGH color, LOW no color */
if(!GetReg(pVD, CompatibilityControl, &ucValue)) /* Set OLDSB=1 */
return IIC_ERR_TIMEOUT;
SetReg(pVD, CompatibilityControl, ucValue & ~0x04 | 0x04);
GetReg(pVD, StatusByte, &ucStatus);
*pState = (ucStatus & 0x01) ? True : False;
break;
case vstFrequency: /* HIGH 60Hz, LOW 50Hz */
if(!GetReg(pVD, CompatibilityControl, &ucValue)) /* Set OLDSB=1 */
return IIC_ERR_TIMEOUT;
SetReg(pVD, CompatibilityControl, ucValue & ~0x04 | 0x04);
GetReg(pVD, StatusByte, &ucStatus);
*pState = (ucStatus & 0x20) ? 60 : 50;
break;
case vstPowerUp:
GetReg(pVD, ScalerStatus, &ucStatus);
/* True: Power up OK, False: Power up failed */
*pState = (ucStatus & 0x08) ? True : False;
break;
case vstDataServices:
GetReg(pVD, DR, &ucStatus);
*pState = 0; /* Clear all */
if (ucStatus & 0x08) /* Closed caption found */
*pState |=
(vdsEuroClosedCaption | vdsUSClosedCaption);
if (ucStatus & 0x10) /* Widescreen signal found */
*pState |= vdsWSS;
if (ucStatus & 0x20) /* VPS found */
*pState |= vdsVPS;
if (ucStatus & 0xc0) /* others found */
*pState |= (vdsEuroTeleText |
vdsUSTeleText |
vdsTeleText |
vdsVITC_EBU |
vdsVITC_SMPTE |
vdsUSNABTS |
vdsMoji |
vdsJapFormatSwitch);
break;
case vstFidText:
GetReg(pVD, LN1, &ucStatus);
*pState = (ucStatus & 0x20) ? 2 : 1;
break;
default:
return BOARD_ERR_VAL_OUT_OF_RANGE;
}
return TMLIBDEV_OK;
}
extern tmLibdevErr_t
saa7114GetSupportedDataServices(tmVideoDataService_t fieldOne[], tmVideoDataService_t fieldTwo[], UInt8 tblSize)
{
int i;
/* Write supported data services into arrays */
for (i = 0; i < tblSize; i++)
{
if (i < 2)
{
/* No data slicing allowed in first two lines */
fieldOne [i] = fieldTwo [i] = vdsNone;
}
else
{
/* Allow all kind of data services */
fieldOne [i] = fieldTwo [i] = (tmVideoDataService_t) (vdsEuroTeleText | vdsEuroClosedCaption | vdsVPS | vdsWSS |
vdsUSTeleText | vdsUSClosedCaption | vdsTeleText | vdsVITC_EBU |
vdsVITC_SMPTE | vdsUSNABTS | vdsMoji | vdsJapFormatSwitch);
}
}
return TMLIBDEV_OK;
}
extern tmLibdevErr_t
saa7114SetDataServices(pboardVIDec_t pVD, tmVideoDataService_t fieldOne[], tmVideoDataService_t fieldTwo[], UInt8 tblSize)
{
/* Equivalent to Video DecHAL VideoDecOpenTT */
tmLibdevErr_t nReturn = TMLIBDEV_OK;
int nCount; /* Counter */
int nLoop; /* Counter */
UInt8 ucReg; /* Value to program */
int nProgrammableTextDataType; /* Programmable text data type */
int nAllowedDataTypes;
if (tblSize > 25) /* Check upper bound */
{
tblSize = 25;
}
nProgrammableTextDataType = 0;
nAllowedDataTypes = vdsEuroTeleText | vdsEuroClosedCaption | vdsVPS | vdsWSS |
vdsUSTeleText | vdsUSClosedCaption | vdsTeleText | vdsVITC_EBU |
vdsVITC_SMPTE | vdsUSNABTS | vdsMoji | vdsJapFormatSwitch;
/* Collect all teletext standards to be used */
for (nCount = 0; nCount < tblSize; nCount++)
nProgrammableTextDataType |= (fieldOne[nCount] | fieldTwo[nCount]);
if (nProgrammableTextDataType & ~nAllowedDataTypes)
return BOARD_ERR_VAL_OUT_OF_RANGE; /* Illegal standard requested */
for (nCount = 2; nCount < tblSize; nCount++)
{
ucReg = 0xff; /* Standard value. */
/* Do not acquire. */
for(nLoop = 0; /* Search for programm value. */
(nLoop < MAX_TT) && /* Search odd table */
(Convert7114TT[nLoop].nBitMask != fieldOne[nCount]);
nLoop++);
if (nLoop < MAX_TT) /* Found ! */
ucReg = ucReg & ~0xf0 | (Convert7114TT[nLoop].nNibble << 4);
for(nLoop = 0; /* Search for programm value. */
(nLoop < MAX_TT) && /* Search even table */
(Convert7114TT[nLoop].nBitMask != fieldTwo[nCount]);
nLoop++);
if (nLoop < MAX_TT) /* Found ! */
ucReg = ucReg & ~0x0f | Convert7114TT[nLoop].nNibble;
if (!SetReg(pVD, LCR2 + nCount - 2, ucReg)) /* Check device access */
return (tmLibdevErr_t) lastI2cError;
}
SetReg(pVD, FC, 0); /* Set framing code */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -