📄 cim_vip.c
字号:
q_word.low = q_word.high = 0;
q_word.high |= (buffer->bist << VIP_MSR_DIAG_BIST_SHIFT) & VIP_MSR_DIAG_BIST_WMASK;
q_word.low |= (buffer->enable_upper ? VIP_MSR_DIAG_MSB_ENABLE : 0x00000000);
q_word.low |= (buffer->select_upper << VIP_MSR_DIAG_SEL_UPPER_SHIFT) & VIP_MSR_DIAG_SEL_UPPER_MASK;
q_word.low |= (buffer->enable_lower ? VIP_MSR_DIAG_LSB_ENABLE : 0x00000000 );
q_word.low |= (buffer->select_lower << VIP_MSR_DIAG_SEL_LOWER_SHIFT) & VIP_MSR_DIAG_SEL_LOWER_MASK;
msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &q_word);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_configure_pages
*
* This routine sets the number of pages, and their offset from each other.
*---------------------------------------------------------------------------*/
int vip_configure_pages (int page_count, unsigned long page_offset)
{
unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
/* SET THE NEW PAGE COUNT */
vip_control2 &= ~VIP_CONTROL2_PAGECNT_MASK;
vip_control2 |= (page_count << VIP_CONTROL2_PAGECNT_SHIFT) & VIP_CONTROL2_PAGECNT_MASK;
/* WRITE THE PAGE OFFSET */
WRITE_VIP32 (VIP_CONTROL2, vip_control2);
WRITE_VIP32 (VIP_PAGE_OFFSET, page_offset);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_set_interrupt_line
*
* This routine sets the line at which a line interrupt should be generated.
*---------------------------------------------------------------------------*/
int vip_set_interrupt_line (int line)
{
WRITE_VIP32 (VIP_CURRENT_TARGET, (line << VIP_CTARGET_TLINE_SHIFT) & VIP_CTARGET_TLINE_MASK);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_reset
*
* This routine does a one-shot enable of the VIP hardware. It is useful
* for handling unrecoverable VIP errors.
*---------------------------------------------------------------------------*/
int vip_reset (void)
{
unsigned long vip_control1, vip_control3;
/* INVERT THE PAUSE BIT */
vip_control1 = READ_VIP32 (VIP_CONTROL1);
vip_control3 = READ_VIP32 (VIP_CONTROL3);
WRITE_VIP32 (VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET);
WRITE_VIP32 (VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET);
WRITE_VIP32 (VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_set_subwindow_enable
*
* This routine turns on SubWindow capture, that is a portion of the incoming
* signal is captured rather than the entire frame. The window always has
* the same width as the frame, only the vertical component can be
* modified.
*---------------------------------------------------------------------------*/
int vip_set_subwindow_enable (VIPSUBWINDOWBUFFER *buffer)
{
unsigned long vip_control2;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
vip_control2 = READ_VIP32 (VIP_CONTROL2);
if (buffer->enable)
{
/* WRITE THE WINDOW VALUE */
WRITE_VIP32(VIP_VERTICAL_START_STOP,
((buffer->stop << VIP_VSTART_VERTEND_SHIFT) & VIP_VSTART_VERTEND_MASK) |
((buffer->start << VIP_VSTART_VERTSTART_SHIFT) & VIP_VSTART_VERTSTART_MASK));
/* ENABLE IN THE CONTROL REGISTER */
vip_control2 |= VIP_CONTROL2_SWC_ENABLE;
}
else
{
/* DISABLE SUBWINDOW CAPTURE IN THE CONTROL REGISTER */
vip_control2 &= ~VIP_CONTROL2_SWC_ENABLE;
}
WRITE_VIP32 (VIP_CONTROL2, vip_control2);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_reset_interrupt_state
*
* This routine resets the state of one or more interrupts.
*---------------------------------------------------------------------------*/
int vip_reset_interrupt_state(unsigned long interrupt_mask)
{
unsigned long temp;
temp = READ_VIP32(VIP_INTERRUPT);
WRITE_VIP32 (VIP_INTERRUPT, temp | (interrupt_mask & VIP_ALL_INTERRUPTS));
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_save_state
*
* This routine saves the necessary register contents in order to restore
* at a later point to the same state.
*
* NOTE: Capture state is forced to OFF in this routine
*---------------------------------------------------------------------------*/
int vip_save_state(VIPSTATEBUFFER *save_buffer)
{
if (!save_buffer)
return CIM_STATUS_INVALIDPARAMS;
/* FORCE CAPTURE TO BE DISABLED */
vip_set_capture_state (VIP_STOPCAPTURE);
/* READ AND SAVE THE REGISTER CONTENTS */
save_buffer->control1 = READ_VIP32(VIP_CONTROL1);
save_buffer->control2 = READ_VIP32(VIP_CONTROL2);
save_buffer->vip_int = READ_VIP32(VIP_INTERRUPT);
save_buffer->current_target = READ_VIP32(VIP_CURRENT_TARGET);
save_buffer->max_address = READ_VIP32(VIP_MAX_ADDRESS);
save_buffer->taska_evenbase = READ_VIP32(VIP_TASKA_VID_EVEN_BASE);
save_buffer->taska_oddbase = READ_VIP32(VIP_TASKA_VID_ODD_BASE);
save_buffer->taska_vbi_evenbase = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE);
save_buffer->taska_vbi_oddbase = READ_VIP32(VIP_TASKA_VBI_ODD_BASE);
save_buffer->taska_data_pitch = READ_VIP32(VIP_TASKA_VID_PITCH);
save_buffer->control3 = READ_VIP32(VIP_CONTROL3);
save_buffer->taska_v_oddoffset = READ_VIP32(VIP_TASKA_U_OFFSET);
save_buffer->taska_u_oddoffset = READ_VIP32(VIP_TASKA_V_OFFSET);
save_buffer->taskb_evenbase = READ_VIP32(VIP_TASKB_VID_EVEN_BASE);
save_buffer->taskb_oddbase = READ_VIP32(VIP_TASKB_VID_ODD_BASE);
save_buffer->taskb_vbi_evenbase = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE);
save_buffer->taskb_vbi_oddbase = READ_VIP32(VIP_TASKB_VBI_ODD_BASE);
save_buffer->taskb_pitch = READ_VIP32(VIP_TASKB_VID_PITCH);
save_buffer->taskb_voffset = READ_VIP32(VIP_TASKB_U_OFFSET);
save_buffer->taskb_uoffset = READ_VIP32(VIP_TASKB_V_OFFSET);
save_buffer->msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE);
save_buffer->msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE);
save_buffer->msg_size = READ_VIP32(VIP_ANC_MSG_SIZE);
save_buffer->page_offset = READ_VIP32(VIP_PAGE_OFFSET);
save_buffer->vert_start_stop = READ_VIP32(VIP_VERTICAL_START_STOP);
save_buffer->vsync_err_count = READ_VIP32(VIP_VSYNC_ERR_COUNT);
save_buffer->taska_u_evenoffset = READ_VIP32(VIP_TASKA_U_EVEN_OFFSET);
save_buffer->taska_v_evenoffset = READ_VIP32(VIP_TASKA_V_EVEN_OFFSET);
/* READ ALL VIP MSRS */
msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &(save_buffer->msr_config));
msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI, &(save_buffer->msr_smi));
msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &(save_buffer->msr_pm));
msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &(save_buffer->msr_diag));
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_restore_state
*
* This routine restores the state of the vip registers - which were
* previously saved using vip_save_state.
*---------------------------------------------------------------------------*/
int vip_restore_state (VIPSTATEBUFFER *restore_buffer)
{
if (!restore_buffer)
return CIM_STATUS_OK;
/* RESTORE THE REGISTERS */
WRITE_VIP32(VIP_CURRENT_TARGET, restore_buffer->current_target);
WRITE_VIP32(VIP_MAX_ADDRESS, restore_buffer->max_address);
WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, restore_buffer->taska_evenbase);
WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, restore_buffer->taska_oddbase);
WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE, restore_buffer->taska_vbi_evenbase);
WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE, restore_buffer->taska_vbi_oddbase);
WRITE_VIP32(VIP_TASKA_VID_PITCH, restore_buffer->taska_data_pitch);
WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
WRITE_VIP32(VIP_TASKA_U_OFFSET, restore_buffer->taska_v_oddoffset);
WRITE_VIP32(VIP_TASKA_V_OFFSET, restore_buffer->taska_u_oddoffset);
WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, restore_buffer->taskb_evenbase);
WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, restore_buffer->taskb_oddbase);
WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE, restore_buffer->taskb_vbi_evenbase);
WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE, restore_buffer->taskb_vbi_oddbase);
WRITE_VIP32(VIP_TASKB_VID_PITCH, restore_buffer->taskb_pitch);
WRITE_VIP32(VIP_TASKB_U_OFFSET, restore_buffer->taskb_voffset);
WRITE_VIP32(VIP_TASKB_V_OFFSET, restore_buffer->taskb_uoffset);
WRITE_VIP32(VIP_ANC_MSG1_BASE, restore_buffer->msg1_base);
WRITE_VIP32(VIP_ANC_MSG2_BASE, restore_buffer->msg2_base);
WRITE_VIP32(VIP_ANC_MSG_SIZE, restore_buffer->msg_size);
WRITE_VIP32(VIP_PAGE_OFFSET, restore_buffer->page_offset);
WRITE_VIP32(VIP_VERTICAL_START_STOP, restore_buffer->vert_start_stop);
WRITE_VIP32(VIP_VSYNC_ERR_COUNT, restore_buffer->vsync_err_count);
WRITE_VIP32(VIP_TASKA_U_EVEN_OFFSET, restore_buffer->taska_u_evenoffset);
WRITE_VIP32(VIP_TASKA_V_EVEN_OFFSET, restore_buffer->taska_v_evenoffset);
/* RESTORE THE VIP MSRS */
msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &(restore_buffer->msr_config));
msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI, &(restore_buffer->msr_smi));
msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &(restore_buffer->msr_pm));
msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &(restore_buffer->msr_diag));
/* RESTORE THE CONTROL WORDS LAST */
WRITE_VIP32(VIP_CONTROL1, restore_buffer->control1);
WRITE_VIP32(VIP_CONTROL2, restore_buffer->control2);
WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_interrupt_state
*
* This routine returns the current interrupt state of the system. The
* rv can be tested with the following flags to determine if the appropriate
* event has occured.
*---------------------------------------------------------------------------*/
unsigned long vip_get_interrupt_state(void)
{
unsigned long interrupt_mask = READ_VIP32(VIP_INTERRUPT);
return (~(interrupt_mask << 16) & interrupt_mask & VIP_ALL_INTERRUPTS);
}
/*---------------------------------------------------------------------------
* vip_test_genlock_active
*
* This routine reads the live status of the genlock connection between the VIP
* and VG blocks.
*---------------------------------------------------------------------------*/
int vip_test_genlock_active (void)
{
if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_GENLK_ACTIVE)
return 1;
return 0;
}
/*---------------------------------------------------------------------------
* vip_test_signal_status
*
* This routine reads the live signal status coming into the VIP block.
*---------------------------------------------------------------------------*/
int vip_test_signal_status (void)
{
if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_VIP_VID_OK)
return 1;
return 0;
}
/*---------------------------------------------------------------------------
* vip_get_current_field
*
* This routine returns the current field being received.
*---------------------------------------------------------------------------*/
unsigned long vip_get_current_field (void)
{
if (READ_VIP32(VIP_STATUS) & VIP_STATUS_FIELD)
return VIP_EVEN_FIELD;
return VIP_ODD_FIELD;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* CIMARRON VIP READ ROUTINES
* These routines are included for use in diagnostics or when debugging. They
* can be optionally excluded from a project.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#if CIMARRON_INCLUDE_VIP_READ_ROUTINES
/*---------------------------------------------------------------------------
* vip_get_current_mode
*
* This routine reads the current VIP operating mode.
*---------------------------------------------------------------------------*/
int vip_get_current_mode (VIPSETMODEBUFFER *buffer)
{
unsigned long vip_control1, vip_control2, vip_control3;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
vip_control1 = READ_VIP32 (VIP_CONTROL1);
vip_control2 = READ_VIP32 (VIP_CONTROL2);
vip_control3 = READ_VIP32 (VIP_CONTROL3);
/* READ CURRENT OPERATING MODE AND ENABLES */
buffer->stream_enables = vip_control1 & VIP_ENABLE_ALL;
buffer->operating_mode = vip_control1 & VIP_CONTROL1_MODE_MASK;
/* READ CURRENT PLANAR CAPTURE SETTINGS */
buffer->flags = 0;
buffer->planar_capture = 0;
if (vip_control1 & VIP_CONTROL1_PLANAR)
{
buffer->flags |= VIP_MODEFLAG_PLANARCAPTURE;
if (vip_control1 & VIP_CONTROL1_DISABLE_DECIMATION)
{
if (vip_control3 & VIP_CONTROL3_DECIMATE_EVEN)
buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGFIELDS;
else
buffer->planar_capture = VIP_420CAPTURE_EVERYLINE;
}
else
buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGLINES;
}
/* READ MISCELLANEOUS FLAGS */
if (vip_control1 & VIP_CONTROL1_NON_INTERLACED)
buffer->flags |= VIP_MODEFLAG_PROGRESSIVE;
if (vip_control3 & VIP_CONTROL3_BASE_UPDATE)
buffer->flags |= VIP_MODEFLAG_TOGGLEEACHFIELD;
if (vip_control2 & VIP_CONTROL2_INVERT_POLARITY)
buffer->flags |= VIP_MODEFLAG_INVERTPOLARITY;
if (vip_control1 & VIP_CONTROL1_MSG_STRM_CTRL)
buffer->flags |= VIP_MODEFLAG_FLIPMESSAGEWHENFULL;
if (vip_control2 & VIP_CONTROL2_REPEAT_ENABLE)
buffer->flags |= VIP_MODEFLAG_ENABLEREPEATFLAG;
if (vip_control3 & VIP_CONTROL3_TASK_POLARITY)
buffer->flags |= VIP_MODEFLAG_INVERTTASKPOLARITY;
if (vip_control1 & VIP_CONTROL1_DISABLE_ZERO_DETECT)
buffer->flags |= VIP_MODEFLAG_DISABLEZERODETECT;
if (vip_control2 & VIP_CONTROL2_ANC10)
buffer->flags |= VIP_MODEFLAG_10BITANCILLARY;
/* READ THE CURRENT VIP 601 SETTINGS */
vip_get_601_configuration (&buffer->vip601_settings);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* vip_get_601_configuration
*
* This routine returns the current 601 configuration information.
*---------------------------------------------------------------------------*/
int vip_get_601_configuration (VIP_601PARAMS *buffer)
{
unsigned long vip_control3, vip_control1;
if (!buffer)
return CIM_STATUS_INVALIDPARAMS;
vip_control1 = READ_VIP32 (VIP_CONTROL3);
vip_control3 = READ_VIP32 (VIP_CONTROL3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -