//------------------------------------------------------------------------------ /// 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; }
//------------------------------------------------------------------------------ /// 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; }
//------------------------------------------------------------------------------ //./ Starts a SPI master transfer. This is a non blocking function. It will //./ return as soon as the transfer is started. //./ Returns 0 if the transfer has been started successfully; otherwise returns //./ SPID_ERROR_LOCK is the driver is in use, or SPID_ERROR if the command is not //./ valid. //./ \param pSpid Pointer to a Spid instance. //./ \param pCommand Pointer to the SPI command to execute. //------------------------------------------------------------------------------ unsigned char SPI_D_SendCommand(SpiD *pSpiD, SpiDCmd *pCommand) { AT91S_SPI *pSpiHw = pSpiD->pSpiHw; unsigned int spiMr; // Try to get the dataflash semaphore if (pSpiD->semaphore == 0) { return SPI_D_ERROR_LOCK; } pSpiD->semaphore--; // Enable the SPI Peripheral PERIPH_ENABLE(pSpiD->spiId); // Disable PDC transmitter and receiver #if !defined(at91sam3u) WRITE_SPI(pSpiHw, SPI_PTCR, AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS); #endif // Write to the MR register spiMr = READ_SPI(pSpiHw, SPI_MR); spiMr |= AT91C_SPI_PCS; spiMr &= ~((1 << pCommand->spiCs) << 16); WRITE_SPI(pSpiHw, SPI_MR, spiMr); // Initialize DMA controller using channel 0 for RX, 1 for TX. configureDmaChannels(); configureLinkList(pSpiHw, pCommand); // Initialize the callback pSpiD->pCurrentCommand = pCommand; // Enable the SPI TX & RX WRITE_SPI(pSpiHw, SPI_CR, AT91C_SPI_SPIEN); // Start DMA 0(RX) && 1(TX) DMA_EnableChannels((1 << DMA_CHANNEL_0) | (1 << DMA_CHANNEL_1)); // Enable DMA Interrupts DMA_EnableIt( (DMA_CBTC << DMA_CHANNEL_0) | (DMA_CBTC << DMA_CHANNEL_1)); return 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 ; }