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

📄 udma.c

📁 基于TI公司Cortex-M3的uart超级通信开发
💻 C
📖 第 1 页 / 共 3 页
字号:

    //
    // Get the base address of the control table.
    //
    pControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);

    //
    // Get the current control word value and mask off the mode and size
    // fields.
    //
    ulControl = (pControlTable[ulChannel].ulControl &
                 ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M));

    //
    // Adjust the mode if the alt control structure is selected.
    //
    if(ulChannel & UDMA_ALT_SELECT)
    {
        if((ulMode == UDMA_MODE_MEM_SCATTER_GATHER) ||
           (ulMode == UDMA_MODE_PER_SCATTER_GATHER))
        {
            ulMode |= UDMA_MODE_ALT_SELECT;
        }
    }

    //
    // Set the transfer size and mode in the control word (but dont write the
    // control word yet as it could kick off a transfer).
    //
    ulControl |= ulMode | ((ulTransferSize - 1) << 4);

    //
    // Get the data item size from the control word (set previously).
    //
    ulSize = (ulControl & UDMA_CHCTL_DSTSIZE_M) >> 28;

    //
    // Convert the transfer size to be in units of bytes.  Shift (multiply) to
    // get the value in bytes, based on the data item size.
    //
    ulTransferSize = ulTransferSize << ulSize;

    //
    // Get the address increment value for the source, from the control word.
    //
    ulInc = (ulControl & UDMA_CHCTL_SRCINC_M);

    //
    // Compute the ending source address of the transfer.  If the source
    // increment is set to none, then the ending address is the same as the
    // beginning.
    //
    if(ulInc != UDMA_SRC_INC_NONE)
    {
        pvSrcAddr = (void *)((unsigned long)pvSrcAddr + ulTransferSize - 1);
    }

    //
    // Load the source ending address into the control block.
    //
    pControlTable[ulChannel].pvSrcEndAddr = pvSrcAddr;

    //
    // Get the address increment value for the destination, from the control
    // word.
    //
    ulInc = (ulControl & UDMA_CHCTL_DSTINC_M);

    //
    // Compute the ending destination address of the transfer.  If the
    // destination increment is set to none, then the ending address is the
    // same as the beginning.
    //
    if(ulInc != UDMA_DST_INC_NONE)
    {
        pvDstAddr = (void *)((unsigned long)pvDstAddr + ulTransferSize - 1);
    }

    //
    // Load the destination ending address into the control block.
    //
    pControlTable[ulChannel].pvDstEndAddr = pvDstAddr;

    //
    // Write the new control word value.
    //
    pControlTable[ulChannel].ulControl = ulControl;
}

//*****************************************************************************
//
//! Gets the current transfer size for a uDMA channel.
//!
//! \param ulChannel is the logical or of the uDMA channel number with either
//! \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
//!
//! This function is used to get the uDMA transfer size for a channel.  The
//! transfer size is the number of items to transfer, where the size of an item
//! might be 8, 16, or 32 bits.  If a partial transfer has already occurred,
//! then the number of remaining items will be returned.  If the transfer is
//! complete, then 0 will be returned.
//!
//! The \e ulChannel parameter is one of the choices documented in the
//! uDMAChannelEnable() function.  It should be the logical OR of the channel
//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to choose whether
//! the primary or alternate data structure is used.
//!
//! \return Returns the number of items remaining to transfer.
//
//*****************************************************************************
unsigned long
uDMAChannelSizeGet(unsigned long ulChannel)
{
    tDMAControlTable *pControlTable;
    unsigned long ulControl;

    //
    // Check the arguments.
    //
    ASSERT(ulChannel < 64);
    ASSERT(HWREG(UDMA_CTLBASE) != 0);

    //
    // Get the base address of the control table.
    //
    pControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);

    //
    // Get the current control word value and mask off all but the size field.
    //
    ulControl = pControlTable[ulChannel].ulControl & UDMA_CHCTL_XFERSIZE_M;

    //
    // Shift the size field and add one, then return to user.
    //
    return((ulControl >> 4) + 1);
}

