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

📄 tmiic.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    req.direction           = IIC_READ;
    req.byteCount           = 1;
    req.address             = address;
    req.subaddress          = subaddress;
    req.numRetries          = MAX_NUM_RETRIES;
    req.waitBeforeRetry     = TM1100_SLEEP_BEFORE_RETRY;
    req.data                = &data;
    req.mode                = IIC_Synchronous_By_Polling;
    req.type                = (subaddress < 0) ? IIC_SIMPLE : IIC_SUBADDRESS;
    req.completion_function = Null;

    err  = iicDispatch(instance, &req);

    *value                  = data;     
    
    err |= iicClose(instance);
    
    return err;
}

/*
 * Function         : IIC dispatch function.
 * Parameters       : iic_request  (I) description of required
 *                                     iic actions to be taken
 * Function Result  : True iff a synchronous iic request was
 *                         suspended in order to wait for completion.
 */

tmLibdevErr_t
iicDispatch(Int instance, piicRequest_t iic_request)
{
    UInt         ien;
 
    tmAssert(iic_request != Null, TMLIBDEV_ERR_NULL_PARAMETER);
    tmAssert(capabilities.numCurrentInstances != 0, TMLIBDEV_ERR_NOT_OWNER);
    
    /* since no checking is done on the instance, it is best to add this 
       safety check */
    if (procCap->hostID == tmTmSimHost) {
        return TMLIBDEV_ERR_NOT_OWNER;
    }

    if (iic_request->address > 0xFF)
        return (IIC_ERR_BAD_ADDRESS);
    if (iic_request->byteCount > LARGEST_TRANSFER)
        return (IIC_ERR_BAD_COUNT);
        
    /*
     * Fill in some standard values in the request.
     */

    iic_request->requester     = AppModel_current_thread;
    iic_request->done          = False;
    iic_request->index         = 0;
    iic_request->errorCode     = 0;

    if (iic_request->direction == IIC_READ) {
        iic_request->address  |= 1;       /* only read at uneven addresses */

#if TM1000_COMPATIBLE    
        if (TM1000) {
            if (iic_request->byteCount == 2)
                return (IIC_ERR_BAD_COUNT);
            if ((iic_request->byteCount > 1) && ((iic_request->byteCount % 4) == 1))
                return (IIC_ERR_BAD_COUNT);
        }
#endif

    } else { 

        Int byteCount = iic_request->byteCount + 
                   (iic_request->type == IIC_SUBADDRESS?1:0);

        iic_request->address  &= 0xFE;    /* only write at even addresses */
        
#if TM1000_COMPATIBLE    
        if (TM1000) {
            if (byteCount > 4)
                return (IIC_ERR_BAD_COUNT);
        }
#endif
        if (TM1100_1_2) {
            if ((byteCount > 1) && ((byteCount % 4) == 1))
                return (IIC_ERR_BAD_COUNT);
        }
        
    }
    
    /*
     * Start the request if we're not working on something else,
     * otherwise, insert the request in the queue.
     */

    ien = intCLEAR_IEN();
    
    if (iic_current_request == Null) 
    {
        IIC_DP(("dispatch iic request %x to %x. ", iic_request, iic_request->address));
        iic_queue_first = iic_queue_last = Null;
        iic_current_request     = iic_request;
        start_next_transfer(False); /* starts iic_current_request, no retries */
        
    } else 
    {   /* INSERT_REQUEST */
        IIC_DP(("queue iic request %x to %x. ", iic_request, iic_request->address));
        
        if (iic_queue_first == Null) 
            iic_queue_first      = iic_request;
        else 
            iic_queue_last->link = (iic_request);
        iic_request->link        = Null;
        iic_queue_last           = iic_request;
    }
    
    intRESTORE_IEN(ien);

    /*
     * Await completion, as specified:
     */

    switch (iic_request->mode) {
    case IIC_Asynchronous:
        IIC_DP(("Async\n"));
        return TMLIBDEV_OK;

    case IIC_Synchronous_By_Polling:
    
        if (!iic_request->done) {
            
            /*
             * Note that the MAX_WAIT_IN_US is the time we will wait
             * for this transaction to finish. So, if other transactions
             * are pending that take much time, we will time out. 
             * 
             */
            IIC_DP(("Poll- "));
                        
            for (LoopCount = 0; LoopCount < MAX_WAIT_IN_US / 5; LoopCount++) 
            {
                if (iic_request->done) {
                    goto done;
                }
                IIC_DP(("."));
                microsleep(10);
            }
            iic_request->errorCode |= IIC_ERR_TIMEOUT;
            IIC_DP(("Timed Out! "));
        }
done:
        if (TM1000) {
            /* this block of code seems redundant and causes problems
             * when async transactions are used.
             * It was deleted as duplicated at about 072p6.
             * Then we found that it is required on TM1000, 
             * so it is added back conditionally.
             */
            iic_current_request   = iic_queue_first;
            IIC_DP(("For TM1000, dispatch next in sync iic %x\n", iic_current_request));
            if (iic_current_request != Null) 
            {
                iic_queue_first = iic_queue_first->link;
                
                if (iic_queue_first == Null) {
                    iic_queue_last = Null;
                } 
                start_next_transfer(False); /* starts iic_current_request, no retries */
            }
        }
        IIC_DP(("%x Complete.\n", iic_request));
        return iic_request->errorCode;

    case IIC_Synchronous:
        IIC_DP(("Sync\n"));
        if (!iic_request->done)
            AppModel_suspend_self();
        return iic_request->errorCode;
        
    default:
    
        return TMLIBDEV_OK;    /* keep apcc happy */
    
    }
}


