Real Time FIR Filter - Distinctive Excellence award winner :)

Dependencies:   mbed

Revision:
0:b3e50e98acac
--- /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);
+
+}