Esempio n. 1
0
//------------------------------------------------------------------------------
//         Local functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// This handler function must be called by the DMAC interrupt service routine.
/// Identifies which event was activated and calls the associated function.
//------------------------------------------------------------------------------ 
void DMAD_Handler()
{
    unsigned int  status;
    unsigned char channel;
    DmaTransfer *pTransfer;
    status = DMA_GetStatus();
    // Check if the buffer transfer completed is set.
    if(status & AT91C_BTC)
    {
        // Scan each channel status.
        for(channel = 0; channel < DMA_CHANNEL_NUM; channel++) {
            if(!(status & (DMA_BTC << channel))){
                continue;
            }
            
            dmad.transfers[channel].transferSize -= dmad.transfers[channel].bufSize;
            // if next buffer is to be the last buffer in the transfer, then clear the automatic mode bit.
            if(dmad.transfers[channel].transferSize <= dmad.transfers[channel].bufSize) {
                DMA_ClearAutoMode(channel);
            }
            // Transfer finished
            if(dmad.transfers[channel].transferSize == 0) {
                pTransfer = &(dmad.transfers[channel]);
                pTransfer->callback();
                DMA_DisableIt(DMA_BTC << channel); 
                DMA_DisableChannel(channel);
            }
            else
            {
                // Write the KEEPON field to clear the STALL states.
                DMA_KeeponChannel(channel);
            }
        }
    }
}
Esempio n. 2
0
//------------------------------------------------------------------------------
/// Starts buffer transfer on the given channel
/// \param channel Particular channel number.
/// \param size Total transfer size in byte.
/// \param callback Optional callback function.
/// \param polling Polling channel status enable.
//------------------------------------------------------------------------------
unsigned char DMAD_BufferTransfer(unsigned char channel, 
                                  unsigned int size, 
                                  DmaCallback callback, 
                                  unsigned char polling)
{
    DmaTransfer *pTransfer = &(dmad.transfers[channel]);
    // Check that no transfer is pending on the channel
    if (pTransfer-> transferSize > 0 ) {
        TRACE_ERROR("DAM transfer is already pending\n\r");
        return DMAD_ERROR_BUSY;
    }
    pTransfer->status = DMAD_ERROR_BUSY; 
    pTransfer->transferSize = size;
    pTransfer->callback = callback; 
    
    if(!polling){
        DMA_EnableIt(DMA_BTC << channel);
    }
    // Enable the channel.
    DMA_EnableChannel(channel);
    
    if(polling){
        while ((DMA_GetChannelStatus() & (DMA_ENA << channel)) == (DMA_ENA << channel));
        pTransfer->callback();
        DMA_DisableChannel(channel);
    }
    return 0;
}
Esempio n. 3
0
//------------------------------------------------------------------------------
/// Starts buffer transfer on the given channel
/// \param channel Particular channel number.
/// \param size Total transfer size in byte.
/// \param callback Optional callback function.
/// \param polling Polling channel status enable.
//------------------------------------------------------------------------------
U8 DMAD_BufferTransfer(U8 channel, U32 size, DmaCallback callback, U8 polling)
{
	DmaTransfer *pTransfer = &(dmad.transfers[channel]);
	
	if (pTransfer-> transferSize > 0 ) // Check that no transfer is pending on the channel
	{
		DEBUG_MSG("DAM transfer is already pending");
		return DMAD_ERROR_BUSY;
	}
	pTransfer->status = DMAD_ERROR_BUSY; 
	pTransfer->transferSize = size;
	pTransfer->callback = callback; 

	if(!polling)
	{
		DMA_EnableIt(0x1 << channel);
	}
	DMA_EnableChannel(channel); // Enable the channel.
	if(polling)
	{
		while ((DMA_GetChannelStatus() & (0x1 << channel)) == (0x1 << channel));
		if (pTransfer->callback)
		{
			pTransfer->callback();
		}
		pTransfer->transferSize = 0;
		DMA_DisableChannel(channel);
	}
	return 0;
}
Esempio n. 4
0
//------------------------------------------------------------------------------
//         Local functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// This handler function must be called by the DMAC interrupt service routine.
/// Identifies which event was activated and calls the associated function.
//------------------------------------------------------------------------------
extern void DMAC_IrqHandler( void )
{
    uint32_t dwStatus ;
    uint32_t dwChannel ;
    DmaTransfer *pTransfer ;

    dwStatus = DMA_GetStatus( DMAC ) ;

    // Check if the buffer transfer completed is set.
    if ( dwStatus & (DMAC_EBCISR_BTC0|DMAC_EBCISR_BTC1|DMAC_EBCISR_BTC2|DMAC_EBCISR_BTC3|DMAC_EBCISR_BTC4|DMAC_EBCISR_BTC5) )
    {
        // Scan each dwChannel status.
        for ( dwChannel = 0 ; dwChannel < DMA_CHANNEL_NUM ; dwChannel++ )
        {
            if ( !(dwStatus & (DMAC_EBCISR_BTC0 << dwChannel)) )
            {
                continue ;
            }

            dmad.transfers[dwChannel].transferSize -= dmad.transfers[dwChannel].bufSize ;

            // if next buffer is to be the last buffer in the transfer, then clear the automatic mode bit.
            if ( dmad.transfers[dwChannel].transferSize <= dmad.transfers[dwChannel].bufSize )
            {
                DMA_ClearAutoMode( DMAC, dwChannel ) ;
            }

            // Transfer finished
            if ( dmad.transfers[dwChannel].transferSize == 0 )
            {
                pTransfer = &(dmad.transfers[dwChannel]) ;
                pTransfer->callback() ;
                DMA_DisableIt( DMAC, DMAC_EBCIDR_BTC0 << dwChannel ) ;
                DMA_DisableChannel( DMAC, dwChannel ) ;
            }
            else
            {
                // Write the KEEPON field to clear the STALL states.
                DMA_KeeponChannel( DMAC, dwChannel ) ;
            }
        }
    }
}
Esempio n. 5
0
//------------------------------------------------------------------------------
/// Starts buffer transfer on the given dwChannel
/// \param dwChannel Particular dwChannel number.
/// \param size Total transfer size in byte.
/// \param callback Optional callback function.
/// \param polling Polling dwChannel status enable.
//------------------------------------------------------------------------------
extern uint32_t DMAD_BufferTransfer( uint32_t dwChannel, uint32_t dwSize,
                                     DmaCallback callback, uint32_t dwPolling )
{
    DmaTransfer *pTransfer = &(dmad.transfers[dwChannel]) ;

    // Check that no transfer is pending on the dwChannel
    if ( pTransfer-> transferSize > 0 )
    {
        TRACE_ERROR( "DAM transfer is already pending\n\r" ) ;

        return DMAD_ERROR_BUSY ;
    }

    pTransfer->status = DMAD_ERROR_BUSY ;
    pTransfer->transferSize = dwSize ;
    pTransfer->callback = callback ;

    if ( dwPolling == 0 )
    {
        DMA_EnableIt( DMAC, DMA_BTC << dwChannel ) ;
    }

    // Enable the dwChannel.
    DMA_EnableChannel( DMAC, dwChannel ) ;

    if ( dwPolling != 0 )
    {
        while ( (DMA_GetChannelStatus( DMAC ) & (DMAC_CHSR_ENA0 << dwChannel)) == (DMAC_CHSR_ENA0 << dwChannel)) ;

        if ( pTransfer->callback )
        {
            pTransfer->callback() ;
        }
        pTransfer->transferSize = 0 ;
        DMA_DisableChannel( DMAC, dwChannel ) ;
    }

    return 0 ;
}
Esempio n. 6
0
//------------------------------------------------------------------------------
/// This handler function must be called by the DMAC interrupt service routine.
/// Identifies which event was activated and calls the associated function.
//------------------------------------------------------------------------------ 
void DMAD_Handler()
{
	U32 status;
	U8 channel;
	DmaTransfer *pTransfer;

	status = DMA_GetStatus();
	if(status & (0xFF)) // Check if the buffer transfer completed is set.
	{
		for(channel = 0; channel < 8; channel++) // Scan each channel status.
		{
			if(!(status & (0x1 << channel)))
			{
				continue;
			}

			dmad.transfers[channel].transferSize -= dmad.transfers[channel].bufSize;
			if(dmad.transfers[channel].transferSize <= dmad.transfers[channel].bufSize) // if next buffer is to be the last buffer in the transfer, then clear the automatic mode bit.
			{
				DMA_ClearAutoMode(channel);
			}

			if(dmad.transfers[channel].transferSize == 0) // Transfer finished
			{
				pTransfer = &(dmad.transfers[channel]);
				pTransfer->callback();
				DMA_DisableIt(0x1 << channel); 
				DMA_DisableChannel(channel);
			}
			else
			{
				DMA_KeeponChannel(channel); // Write the KEEPON field to clear the STALL states.
			}
		}
	}
}