Gonzalo Brusco
/
QuiPAD
Real Time FIR Filter - Distinctive Excellence award winner :)
main.c@0:b3e50e98acac, 2011-08-13 (annotated)
- Committer:
- Gonzakpo
- Date:
- Sat Aug 13 17:35:52 2011 +0000
- Revision:
- 0:b3e50e98acac
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Gonzakpo | 0:b3e50e98acac | 1 | /* |
Gonzakpo | 0:b3e50e98acac | 2 | ============================================================================================== |
Gonzakpo | 0:b3e50e98acac | 3 | Name : QuiPad |
Gonzakpo | 0:b3e50e98acac | 4 | Contest Registration Number : NXP3854 |
Gonzakpo | 0:b3e50e98acac | 5 | Description : Real time FIR filter controlled by a touchpad |
Gonzakpo | 0:b3e50e98acac | 6 | ============================================================================================== |
Gonzakpo | 0:b3e50e98acac | 7 | */ |
Gonzakpo | 0:b3e50e98acac | 8 | |
Gonzakpo | 0:b3e50e98acac | 9 | #include "mbed.h" |
Gonzakpo | 0:b3e50e98acac | 10 | #include "cr_dsplib.h" |
Gonzakpo | 0:b3e50e98acac | 11 | #include "filters.h" |
Gonzakpo | 0:b3e50e98acac | 12 | #include "dma.h" |
Gonzakpo | 0:b3e50e98acac | 13 | #include "adc_dac.h" |
Gonzakpo | 0:b3e50e98acac | 14 | #include "timer.h" |
Gonzakpo | 0:b3e50e98acac | 15 | #include "config.h" |
Gonzakpo | 0:b3e50e98acac | 16 | #include "touchpad.h" |
Gonzakpo | 0:b3e50e98acac | 17 | #include "leds_mbed.h" |
Gonzakpo | 0:b3e50e98acac | 18 | |
Gonzakpo | 0:b3e50e98acac | 19 | |
Gonzakpo | 0:b3e50e98acac | 20 | #define init_ahb_ram0 0x2007c000 |
Gonzakpo | 0:b3e50e98acac | 21 | #define mid_ahb_ram0 0x2007DE00 |
Gonzakpo | 0:b3e50e98acac | 22 | #define init_ahb_ram1 0x20080000 |
Gonzakpo | 0:b3e50e98acac | 23 | #define mid_ahb_ram1 0x20081E00 |
Gonzakpo | 0:b3e50e98acac | 24 | |
Gonzakpo | 0:b3e50e98acac | 25 | /*Los buffers y listas de guardan en la memoria AHB SRAM*/ |
Gonzakpo | 0:b3e50e98acac | 26 | /*Esto es porque esta seccion de la memoria tiene menor tiempo de accesso*/ |
Gonzakpo | 0:b3e50e98acac | 27 | /*Los buffer del DAC tienen 3 muestras extra por un detalle del algoritmo de filtrado */ |
Gonzakpo | 0:b3e50e98acac | 28 | /*Esas tres muestras son descartadas luego al ser ignoradas por el DMA */ |
Gonzakpo | 0:b3e50e98acac | 29 | int dac_buff_ping[BLOCKSIZE+3] __attribute__ ((at(init_ahb_ram0))); /*Buffers de datos para el DAC*/ |
Gonzakpo | 0:b3e50e98acac | 30 | int dac_buff_pong[BLOCKSIZE+3] __attribute__ ((at(init_ahb_ram1))); |
Gonzakpo | 0:b3e50e98acac | 31 | int adc_buff_ping[(COEFF_AMOUNT-1)+BLOCKSIZE] __attribute__ ((at(mid_ahb_ram0))); /*Buffers de datos para el ADC*/ |
Gonzakpo | 0:b3e50e98acac | 32 | int adc_buff_pong[(COEFF_AMOUNT-1)+BLOCKSIZE] __attribute__ ((at(mid_ahb_ram1))); |
Gonzakpo | 0:b3e50e98acac | 33 | /* Los buffers estan distribuidos de tal forma que el filtrado de datos se realice solo en una |
Gonzakpo | 0:b3e50e98acac | 34 | * memoria SRAM a la vez y no estorbe la otra. De la misma forma, el DMA usa la otra memoria unicamente. |
Gonzakpo | 0:b3e50e98acac | 35 | * Asi logro que el DMA y el filtrado no compitan por la memoria y acelero el filtrado. |
Gonzakpo | 0:b3e50e98acac | 36 | */ |
Gonzakpo | 0:b3e50e98acac | 37 | |
Gonzakpo | 0:b3e50e98acac | 38 | int main(void) |
Gonzakpo | 0:b3e50e98acac | 39 | { |
Gonzakpo | 0:b3e50e98acac | 40 | tS_blockfir32_Coeff filter_pad; |
Gonzakpo | 0:b3e50e98acac | 41 | |
Gonzakpo | 0:b3e50e98acac | 42 | int i; |
Gonzakpo | 0:b3e50e98acac | 43 | |
Gonzakpo | 0:b3e50e98acac | 44 | /* La declaro como static para que se almacene en RAM */ |
Gonzakpo | 0:b3e50e98acac | 45 | static int filterRAM[256]; |
Gonzakpo | 0:b3e50e98acac | 46 | |
Gonzakpo | 0:b3e50e98acac | 47 | /* Estructura para obtencion de coordenadas */ |
Gonzakpo | 0:b3e50e98acac | 48 | touchpad_position current_position, prev_position, valid_position; |
Gonzakpo | 0:b3e50e98acac | 49 | |
Gonzakpo | 0:b3e50e98acac | 50 | valid_position.pos_x = 0; |
Gonzakpo | 0:b3e50e98acac | 51 | valid_position.pos_y = 0; |
Gonzakpo | 0:b3e50e98acac | 52 | |
Gonzakpo | 0:b3e50e98acac | 53 | /* Inicializacio DMA */ |
Gonzakpo | 0:b3e50e98acac | 54 | |
Gonzakpo | 0:b3e50e98acac | 55 | static dmaLinkedListNode DACdmaList[2]; /*Lista del DMA del DAC*/ |
Gonzakpo | 0:b3e50e98acac | 56 | static dmaLinkedListNode ADCdmaList[2]; /*Lista del DMA del ADC*/ |
Gonzakpo | 0:b3e50e98acac | 57 | |
Gonzakpo | 0:b3e50e98acac | 58 | dmaLinkedListNode *pNodeDACping = &(DACdmaList[0]); |
Gonzakpo | 0:b3e50e98acac | 59 | dmaLinkedListNode *pNodeDACpong = &(DACdmaList[1]); |
Gonzakpo | 0:b3e50e98acac | 60 | dmaLinkedListNode *pNodeADCping = &(ADCdmaList[0]); |
Gonzakpo | 0:b3e50e98acac | 61 | dmaLinkedListNode *pNodeADCpong = &(ADCdmaList[1]); |
Gonzakpo | 0:b3e50e98acac | 62 | |
Gonzakpo | 0:b3e50e98acac | 63 | /* Configuro los nodos de las listas de los canales DMA */ |
Gonzakpo | 0:b3e50e98acac | 64 | |
Gonzakpo | 0:b3e50e98acac | 65 | /* Nodos del DMA que copia de la memoria al DAC */ |
Gonzakpo | 0:b3e50e98acac | 66 | pNodeDACping->sourceAddr = (unsigned int) dac_buff_ping; /*Direccion inicial de lectura del buffer DAC*/ |
Gonzakpo | 0:b3e50e98acac | 67 | pNodeDACping->destAddr = (unsigned int) &(LPC_DAC->DACR); /*Direccion del DAC*/ |
Gonzakpo | 0:b3e50e98acac | 68 | pNodeDACping->nextNode = (unsigned int) pNodeDACpong; /*Proximo nodo de la lista*/ |
Gonzakpo | 0:b3e50e98acac | 69 | pNodeDACping->dmaControl = (unsigned int)BLOCKSIZE | /*Numero de transferencias en total (BLOCKSIZE)*/ |
Gonzakpo | 0:b3e50e98acac | 70 | ((unsigned int)0x0 << 12) | /*Numero de transferencias por burst de origen (1)*/ |
Gonzakpo | 0:b3e50e98acac | 71 | ((unsigned int)0x0 << 15) | /*Numero de transferencias por burst de destino (1)*/ |
Gonzakpo | 0:b3e50e98acac | 72 | ((unsigned int)0x2 << 18) | /*Ancho de bus de origen de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 73 | ((unsigned int)0x2 << 21) | /*Ancho de bus de destino de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 74 | ((unsigned int)0x0 << 24) | /*Reservado*/ |
Gonzakpo | 0:b3e50e98acac | 75 | ((unsigned int)0x1 << 26) | /*Incrementar source address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 76 | ((unsigned int)0x0 << 27) | /*No incrementar el destination address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 77 | ((unsigned int)0x0 << 28) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 78 | ((unsigned int)0x0 << 29) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 79 | ((unsigned int)0x0 << 30) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 80 | ((unsigned int)0x0 << 31); /*Deshabilito interrupcion de "transferencia completa"*/ |
Gonzakpo | 0:b3e50e98acac | 81 | |
Gonzakpo | 0:b3e50e98acac | 82 | pNodeDACpong->sourceAddr = (unsigned int) dac_buff_pong; /*Direccion inicial de lectura del buffer DAC*/ |
Gonzakpo | 0:b3e50e98acac | 83 | pNodeDACpong->destAddr = (unsigned int) &(LPC_DAC->DACR); /*Direccion del DAC*/ |
Gonzakpo | 0:b3e50e98acac | 84 | pNodeDACpong->nextNode = (unsigned int) pNodeDACping; /*Proximo nodo de la lista*/ |
Gonzakpo | 0:b3e50e98acac | 85 | pNodeDACpong->dmaControl = (unsigned int)BLOCKSIZE | /*Numero de transferencias en total (BLOCKSIZE)*/ |
Gonzakpo | 0:b3e50e98acac | 86 | ((unsigned int)0x0 << 12) | /*Numero de transferencias por burst de origen (1)*/ |
Gonzakpo | 0:b3e50e98acac | 87 | ((unsigned int)0x0 << 15) | /*Numero de transferencias por burst de destino (1)*/ |
Gonzakpo | 0:b3e50e98acac | 88 | ((unsigned int)0x2 << 18) | /*Ancho de bus de origen de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 89 | ((unsigned int)0x2 << 21) | /*Ancho de bus de destino de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 90 | ((unsigned int)0x0 << 24) | /*Reservado*/ |
Gonzakpo | 0:b3e50e98acac | 91 | ((unsigned int)0x1 << 26) | /*Incrementar source address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 92 | ((unsigned int)0x0 << 27) | /*No incrementar el destination address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 93 | ((unsigned int)0x0 << 28) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 94 | ((unsigned int)0x0 << 29) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 95 | ((unsigned int)0x0 << 30) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 96 | ((unsigned int)0x0 << 31); /*Deshabilito interrupcion de "transferencia completa"*/ |
Gonzakpo | 0:b3e50e98acac | 97 | |
Gonzakpo | 0:b3e50e98acac | 98 | /* Nodos del DMA que copia del ADC a la memoria */ |
Gonzakpo | 0:b3e50e98acac | 99 | pNodeADCping->sourceAddr = (unsigned int) &(LPC_ADC->ADDR0); /*Direccion de los datos de salida del ADC*/ |
Gonzakpo | 0:b3e50e98acac | 100 | pNodeADCping->destAddr = (unsigned int) &(adc_buff_ping[(COEFF_AMOUNT-1)]) ; /*Direccion del buffer del ADC*/ |
Gonzakpo | 0:b3e50e98acac | 101 | pNodeADCping->nextNode = (unsigned int) pNodeADCpong; /*Proximo nodo de la lista*/ |
Gonzakpo | 0:b3e50e98acac | 102 | pNodeADCping->dmaControl = (unsigned int)BLOCKSIZE | /*Numero de transferencias en total (BLOCKSIZE)*/ |
Gonzakpo | 0:b3e50e98acac | 103 | ((unsigned int)0x0 << 12) | /*Numero de transferencias por burst de origen (1)*/ |
Gonzakpo | 0:b3e50e98acac | 104 | ((unsigned int)0x0 << 15) | /*Numero de transferencias por burst de destino (1)*/ |
Gonzakpo | 0:b3e50e98acac | 105 | ((unsigned int)0x2 << 18) | /*Ancho de bus de origen de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 106 | ((unsigned int)0x2 << 21) | /*Ancho de bus de destino de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 107 | ((unsigned int)0x0 << 24) | /*Reservado*/ |
Gonzakpo | 0:b3e50e98acac | 108 | ((unsigned int)0x0 << 26) | /*No Incrementar source address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 109 | ((unsigned int)0x1 << 27) | /*Incrementar el destination address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 110 | ((unsigned int)0x0 << 28) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 111 | ((unsigned int)0x0 << 29) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 112 | ((unsigned int)0x0 << 30) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 113 | ((unsigned int)0x1 << 31); /*Habilito interrupcion de "transferencia completa"*/ |
Gonzakpo | 0:b3e50e98acac | 114 | |
Gonzakpo | 0:b3e50e98acac | 115 | pNodeADCpong->sourceAddr = (unsigned int) &(LPC_ADC->ADDR0); /*Direccion de los datos de salida del ADC*/ |
Gonzakpo | 0:b3e50e98acac | 116 | pNodeADCpong->destAddr = (unsigned int) &(adc_buff_pong[(COEFF_AMOUNT-1)]) ; /*Direccion del buffer del ADC*/ |
Gonzakpo | 0:b3e50e98acac | 117 | pNodeADCpong->nextNode = (unsigned int) pNodeADCping; /*Proximo nodo de la lista*/ |
Gonzakpo | 0:b3e50e98acac | 118 | pNodeADCpong->dmaControl = (unsigned int)BLOCKSIZE | /*Numero de transferencias en total (BLOCKSIZE)*/ |
Gonzakpo | 0:b3e50e98acac | 119 | ((unsigned int)0x0 << 12) | /*Numero de transferencias por burst de origen (1)*/ |
Gonzakpo | 0:b3e50e98acac | 120 | ((unsigned int)0x0 << 15) | /*Numero de transferencias por burst de destino (1)*/ |
Gonzakpo | 0:b3e50e98acac | 121 | ((unsigned int)0x2 << 18) | /*Ancho de bus de origen de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 122 | ((unsigned int)0x2 << 21) | /*Ancho de bus de destino de 32 bits */ |
Gonzakpo | 0:b3e50e98acac | 123 | ((unsigned int)0x0 << 24) | /*Reservado*/ |
Gonzakpo | 0:b3e50e98acac | 124 | ((unsigned int)0x0 << 26) | /*No Incrementar source address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 125 | ((unsigned int)0x1 << 27) | /*Incrementar el destination address luego de cada transferencia*/ |
Gonzakpo | 0:b3e50e98acac | 126 | ((unsigned int)0x0 << 28) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 127 | ((unsigned int)0x0 << 29) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 128 | ((unsigned int)0x0 << 30) | /*No usado en el LPC17xx*/ |
Gonzakpo | 0:b3e50e98acac | 129 | ((unsigned int)0x1 << 31); /*Habilito interrupcion de "transferencia completa"*/ |
Gonzakpo | 0:b3e50e98acac | 130 | |
Gonzakpo | 0:b3e50e98acac | 131 | /* Inicializo perifericos */ |
Gonzakpo | 0:b3e50e98acac | 132 | init_touchpad(); |
Gonzakpo | 0:b3e50e98acac | 133 | initADC(); |
Gonzakpo | 0:b3e50e98acac | 134 | initDAC(); |
Gonzakpo | 0:b3e50e98acac | 135 | initDMAs(pNodeADCping , pNodeDACping); |
Gonzakpo | 0:b3e50e98acac | 136 | init_timer(); |
Gonzakpo | 0:b3e50e98acac | 137 | |
Gonzakpo | 0:b3e50e98acac | 138 | /* Una vez inicializado el sistema, se tienen que atender las interrupciones generadas por el |
Gonzakpo | 0:b3e50e98acac | 139 | * DMA (cuando se llenan los buffer) y llamar a la funcion de filtrado FIR. */ |
Gonzakpo | 0:b3e50e98acac | 140 | |
Gonzakpo | 0:b3e50e98acac | 141 | /* Loop infinito. */ |
Gonzakpo | 0:b3e50e98acac | 142 | while(1) |
Gonzakpo | 0:b3e50e98acac | 143 | { |
Gonzakpo | 0:b3e50e98acac | 144 | if(BufferTransferCompleted == TRUE) |
Gonzakpo | 0:b3e50e98acac | 145 | { |
Gonzakpo | 0:b3e50e98acac | 146 | BufferTransferCompleted = FALSE; |
Gonzakpo | 0:b3e50e98acac | 147 | |
Gonzakpo | 0:b3e50e98acac | 148 | /* Obtengo posicion del touchpad */ |
Gonzakpo | 0:b3e50e98acac | 149 | current_position = get_position(); |
Gonzakpo | 0:b3e50e98acac | 150 | |
Gonzakpo | 0:b3e50e98acac | 151 | /* Aplico filtrado al valor de posicion para evitar ruido */ |
Gonzakpo | 0:b3e50e98acac | 152 | /* Verifico que la misma posicion se haya registrado dos veces seguidas */ |
Gonzakpo | 0:b3e50e98acac | 153 | /* En caso negativo, la descarto */ |
Gonzakpo | 0:b3e50e98acac | 154 | if ((prev_position.pos_x == current_position.pos_x) && (prev_position.pos_y == current_position.pos_y)) |
Gonzakpo | 0:b3e50e98acac | 155 | { |
Gonzakpo | 0:b3e50e98acac | 156 | valid_position.pos_x = current_position.pos_x; |
Gonzakpo | 0:b3e50e98acac | 157 | valid_position.pos_y = current_position.pos_y; |
Gonzakpo | 0:b3e50e98acac | 158 | } |
Gonzakpo | 0:b3e50e98acac | 159 | |
Gonzakpo | 0:b3e50e98acac | 160 | prev_position.pos_x = current_position.pos_x; |
Gonzakpo | 0:b3e50e98acac | 161 | prev_position.pos_y = current_position.pos_y; |
Gonzakpo | 0:b3e50e98acac | 162 | |
Gonzakpo | 0:b3e50e98acac | 163 | show_number_on_leds(valid_position.pos_y); |
Gonzakpo | 0:b3e50e98acac | 164 | |
Gonzakpo | 0:b3e50e98acac | 165 | /* Copio el filtro a utilizar a la RAM (mejora el tiempo de filtrado) */ |
Gonzakpo | 0:b3e50e98acac | 166 | for(i = 0; i < 256; i++) |
Gonzakpo | 0:b3e50e98acac | 167 | { |
Gonzakpo | 0:b3e50e98acac | 168 | /* filterRAM[i] = filters[valid_position.pos_x][valid_position.pos_y][i]; */ |
Gonzakpo | 0:b3e50e98acac | 169 | /* Por ahora, a modo de ejemplo, solo utilizo la coordenada Y */ |
Gonzakpo | 0:b3e50e98acac | 170 | filterRAM[i] = filters[valid_position.pos_y][i]; |
Gonzakpo | 0:b3e50e98acac | 171 | } |
Gonzakpo | 0:b3e50e98acac | 172 | |
Gonzakpo | 0:b3e50e98acac | 173 | filter_pad.NTaps = filter_length; |
Gonzakpo | 0:b3e50e98acac | 174 | filter_pad.pi_Coeff = filterRAM; |
Gonzakpo | 0:b3e50e98acac | 175 | |
Gonzakpo | 0:b3e50e98acac | 176 | if(BufferToProcess == PING) |
Gonzakpo | 0:b3e50e98acac | 177 | { |
Gonzakpo | 0:b3e50e98acac | 178 | /* Copio las ultimas (COEFF-1) muestras del buffer ping al buffer pong */ |
Gonzakpo | 0:b3e50e98acac | 179 | for(i=0; i < COEFF_AMOUNT-1; i++) |
Gonzakpo | 0:b3e50e98acac | 180 | { |
Gonzakpo | 0:b3e50e98acac | 181 | adc_buff_pong[i] = adc_buff_ping[BLOCKSIZE + i]; |
Gonzakpo | 0:b3e50e98acac | 182 | } |
Gonzakpo | 0:b3e50e98acac | 183 | /* Proceso el buffer adc_buff_ping y guardo resultados en dac_buff_ping */ |
Gonzakpo | 0:b3e50e98acac | 184 | vF_dspl_blockfir32(dac_buff_ping, adc_buff_ping, &filter_pad, (COEFF_AMOUNT-1)+BLOCKSIZE); |
Gonzakpo | 0:b3e50e98acac | 185 | } |
Gonzakpo | 0:b3e50e98acac | 186 | else |
Gonzakpo | 0:b3e50e98acac | 187 | { |
Gonzakpo | 0:b3e50e98acac | 188 | /* Copio las ultimas (COEFF-1) muestras del buffer pong al buffer ping */ |
Gonzakpo | 0:b3e50e98acac | 189 | for(i=0; i < COEFF_AMOUNT-1; i++) |
Gonzakpo | 0:b3e50e98acac | 190 | { |
Gonzakpo | 0:b3e50e98acac | 191 | adc_buff_ping[i] = adc_buff_pong[BLOCKSIZE + i]; |
Gonzakpo | 0:b3e50e98acac | 192 | } |
Gonzakpo | 0:b3e50e98acac | 193 | /* Proceso el buffer adc_buff_pong y guardo resultados en dac_buff_pong */ |
Gonzakpo | 0:b3e50e98acac | 194 | vF_dspl_blockfir32(dac_buff_pong, adc_buff_pong, &filter_pad, (COEFF_AMOUNT-1)+BLOCKSIZE); |
Gonzakpo | 0:b3e50e98acac | 195 | } |
Gonzakpo | 0:b3e50e98acac | 196 | } |
Gonzakpo | 0:b3e50e98acac | 197 | } |
Gonzakpo | 0:b3e50e98acac | 198 | |
Gonzakpo | 0:b3e50e98acac | 199 | return 1 ; /* Si se llego aqui, hay un problema! */ |
Gonzakpo | 0:b3e50e98acac | 200 | } |