Gonzalo Brusco
/
QuiPAD
Real Time FIR Filter - Distinctive Excellence award winner :)
Diff: dma.c
- Revision:
- 0:b3e50e98acac
diff -r 000000000000 -r b3e50e98acac dma.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dma.c Sat Aug 13 17:35:52 2011 +0000 @@ -0,0 +1,89 @@ + +#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); + +}