/*
 * Function         : Fills in the capabilities structure.
 * Parameters       : cap  (O)  returned pointer to
 *                              internal capabilities structure
 * Function Result  : resulting error condition
 */

tmLibdevErr_t
iicGetCapabilities(piicCapabilities_t * cap)
{
    tmAssert(cap != Null, TMLIBDEV_ERR_NULL_PARAMETER);

    *cap = &capabilities;

    return TMLIBDEV_OK;
}



/*
 * Function         : Changes parameters of IIC interface,
 *                    like speed and priority.
 *                    Use is optional.
 * Parameters       : setup  (O)  pointer to buffer holding new capabilities
 * Function Result  : resulting error condition
 */

tmLibdevErr_t
iicSetup(piicSetup_t setup)
{
    UInt ien;
    tmAssert(setup != Null, TMLIBDEV_ERR_NULL_PARAMETER);

    ien= intCLEAR_IEN();
    IICSetup= *setup;

    if (capabilities.numCurrentInstances != 0) {
        intInstanceSetup_t int_setup;

        intGetInstanceSetup(intIIC, &int_setup);
        int_setup.priority = IICSetup.interruptPriority;
        intInstanceSetup(intIIC, &int_setup);
    }

    intRESTORE_IEN(ien);
    return TMLIBDEV_OK;
}



/*
 * Function         : Retrieve global parameters.
 * Parameters       : setup    (O)  pointer to buffer
 *                                  receiving returned parameters
 * Function Result  : resulting error condition
 */

extern      tmLibdevErr_t
iicGetSetup(iicSetup_t * setup)
{
    UInt ien;

    tmAssert(setup != Null, TMLIBDEV_ERR_NULL_PARAMETER);

    ien    = intCLEAR_IEN();
    *setup = IICSetup;
    intRESTORE_IEN(ien);

    return TMLIBDEV_OK;
}



/*
 * Function         : Assigns a unique instance for the caller.
 * Parameters       : instance  (O)  pointer to result variable
 * Function Result  : resulting error condition
 */

tmLibdevErr_t
iicOpen(Int * instance)
{
    UInt ien;
    tmLibdevErr_t err;
    intInstanceSetup_t int_setup;

    tmAssert(instance != Null, TMLIBDEV_ERR_NULL_PARAMETER);

    /*
     * Setup IIC handling:
     */

    ien= intCLEAR_IEN();

    if (capabilities.numCurrentInstances == 0) {
        procGetCapabilities(&procCap);

        if (procCap->hostID == tmTmSimHost) {
            /* this could be running under tmsim. Let s try a PCI
             * transaction. If the PCI transaction does not work, it might
             * mean we are running under tmsim
             */
            intRESTORE_IEN(ien);
            return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
        }
        
        if (err = intOpen(intIIC)) {
            intRESTORE_IEN(ien);
            return err;
        } else {
            switch(procCap->deviceID) {
            case PROC_DEVICE_TM1000:
            case PROC_DEVICE_TM1100:
            case PROC_DEVICE_TM1300:
                /*
                 * Enable clock stretch
                 */
                MMIO(ARB_BW_CTL) |= 0x01000000; 
                break;
            default:
                break;
            }

            MMIO(BIU_CTL) |= (1 << 10); 
            MMIO(IIC_CTL) = IIC_CLR_ALL | IIC_ENABLE;


#if TM1000_COMPATIBLE                            
            TM1000 = (procCap->deviceID == PROC_DEVICE_TM1000);
#endif            
            TM1100_1_2 = (procCap->deviceID == PROC_DEVICE_TM1100 &&
                          procCap->revisionID == PROC_REVISION_1_2);
        }
    }
    
    /*
     * Setup interrupt handler
     */

    int_setup.handler          = iic_handler;
    int_setup.priority         = IICSetup.interruptPriority;
    int_setup.level_triggered  = True;
    int_setup.enabled          = True;
    
    intInstanceSetup(intIIC, &int_setup);
    
    capabilities.numCurrentInstances++;
    *instance = ++next_instance;

    intRESTORE_IEN(ien);

    return TMLIBDEV_OK;
}

