]> git.llucax.com Git - z.facultad/66.09/etherled.git/commitdiff
Se implementa un sistema primitivo de 'locking' para los leds. Cada vez que se
authorLeandro Lucarella <llucax@gmail.com>
Tue, 13 Dec 2005 21:10:03 +0000 (21:10 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Tue, 13 Dec 2005 21:10:03 +0000 (21:10 +0000)
lee o se escribe un registro de la placa de red, se deja de atender las
interrupciones del timer de los leds para evitar una condición de carrera del
puerto 2. También se hacen otros cambios pequeños:
* Se hace un cheque sobre el tamaño de la matriz que viene de la red.
* Se cambia el intervalo del timer de los leds (cuanto más grande menos
  interrupciones se saltea). Hay algo más de trabajo por hacer en este área.
* Se corrige un bug en leds.asm, en algún momento se borró el .ds 1 que
  reservaba memoria para curr_col, que estaba tomando 'prestado' el 1er byte de
  la matriz (o peor, tomando un byte de vaya uno a saber dónde).

src/dp8390.c
src/elp.c
src/leds.asm
src/leds.h
src/main.c
src/reg51keil.h
src/reg51sdcc.h

index 5c472a5cb87311ccad342b9eb7b40c175979265d..76d0c6d3a292d321eb74457c11df9aadcba48809 100644 (file)
@@ -40,6 +40,7 @@ recv_state;
 
 static void write_reg(unsigned char reg, unsigned char wr_data)
 {
 
 static void write_reg(unsigned char reg, unsigned char wr_data)
 {
+    leds_lock();
     // Select register address.
     ADDR_PORT &= ~ADDR_PORT_MASK; 
     ADDR_PORT |= reg;
     // Select register address.
     ADDR_PORT &= ~ADDR_PORT_MASK; 
     ADDR_PORT |= reg;
@@ -56,11 +57,13 @@ static void write_reg(unsigned char reg, unsigned char wr_data)
 
     // Set register data port as input again.
     DATA_PORT = DATA_PORT_MASK;
 
     // Set register data port as input again.
     DATA_PORT = DATA_PORT_MASK;
+    leds_unlock();
 } 
 
 
 static unsigned char read_reg(unsigned char reg)
 {
 } 
 
 
 static unsigned char read_reg(unsigned char reg)
 {
+    leds_lock();
     // Select register address.
     ADDR_PORT &= ~ADDR_PORT_MASK;
     ADDR_PORT |= reg;
     // Select register address.
     ADDR_PORT &= ~ADDR_PORT_MASK;
     ADDR_PORT |= reg;
@@ -76,6 +79,7 @@ static unsigned char read_reg(unsigned char reg)
     IOR = 1; 
     NICE = 1;   
 
     IOR = 1; 
     NICE = 1;   
 
+    leds_unlock();
     return reg;
 } 
 
     return reg;
 } 
 
index 6a2a6549f2682392515b5e801477199f82d0843d..69e349065b0e72c2b7fe57303c15107870617453 100644 (file)
--- a/src/elp.c
+++ b/src/elp.c
@@ -18,8 +18,6 @@ byte elp_read_process_command()
     *((byte*) &elp_command) = udp_read_byte();
     netdev_read_end();
 
     *((byte*) &elp_command) = udp_read_byte();
     netdev_read_end();
 
-    printb(*((byte*) &elp_command), 0x01);
-
     // Si es un SET lo proceso
     switch (elp_command.var)
     {
     // Si es un SET lo proceso
     switch (elp_command.var)
     {
@@ -45,7 +43,7 @@ byte elp_read_process_command()
             i = udp_read_byte();
             netdev_read_end();
             // Verifico cantidad de columnas
             i = udp_read_byte();
             netdev_read_end();
             // Verifico cantidad de columnas
-            if ((LEDS_MIN_COLS < i) || (i < LEDS_MAX_COLS))
+            if ((i < LEDS_MIN_COLS) || (i > LEDS_MAX_COLS))
                 return 0;
             leds_matrix_len = i;
             netdev_read_start(leds_matrix_len * 2); // matriz
                 return 0;
             leds_matrix_len = i;
             netdev_read_start(leds_matrix_len * 2); // matriz
@@ -64,12 +62,11 @@ byte elp_read_process_command()
                 return len + 1 /* booleano de 1 byte */;
             // Si es SET procesamos
             netdev_read_start(1); // booleano de 1 byte
                 return len + 1 /* booleano de 1 byte */;
             // Si es SET procesamos
             netdev_read_start(1); // booleano de 1 byte
-            //XXX if (udp_read_byte() == 0x00) // si viene 0 reanuda
-                //XXX TR2 = 1;
-            //XXX else
-            if (udp_read_byte() != 0x00)
+            if (udp_read_byte() == 0x00) // si viene 0 reanuda
+                ET2 = 1;
+            else
             {
             {
-                TR2 = 0;
+                ET2 = 0;
                 leds_write(0x0000); // Si pausa apaga leds
             }
             netdev_read_end();
                 leds_write(0x0000); // Si pausa apaga leds
             }
             netdev_read_end();
@@ -119,7 +116,7 @@ void elp_write_response()
 
         case ELP_VAR_PAUSE:
             netdev_write_start(1 /* booleano de 1 byte */);
 
         case ELP_VAR_PAUSE:
             netdev_write_start(1 /* booleano de 1 byte */);
-            udp_write_byte(!TR2);
+            udp_write_byte(!ET2);
             netdev_write_end();
             break;
 
             netdev_write_end();
             break;
 
index db579cdb008f9db1b6535d980c759584c0ee832b..558f13fd04acdf8a8164220f9d07732df8ec3d86 100644 (file)
@@ -19,15 +19,16 @@ 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_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
 .globl  _leds_timer2_isr    ; void leds_timer2_isr() interrupt 5;
 
 
 ; Constantes
-; UN CICLO DE MAQUINA SON 1.6666 useg (clock 8MHz)
-INTERVAL        = 65000 ; 0.05ms (por el clock de 8MHz)
+INTERVAL        = 666 ; 0.1ms (por el clock de 8MHz)
 LEDS_LOW        = 0x0080
 LEDS_HIGH       = 0x00c0
 LEDS_LOW        = 0x0080
 LEDS_HIGH       = 0x00c0
-DELAY_BASE      = 28 ; 16 columnas anda bien con 28 - (len / 2) == 20
+DELAY_BASE      = 11 ; 16 columnas anda bien con 28 - (len / 2) == 20
 
 ; Área de bancos de registros
 .area   REG_BANK_0    (REL,OVR,DATA)
 
 ; Área de bancos de registros
 .area   REG_BANK_0    (REL,OVR,DATA)
@@ -44,19 +45,25 @@ DELAY_BASE      = 28 ; 16 columnas anda bien con 28 - (len / 2) == 20
 
 ; Variables es memoria RAM común
 .area   DSEG    (DATA)
 
 ; Variables es memoria RAM común
 .area   DSEG    (DATA)
-_leds_matrix_len::
+_leds_matrix_len::  ; Cantidad de columnas de la matriz
     .ds     1
     .ds     1
-_leds_delay::
+_leds_delay::       ; Retardo de dibujado configurado
     .ds     1
     .ds     1
-delay:
+delay:              ; Contador del retardo actual
+    .ds     1
+curr_col:           ; Columna que se está dibujando actualmente
     .ds     1
     .ds     1
-curr_col:
 
 ; Variables en memoria RAM extendida indirecta (8052)
 .area   ISEG    (DATA)
 
 ; 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
 
     .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)
 
 ; Configuramos el vector de interrupciones para atender el timer2
 ;.area   INTV    (ABS, CODE)
@@ -110,7 +117,7 @@ proximo$:
     mov     rcap2h, #>(-INTERVAL) ; high byte del intervalo
 
     mov     t2con, #0x00; setup del timer2 (auto-reload), no lo arrancamos
     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
 
 
     mov     curr_col, #0  ; inicializo el contador de columna en 0
 
@@ -215,6 +222,30 @@ _leds_delay_update::
     subb    a, dpl
     mov     _leds_delay, a
     ret
     subb    a, dpl
     mov     _leds_delay, a
     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
     
 
 ; Manejador de la interrupción del timer2 para el uso de los leds.
     
 
 ; Manejador de la interrupción del timer2 para el uso de los leds.
@@ -222,6 +253,8 @@ _leds_delay_update::
 ;                   void leds_timer2_isr() interrupt 5;
 ;
 _leds_timer2_isr::
 ;                   void leds_timer2_isr() interrupt 5;
 ;
 _leds_timer2_isr::
+    ; limpiamos flag del timer2
+    clr     tf2
     ; vemos si todavía hay que seguir esperando o si ya tenemos que leer
     djnz    delay, 255$
 
     ; vemos si todavía hay que seguir esperando o si ya tenemos que leer
     djnz    delay, 255$
 
index b24a6d632618ca99435ecd76dc9c0c657a138a86..c69a956044fc4aa60aa9877fc870d78f5d8ff9ce 100644 (file)
@@ -42,6 +42,14 @@ void leds_write_high(unsigned char);
 /** Actualiza el delay al recomendado según el tamaño de la matriz */
 void leds_delay_update();
 
 /** Actualiza el delay al recomendado según el tamaño de la matriz */
 void leds_delay_update();
 
+/** Bloquea timer de leds cuando se accede a una zona crítica (P0 y/o P2). */
+void leds_lock();
+
+/** Desbloquea el timer de los leds.
+ * @precond Se llamó a leds_lock();
+ */
+void leds_unlock();
+
 /** Atiende interrupción del timer2 para 'dibujar' la matriz */
 void leds_timer2_isr() interrupt 5;
 
 /** Atiende interrupción del timer2 para 'dibujar' la matriz */
 void leds_timer2_isr() interrupt 5;
 
index 69e0a54476655f3d405dd2a6e904b65e0c419651..9714789a5ad855b0e53a54c70cca47e7f46be20d 100644 (file)
@@ -27,7 +27,7 @@ void main(void)
 
     // Comienza a 'dibujar'
     EA  = 1; // Habilita interrupciones globalmente
 
     // Comienza a 'dibujar'
     EA  = 1; // Habilita interrupciones globalmente
-    //XXX TR2 = 1; // Pone a correr el 'dibujado'
+    ET2 = 1; // Pone a correr el 'dibujado'
 
     // Inicializo IP
     ip_addr_local[0] = 10;
 
     // Inicializo IP
     ip_addr_local[0] = 10;
@@ -76,42 +76,37 @@ void main(void)
                         // Procesamos comando ELP y obtenemos tamaño de la
                         // respuesta
                         len = elp_read_process_command();
                         // Procesamos comando ELP y obtenemos tamaño de la
                         // respuesta
                         len = elp_read_process_command();
-                        printb(len, 0x02);
+                        //printb(len, 0x02);
 
                         // Si el tamaño es 0, hubo error o no está soportado
                         if (!len)
                             goto drop;
 
                         // Si el tamaño es 0, hubo error o no está soportado
                         if (!len)
                             goto drop;
-                        print(0x0004);
+                        //print(0x0004);
 
                         // FIXME por ahora no tenemos forma de 'abortar' el
                         // comando si el checksum es incorrecto, lo verificamos
                         // por deporte.
                         if (!udp_checksum_ok())
                             goto drop;
 
                         // FIXME por ahora no tenemos forma de 'abortar' el
                         // comando si el checksum es incorrecto, lo verificamos
                         // por deporte.
                         if (!udp_checksum_ok())
                             goto drop;
-                        print(0x0008);
+                        //print(0x0008);
 
                         // Terminamos recepción
                         netdev_recv_end();
 
                         // Terminamos recepción
                         netdev_recv_end();
-                        print(0x0010);
+                        //print(0x0010);
 
                         // Respuesta
                         netdev_send_start();
                         eth_write_frame_header();
                         ip_packet_len = UDP_HEADER_SIZE + len;
 
                         // Respuesta
                         netdev_send_start();
                         eth_write_frame_header();
                         ip_packet_len = UDP_HEADER_SIZE + len;
-                        printb(ip_packet_len, 0x20);
+                        //printb(ip_packet_len, 0x20);
                         ip_write_packet_header();
                         udp_dgram_len = len;
                         ip_write_packet_header();
                         udp_dgram_len = len;
-                        printb(udp_dgram_len, 0x40);
+                        //printb(udp_dgram_len, 0x40);
                         udp_write_dgram_header();
                         elp_write_response();
                         udp_write_checksum(ETH_HEADER_SIZE + IP_HEADER_SIZE);
                         netdev_send_end(ETH_HEADER_SIZE + IP_HEADER_SIZE
                                 + UDP_HEADER_SIZE + len);
                         udp_write_dgram_header();
                         elp_write_response();
                         udp_write_checksum(ETH_HEADER_SIZE + IP_HEADER_SIZE);
                         netdev_send_end(ETH_HEADER_SIZE + IP_HEADER_SIZE
                                 + UDP_HEADER_SIZE + len);
-                        printb(ETH_HEADER_SIZE + IP_HEADER_SIZE
-                                + UDP_HEADER_SIZE + len, 0x80);
-                        //XXX
-                        if (elp_command.set && (elp_command.var == ELP_VAR_PAUSE))
-                            TR2 = 1;
                 }
         }
         continue;
                 }
         }
         continue;
index a40d8aba6189d7f84f36c543d6afa9f7acd62e29..426783b8f731dd41ba85c3378710e04f141fd928 100644 (file)
@@ -62,6 +62,7 @@ sbit CP_RL2C = 0xC8;
 
 /*  IE   */
 sbit EA   = 0xAF;
 
 /*  IE   */
 sbit EA   = 0xAF;
+sbit ET2  = 0xAD;
 sbit ES   = 0xAC;
 sbit ET1  = 0xAB;
 sbit EX1  = 0xAA;
 sbit ES   = 0xAC;
 sbit ET1  = 0xAB;
 sbit EX1  = 0xAA;
index 1710d8eeff612747f8a9ef0226af6f13181332a0..29f7d0750b5d46b79613da3b01f85aef8f321cf5 100644 (file)
@@ -62,6 +62,7 @@ sbit at 0xC8 CP_RL2C;
 
 /*  IE   */
 sbit at 0xAF EA;
 
 /*  IE   */
 sbit at 0xAF EA;
+sbit at 0xAD ET2;
 sbit at 0xAC ES;
 sbit at 0xAB ET1;
 sbit at 0xAA EX1;
 sbit at 0xAC ES;
 sbit at 0xAB ET1;
 sbit at 0xAA EX1;