Real Time FIR Filter - Distinctive Excellence award winner :)

Dependencies:   mbed

Revision:
0:b3e50e98acac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cr_dsplib_blockfir32.s	Sat Aug 13 17:35:52 2011 +0000
@@ -0,0 +1,144 @@
+   
+; Los cuatro argumentos de la funcion llegan por r0, r1, r2 y r3.
+; r0 = Puntero a las muestras de salida.
+; r1 = Puntero a las muestras de entrada.
+; r2 = Puntero a la estructura de los coeficientes.
+; r3 = Cantidad de muestras de entrada.
+; r4 = Cantidad de coeficientes.
+; r3 y r5 = Temporales donde se cargan los coeficientes de entrada (r3 esta sobrecargado)
+; r6,r7,r8,r9 = Acumuladores.
+; r10,r11,r12,r14 = Temporales en donde se cargan las muestras de entrada.
+; r0 = Se utiliza como mascara (r0 esta sobrecargado)
+
+    AREA asm_func, CODE, READONLY
+    
+    EXPORT vF_dspl_blockfir32
+
+vF_dspl_blockfir32
+
+    push {r4-r12,lr}   ; Almacena registros en el stack.
+    ldr r4,[r2,#4]     ; Levanta en el registro r4 la cantidad de coeficientes.
+    ldr r2,[r2]        ; Carga en r2 el puntero hacia los coeficientes.
+
+    ; Le resto la cantidad de coeficientes a r3 para evitar que genere el transitorio final.
+    ; r3 = r3 - r4 + 4
+    ; Recordar que las ultimas tres muestras de salida tienen que ser descartadas.
+  
+    sub r3,r3,r4
+    add r3,r3,#4
+
+LoopSample
+    mov r6,#0               ; Limpia los acumuladores (0 a 3)
+    mov r7,r6
+    mov r8,r6
+    mov r9,r6
+
+    push {r0, r3, r4} ; Guarda r3, r4 y r0 (son registros) en el stack.
+
+    ldr r0,=0x80000000
+
+    ldmia r1!,{r10,r11,r12,r14} ; Carga 4 muestras en r10, r11, r12 y r14. r1 queda apuntando a la proxima muestra.
+
+    ; Desplazo hacia la izquierda lo mas posible y complemento el bit MSB.
+    eor r10,r0,r10,LSL#16
+    eor r11,r0,r11,LSL#16
+    eor r12,r0,r12,LSL#16
+    eor r14,r0,r14,LSL#16
+
+    ; Desplazo aritmeticamente lo mas posible hacia la derecha.
+    mov r10,r10,ASR#22
+    mov r11,r11,ASR#22
+    mov r12,r12,ASR#22
+    mov r14,r14,ASR#22
+
+LoopTaps
+    ldmia r2!,{r3,r5} ;Carga 2 coeficientes en r3 y r5. r2 queda apuntando al proximo coeficiente.
+    
+    ; mla = multiply and accumulate
+    ; Multiplica un coeficiente por las cuatro muestras leidas y acumula.
+    mla r6,r10,r3,r6      ; r6 = (r6 + (r10 * r3))[31:0]
+    mla r7,r11,r3,r7      ; r7 = (r7 + (r11 * r3))[31:0]
+    mla r8,r12,r3,r8      ; r8 = (r8 + (r12 * r3))[31:0]
+    mla r9,r14,r3,r9      ; r9 = (r9 + (r14 * r3))[31:0]
+    
+    ldr r10,[r1],#4          ; Se carga en r10 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4)
+
+    ; Enmascaro, complemento el MSB y hago extension de signo.
+    eor r10,r0,r10,LSL#16
+    mov r10,r10,ASR#22
+
+    ldr r3,[r2],#4    ; Se carga en r3 lo apuntado por r2. Luego se incrementa r1 en 4 (r2=r2+4)
+    
+    mla r6,r11,r5,r6   ; r6 = (r6 + (r11 * r5))[31:0]
+    mla r7,r12,r5,r7   ; r7 = (r7 + (r12 * r5))[31:0]
+    mla r8,r14,r5,r8   ; r8 = (r8 + (r14 * r5))[31:0]
+    mla r9,r10,r5,r9   ; r9 = (r9 + (r10 * r5))[31:0]
+    
+    ldr r11,[r1],#4        ; Se carga en r11 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4)
+
+    ; Enmascaro, complemento el MSB y hago extension de signo.
+    eor r11,r0,r11,LSL#16
+    mov r11,r11,ASR#22
+
+    ldr r5,[r2],#4    ; Se carga en r5 lo apuntado por r2. Luego se incrementa r2 en 4 (r2=r2+4)
+                          ; Supongo que como se trabaja con la memoria alineada de a bytes, incrementar en 4 significa
+                          ; pararse en la proxima muestra (las muestras son de 32 bits).
+    
+    mla r6,r12,r3,r6   ; r6 = (r6 + (r12 * r3))[31:0]
+    mla r7,r14,r3,r7   ; r7 = (r7 + (r14 * r3))[31:0]
+    mla r8,r10,r3,r8   ; r8 = (r8 + (r10 * r3))[31:0]
+    mla r9,r11,r3,r9   ; r9 = (r9 + (r11 * r3))[31:0]
+    
+    ldr r12,[r1],#4        ; Se carga en r12 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4)
+
+    ; Enmascaro, complemento el MSB y hago extension de signo.
+    eor r12,r0,r12,LSL#16
+    mov r12,r12,ASR#22
+
+    subs r4,r4,#4   ;Este resta se puso aqu� para evitar que se forme una burbuja antes del branch.
+                          ;r4 = r4 - 4
+
+    mla r6,r14,r5,r6   ; r6 = (r6 + (r14 * r5))[31:0]
+    mla r7,r10,r5,r7   ; r7 = (r7 + (r10 * r5))[31:0]
+    mla r8,r11,r5,r8   ; r8 = (r8 + (r11 * r5))[31:0]
+    mla r9,r12,r5,r9   ; r9 = (r9 + (r12 * r5))[31:0]
+
+    ldr r14,[r1],#4        ; Se carga en r14 lo apuntado por r1. Luego se incrementa r1 en 4 (r1=r1+4)
+
+    ; Enmascaro, complemento el MSB y hago extension de signo.
+    eor r14,r0,r14,LSL#16
+    mov r14,r14,ASR#22
+
+    bne LoopTaps          ; Mira si se terminaron los coeficientes.
+    
+    ; Enmascaro y complemento el MSB (lo vuelvo a formato DAC).
+    ldr r0,=0xFFC0
+    and r6,r0,r6,LSR#16
+    and r7,r0,r7,LSR#16
+    and r8,r0,r8,LSR#16
+    and r9,r0,r9,LSR#16
+    eor r6,r6,#0x8000
+    eor r7,r7,#0x8000
+    eor r8,r8,#0x8000
+    eor r9,r9,#0x8000
+
+    pop {r0, r3, r4} ; Recupera r3, r4 y r0 desde el stack.
+    
+    ; Store the outputs
+    stmia r0!,{r6,r7,r8,r9} ; Guarda r6-4 en r0. r0 queda apuntando al proximo valor.
+
+    subs r3,r3,#4    ; hoisted up to avoid pipe delay before branch
+                                 ; r3 = r3 - 4
+
+    ; Reset Coeffs to start
+    sub r2,r2,r4,LSL#2 ; r2 = r2 - (r4 * 4)
+    
+    ; Walk along the input data by 4 samples each LoopSample iteration
+    sub r1,r1,r4,LSL#2 ; r1 = r1 - (r4 * 4)
+    
+    bne LoopSample ; Se terminaron las muestras de entrada?
+    
+    pop {r4-r12,lr} ; Restauro registros a su estado inicial.
+    bx lr ; Return
+    
+    end
\ No newline at end of file