📄 adi_adv717x.c
字号:
Result = ADI_DEV_RESULT_SUCCESS;
switch (Command)
{
// CASE (control dataflow)
case (ADI_DEV_CMD_SET_DATAFLOW):
// Cannot switch (video) dataflow on/off when PPI is closed
if (pADV717x->ppiHandle != NULL)
{
// Enable dataflow with ADV717x in non-standard video mode
if ((u8Value) && (pADV717x->adv717x_semaphores.ADV717x_mode))
{
// return error when Frame Sync Count or Frame Line Count is not set
if ((pADV717x->adv717x_semaphores.FSCount == 0) || (pADV717x->PPIFrameLines == 0))
return(ADI_ADV717x_RESULT_FRAME_ERROR); // return error
// is FS1 timer config value set?
if ((pADV717x->PPI_FS1_TMR != NULL) && (pADV717x->adv717x_semaphores.FSCount > 0 ))
if ((Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_1,
(void*)pADV717x->PPI_FS1_TMR )) != ADI_DEV_RESULT_SUCCESS)
return (Result);
else
// return result indicating FS timer registers are not configured
return (ADI_ADV717x_RESULT_TIMING_NOT_CONFIGURED);
// is FS2 timer config value set?
if ((pADV717x->PPI_FS2_TMR != NULL) && (pADV717x->adv717x_semaphores.FSCount > 1 ))
if ((Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_2,
(void*)pADV717x->PPI_FS2_TMR )) != ADI_DEV_RESULT_SUCCESS)
return (Result);
else
// return result indicating FS timer registers are not configured
return (ADI_ADV717x_RESULT_TIMING_NOT_CONFIGURED);
// if triple frame sync flag is set (ADV717x operates in Mode 1/2/3)
// Force 3 frame syncs
if(pADV717x->adv717x_semaphores.TripleFrameSync)
if ((Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_TRIPLE_FRAME_SYNC,
(void*) TRUE )) != ADI_DEV_RESULT_SUCCESS)
return (Result);
}
Result = adi_dev_Control( pADV717x->ppiHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)u8Value );
}
// else check if the client is trying to enable dataflow without opening the PPI
else if (u8Value == TRUE)
{
// can not pass this value to PPI as no valid PPI handle is available
// which means the client hasn't defined the dataflow method yet, return error.
return (ADI_DEV_RESULT_DATAFLOW_UNDEFINED);
}
// save the dataflow status
pADV717x->adv717x_semaphores.dataflow = u8Value;
break;
// CASE (query for processor DMA support)
case (ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT):
// PPI needs DMA but ADV717x doesn't
*((u32 *)Value) = FALSE;
break;
// CASE (Set Dataflow method - applies only for PPI)
case (ADI_DEV_CMD_SET_DATAFLOW_METHOD):
// Check if PPI device to used by ADV717x is already open
if (pADV717x->ppiHandle == NULL)
// if not, try to open the PPI device corresponding to ppiDeviceNumber for ADV717x dataflow
Result = PPI_Open(PDDHandle);
// on occurance of error, return the error code
#ifdef ADI_DEV_DEBUG
if (Result != ADI_DEV_RESULT_SUCCESS) return (Result);
#endif
// Pass the dataflow method to the PPI device allocated to ADV717x
Result = adi_dev_Control( pADV717x->ppiHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void*)Value );
break;
// CASE (Read a specific register from the ADV717x)
case(ADI_DEV_CMD_REGISTER_READ):
// CASE (Configure a specific register in the ADV717x)
case(ADI_DEV_CMD_REGISTER_WRITE):
// CASE (Read a specific field from a single device register)
case(ADI_DEV_CMD_REGISTER_FIELD_READ):
// CASE (Write to a specific field in a single device register)
case(ADI_DEV_CMD_REGISTER_FIELD_WRITE):
// CASE (Read block of ADV717x registers starting from first given address)
case(ADI_DEV_CMD_REGISTER_BLOCK_READ):
// CASE (Write to a block of ADV717x registers starting from first given address)
case(ADI_DEV_CMD_REGISTER_BLOCK_WRITE):
// CASE (Read a table of selective registers in ADV717x)
case(ADI_DEV_CMD_REGISTER_TABLE_READ):
// CASE (Write to a table of selective registers in ADV717x)
case(ADI_DEV_CMD_REGISTER_TABLE_WRITE):
// CASE (Read a table of selective register(s) field(s) in ADV717x)
case(ADI_DEV_CMD_REGISTER_FIELD_TABLE_READ):
// CASE (Write to a table of selective register(s) field(s) in ADV717x)
case(ADI_DEV_CMD_REGISTER_FIELD_TABLE_WRITE):
access_device.ManagerHandle = pADV717x->ManagerHandle; // device manager handle
access_device.ClientHandle = pADV717x; // client handle - passed to the internal 'Device' specific function
access_device.DeviceNumber = pADV717x->twiDeviceNumber; // TWI device number
access_device.DeviceAddress = pADV717x->twiDeviceAddress; // TWI address of ADV717x Device
access_device.DCBHandle = pADV717x->DCBHandle; // handle to the callback manager
access_device.DeviceFunction = DeviceAccessFunction; // Function specific to ADV717x driver passed to the 'Device' access service
access_device.Command = Command; // command ID
access_device.Value = Value; // command specific value
access_device.FinalRegAddr = ADV717x_FINAL_REG_ADDRESS; // Address of the last register in ADV717x
access_device.RegisterField = RegisterField; // table for ADV717x Register Field Error check and Register field access
access_device.ReservedValues = ReservedValues; // table to configure reserved bits in ADV717x to recommended values
access_device.ValidateRegister = ValidateRegister; // table containing reserved and read-only registers in ADV717x
access_device.ConfigTable = pADV717x->twiConfigTable; // TWI configuration table
access_device.SelectAccess = SelectTWIAccess; // Device Access type
access_device.pAdditionalinfo = (void *)NULL; // No Additional info
Result = adi_device_access (&access_device);
break;
// CASE (Configure Subcarrier frequency registers)
case (ADI_ADV717x_CMD_SET_SCF_REG):
// CASE (Read Subcarrier frequency registers)
case (ADI_ADV717x_CMD_GET_SCF_REG):
if (Command == ADI_ADV717x_CMD_SET_SCF_REG)
{
SCFRvalue[0] = u8Value; // SCFR0 value
SCFRvalue[1] = (u8) (u32Value >> 8); // SCFR1 value
SCFRvalue[2] = (u8) (u32Value >> 16); // SCFR2 value
SCFRvalue[3] = (u8) (u32Value >> 24); // SCFR3 value
// perform AD717x register write operation
access_device.Command = ADI_DEV_CMD_REGISTER_BLOCK_WRITE;
}
else
// perform AD717x register read operation
access_device.Command = ADI_DEV_CMD_REGISTER_BLOCK_READ;
accessSCFR.Count = 4; // SCFR length (4 bytes)
accessSCFR.Address = ADV717x_SCFR0; // SCFR0 address
accessSCFR.pData = SCFRvalue; // array holding SCFR value
access_device.ManagerHandle = pADV717x->ManagerHandle; // device manager handle
access_device.ClientHandle = pADV717x; // client handle - passed to the internal 'Device' specific function
access_device.DeviceNumber = pADV717x->twiDeviceNumber; // TWI device number
access_device.DeviceAddress = pADV717x->twiDeviceAddress; // TWI address of ADV717x Device
access_device.DCBHandle = pADV717x->DCBHandle; // handle to the callback manager
access_device.DeviceFunction = DeviceAccessFunction; // Function specific to ADV717x driver passed to the 'Device' access service
access_device.Value = (void *)&accessSCFR; // command specific value
access_device.FinalRegAddr = ADV717x_FINAL_REG_ADDRESS; // Address of the last register in ADV717x
access_device.RegisterField = NULL; // table for ADV717x Register Field Error check and Register field access
access_device.ReservedValues = NULL; // table to configure reserved bits in ADV717x to recommended values
access_device.ValidateRegister = NULL; // table containing reserved and read-only registers in ADV717x
access_device.ConfigTable = pADV717x->twiConfigTable; // TWI configuration table
access_device.SelectAccess = SelectTWIAccess; // Device Access type
access_device.pAdditionalinfo = (void *)NULL; // No Additional info
if ((Result = adi_device_access (&access_device))!= ADI_DEV_RESULT_SUCCESS)
return (Result);
if (Command == ADI_ADV717x_CMD_SET_SCF_REG)
{ // Toggle TMR0 bit 7 to reset the timing registers.
ResetTimingReg.Address = ADV717x_TMR0; // ADV717x_TMR0 address to access
ResetTimingReg.Data = 0; // Clear ADV717x_TMR0 bit 7 (Timing register reset bit)
ResetTimingReg.Field = ADV717x_TIMING_REG_RST; // ADV717x_TMR0 Field to configure (Timing register reset bit)
access_device.Command = ADI_DEV_CMD_REGISTER_FIELD_WRITE; // command ID
access_device.Value = (void *)&ResetTimingReg; // command specific value
access_device.RegisterField = RegisterField; // table for ADV717x Register Field Error check and Register field access
access_device.ReservedValues = ReservedValues; // table to configure reserved bits in ADV717x to recommended values
access_device.ValidateRegister = ValidateRegister; // table containing reserved and read-only registers in ADV717x
access_device.ConfigTable = pADV717x->twiConfigTable; // TWI configuration table
access_device.SelectAccess = SelectTWIAccess; // Device Access type
access_device.pAdditionalinfo = (void *)NULL; // No Additional info
if ((Result = adi_device_access (&access_device))!= ADI_DEV_RESULT_SUCCESS)
return (Result);
ResetTimingReg.Data = 1; // Set the TMR0 bit 7 (Timing register reset bit)
if ((Result = adi_device_access (&access_device))!= ADI_DEV_RESULT_SUCCESS)
return (Result);
ResetTimingReg.Data = 0; // Clear the TMR0 bit 7 (Timing register reset bit)
Result = adi_device_access (&access_device);
// Give some time for encoder to synchronize
for (u32Value=0;u32Value<0xFFFF;u32Value++);
}
else
// update Application program with SCF value
*((u32 *)Value) = ((u32)SCFRvalue[3] << 24) | ((u32)SCFRvalue[2] << 16) | ((u32)SCFRvalue[1] << 8) | ((u32)SCFRvalue[0]);
break;
// CASE (set timer for frame sync 1 (PPI_FS1))
case (ADI_ADV717x_CMD_SET_TIMER_FRAME_SYNC_1):
// Update the PPI FS1 Timer Configuration value
pADV717x->PPI_FS1_TMR = (ADI_PPI_FS_TMR*) Value;
if ((pADV717x->ppiHandle) && (pADV717x->adv717x_semaphores.ADV717x_mode))
Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_1, (void*)pADV717x->PPI_FS1_TMR );
break;
// CASE (set timer for frame sync 2 (PPI_FS2))
case (ADI_ADV717x_CMD_SET_TIMER_FRAME_SYNC_2):
// Update the PPI FS2 Timer Configuration value
pADV717x->PPI_FS2_TMR = (ADI_PPI_FS_TMR*) Value;
if ((pADV717x->ppiHandle) && (pADV717x->adv717x_semaphores.ADV717x_mode))
Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_2, (void*)pADV717x->PPI_FS2_TMR );
break;
// CASE (Set the number of frame syncs to be generated)
case (ADI_ADV717x_CMD_SET_FRAME_SYNC_COUNT):
if (pADV717x->adv717x_semaphores.ADV717x_mode) // Command valid only if ADV717x is in non-standard mode
{
switch ((ADI_ADV717x_FS_COUNT)Value)
{
case ADI_ADV717x_FRAME_COUNT_1: // 1 Frame sync
pADV717x->PPIControl &= ~0x0030; // Clear Port CFG
pADV717x->adv717x_semaphores.FSCount = 1; // 1 Frame Sync
break;
case ADI_ADV717x_FRAME_COUNT_2: // 2 Frame syncs
pADV717x->PPIControl &= ~0x0030; // Clear Port CFG
pADV717x->PPIControl |= 0x0010; // Set Port CFG as 1 (2 or 3 frame syncs)
pADV717x->adv717x_semaphores.FSCount = 2; // 2 Frame Syncs
break;
case ADI_ADV717x_FRAME_COUNT_3_FS1: // 3 Frame Syncs with PPI_FS3 to assertion of PPI_FS1
pADV717x->PPIControl &= ~0x0030; // Clear Port CFG
pADV717x->PPIControl |= 0x0010; // Set Port CFG as 1 (2 or 3 frame syncs)
pADV717x->adv717x_semaphores.TripleFrameSync = 1; // update triple frame sync flag
pADV717x->adv717x_semaphores.FSCount = 3; // 3 Frame Syncs
break;
case ADI_ADV717x_FRAME_COUNT_3_FS2: // 3 Frame Syncs with PPI_FS3 to assertion of PPI_FS2
pADV717x->PPIControl &= ~0x0030; // Clear Port CFG
pADV717x->PPIControl |= 0x0030; // Set Port CFG as 3 (3 Frame Syncs with PPI_FS3 to assertion of PPI_FS2)
pADV717x->adv717x_semaphores.TripleFrameSync = 1; // update triple frame sync flag
pADV717x->adv717x_semaphores.FSCount = 3; // 3 Frame Syncs
break;
default:
return(ADI_ADV717x_RESULT_FRAME_ERROR); // return error
}
if (pADV717x->ppiHandle) // if PPI device is already opened
{
// update the PPI control register
Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_CONTROL_REG, (void*)pADV717x->PPIControl );
if (pADV717x->adv717x_semaphores.TripleFrameSync) // if TripleFrameSync Flag is set
// Force triple frame sync
Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_TRIPLE_FRAME_SYNC, (void*) TRUE ); // Force 3 frame syncs
}
}
else
return(ADI_ADV717x_RESULT_OPERATING_MODE_MISMATCH); // return error
break;
// CASE (Set PPI Frame Lines count)
case (ADI_ADV717x_CMD_SET_FRAME_LINES_COUNT):
if (pADV717x->adv717x_semaphores.ADV717x_mode) // Command valid only if ADV717x is in non-standard mode
// Update the PPI Frame Lines Count
pADV717x->PPIFrameLines = u32Value;
else
return(ADI_ADV717x_RESULT_OPERATING_MODE_MISMATCH); // return error
if (pADV717x->ppiHandle) // if PPI device is already opened
Result = adi_dev_Control( pADV717x->ppiHandle, ADI_PPI_CMD_SET_LINES_PER_FRAME_REG, (void*)pADV717x->PPIFrameLines );
break;
/*************************************
PPI related commands
*************************************/
// CASE (Set PPI Device Number that will be used to send video data to ADV717x)
case (ADI_ADV717x_CMD_SET_PPI_DEVICE_NUMBER):
// Close the present PPI device being used
Result = PPI_Close(PDDHandle);
// Update the PPI device number
pADV717x->ppiDeviceNumber = u8Value;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -