예제 #1
0
파일: SpiD_Dma.c 프로젝트: Flyagin/BS-MRZV
//------------------------------------------------------------------------------
//./ Configure the DMA Channels: 0 RX, 1 TX.
//./ Channels are disabled after configure.
//------------------------------------------------------------------------------
static void configureDmaChannels(void)
{
    // Enable DMA Peripheral
    PERIPH_ENABLE(AT91C_ID_HDMA);
    // Enable DMA
    DMA_Enable();

    // Free status
    DMA_DisableIt(0xFFFFFFFF);
    DMA_GetChannelStatus();
    DMA_GetStatus();
    DMA_DisableChannels((1 << DMA_CHANNEL_0) | (1 << DMA_CHANNEL_1));
    // RX channel 0
    DMA_SetConfiguration(DMA_CHANNEL_0,
                          AT91C_HDMA_SRC_PER_2
                        | AT91C_HDMA_DST_PER_2
                        | AT91C_HDMA_SRC_H2SEL_HW
                        | AT91C_HDMA_DST_H2SEL_SW
                        | AT91C_HDMA_SOD_ENABLE
                        | AT91C_HDMA_FIFOCFG_LARGESTBURST
                        );

    // TX channel 1
    DMA_SetConfiguration(DMA_CHANNEL_1,
                          AT91C_HDMA_SRC_PER_1
                        | AT91C_HDMA_DST_PER_1
                        | AT91C_HDMA_SRC_H2SEL_SW
                        | AT91C_HDMA_DST_H2SEL_HW
                        | AT91C_HDMA_SOD_ENABLE
                        | AT91C_HDMA_FIFOCFG_LARGESTBURST
                        );
}
예제 #2
0
//------------------------------------------------------------------------------
/// Sends the contents of a data buffer a SSC peripheral, using the PDC. Returns
/// true if the buffer has been queued for transmission; otherwise returns
/// false.
/// \param ssc  Pointer to an AT91S_SSC instance.
/// \param buffer  Data buffer to send.
/// \param length  Size of the data buffer.
//------------------------------------------------------------------------------
unsigned char SSC_WriteBuffer(AT91S_SSC *ssc,
                                     void *buffer,
                                     unsigned int length)
{
#if !defined(CHIP_SSC_DMA)
    // Check if first bank is free
    if (ssc->SSC_TCR == 0) {

        ssc->SSC_TPR = (unsigned int) buffer;
        ssc->SSC_TCR = length;
        ssc->SSC_PTCR = AT91C_PDC_TXTEN;
        return 1;
    }
    // Check if second bank is free
    else if (ssc->SSC_TNCR == 0) {

        ssc->SSC_TNPR = (unsigned int) buffer;
        ssc->SSC_TNCR = length;
        return 1;
    }
#else

    unsigned short* startSourceAddr;
    unsigned short* startDestAddr;
    unsigned int srcAddress;
    unsigned int destAddress;
    unsigned int buffSize;
    unsigned int LLI_rownumber = 0;

    startSourceAddr = (unsigned short*)(buffer);
    startDestAddr = (unsigned short*)(&ssc->SSC_THR);
    srcAddress  = (unsigned int)startSourceAddr;    // Set the data start address
    destAddress = (unsigned int)startDestAddr;
    buffSize = length;
    if(buffSize > 0x8000){
        TRACE_WARNING("SSC DMA, size too big %d\n\r", buffSize);
        buffSize = 0x8000;
    }

    // Set DMA channel DSCR
    DMA_SetDescriptorAddr(BOARD_SSC_DMA_CHANNEL, (unsigned int)&LLI_CH[0]);

    // Clear any pending interrupts
    DMA_GetStatus();

    //Set DMA channel control B
    DMA_SetSourceBufferMode(BOARD_SSC_DMA_CHANNEL, DMA_TRANSFER_LLI,
                            (AT91C_HDMA_SRC_ADDRESS_MODE_INCR >> 24));
    DMA_SetDestBufferMode(BOARD_SSC_DMA_CHANNEL, DMA_TRANSFER_LLI,
                            (AT91C_HDMA_DST_ADDRESS_MODE_FIXED >> 28));
    DMA_SetFlowControl(BOARD_SSC_DMA_CHANNEL, AT91C_HDMA_FC_MEM2PER >> 21);

    // Set DMA channel config
    DMA_SetConfiguration(BOARD_SSC_DMA_CHANNEL, BOARD_SSC_DMA_HW_SRC_REQ_ID \
                                        | BOARD_SSC_DMA_HW_DEST_REQ_ID \
                                        | AT91C_HDMA_SRC_H2SEL_SW \
                                        | AT91C_HDMA_DST_H2SEL_HW \
                                        | AT91C_HDMA_SOD_DISABLE \
                                        | AT91C_HDMA_FIFOCFG_LARGESTBURST);

    // Set link list
    while(srcAddress < ((unsigned int)(startSourceAddr + buffSize)))
    {
        if(((unsigned int)(startSourceAddr + buffSize)) - srcAddress <= (BOARD_SSC_DMA_FIFO_SIZE) )
        {
            AT91F_Prepare_Multiple_Transfer(BOARD_SSC_DMA_CHANNEL, LLI_rownumber, LAST_ROW,
                                        srcAddress,
                                        destAddress,
                                        (((((unsigned int)(startSourceAddr + buffSize))
                                                - srcAddress)/2)
                                                  | AT91C_HDMA_SRC_WIDTH_HALFWORD
                                                  | AT91C_HDMA_DST_WIDTH_HALFWORD
                                                  | AT91C_HDMA_SCSIZE_1
                                                  | AT91C_HDMA_DCSIZE_1
                                                      ),
                                        ( //| AT91C_HDMA_DST_DSCR_FETCH_FROM_MEM
                                         AT91C_HDMA_DST_DSCR_FETCH_DISABLE
                                        | AT91C_HDMA_DST_ADDRESS_MODE_FIXED
                                        | AT91C_HDMA_SRC_DSCR_FETCH_FROM_MEM
                                        //| AT91C_HDMA_SRC_DSCR_FETCH_DISABLE
                                        | AT91C_HDMA_SRC_ADDRESS_MODE_INCR
                                        | AT91C_HDMA_FC_MEM2PER));
        }
        else
        {
            AT91F_Prepare_Multiple_Transfer(BOARD_SSC_DMA_CHANNEL, LLI_rownumber, 0,
                                        srcAddress,
                                        destAddress,
                                        ((BOARD_SSC_DMA_FIFO_SIZE)/2
                                            | AT91C_HDMA_SRC_WIDTH_HALFWORD
                                            | AT91C_HDMA_DST_WIDTH_HALFWORD
                                            | AT91C_HDMA_SCSIZE_1
                                            | AT91C_HDMA_DCSIZE_1
                                                ),
                                        ( //| AT91C_HDMA_DST_DSCR_FETCH_FROM_MEM
                                        AT91C_HDMA_DST_DSCR_FETCH_DISABLE
                                        | AT91C_HDMA_DST_ADDRESS_MODE_FIXED
                                        | AT91C_HDMA_SRC_DSCR_FETCH_FROM_MEM
                                        //| AT91C_HDMA_SRC_DSCR_FETCH_DISABLE
                                        | AT91C_HDMA_SRC_ADDRESS_MODE_INCR
                                        | AT91C_HDMA_FC_MEM2PER));

        }

        srcAddress += BOARD_SSC_DMA_FIFO_SIZE;

        
        LLI_rownumber++;
    }
#endif
    // No free banks
    return 0;
}