Real Time FIR Filter - Distinctive Excellence award winner :)

Dependencies:   mbed

dma.c

Committer:
Gonzakpo
Date:
2011-08-13
Revision:
0:b3e50e98acac

File content as of revision 0:b3e50e98acac:


#include "dma.h"

bool_t BufferTransferCompleted = FALSE;
pingpong_t BufferToProcess = PONG;

/* Interrupcion del DMA */
/* Se encarga de informar que se termino de leer un bloque desde el ADC */
extern "C" void DMA_IRQHandler(void)
{
    /* Aquí llega cuando se produce una interrupcion del DMA.
     * Dicha interrupcion se genera cada vez que se llena uno de los dos
     * buffers de entrada de datos del ADC. Como esto tambien esta sincronizado
     * con el DAC, la interrupcion tambien coincide con el cambio de buffer del
     * DAC.
     */
     
    /* Limpio flag de interrupcion */
    LPC_GPDMA->DMACIntTCClear = (1 << 0);

    /* Informo la aparicion de la interrupcion */
    BufferTransferCompleted = TRUE;

    /* Verifico que buffer corresponde procesar */
    /* Recordar que los buffers PING y PONG se procesan alternadamente */
    if(BufferToProcess == PONG)
    {
        BufferToProcess = PING;
    }
    else
    {
        BufferToProcess = PONG;
    }

}


void initDMAs(dmaLinkedListNode * pListADC, dmaLinkedListNode * pListDAC)
{
    LPC_SC->PCONP |= (1UL << 29);        /* Enciendo modulo DMA */

    LPC_GPDMA->DMACConfig = 1;     /* Habilito el DMA */

    LPC_GPDMA->DMACIntTCClear = 0xFF; /* Limpio cualquier interrupcion previa*/
    LPC_GPDMA->DMACIntErrClr = 0xFF;
    NVIC_EnableIRQ(DMA_IRQn);
    
    LPC_SC->RESERVED9 |= 1; /* Selecciono a MAT0.0 como fuente de DMA request (RESERVED9 == DMAREQSEL) */

    /* Inicializo el canal 0 con el primer nodo de la lista del ADC */
    LPC_GPDMACH0->DMACCSrcAddr = pListADC->sourceAddr;
    LPC_GPDMACH0->DMACCDestAddr = pListADC->destAddr;
    LPC_GPDMACH0->DMACCControl = pListADC->dmaControl;
    LPC_GPDMACH0->DMACCLLI = pListADC->nextNode;

    /* Configuro el canal 0 del DMA:
       SrcPeripheral = MAT0.0 = 8
       DestPeripheral = 0
       Transfer Type = Peripheral to Memory = 2
       IE = 0 (sin interrupciones de error)
       ITC = 1 (con interrupciones de transferencia completa)
       Halt = 0 (acepta DMA requests)
    */
    LPC_GPDMACH0->DMACCConfig = (0x8 << 1) | (0x2 << 11) | (0x1 << 15);

    /* Inicializo el canal 1 con el primer nodo de la lista del DAC */
    LPC_GPDMACH1->DMACCSrcAddr = pListDAC->sourceAddr;
    LPC_GPDMACH1->DMACCDestAddr = pListDAC->destAddr;
    LPC_GPDMACH1->DMACCControl = pListDAC->dmaControl;
    LPC_GPDMACH1->DMACCLLI = pListDAC->nextNode; /*Segun el user manual (pg 601) los dos bits menos significativos deben ser ceros*/
                                                 /*Seguramente sea porque la memoria esta alineada de cierta forma que sea imposible
                                                  * que estos dos bits no sean cero. En la note de aplicacion de DMA multiplican por
                                                  * 0xFFFFFFFC para asegurarse de eso. No creo que sea necesario y no tiene sentido.*/

    /* Configuro el canal 1 del DMA:
       SrcPeripheral = 0
       DestPeripheral = MAT0.0 = 8
       Transfer Type = Memory to Peripheral = 1
       IE = 0 (sin interrupciones de error)
       ITC = 0 (sin interrupciones de transferencia completa)
       Halt = 0 (acepta DMA requests)
    */
    LPC_GPDMACH1->DMACCConfig = (0x8 << 6) | (0x1 << 11);

    /*Listo, habilito los canales DMA apropiados*/
    LPC_GPDMACH0->DMACCConfig |= (1 << 0);
    LPC_GPDMACH1->DMACCConfig |= (1 << 0);

}