//*****************************************************************************
//
//! Gets the transfer mode for a uDMA channel.
//!
//! \param ulChannel is the logical or of the uDMA channel number with either
//! \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT.
//!
//! This function is used to get the transfer mode for the uDMA channel.  It
//! can be used to query the status of a transfer on a channel.  When the
//! transfer is complete the mode will be \b UDMA_MODE_STOP.
//!
//! The \e ulChannel parameter is one of the choices documented in the
//! uDMAChannelEnable() function.  It should be the logical OR of the channel
//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to choose whether the
//! primary or alternate data structure is used.
//!
//! \return Returns the transfer mode of the specified channel and control
//! structure, which will be one of the following values: \b UDMA_MODE_STOP,
//! \b UDMA_MODE_BASIC, \b UDMA_MODE_AUTO, \b UDMA_MODE_PINGPONG,
//! \b UDMA_MODE_MEM_SCATTER_GATHER, or \b UDMA_MODE_PER_SCATTER_GATHER.
//
//*****************************************************************************
unsigned long
uDMAChannelModeGet(unsigned long ulChannel)
{
    tDMAControlTable *pControlTable;
    unsigned long ulControl;

    //
    // Check the arguments.
    //
    ASSERT(ulChannel < 64);
    ASSERT(HWREG(UDMA_CTLBASE) != 0);

    //
    // Get the base address of the control table.
    //
    pControlTable = (tDMAControlTable *)HWREG(UDMA_CTLBASE);

    //
    // Get the current control word value and mask off all but the mode field.
    //
    ulControl = pControlTable[ulChannel].ulControl & UDMA_CHCTL_XFERMODE_M;

    //
    // Check if scatter/gather mode, and if so, mask off the alt bit.
    //
    if(((ulControl & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_MEM_SCATTER_GATHER) ||
       ((ulControl & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_PER_SCATTER_GATHER))
    {
        ulControl &= ~UDMA_MODE_ALT_SELECT;
    }

    //
    // Return the mode to the caller.
    //
    return(ulControl);
}

//*****************************************************************************
//
//! Selects the secondary peripheral for a set of uDMA channels.
//!
//! \param ulSecPeriphs is the logical or of the uDMA channels for which to
//! use the secondary peripheral, instead of the default peripheral.
//!
//! This function is used to select the secondary peripheral assignment for
//! a set of uDMA channels.  By selecting the secondary peripheral assignment
//! for a channel, the default peripheral assignment is no longer available
//! for that channel.
//!
//! The parameter \e ulSecPeriphs can be the logical OR of any of the
//! following macros.  If one of the macros below is in the list passed
//! to this function, then the secondary peripheral (marked as \b _SEC_)
//! will be selected.
//!
//! - \b UDMA_DEF_USBEP1RX_SEC_UART2RX
//! - \b UDMA_DEF_USBEP1TX_SEC_UART2TX
//! - \b UDMA_DEF_USBEP2RX_SEC_TMR3A
//! - \b UDMA_DEF_USBEP2TX_SEC_TMR3B
//! - \b UDMA_DEF_USBEP3RX_SEC_TMR2A
//! - \b UDMA_DEF_USBEP3TX_SEC_TMR2B
//! - \b UDMA_DEF_ETH0RX_SEC_TMR2A
//! - \b UDMA_DEF_ETH0TX_SEC_TMR2B
//! - \b UDMA_DEF_UART0RX_SEC_UART1RX
//! - \b UDMA_DEF_UART0TX_SEC_UART1TX
//! - \b UDMA_DEF_SSI0RX_SEC_SSI1RX
//! - \b UDMA_DEF_SSI0TX_SEC_SSI1TX
//! - \b UDMA_DEF_RESERVED_SEC_UART2RX
//! - \b UDMA_DEF_RESERVED_SEC_UART2TX
//! - \b UDMA_DEF_ADC00_SEC_TMR2A
//! - \b UDMA_DEF_ADC01_SEC_TMR2B
//! - \b UDMA_DEF_ADC02_SEC_RESERVED
//! - \b UDMA_DEF_ADC03_SEC_RESERVED
//! - \b UDMA_DEF_TMR0A_SEC_TMR1A
//! - \b UDMA_DEF_TMR0B_SEC_TMR1B
//! - \b UDMA_DEF_TMR1A_SEC_EPI0RX
//! - \b UDMA_DEF_TMR1B_SEC_EPI0TX
//! - \b UDMA_DEF_UART1RX_SEC_RESERVED
//! - \b UDMA_DEF_UART1TX_SEC_RESERVED
//! - \b UDMA_DEF_SSI1RX_SEC_ADC10
//! - \b UDMA_DEF_SSI1TX_SEC_ADC11
//! - \b UDMA_DEF_RESERVED_SEC_ADC12
//! - \b UDMA_DEF_RESERVED_SEC_ADC13
//! - \b UDMA_DEF_I2S0RX_SEC_RESERVED
//! - \b UDMA_DEF_I2S0TX_SEC_RESERVED
//!
//! \return None.
//
//*****************************************************************************
void
uDMAChannelSelectSecondary(unsigned long ulSecPeriphs)
{
    //
    // Select the secondary peripheral for the specified channels.
    //
    HWREG(UDMA_CHALT) |= ulSecPeriphs;
}

//*****************************************************************************
//
//! Selects the default peripheral for a set of uDMA channels.
//!
//! \param ulDefPeriphs is the logical or of the uDMA channels for which to
//! use the default peripheral, instead of the secondary peripheral.
//!
//! This function is used to select the default peripheral assignment for
//! a set of uDMA channels.
//!
//! The parameter \e ulDefPeriphs can be the logical OR of any of the
//! following macros.  If one of the macros below is in the list passed
//! to this function, then the default peripheral (marked as \b _DEF_)
//! will be selected.
//!
//! - \b UDMA_DEF_USBEP1RX_SEC_UART2RX
//! - \b UDMA_DEF_USBEP1TX_SEC_UART2TX
//! - \b UDMA_DEF_USBEP2RX_SEC_TMR3A
//! - \b UDMA_DEF_USBEP2TX_SEC_TMR3B
//! - \b UDMA_DEF_USBEP3RX_SEC_TMR2A
//! - \b UDMA_DEF_USBEP3TX_SEC_TMR2B
//! - \b UDMA_DEF_ETH0RX_SEC_TMR2A
//! - \b UDMA_DEF_ETH0TX_SEC_TMR2B
//! - \b UDMA_DEF_UART0RX_SEC_UART1RX
//! - \b UDMA_DEF_UART0TX_SEC_UART1TX
//! - \b UDMA_DEF_SSI0RX_SEC_SSI1RX
//! - \b UDMA_DEF_SSI0TX_SEC_SSI1TX
//! - \b UDMA_DEF_RESERVED_SEC_UART2RX
//! - \b UDMA_DEF_RESERVED_SEC_UART2TX
//! - \b UDMA_DEF_ADC00_SEC_TMR2A
//! - \b UDMA_DEF_ADC01_SEC_TMR2B
//! - \b UDMA_DEF_ADC02_SEC_RESERVED
//! - \b UDMA_DEF_ADC03_SEC_RESERVED
//! - \b UDMA_DEF_TMR0A_SEC_TMR1A
//! - \b UDMA_DEF_TMR0B_SEC_TMR1B
//! - \b UDMA_DEF_TMR1A_SEC_EPI0RX
//! - \b UDMA_DEF_TMR1B_SEC_EPI0TX
//! - \b UDMA_DEF_UART1RX_SEC_RESERVED
//! - \b UDMA_DEF_UART1TX_SEC_RESERVED
//! - \b UDMA_DEF_SSI1RX_SEC_ADC10
//! - \b UDMA_DEF_SSI1TX_SEC_ADC11
//! - \b UDMA_DEF_RESERVED_SEC_ADC12
//! - \b UDMA_DEF_RESERVED_SEC_ADC13
//! - \b UDMA_DEF_I2S0RX_SEC_RESERVED
//! - \b UDMA_DEF_I2S0TX_SEC_RESERVED
//!
//! \return None.
//
//*****************************************************************************
void
uDMAChannelSelectDefault(unsigned long ulDefPeriphs)
{
    //
    // Select the default peripheral for the specified channels.
    //
    HWREG(UDMA_CHALT) &= ~ulDefPeriphs;
}

//*****************************************************************************
//
//! Registers an interrupt handler for the uDMA controller.
//!
//! \param ulIntChannel identifies which uDMA interrupt is to be registered.
//! \param pfnHandler is a pointer to the function to be called when the
//! interrupt is activated.
//!
//! This sets and enables the handler to be called when the uDMA controller
//! generates an interrupt.  The \e ulIntChannel parameter should be one of the
//! following:
//!
//! - \b UDMA_INT_SW to register an interrupt handler to process interrupts
//!   from the uDMA software channel (UDMA_CHANNEL_SW)
//! - \b UDMA_INT_ERR to register an interrupt handler to process uDMA error
//!   interrupts
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \note The interrupt handler for uDMA is for transfer completion when the
//! channel UDMA_CHANNEL_SW is used, and for error interrupts.  The
//! interrupts for each peripheral channel are handled through the individual
//! peripheral interrupt handlers.
//!
//! \return None.
//
//*****************************************************************************
void
uDMAIntRegister(unsigned long ulIntChannel, void (*pfnHandler)(void))
{
    //
    // Check the arguments.
    //
    ASSERT(pfnHandler);
    ASSERT((ulIntChannel == UDMA_INT_SW) || (ulIntChannel == UDMA_INT_ERR));

    //
    // Register the interrupt handler.
    //
    IntRegister(ulIntChannel, pfnHandler);

    //
    // Enable the memory management fault.
    //
    IntEnable(ulIntChannel);
}

//*****************************************************************************
//
//! Unregisters an interrupt handler for the uDMA controller.
//!
//! \param ulIntChannel identifies which uDMA interrupt to unregister.
//!
//! This function will disable and clear the handler to be called for the
//! specified uDMA interrupt.  The \e ulIntChannel parameter should be one of
//! \b UDMA_INT_SW or \b UDMA_INT_ERR as documented for the function
//! uDMAIntRegister().
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
uDMAIntUnregister(unsigned long ulIntChannel)
{
    //
    // Disable the interrupt.
    //
    IntDisable(ulIntChannel);

    //
    // Unregister the interrupt handler.
    //
    IntUnregister(ulIntChannel);
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

⌨️ 快捷键说明

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