Real Time FIR Filter - Distinctive Excellence award winner :)

Dependencies:   mbed

cr_dsplib_blockfir32.s

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

File content as of revision 0:b3e50e98acac:

   
; 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