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

📄 mcd_dmaapi.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
📖 第 1 页 / 共 3 页
字号:
           || prevRep.lastDestAddr != progRep->lastDestAddr
           || prevRep.dmaSize != progRep->dmaSize
           || prevRep.currBufDesc != progRep->currBufDesc)
       {
          /* If they don't match, remember previous values and try again:*/
          prevRep.lastSrcAddr = progRep->lastSrcAddr;
          prevRep.lastDestAddr = progRep->lastDestAddr;
          prevRep.dmaSize = progRep->dmaSize;
          prevRep.currBufDesc = progRep->currBufDesc;
          again = MCD_TRUE;
       }
       else
          again = MCD_FALSE;
    } while (again == MCD_TRUE);


    /* Update the dCount, srcAddr and destAddr */
    /* To calculate dmaCount, we consider destination address. C
       overs M1,P1,Z for destination */
    switch(MCD_remVariants.remDestRsdIncr[channel]) {
        case MINUS1:
           subModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
           addModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
           LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - addModVal;
           LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal;
           destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr;
           bytesNotXfered = (destDiffBytes/MCD_remVariants.remDestIncr[channel]) *
                            ( MCD_remVariants.remDestIncr[channel]
                            + MCD_remVariants.remXferSize[channel]);
           progRep->dmaSize = destDiffBytes - bytesNotXfered + addModVal - subModVal;
           break;
        case ZERO:
           progRep->lastDestAddr = progRep->currBufDesc->destAddr;
           break;
        case PLUS1:
           /* This value has to be subtracted from the final calculated dCount. */
           subModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
           /* These bytes are already in lastDestAddr. */
            addModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
            LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - subModVal;
            LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal;
            destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr);
            numIterations = ( LWAlignedCurrDestAddr - LWAlignedInitDestAddr)/MCD_remVariants.remDestIncr[channel];
            bytesNotXfered =  numIterations *
                ( MCD_remVariants.remDestIncr[channel]
                  - MCD_remVariants.remXferSize[channel]);
           progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal;
           break;
        default:
           break;
    }

    /* This covers M1,P1,Z for source */
    switch(MCD_remVariants.remSrcRsdIncr[channel]) {
        case MINUS1:
            progRep->lastSrcAddr =
                progRep->currBufDesc->srcAddr +
                 ( MCD_remVariants.remSrcIncr[channel] *
                   (progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
            break;
        case ZERO:
            progRep->lastSrcAddr = progRep->currBufDesc->srcAddr;
            break;
       case PLUS1:
            progRep->lastSrcAddr =
                progRep->currBufDesc->srcAddr +
                 ( MCD_remVariants.remSrcIncr[channel] *
                   (progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
          break;
       default: break;
    }

    return(MCD_OK);
}
/******************* End of MCD_XferProgrQuery() ********************/

/********************************************************************/
/* MCD_resmActions() does the majority of the actions of a DMA resume.
 * It is called from MCD_killDma() and MCD_resumeDma().  It has to be
 * a separate function because the kill function has to negate the task
 * enable before resuming it, but the resume function has to do nothing
 * if there is no DMA on that channel (i.e., if the enable bit is 0).
 */
static void MCD_resmActions (int channel)
{
   MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
   MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus;
   MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; /* This register is selected to know
                                        which initiator is actually asserted. */
   if((MCD_dmaBar->ptdDebug >> channel ) & 0x1)
       MCD_chStatus[channel] = MCD_RUNNING;
   else
       MCD_chStatus[channel] = MCD_IDLE;
}
/********************* End of MCD_resmActions() *********************/

/********************************************************************/
/* Function:    MCD_killDma
 * Purpose:     Halt the DMA on the requested channel, without any
 *              intention of resuming the DMA.
 * Arguments:   channel - requested channel
 * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
 *
 * Notes:
 *  A DMA may be killed from any state, including paused state, and it
 *  always goes to the MCD_HALTED state even if it is killed while in
 *  the MCD_NO_DMA or MCD_IDLE states.
 */
int MCD_killDma (int channel)
{
   /* MCD_XferProg progRep; */

    if((channel < 0) || (channel >= NCHANNELS))
        return(MCD_CHANNEL_INVALID);

    MCD_dmaBar->taskControl[channel] = 0x0;
    MCD_resumeDma (channel);
    /*
     * This must be after the write to the TCR so that the task doesn't
     * start up again momentarily, and before the status assignment so
     * as to override whatever MCD_resumeDma() may do to the channel
     * status.
     */
    MCD_chStatus[channel] = MCD_HALTED;

    /*
     * Update the current buffer descriptor's lastDestAddr field
     *
     * MCD_XferProgrQuery (channel, &progRep);
     * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
     */
    return(MCD_OK);
}
/************************ End of MCD_killDma() **********************/

/********************************************************************/
/* Function:    MCD_continDma
 * Purpose:     Continue a DMA which as stopped due to encountering an
 *              unready buffer descriptor.
 * Arguments:   channel - channel to continue the DMA on
 * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
 *
 * Notes:
 *  This routine does not check to see if there is a task which can
 *  be continued. Also this routine should not be used with single DMAs.
 */
int MCD_continDma (int channel)
{
    if((channel < 0) || (channel >= NCHANNELS))
        return(MCD_CHANNEL_INVALID);

    MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN;
    MCD_chStatus[channel] = MCD_RUNNING;

    return(MCD_OK);
}
/********************** End of MCD_continDma() **********************/

/*********************************************************************
 * MCD_pauseDma() and MCD_resumeDma() below use the DMA's debug unit
 * to freeze a task and resume it.  We freeze a task by breakpointing
 * on the stated task.  That is, not any specific place in the task,
 * but any time that task executes.  In particular, when that task
 * executes, we want to freeze that task and only that task.
 *
 * The bits of the debug control register influence interrupts vs.
 * breakpoints as follows:
 * - Bits 14 and 0 enable or disable debug functions.  If enabled, you
 *   will get the interrupt but you may or may not get a breakpoint.
 * - Bits 2 and 1 decide whether you also get a breakpoint in addition
 *   to an interrupt.
 *
 * The debug unit can do these actions in response to either internally
 * detected breakpoint conditions from the comparators, or in response
 * to the external breakpoint pin, or both.
 * - Bits 14 and 1 perform the above-described functions for
 *   internally-generated conditions, i.e., the debug comparators.
 * - Bits 0 and 2 perform the above-described functions for external
 *   conditions, i.e., the breakpoint external pin.
 *
 * Note that, although you "always" get the interrupt when you turn
 * the debug functions, the interrupt can nevertheless, if desired, be
 * masked by the corresponding bit in the PTD's IMR. Note also that
 * this means that bits 14 and 0 must enable debug functions before
 * bits 1 and 2, respectively, have any effect.
 *
 * NOTE: It's extremely important to not pause more than one DMA channel 
 *  at a time.
 ********************************************************************/

/********************************************************************/
/* Function:    MCD_pauseDma
 * Purpose:     Pauses the DMA on a given channel (if any DMA is running
 *              on that channel).
 * Arguments:   channel
 * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
 */
int MCD_pauseDma (int channel)
{
    /* MCD_XferProg progRep; */

    if((channel < 0) || (channel >= NCHANNELS))
        return(MCD_CHANNEL_INVALID);

    if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
    {
        MCD_dmaBar->debugComp1 = channel;
        MCD_dmaBar->debugControl = DBG_CTL_ENABLE | (1 << (channel + 16));
        MCD_chStatus[channel] = MCD_PAUSED;

        /*
         * Update the current buffer descriptor's lastDestAddr field
         *
         * MCD_XferProgrQuery (channel, &progRep);
         * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
         */
    }
    return(MCD_OK);
}
/************************* End of MCD_pauseDma() ********************/

/********************************************************************/
/* Function:    MCD_resumeDma
 * Purpose:     Resumes the DMA on a given channel (if any DMA is
 *              running on that channel).
 * Arguments:   channel - channel on which to resume DMA
 * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
 */
int MCD_resumeDma (int channel)
{
    if((channel < 0) || (channel >= NCHANNELS))
        return(MCD_CHANNEL_INVALID);

    if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
        MCD_resmActions (channel);

    return(MCD_OK);
}
/************************ End of MCD_resumeDma() ********************/

/********************************************************************/
/* Function:    MCD_csumQuery
 * Purpose:     Provide the checksum after performing a non-chained DMA
 * Arguments:   channel - channel to report on
 *              csum - pointer to where to write the checksum/CRC
 * Returns:     MCD_ERROR if the channel is invalid, else MCD_OK
 *
 * Notes:
 *
 */
int MCD_csumQuery (int channel, u32 *csum)
{
#ifdef MCD_INCLUDE_EU
    if((channel < 0) || (channel >= NCHANNELS))
        return(MCD_CHANNEL_INVALID);

    *csum = MCD_relocBuffDesc[channel].csumResult;
    return(MCD_OK);
#else
    return(MCD_ERROR);
#endif
}
/*********************** End of MCD_resumeDma() *********************/

/********************************************************************/
/* Function:    MCD_getCodeSize
 * Purpose:     Provide the size requirements of the microcoded tasks
 * Returns:     Size in bytes
 */
int MCD_getCodeSize(void)
{
#ifdef MCD_INCLUDE_EU
    return(0x2b5c);
#else
    return(0x173c);
#endif
}
/********************** End of MCD_getCodeSize() ********************/

/********************************************************************/
/* Function:    MCD_getVersion
 * Purpose:     Provide the version string and number
 * Arguments:   longVersion - user supplied pointer to a pointer to a char
 *                    which points to the version string
 * Returns:     Version number and version string (by reference)
 */
char MCD_versionString[] = "Multi-channel DMA API Alpha v0.3 (2004-04-26)";
#define MCD_REV_MAJOR   0x00
#define MCD_REV_MINOR   0x03

int MCD_getVersion(char **longVersion)
{
    *longVersion = MCD_versionString;
    return((MCD_REV_MAJOR << 8) | MCD_REV_MINOR);
}
/********************** End of MCD_getVersion() *********************/

/********************************************************************/
/* Private version of memcpy()
 * Note that everything this is used for is longword-aligned.
 */
static void MCD_memcpy (int *dest, int *src, u32 size)
{
    u32 i;

    for (i = 0;  i < size;  i += sizeof(int), dest++, src++)
        *dest = *src;
}
/********************************************************************/

⌨️ 快捷键说明

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