From db76f3270c5bee0eb1b5ee71fa1946e8d5132d43 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 13 Dec 2005 21:10:03 +0000 Subject: [PATCH] =?utf8?q?Se=20implementa=20un=20sistema=20primitivo=20de?= =?utf8?q?=20'locking'=20para=20los=20leds.=20Cada=20vez=20que=20se=20lee?= =?utf8?q?=20o=20se=20escribe=20un=20registro=20de=20la=20placa=20de=20red?= =?utf8?q?,=20se=20deja=20de=20atender=20las=20interrupciones=20del=20time?= =?utf8?q?r=20de=20los=20leds=20para=20evitar=20una=20condici=C3=B3n=20de?= =?utf8?q?=20carrera=20del=20puerto=202.=20Tambi=C3=A9n=20se=20hacen=20otr?= =?utf8?q?os=20cambios=20peque=C3=B1os:=20*=20Se=20hace=20un=20cheque=20so?= =?utf8?q?bre=20el=20tama=C3=B1o=20de=20la=20matriz=20que=20viene=20de=20l?= =?utf8?q?a=20red.=20*=20Se=20cambia=20el=20intervalo=20del=20timer=20de?= =?utf8?q?=20los=20leds=20(cuanto=20m=C3=A1s=20grande=20menos=20=20=20inte?= =?utf8?q?rrupciones=20se=20saltea).=20Hay=20algo=20m=C3=A1s=20de=20trabaj?= =?utf8?q?o=20por=20hacer=20en=20este=20=C3=A1rea.=20*=20Se=20corrige=20un?= =?utf8?q?=20bug=20en=20leds.asm,=20en=20alg=C3=BAn=20momento=20se=20borr?= =?utf8?q?=C3=B3=20el=20.ds=201=20que=20=20=20reservaba=20memoria=20para?= =?utf8?q?=20curr=5Fcol,=20que=20estaba=20tomando=20'prestado'=20el=201er?= =?utf8?q?=20byte=20de=20=20=20la=20matriz=20(o=20peor,=20tomando=20un=20b?= =?utf8?q?yte=20de=20vaya=20uno=20a=20saber=20d=C3=B3nde).?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/dp8390.c | 4 ++++ src/elp.c | 15 ++++++--------- src/leds.asm | 51 ++++++++++++++++++++++++++++++++++++++++--------- src/leds.h | 8 ++++++++ src/main.c | 19 +++++++----------- src/reg51keil.h | 1 + src/reg51sdcc.h | 1 + 7 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/dp8390.c b/src/dp8390.c index 5c472a5..76d0c6d 100644 --- a/src/dp8390.c +++ b/src/dp8390.c @@ -40,6 +40,7 @@ recv_state; static void write_reg(unsigned char reg, unsigned char wr_data) { + leds_lock(); // 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; + leds_unlock(); } static unsigned char read_reg(unsigned char reg) { + leds_lock(); // 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; + leds_unlock(); return reg; } diff --git a/src/elp.c b/src/elp.c index 6a2a654..69e3490 100644 --- 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(); - printb(*((byte*) &elp_command), 0x01); - // 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 - 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 @@ -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 - //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(); @@ -119,7 +116,7 @@ void elp_write_response() case ELP_VAR_PAUSE: netdev_write_start(1 /* booleano de 1 byte */); - udp_write_byte(!TR2); + udp_write_byte(!ET2); netdev_write_end(); break; diff --git a/src/leds.asm b/src/leds.asm index db579cd..558f13f 100644 --- a/src/leds.asm +++ b/src/leds.asm @@ -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_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 = 65000 ; 0.05ms (por el clock de 8MHz) +INTERVAL = 666 ; 0.1ms (por el clock de 8MHz) 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) @@ -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) -_leds_matrix_len:: +_leds_matrix_len:: ; Cantidad de columnas de la matriz .ds 1 -_leds_delay:: +_leds_delay:: ; Retardo de dibujado configurado .ds 1 -delay: +delay: ; Contador del retardo actual + .ds 1 +curr_col: ; Columna que se está dibujando actualmente .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) @@ -110,7 +117,7 @@ proximo$: 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 @@ -215,6 +222,30 @@ _leds_delay_update:: 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. @@ -222,6 +253,8 @@ _leds_delay_update:: ; 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$ diff --git a/src/leds.h b/src/leds.h index b24a6d6..c69a956 100644 --- a/src/leds.h +++ b/src/leds.h @@ -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(); +/** 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; diff --git a/src/main.c b/src/main.c index 69e0a54..9714789 100644 --- a/src/main.c +++ b/src/main.c @@ -27,7 +27,7 @@ void main(void) // 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; @@ -76,42 +76,37 @@ void main(void) // 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; - 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; - print(0x0008); + //print(0x0008); // 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; - printb(ip_packet_len, 0x20); + //printb(ip_packet_len, 0x20); 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); - 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; diff --git a/src/reg51keil.h b/src/reg51keil.h index a40d8ab..426783b 100644 --- a/src/reg51keil.h +++ b/src/reg51keil.h @@ -62,6 +62,7 @@ sbit CP_RL2C = 0xC8; /* IE */ sbit EA = 0xAF; +sbit ET2 = 0xAD; sbit ES = 0xAC; sbit ET1 = 0xAB; sbit EX1 = 0xAA; diff --git a/src/reg51sdcc.h b/src/reg51sdcc.h index 1710d8e..29f7d07 100644 --- a/src/reg51sdcc.h +++ b/src/reg51sdcc.h @@ -62,6 +62,7 @@ sbit at 0xC8 CP_RL2C; /* IE */ sbit at 0xAF EA; +sbit at 0xAD ET2; sbit at 0xAC ES; sbit at 0xAB ET1; sbit at 0xAA EX1; -- 2.43.0