X-Git-Url: https://git.llucax.com/z.facultad/66.09/etherled.git/blobdiff_plain/0052faf6d85ec776823a1a33efc8d911b4b4e2f6..afe814271b1b8c0519595d12d5a9cad8a24a3cc9:/src/leds.asm?ds=sidebyside diff --git a/src/leds.asm b/src/leds.asm index db579cd..ab80fbf 100644 --- a/src/leds.asm +++ b/src/leds.asm @@ -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 = 65000 ; 0.05ms (por el clock de 8MHz) -LEDS_LOW = 0x0080 -LEDS_HIGH = 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 + mov rcap2l, #-DELAY_FACTOR ; base del retardo lcall _leds_delay_update - mov delay, _leds_delay ; 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 @@ -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_delay, 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 @@ -278,7 +310,6 @@ _leds_timer2_isr:: pop psw pop acc -255$: reti ; listo! seguimos viaje... @@ -302,39 +333,39 @@ DEFAULT_MATRIX_LEN: ;.db 32 DEFAULT_MATRIX: -; .dw 0b0000111111110000 ; columna 0 -; .dw 0b0011111111111100 ; columna 1 -; .dw 0b0111000000001110 ; columna 2 -; .dw 0b0110000000000110 ; columna 3 -; .dw 0b1100001100000011 ; columna 4 -; .dw 0b1100011000110011 ; columna 5 -; .dw 0b1100110000110011 ; columna 6 -; .dw 0b1100110000000011 ; columna 7 -; .dw 0b1100110000000011 ; columna 8 -; .dw 0b1100110000110011 ; columna 9 -; .dw 0b1100011000110011 ; columna 10 -; .dw 0b1100001100000011 ; columna 11 -; .dw 0b0110000000000110 ; columna 12 -; .dw 0b0111000000001110 ; columna 13 -; .dw 0b0011111111111100 ; columna 14 -; .dw 0b0000111111110000 ; columna 15 - - .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 0b0000111111110000 ; columna 0 + .dw 0b0011111111111100 ; columna 1 + .dw 0b0111000000001110 ; columna 2 + .dw 0b0110000000000110 ; columna 3 + .dw 0b1100001100000011 ; columna 4 + .dw 0b1100011000110011 ; columna 5 + .dw 0b1100110000110011 ; columna 6 + .dw 0b1100110000000011 ; columna 7 + .dw 0b1100110000000011 ; columna 8 + .dw 0b1100110000110011 ; columna 9 + .dw 0b1100011000110011 ; columna 10 + .dw 0b1100001100000011 ; columna 11 + .dw 0b0110000000000110 ; columna 12 + .dw 0b0111000000001110 ; columna 13 + .dw 0b0011111111111100 ; columna 14 + .dw 0b0000111111110000 ; columna 15 + +; .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