⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmicp.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
  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 + -