]> git.llucax.com Git - z.facultad/66.09/etherled.git/commitdiff
Agrego ejemplo de los leds andando escrito en ASM para sdcc. Falta hacer el .h
authorLeandro Lucarella <llucax@gmail.com>
Sun, 11 Dec 2005 07:40:16 +0000 (07:40 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Sun, 11 Dec 2005 07:40:16 +0000 (07:40 +0000)
de C y probar de integrarlo.

pruebas/sdcc/leds_asm/Makefile [new file with mode: 0644]
pruebas/sdcc/leds_asm/leds.asm [new file with mode: 0644]
pruebas/sdcc/leds_asm/leds.lnk [new file with mode: 0644]

diff --git a/pruebas/sdcc/leds_asm/Makefile b/pruebas/sdcc/leds_asm/Makefile
new file mode 100644 (file)
index 0000000..1d4ec5c
--- /dev/null
@@ -0,0 +1,14 @@
+
+all:
+       @asx8051 -plosgff leds.asm
+       @aslink -nf leds.lnk
+       @packihx leds.ihx > leds.hex
+
+cleantmp:
+       @rm -f *.sym *.rel *.map *.ihx *.lst *.mem *.rst
+
+clean: cleantmp
+       @rm -f *.hex
+
+.PHONY: clean cleantmp
+       
diff --git a/pruebas/sdcc/leds_asm/leds.asm b/pruebas/sdcc/leds_asm/leds.asm
new file mode 100644 (file)
index 0000000..5fd5314
--- /dev/null
@@ -0,0 +1,313 @@
+; vim: set filetype=asx8051 et sw=4 sts=4 :
+
+; Módulo y opciones
+.module     leds
+.optsdcc    -mmcs51 --model-small
+
+; Variables globales
+.globl  _leds_matrix
+.globl  _leds_matrix_len
+.globl  _leds_delay
+
+; Funciones globales
+.globl  _leds_init
+.globl  _leds_write
+.globl  _leds_write0
+.globl  _leds_write1
+.globl  _leds_delay_update
+
+; Constantes
+; UN CICLO DE MAQUINA SON 1.6666 useg (clock 8MHz)
+INTERVAL        = 66 ; 0.1ms (por el clock de 8MHz)
+LEDS0           = 0x0080
+LEDS1           = 0x00c0
+MAX_COLS        = 64
+DELAY_BASE      = 28
+
+; Área de bancos de registros
+.area   REG_BANK_0    (REL,OVR,DATA)
+    .ds     8
+    ; Usamos siempre banco 0
+    ar0     = 0x00
+    ar1     = 0x01
+    ar2     = 0x02
+    ar3     = 0x03
+    ar4     = 0x04
+    ar5     = 0x05
+    ar6     = 0x06
+    ar7     = 0x07
+
+; Variables es memoria RAM común
+.area   DSEG    (DATA)
+_leds_matrix_len::
+    .ds     1
+_leds_delay::
+    .ds     1
+delay:
+    .ds     1
+curr_col:
+__stack:  ; XXX
+    .ds     1
+
+; Variables en memoria RAM extendida indirecta (8052)
+.area   ISEG    (DATA)
+_leds_matrix::
+    .ds     MAX_COLS * 2  ; 2 bytes por columna
+
+
+; Configuramos el vector de interrupciones para atender el timer2
+.area   INTV    (ABS, CODE)
+    .org    0x0000     ; XXX
+    ljmp    _leds_init ; XXX
+
+    .org    0x002b
+    clr     tf2 ; limpio bit de interrupción porque para el timer2 no es autom.
+    ljmp    timer2_isr
+
+
+; Área de código del programa
+.area   CSEG    (CODE)
+
+; Inicializa leds.
+; Primitiva de C:
+;                   void leds_init();
+;
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_init::
+    mov     sp, #__stack ; XXX
+    ; guardo registros que uso
+    push    ar0
+    push    ar1
+    push    ar2
+
+    ; leo de la ROM el tamaño por default
+    mov     dptr, #MAT_D_LEN
+    clr     a
+    movc    a, @a+dptr
+    mov     _leds_matrix_len, a
+    clr     c
+    rlc     a ; multiplicamos por 2 porque hay 2 bytes por columna
+    mov     r2, a ; tamaño en bytes de la matriz
+
+    ; Cargo milisegundos
+    acall   _leds_delay_update
+    mov     delay, _leds_delay
+
+    ; copio imagen por default de la ROM a la RAM
+    mov     dptr, #MAT_D
+    mov     r0, #0              ; indice del "array" en la ROM
+    mov     r1, #_leds_matrix   ; dirección de memoria de la RAM
+    mov     a, r0
+seguir$:
+    movc    a, @a+dptr         ; leo de la ROM con el índice
+    mov     @r1, a ; escribo en el puntero a la RAM
+    inc     r1 ; incremento puntero
+    inc     r0 ; incremento índice
+    mov     a, r0 ; para comparar
+    cjne    a, ar2, seguir$ ; 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     ie, #0b10100000 ; habilito interrupcion timer 2
+                            ; bits de IE (interrupt enable) en 1:
+                            ; IE.7 (Global enable/disable)
+                            ; IE.5 (Enable timer 2 interrupt)
+    mov     t2con, #0b00000100 ; setup timer 2 (auto-reload y start)
+
+    mov     curr_col, #0  ; inicializo el contador de columna en 0
+
+    ; Limpiamos stack
+    push    ar2
+    push    ar1
+    push    ar0
+
+    ret
+
+
+; Escribe en los leds.
+; Primitiva de C:
+;                   void leds_write(unsigned int);
+;
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_write::
+    ; parte baja
+    mov     a, dpl ; de C me viene la parte baja del argumento en el dpl
+    mov     dptr, #LEDS0
+    cpl     a ; complemento para ver encendidos los "1"
+    movx    @dptr, a
+    ; parte alta
+    mov     a, dph ; de C me viene la parte alta del argumento en el dph
+    mov     dptr, #LEDS1
+    cpl     a ; complemento para ver encendidos los "1"
+    movx    @dptr, a
+    ret
+
+
+; Escribe en los leds del primer latch.
+; Primitiva de C:
+;                   void leds_write0(unsigned char);
+;
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_write0::
+    ; parte baja
+    mov     a, dpl       ; de C me viene el argumento en el dpl
+    mov     dptr, #LEDS0
+    cpl     a ; complemento para ver encendidos los "1"
+    movx    @dptr, a
+    ret
+
+
+; Escribe en los leds del segundo latch.
+; Primitiva de C:
+;                   void leds_write1(unsigned char);
+;
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_write1::
+    ; parte baja
+    mov     a, dpl       ; de C me viene el argumento en el dpl
+    mov     dptr, #LEDS1
+    cpl     a ; complemento para ver encendidos los "1"
+    movx    @dptr, a
+    ret
+
+
+; Actualiza el retardo de la matriz según la cantidad de columnas
+; Primitiva de C:
+;                   void leds_delay_update();
+;
+; La fórmula utilizada es: (DELAY_BASE - (leds_matrix_len / 2)) * 0.1 ms
+; C se encarga de hacer push y pop del dptr, a y psw si lo necesita.
+_leds_delay_update::
+    mov     a, _leds_matrix_len
+    clr     c
+    rrc     a ; divido por 2
+    mov     dpl, a
+    mov     a, #DELAY_BASE
+    subb    a, dpl
+    mov     _leds_matrix_len, a
+    ret
+    
+
+; Manejador de la interrupción del timer2
+timer2_isr:
+    ; vemos si todavía hay que seguir esperando o si ya tenemos que leer
+    djnz    delay, fin$
+
+    ; comenzamos realmente a leer la próxima columna
+    mov     delay, _leds_delay
+
+    ; guardamos en el stack el estado actual de los registros que vamos a usar
+    push    acc
+    push    psw
+    push    ar0
+    push    dpl
+    push    dph
+
+    ; vemos si hay que empezar a leer por la 1ra columna de nuevo
+    mov     a, curr_col
+    cjne    a, _leds_matrix_len, continua$
+    
+    ; hay que empezar de nuevo
+    mov     curr_col, #0
+    mov     a, curr_col ; dejamos en a la columna actual
+
+continua$:
+    ; multiplicamos por 2 porque hay 2 bytes por columna
+    clr     c
+    rlc     a                   
+
+    ; uso r0 como puntero al comienzo de la matriz
+    mov     r0, #_leds_matrix
+    add     a, r0 ; le sumo al puntero el offset actual segun la columna
+    mov     r0, a
+
+    ; imprimo en LEDS1
+    mov     a, @r0 ; leo el contenido de la matriz
+    mov     dptr, #LEDS1
+    cpl     a ; complemento para ver encendidos los "1"
+    movx    @dptr, a
+
+    ; imprimo en LEDS0
+    inc     r0     ; busco proximo byte de la columna
+    mov     a, @r0 ; leo el contenido de la matriz
+    mov     dptr, #LEDS0
+    cpl     a ; complemento para ver encendidos los "1"
+    movx    @dptr, a
+
+    ; avanzamos a la proxima columna
+    mov     a, curr_col
+    inc     a
+    mov     curr_col, a
+
+    ; sacamos nuestra basura del stack
+    pop     dph
+    pop     dpl
+    pop     ar0
+    pop     psw
+    pop     acc
+
+fin$:
+    reti ; listo! seguimos viaje...
+
+
+; Matriz por default
+MAT_D_LEN:
+    .db     16
+    ;.db     32
+
+MAT_D:
+    .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     0b0000111111110000    ; columna 0
+;    .dw     0b0011111111111100    ; columna 1
+;    .dw     0b0111000000001110    ; columna 2
+;    .dw     0b0110000000000110    ; columna 3
+;    .dw     0b1100110000000011    ; columna 4
+;    .dw     0b1100011000110011    ; columna 5
+;    .dw     0b1100001100110011    ; columna 6
+;    .dw     0b1100001100000011    ; columna 7
+;    .dw     0b1100001100000011    ; columna 8
+;    .dw     0b1100001100110011    ; columna 9
+;    .dw     0b1100011000110011    ; columna 10
+;    .dw     0b1100110000000011    ; columna 11
+;    .dw     0b0110000000000110    ; columna 12
+;    .dw     0b0111000000001110    ; columna 13
+;    .dw     0b0011111111111100    ; columna 14
+;    .dw     0b0000111111110000    ; columna 15
+
+;MAT_D:
+;    .dw     0b0000001111100000    ; columna 0
+;    .dw     0b0000111110000000    ; columna 1
+;    .dw     0b0111111000000000    ; columna 2
+;    .dw     0b1111000000000000    ; columna 3
+;    .dw     0b0111100000000000    ; columna 4
+;    .dw     0b0011110000000000    ; columna 5
+;    .dw     0b0001111000000000    ; columna 6
+;    .dw     0b0000111100000000    ; columna 7
+;    .dw     0b0000011110000000    ; columna 8
+;    .dw     0b0000001111000000    ; columna 9
+;    .dw     0b0000000111100000    ; columna 10
+;    .dw     0b0000000011110000    ; columna 11
+;    .dw     0b0000000001111000    ; columna 12
+;    .dw     0b0000000000111100    ; columna 13
+;    .dw     0b0000000000011110    ; columna 14
+;    .dw     0b0000000000001111    ; columna 15
+
+;end
diff --git a/pruebas/sdcc/leds_asm/leds.lnk b/pruebas/sdcc/leds_asm/leds.lnk
new file mode 100644 (file)
index 0000000..139fc87
--- /dev/null
@@ -0,0 +1,15 @@
+-myuxi
+-Y
+-b INTV = 0x0000
+-b CSEG = 0x0030
+-b ISEG = 0x0080
+-b BSEG = 0x0000
+-k /usr/share/sdcc/lib/small
+-k /usr/share/sdcc/lib/small
+-l mcs51
+-l libsdcc
+-l libint
+-l liblong
+-l libfloat
+leds.rel
+-e