📄 tmicp.c
字号:
256, -160, 256, 320, 0, -160,
256, -160, 256, 320, 0, -160,
256, -160, 256, 320, 0, -160,
256, -160, 256, 320, 0, -160,
256, -160, 256, 320, 0, -160,
256, -160, 256, 320, 0, -160,
256, -160, 256, 320, 0, -160,
256, -160, 256, 320, 0, -160,
};
#endif
/****************************************************************************/
/*
* Internal Function Prototypes
*/
tmLibdevErr_t
icpCheckFillParameters(Int instance, icpImageHorzVert_t * image);
/****************************** Library Functions ****************************/
/*
* Function : icpLoadMicroCode
* Load the micro_code as specified in the file at the
* compile time. The file should contain
* (possibly commented)
* output of microcode assembler.
*
* Micro code needs to be copied back to memory only once
* unless there is any self-modifying code.
*
* This function is tranparent to the user.
* Micro code is loaded
* inside the icpInstanceSetup() function.
* Parameters : None
* Function Result : Return TMLIBDEV_OK on success.
* Precondition : Micro code .s file needs to be linked at
* the compile time.
* Postcondition : Micro code is loaded at 128 bytes aligned address.
*
*/
static UInt32 ucode_buffer[MAX_MICROCODE_SIZE];
UInt32 *aligned_ucode;
tmLibdevErr_t
icpLoadMicroCode(Int instance)
{
Int i;
tmAssert(icp_instance == instance, TMLIBDEV_ERR_NOT_OWNER);
/* Fill buffer with jump-to-itself instructions. */
for (i = 0; i < MAX_MICROCODE_SIZE / 4; i++) {
ucode_buffer[i] = ((UInt32) & (ucode_buffer[i])) >> 2;
}
/* Align at 128 byte (2 cache block) boundary. */
aligned_ucode = (UInt32 *) (((UInt32) (ucode_buffer) + 0x7f) & 0xffffff80);
for (i = 0; i <= ACTUAL_MICROCODE_SIZE / 4; i++) {
aligned_ucode[i] = micro_code[i];
}
/*
* Need the following conversion to be consistent with C
*
* This is doing relocation for the long JUMP's
*/
for (i = 0; i <= ACTUAL_MICROCODE_SIZE / 4; i++) {
if ((aligned_ucode[i] & 0xc0000000) == 0)
aligned_ucode[i] = aligned_ucode[i] + ((UInt32) aligned_ucode >> 2);
}
/* Cache operations. */
_cache_copyback((UInt8 *) ucode_buffer, MAX_MICROCODE_SIZE);
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function : icpLoadCoeff
* Load ICP with filter coefficients.
* If the input poiter is NULL then
* load the standard coefficients.
* This is called only when changing coefficients.
* The user can issue icpLoadCoeff at any time during ICP
* processing to load a new set of coefficients.
* Parameters : Pointer to the coeffcients table stored as Int16.
* Function Result : Returns TMLIBDEV_OK on success
* ICP_ERR_COEFF_TABLE -> Coeffcients are
* outside the range [-512,511].
* Precondition : Micro code is already loaded.
* Coefficients may not be in SDRAM
* All other ICP controls are set and checked outside.
* Postcondition : Coefficient table is loaded in SDRAM from
* the given table.
*/
tmLibdevErr_t
icpLoadCoeff(Int instance, Int16 * coeff)
{
tmAssert(icp_instance == instance, TMLIBDEV_ERR_NOT_OWNER);
/* Error checking */
#ifndef NDEBUG
if (coeff != NULL) {
Int i;
for (i = 0; i < 32 * 6; i += 6) {
tmAssert(coeff[i] >= -512 && coeff[i] <= 511,
ICP_ERR_COEFF_TABLE);
tmAssert(coeff[i + 1] >= -512 && coeff[i + 1] <= 511,
ICP_ERR_COEFF_TABLE);
tmAssert(coeff[i + 2] >= -512 && coeff[i + 2] <= 511,
ICP_ERR_COEFF_TABLE);
tmAssert(coeff[i + 3] >= -512 && coeff[i + 3] <= 511,
ICP_ERR_COEFF_TABLE);
tmAssert(coeff[i + 5] >= -512 && coeff[i + 5] <= 511,
ICP_ERR_COEFF_TABLE);
}
}
#endif
if (!icpCheckBUSY());
/* Set the flags to read the coefficients */
if (coeff == NULL) {
_cache_copyback((UInt8 *) icpFilterCoeff, (6*32*sizeof(Int16)));
MMIO(ICP_DP) = (UInt32) icpFilterCoeff;
}
else {
_cache_copyback((UInt8 *) coeff, (6*32*sizeof(Int16)));
MMIO(ICP_DP) = (UInt32) coeff;
}
/* Load the ICP registers */
icpSetReg(ICP_MPC, (UInt32) & aligned_ucode[0]);
icpStart();
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function : icpOpen
* Assign instance for usage. ICP is
* a single instance device.
* Set up the little endian or big endian mode
* Parameters : 1. Pointer to the instance
* Function Result : Return TMLIBDEV_OK on success
* ICP_ERR_DEVICE_IN_USE if someone else is
* using ICP before and
* ICP has already been initialized.
*/
tmLibdevErr_t
icpOpen(Int * instance)
{
UInt ien;
ien = intCLEAR_IEN(); /* no calls here so no need of AppModel */
/* ?? so who cares, it's just an open function ?? */
/* Error if ICP is busy or incorrect instance */
if (icp_open) {
intRESTORE_IEN(ien);
return (TMLIBDEV_ERR_NO_MORE_INSTANCES);
}
icpReset(); /* Reset the ICP for the new user */
/* atomic by nature */
icp_open = 1;
icp_instance = instance_counter++;
capabilities.numCurrentInstances++;
*instance = icp_instance;
intRESTORE_IEN(ien);
return (TMLIBDEV_OK);
} /* end icpOpen */
/*****************************************************************************/
/*
* Function : icpInstanceSetup
* Prepare ICP for operation by:
* Loading the micro code.
* Install interrupt handler, if requested.
* Parameters : 1. Pointer to the icp setup block icpInstanceSetup_t
* Function Result : Return zero on success
* ICP_ERR_DEVICE_IN_USE; Someone else already has
* the device control
* ICP_ERR_LOAD_MICRO_CODE; Could not load the micro code
* Precondition : Require icpOpen() to be called first.
*/
tmLibdevErr_t
icpInstanceSetup(Int instance, icpInstanceSetup_t * setup)
{
tmLibdevErr_t err;
intInstanceSetup_t int_setup;
/* Error processing */
tmAssert(icp_instance == instance, TMLIBDEV_ERR_NOT_OWNER);
if (icp_instance != instance)
return TMLIBDEV_ERR_NOT_OWNER;
if (!icp_setup) {
if (icpLoadMicroCode(instance)) /* Use the latest version */
return (ICP_ERR_LOAD_MICRO_CODE);
}
if (setup->reset)
icpReset();
#ifdef __LITTLE_ENDIAN__
icpEnableLITTLE_ENDIAN();
#else
icpDisableLITTLE_ENDIAN();
#endif
if (!interrupt_installed)
intOpen(intICP);
/* tmAssert( sizeof(int_setup) == 4 * WORDSIZE ); */
int_setup.handler = setup->isr;
int_setup.priority = setup->interruptPriority;
int_setup.level_triggered = True;
int_setup.enabled = True;
if (err = intInstanceSetup(intICP, &int_setup))
return err;
if (setup->isr == NULL)
icpDisableINTERRUPT();
else
icpEnableINTERRUPT();
interrupt_installed = 1;
icp_setup = 1;
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function : icpClose
* De-install the interrupt handler
* Parameters : 1. Pointer to ICP setup block.
* Function Result : Return TMLIBDEV_OK on success
* ICP_ERR_BUSY; Someone else is running the ICP.
* Precondition : ICP is open by icpOpen().
* Postcondtion : ICP interrupts are disabled. Ready to be
* opened by someone.
*/
tmLibdevErr_t
icpClose(Int instance)
{
tmLibdevErr_t err = TMLIBDEV_OK;
tmAssert(icp_instance == instance, TMLIBDEV_ERR_NOT_OWNER);
AppModel_suspend_scheduling();
if (icpCheckBUSY()) {
err = ICP_ERR_BUSY;
goto icpCloseExit;
}
icpReset();
if (err = intClose(intICP))
goto icpCloseExit;
/* Disable ICP Interrupt */
icpDisableINTERRUPT(); /* Clear the ICP Interrupt enable and busy bit */
/* atomic by nature */
interrupt_installed = 0;
instance_counter--;
capabilities.numCurrentInstances--;
icp_open = 0; /* ICP is available for use again */
icpCloseExit:
AppModel_resume_scheduling();
return err;
}
/*****************************************************************************/
/*
* Function : icpMove
* Moves an image from *scrImage in SDRAM to
* *destImage in SDRAM.
* Parameters : 1. Instance
* 2. Pointer to the icpImageHorzVert_t block.
* Function Result : Return TMLIBDEV_OK on success
* ICP_ERR_DEVICE_IN_USE; Incorrect owner.
* ICP_ERR_SETUP_REQUIRED; ICP has not been setup.
* Use icpSetup().
* ICP_ERR_INVALID_HEIGHT; Source height <= 0.
* ICP_ERR_INVALID_WIDTH; Source width <=0.
* ICP_ERR_INVALID_STRIDE; Source or destination
* stride <= 0.
* ICP_ERR_ADDRESS_NOT_64_ALIGNED; Address pointer
* must be aligned at a 64 byte block boundary.
* ICP_ERR_BUSY; Attempt to call icpMove while ICP *
* is busy processing
* Precondition : Micro code is already loaded
* Source image is assumed to be COPYBACK'ed in memory.
*/
tmLibdevErr_t
icpMove(Int instance, icpImageHorzVert_t * image)
{
tmLibdevErr_t rval;
/*
* Since the same block is loaded for the ICP horizontal, move, and
* vertical filter, a common function loads the block
*/
if (rval = icpCheckFillParameters(instance, image))
return (rval);
blk.fracInc = 0x0001;
blk.control = 0x8000;
/* Copyback to memory */
_cache_copyback((UInt8 *) & blk, sizeof(icpParamTable_t));
/* Load the ICP registers */
icpSetReg(ICP_MPC, (UInt32) & aligned_ucode[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -