]> git.llucax.com Git - z.facultad/66.09/etherled.git/blobdiff - src/leds.asm
Elimino config.h que estaba de más y hago que borre todos los archivos
[z.facultad/66.09/etherled.git] / src / leds.asm
index bc729f119f8ad42b40793e2e657a8fd8542f2848..ab80fbf5f6231f8d04d777b34dd271f10d6e5600 100644 (file)
@@ -10,7 +10,6 @@ LEDS_MAX_COLS    = 32       ; Cantidad máxima de columnas
 ; Variables públicas
 .globl  _leds_matrix_len    ; unsigned char
 .globl  _leds_matrix        ; unsigned int[LEDS_MAX_COLS]
-.globl  _leds_delay         ; unsigned char
 
 ; Funciones públicas
 .globl  _leds_init          ; void leds_init();
@@ -19,15 +18,17 @@ LEDS_MAX_COLS    = 32       ; Cantidad máxima de columnas
 .globl  _leds_write_low     ; void leds_write_low(unsigned char);
 .globl  _leds_write_high    ; void leds_write_high(unsigned char);
 .globl  _leds_delay_update  ; void leds_delay_update();
+.globl  _leds_lock          ; void leds_lock();
+.globl  _leds_unlock        ; void leds_unlock();
 .globl  _leds_timer2_isr    ; void leds_timer2_isr() interrupt 5;
 
 
 ; Constantes
-; UN CICLO DE MAQUINA SON 1.6666 useg (clock 8MHz)
-INTERVAL        = 33 ; 0.05ms (por el clock de 8MHz)
-LEDS_HIGH       = 0x0080
-LEDS_LOW        = 0x00c0
-DELAY_BASE      = 28 ; 16 columnas anda bien con 28 - (len / 2) == 20
+LEDS_LOW        = 0x0080 ; posición de xdata donde está el latch 1
+LEDS_HIGH       = 0x00c0 ; posición de xdata donde está el latch 2
+DELAY_FACTOR    = 0      ; base del contador para el retardo
+DELAY_BASE      = 13     ; punto medio del retardo
+DELAY_DIVISOR   = 3      ; divisor para la cantidad de columnas
 
 ; Área de bancos de registros
 .area   REG_BANK_0    (REL,OVR,DATA)
@@ -44,19 +45,21 @@ DELAY_BASE      = 28 ; 16 columnas anda bien con 28 - (len / 2) == 20
 
 ; Variables es memoria RAM común
 .area   DSEG    (DATA)
-_leds_matrix_len::
+_leds_matrix_len::  ; Cantidad de columnas de la matriz
     .ds     1
-_leds_delay::
+curr_col:           ; Columna que se está dibujando actualmente
     .ds     1
-delay:
-    .ds     1
-curr_col:
 
 ; Variables en memoria RAM extendida indirecta (8052)
 .area   ISEG    (DATA)
-_leds_matrix::
+_leds_matrix::      ; Matriz a dibujar
     .ds     LEDS_MAX_COLS * 2  ; 2 bytes por columna
 
+; Variables de bit
+.area   BSEG    (BIT)
+lock:               ; Variable utilizada para el 'locking', indica si el timer
+    .ds     1       ; estaba andando al momento de lockear para que el unlock
+                    ; pueda reactivarlo de ser necesario
 
 ; Configuramos el vector de interrupciones para atender el timer2
 ;.area   INTV    (ABS, CODE)
@@ -89,8 +92,8 @@ _leds_init::
     mov     r2, a ; tamaño en bytes de la matriz
 
     ; Cargo milisegundos
-    acall   _leds_delay_update
-    mov     delay, _leds_delay
+    mov     rcap2l, #-DELAY_FACTOR  ; base del retardo
+    lcall   _leds_delay_update
 
     ; copio imagen por default de la ROM a la RAM
     mov     dptr, #DEFAULT_MATRIX
@@ -105,12 +108,8 @@ proximo$:
     mov     a, r0 ; para comparar
     cjne    a, ar2, proximo$ ; veo si quedan más bytes por leer
 
-    ; cargo los capture registers
-    mov     rcap2l, #<(-INTERVAL) ; low byte del intervalo
-    mov     rcap2h, #>(-INTERVAL) ; high byte del intervalo
-
     mov     t2con, #0x00; setup del timer2 (auto-reload), no lo arrancamos
-    setb    et2 ; habilito interrupcion timer2 (IE.5)
+    setb    tr2 ; largo a correr el timer2
 
     mov     curr_col, #0  ; inicializo el contador de columna en 0
 
@@ -130,20 +129,20 @@ proximo$:
 _leds_test::
     ; escribo patrones en los leds
     mov     dptr, #0xffff
-    acall   _leds_write
-    acall   sleep
+    lcall   _leds_write
+    lcall   sleep
 
     mov     dptr, #0xaaaa
-    acall   _leds_write
-    acall   sleep
+    lcall   _leds_write
+    lcall   sleep
     
     mov     dptr, #0x5555
-    acall   _leds_write
-    acall   sleep
+    lcall   _leds_write
+    lcall   sleep
 
     mov     dptr, #0x0000
-    acall   _leds_write
-    acall   sleep
+    lcall   _leds_write
+    lcall   sleep
     
     ret    
 
@@ -204,16 +203,52 @@ _leds_write_high::
 ; Primitiva de C:
 ;                   void leds_delay_update();
 ;
-; La fórmula utilizada es: (DELAY_BASE - (leds_matrix_len / 2)) * 0.1 ms
+; La fórmula utilizada es:
+;   DELAY_FACTOR * (DELAY_BASE - (leds_matrix_len / DELAY_DIVISOR))
+; En realidad ya está cargado rcap2l DELAY_FACTOR (constante) y en rcap2h se
+; carga el resultado de:
+;   DELAY_BASE - (leds_matrix_len / DELAY_DIVISOR)
 ; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
 _leds_delay_update::
+    push    b ; uso b, lo guardo
     mov     a, _leds_matrix_len
-    clr     c
-    rrc     a ; divido por 2
+    mov     b, #DELAY_DIVISOR
+    div     ab ; en a me queda leds_matrix_len / DELAY_DIVISOR
     mov     dpl, a
     mov     a, #DELAY_BASE
-    subb    a, dpl
-    mov     _leds_matrix_len, a
+    subb    a, dpl ; en a me queda DELAY_BASE - leds_matrix_len / DELAY_DIVISOR
+    jnb     cy, 1$ ; Si leds_matrix_len / DELAY_DIVISOR > DELAY_BASE
+    mov     a, #1 ; ponemos 1 para que no quede nulo el intervalo (o 'negativo')
+1$:               ; Si no, seguimos como siempre
+    mov     dpl, a  ; complemento a la base
+    mov     a, #0
+    subb    a, dpl 
+    mov     rcap2h, a ; Cargo el nuevo retardo
+    pop     b ; devuelvo b
+    ret
+
+
+; Bloquea el timer de los leds cuando se accede a una zona crítica (P0 y/o P2).
+; Primitiva de C:
+;                   void leds_lock();
+;
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_lock::
+    mov     c, et2      ; En lock me queda si está el timer andando o no.
+    mov     lock, c
+    clr     et2         ; Sea como sea, lo paro.
+    ret
+
+
+; Desbloquea el timer de los leds.
+; Primitiva de C:
+;                   void leds_unlock();
+;
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_unlock::
+    jnb     lock, 1$    ; Si no estába andando, no hago nada
+    setb    et2         ; Si estaba andando lo prendo
+1$:
     ret
     
 
@@ -222,11 +257,8 @@ _leds_delay_update::
 ;                   void leds_timer2_isr() interrupt 5;
 ;
 _leds_timer2_isr::
-    ; vemos si todavía hay que seguir esperando o si ya tenemos que leer
-    djnz    delay, 255$
-
-    ; comenzamos realmente a leer la próxima columna
-    mov     delay, _leds_delay
+    ; limpiamos flag del timer2
+    clr     tf2
 
     ; guardamos en el stack el estado actual de los registros que vamos a usar
     push    acc
@@ -253,16 +285,16 @@ _leds_timer2_isr::
     add     a, r0 ; le sumo al puntero el offset actual segun la columna
     mov     r0, a
 
-    ; imprimo en LEDS_LOW
+    ; imprimo en LEDS_HIGH
     mov     a, @r0 ; leo el contenido de la matriz
-    mov     dptr, #LEDS_LOW
+    mov     dptr, #LEDS_HIGH
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
 
-    ; imprimo en LEDS_HIGH
+    ; imprimo en LEDS_LOW
     inc     r0     ; busco proximo byte de la columna
     mov     a, @r0 ; leo el contenido de la matriz
-    mov     dptr, #LEDS_HIGH
+    mov     dptr, #LEDS_LOW
     cpl     a ; complemento para ver encendidos los "1"
     movx    @dptr, a
 
@@ -278,7 +310,6 @@ _leds_timer2_isr::
     pop     psw
     pop     acc
 
-255$:
     reti ; listo! seguimos viaje...
 
 
@@ -319,22 +350,39 @@ DEFAULT_MATRIX:
     .dw     0b0011111111111100    ; columna 14
     .dw     0b0000111111110000    ; columna 15
 
-    .dw     0b1111000000001111    ; columna 0
-    .dw     0b1100000000000011    ; columna 1
-    .dw     0b1000111111110001    ; columna 2
-    .dw     0b1001111111111001    ; columna 3
-    .dw     0b0011001111111100    ; columna 4
-    .dw     0b0011100111001100    ; columna 5
-    .dw     0b0011110011001100    ; columna 6
-    .dw     0b0011110011111100    ; columna 7
-    .dw     0b0011110011111100    ; columna 8
-    .dw     0b0011110011001100    ; columna 9
-    .dw     0b0011100111001100    ; columna 01
-    .dw     0b0011001111111100    ; columna 00
-    .dw     0b1001111111111001    ; columna 01
-    .dw     0b1000111111110001    ; columna 03
-    .dw     0b1100000000000011    ; columna 04
-    .dw     0b1111000000001111    ; columna 05
+;    .dw     0b0000011111100000
+;    .dw     0b0001111111111000
+;    .dw     0b0011100000011100
+;    .dw     0b0111110000000110
+;    .dw     0b0110111000000110
+;    .dw     0b1100011100000011
+;    .dw     0b1100001110000011
+;    .dw     0b1111111111111111
+;    .dw     0b1111111111111111
+;    .dw     0b1100001110000011
+;    .dw     0b1100011100000011
+;    .dw     0b0110111000000110
+;    .dw     0b0111110000000110
+;    .dw     0b0011100000011100
+;    .dw     0b0001111111111000
+;    .dw     0b0000011111100000
+
+;    .dw     0b1111000000001111    ; columna 0
+;    .dw     0b1100000000000011    ; columna 1
+;    .dw     0b1000111111110001    ; columna 2
+;    .dw     0b1001111111111001    ; columna 3
+;    .dw     0b0011001111111100    ; columna 4
+;    .dw     0b0011100111001100    ; columna 5
+;    .dw     0b0011110011001100    ; columna 6
+;    .dw     0b0011110011111100    ; columna 7
+;    .dw     0b0011110011111100    ; columna 8
+;    .dw     0b0011110011001100    ; columna 9
+;    .dw     0b0011100111001100    ; columna 01
+;    .dw     0b0011001111111100    ; columna 00
+;    .dw     0b1001111111111001    ; columna 01
+;    .dw     0b1000111111110001    ; columna 03
+;    .dw     0b1100000000000011    ; columna 04
+;    .dw     0b1111000000001111    ; columna 05
 
 ;    .dw     0b0000001111100000    ; columna 0
 ;    .dw     0b0000111110000000    ; columna 1