/*
 * Function         : Deallocates the instance.
 * Parameters       : instance  (O)  instance to give up
 * Function Result  : resulting error condition
 */

tmLibdevErr_t
iicClose(Int instance)
{
    UInt ien;
    tmAssert(capabilities.numCurrentInstances != 0, TMLIBDEV_ERR_NOT_OWNER);

    ien= intCLEAR_IEN();

    if (--capabilities.numCurrentInstances == 0) {
        intClose(intIIC);
    }

    intRESTORE_IEN(ien);
    return TMLIBDEV_OK;
}

/**************************************************************************
 *  IIC Slave now part of IIC library
 *************************************************************************/

static Int IicOpened     = 0;
static Int IicInstance   = 0;
static iicsSetup_t IICSSetup = {False, 184, 0, Null};



/*-----------------------------functions------------------------------------*/

tmLibdevErr_t iicsOpen(int* instance)
{
    UInt ien, err;


    err = procGetCapabilities(&procCap);
    if (err) return err;

    switch (procCap->deviceID)
    {
        case PROC_DEVICE_TM1000 : 
        case PROC_DEVICE_TM1100 :
        case PROC_DEVICE_TM1300 :
             return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
            
        default:
        case PROC_DEVICE_UNKNOWN:
        case PROC_DEVICE_TM2500 :     /* Classic TV     */
        case PROC_DEVICE_TM2600 :     /* HD-SD          */
        case PROC_DEVICE_TM2700 :     /* HD-HD          */
        case PROC_DEVICE_TM2800 :     /* DVB TV / SD-SD */
            break;
    }

    if (IicOpened++ > 0) return TMLIBDEV_OK; 
    
    ien= intCLEAR_IEN();
    
    /* Make sure the shared ISR is installed */
    iicOpen(&IicInstance);
    
    /* Reset the IICS device */
    iicsAckRESET();
    
    intRESTORE_IEN(ien);
    return TMLIBDEV_OK;
}

tmLibdevErr_t iicsSetup(piicsSetup_t pSetup)
{   
    UInt ien;

    tmAssert(pSetup != Null, TMLIBDEV_ERR_NULL_PARAMETER);
    ien= intCLEAR_IEN();
    
    if (IicOpened > 0) {

        IICSSetup               = *pSetup;
        IICSSetup.iicAddress   &= ~0x1;
        IICSSetup.iicsMask     &=  0xF;
    
        _iicsISR            = IICSSetup.iicsISR;
        _iicsMask           = IICSSetup.iicsMask;
        
        iicsSetSLAVE_ADR(IICSSetup.iicAddress);
        iicsSetINTEN(IICSSetup.iicsMask);
    
    }
    
    intRESTORE_IEN(ien);
    return TMLIBDEV_OK;
}

tmLibdevErr_t iicsGetSetup(piicsSetup_t pSetup)
{   
    tmAssert(pSetup != Null, TMLIBDEV_ERR_NULL_PARAMETER);
    
    *pSetup                 = IICSSetup;
    
    return TMLIBDEV_OK;
}

tmLibdevErr_t iicsClose(int instance)
{
    UInt ien;
    ien= intCLEAR_IEN();

    if (--IicOpened == 0) {
        iicClose(IicInstance);
        IicInstance         = 0;
        
        _iicsISR            = Null;
        _iicsMask           = 0;
        
        iicsSetINTEN(0);
        return TMLIBDEV_OK;
    }
    
    intRESTORE_IEN(ien);
    return TMLIBDEV_OK;
}

/*--------------------------------------------------------------------------*/







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -