All pastes #825123 Raw Edit

arm

public text v1 · immutable
#825123 ·published 2007-12-20 10:50 UTC
rendered paste body
/* ----------------------------------------------------------
@ led_blink_irq.s: Utilisation des interruptions AIC, d'un   
@ des trois timers et du PIO
---------------------------------------------------------- */
   .include "carte.inc"

 
 
 
 
    .global _start @ Pour éviter le warning de arm-elf-ld

 _start: 
main:     @ Pour le point d'arrêt automatique
   @mov r13,#0x20000 @ pile en 0x20000

	adr	r9, tableau
	ldr	r8, =ft

	bl	INIT_PIO_AIC
	bl	INIT_USART

	@affichage initial
	bl	AFFICH_CADRE

@On attend que la procédure de départ soit finie pour commencer la partie
att_depart:
	cmp	r9, r8
	bne	att_depart


exit:
   @ Retour â  Angel par exception (appel systême)
   mov r0, #0x18  
   ldr r1, =0x20026 
   swi  0x123456
@ ===============================================================
@ Fin du programme principal
@ ===============================================================

@=====Affiche le cadre du plateau de jeu=========================
AFFICH_CADRE:
@----------------Dimensions du cadre ~ 80 / 22-------------------
	stmfd	r13!, {r0, r1, r14}

	mov	r1, #1	@r1 est le compteur pour savoir combien de caractère on a affiché
	@affichage de la 1e ligne

	@Passage en mode graphique pour pouvoir afficher le cadre
	mov r0, #0xe
	bl	PUTCHAR

	@angle en haut à gauche
	mov	r0, #0x6c
	bl	PUTCHAR

	@ligne horizontale
	mov	r0, #0x71
tq_affich_ligne_plateau:
	cmp	r1, #50
	beq	ftq_affich_ligne_plateau
	bl	PUTCHAR
	add	r1, r1, #1
	b	tq_affich_ligne_plateau
ftq_affich_ligne_plateau:

	@angle au milieu à gauche
	mov	r0, #0x77
	bl	PUTCHAR
	add	r1, r1, #1	@pour avoir une longueur de 80

	@ligne horizontale
	mov	r0, #0x71
tq_affich_ligne_score:
	cmp	r1, #79		@le 80e caractère est un angle
	beq	ftq_affich_ligne_score
	bl	PUTCHAR
	add	r1, r1, #1
	b	tq_affich_ligne_score
ftq_affich_ligne_score:

	@angle au milieu à droite
	mov	r0, #0x6b
	bl	PUTCHAR


	@barre verticale
	mov	r1, #2	@on commence à la 2e ligne
	mov	r0, #0x78
tq_affich_barre:
	cmp	r1, #20		@le plateau fait 20 lignes de hauteur
	beq	ftq_affich_barre

	@positionnement du caractère
	bl	ITOA
	mov	r4, #'0'
	mov	r5, #'0'
	stmfd	r13!, {r2, r3, r4, r5}
	bl	POS
	sub	r13, r13, #16
	@affichage du caractère
	bl	PUTCHAR

	mov	r4, #'5'
	mov	r5, #'0'
	stmfd	r13!, {r2, r3, r4, r5}
	bl	POS
	sub	r13, r13, #16
	@affichage du caractère
	bl	PUTCHAR


	add	r1, r1, #1
	b	tq_affich_barre
ftq_affich_barre:


	@Sortie du mode graphique
	mov	r0, #0x1b
	bl	PUTCHAR
	mov	r0, #'n'
	bl	PUTCHAR


	ldmfd	r13!, {r0, r1, r15}



@===================Integer TO Ascii, entier placé par registre r1, renvoie les caractères par registres r2, r3=============================
ITOA:

	mov	r3, r1
	mov	r2, #0

tq_itoa:
	cmp	r3, #10	
	blo	ftq_itoa

	add	r2, r2, #1
	sub	r3, r3, #10
	b	ftq_itoa
ftq_itoa:
	@on convertit chaque chiffre en caractère
	add	r2, r2, #48
	add	r3, r3, #48
	mov	r15, r14

@=====Position du curseur (4 paramètres placés par pile)=========
POS:

	stmfd	r13!, {r0, r14}

	mov	r0, #0x1B
	bl	PUTCHAR
	mov	r0, #'['
	bl	PUTCHAR
	ldr	r0, [r13, #8]
	bl	PUTCHAR
	ldr	r0, [r13, #12]
	bl	PUTCHAR
	mov	r0, #';'
	bl	PUTCHAR
	ldr	r0, [r13, #16]
	bl	PUTCHAR
	ldr	r0, [r13, #20]
	bl	PUTCHAR
	mov	r0, #'H'
	bl	PUTCHAR


	ldmfd	r13!, {r0, r15}


@=============Initiallisation PIO / AIC===========================
INIT_PIO_AIC:
	@ initialisation des leds 
	@ -----------------------
	ldr r12,=PIO_BASE
	ldr r0,=(LED8|LED7|LED6|LED5|LED4|LED2|LED3|LED1)
	str r0,[r12, #PIO_PER] @ Autoriser les ports 
	str r0,[r12, #PIO_OER] @ P6 et P16 en sortie
	@str r0,[r1, #PIO_CODR]@ eteindre les leds 8 et 1 
	@ initialisation du timer1 
	@ -----------------------
	ldr r10,=TC1_BASE
	mov r0,#0b10
	str r0,[r10, #TC_CCR] @ interdire l'horloge du compteur
	mvn r0,#0x0
	str r0,[r10, #TC_IDR] @ interdire la génération d'interruption
	ldr r0,[r10, #TC_SR]  @ lire le SR de TC1
	ldr r0,=0x4004
	str r0,[r10, #TC_CMR] @ TC1 utilise MCK/1024 et redémarrage auto
	mov r0,#1
	str r0,[r10, #TC_CCR] @ Autoriser l'horloge
	mov r0,#0x10
	str r0,[r10, #TC_IER] @ Valider l'interruption de comparaison avec RC
	@ Initialisation AIC 
	@ -----------------------
	ldr r11,=AIC_BASE
	mov r0,#0b100000
	str r0,[r11, #AIC_IDCR]    @ Interdire l'interruption du Timer1 dans l'AIC 
	adr r0, DRIVER_TIMER @ Mettre l'adresse de la routine d'interruption
	str r0,[r11, #AIC_SVR5]    @ dans AIC_SVR5 (vecteur relatif à TC1_IRQ)
	mov r0,#0x04              @ Priorité 4 pour l'interruption TC1
	str r0,[r11, #AIC_SMR5]    
	mov r0,#0b100000
	str r0,[r11, #AIC_ICCR]    @ RAZ de l'interruption TC1
	str r0,[r11, #AIC_IECR]    @ Autorise l'interruption TC1
	
	@ paramètres de timing du timer1 
	@ ----------------------- 
	ldr r0,=64453        @ 64453 * MCK/1024 -> une seconde
	str r0,[r10, #TC_RC]  @ Placer le délai dans le registre C
	mov r0,#0b100        @ Mise à  1 bu bit 2 de CCR
	str r0,[r10, #TC_CCR] @ -> RAZ compteur et démarrage

	mov	r15, r14



@ ===============================================================
@ Gestionnaire de l'interruption du timer 1 
@ ===============================================================
DRIVER_TIMER:
	@ ------------------------
	@- Ajuster et sauvegarder le registre de retour du mode IRQ dans la pile IRQ
	sub         r14, r14, #4 @ r14 pointe une instruction trop loin
	stmfd       sp!, {r14}  @ sauvegarder l'adresse de retour dans la pile IRQ
	@ Sauvegarder SPSR et R0 dans la pile IRQ 
	mrs         r14, spsr
	stmfd       sp!, {r0, r14}
	@ passer en mode systême 
	mrs         r14, cpsr
	orr         r14, r14, #0b11111 @  (mode systême)
	msr         cpsr, r14
	@ Sauvegarde de registres dans la pile systême 
	stmfd       sp!, { r1, r2, r14}
	@ autoriser les interruptions 
	mrs         r14, cpsr
	bic         r14, r14, #0x80 @ CPSR[I] <- 0
	msr         cpsr, r14


	@ -----------------------
@	ldr r1,=TC1_BASE
	ldr r0,[r10, #TC_SR]    @ Lecture SR pour le remettre à  0 
	@ (pour signifier qu'on traite l'IT)

@	ldr r1,=PIO_BASE

	ldr	r0, =LED1|LED2|LED3|LED4
	ldrb	r2, [r9], #1
	mov	r3, r2, lsl #16
	and	r0, r0, r3
	
	str	r0, [r12, #PIO_CODR]
	
	mvn	r0, r0


	str	r0, [r12, #PIO_SODR]

	@ Fin interruption

fin_irq:
	@- Interdire les interruptions  
	mrs         r0, cpsr
	orr         r0, r0, #0b10000000 @ CPSR[I] <- 1
	msr         cpsr, r0
			 
	@ Restaurer les registres depuis la pile systême 
	ldmfd       sp!, { r1, r2, r14}
	@- repasser en mode IRQ 
	mrs         r0, cpsr
	bic         r0, r0, #0x1F    @ CPSR[MO..M4] <- 0b00000
	orr         r0, r0, #0b10010 @ CPSR[MO..M4] <- 0b10010
	msr         cpsr, r0 
	@ Indiquer la prise en compte de l'interruption à  l'AIC
	@ = écriture de n'importe quoi dans AIC_EOICR
@	ldr         r0, =AIC_BASE
	str         r11, [r11, #AIC_EOICR]
	@ Restaurer SPSR_irq et r0 à  partir de la pile IRQ 
	ldmfd       sp!, {r0, r14}
	msr         spsr, r14
	@ Restaurer  LR_irq depuis la pile IRQ et le mettre directement dans le PC 
	ldmfd       sp!, {pc}^
			 
	@ Fin du sous_programme d'interruption
	
		


@==================================================================@
@ Sous-programme initialisation USART                              @
@ -----------------------------------                              @
@ Paramètres : néant                                               @
@ Valeur de retour : néant                                         @
@==================================================================@
INIT_USART:
    stmfd r13!,{r0,r1,r14}

@ Au cas ou, on desactive les ports du PIO
@ pour USART1
@ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    ldr   r0,=PIO_BASE
    ldr   r1,=0x700000
    str   r1,[r0,#PIO_PDR]
    str   r1,[r0,#PIO_IDR]

@ On initialise l'USART pour recevoir et transmettre des caractères
@ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    ldr   r0,=USART1_BASE

    @ On fait un reset de l'émetteur et du récepteur
    @-----------------------------------------------
    ldr   r1,=(US_RSTRX|US_RSTTX|US_RSTSTA)
    str   r1,[r0,#US_CR]

    @ On active l'émetteur et le récepteur
    @-------------------------------------
    ldr   r1,=(US_RXEN|US_TXEN)
    str   r1,[r0,#US_CR]

    @ Configuration des modes
    @------------------------
    @   - Clock Selection = MCK (US_CLKS_MCK)
    @   - Taille de caractère = 8 (US_CHRL_8)
    @   - Mode Asynchrone (SYNC=0)
    @   - Pas de parité (US_PAR_NO)
    @   - 1 stop bit (US_NBSTOP_1)
    @   - Normal Channel Mode (US_CHMODE_NORMAL)
    ldr r1,=(US_CLKS_MCK8|US_CHRL_8|US_PAR_NO|US_NBSTOP_1|US_CHMODE_NORMAL)
    str r1,[r0,#US_MR]

    @Initialisation du baud rate generator register (CD)
    @---------------------------------------------------
    @ Cette valeur est calculée à partir de
    @   - MCK = 66.6 MHz
    @   - débit du terminal = 57600
    @   - mode asynchrone (débit = MCK/(CD*16))
    mov   r1,#9
    str   r1,[r0,#US_BRGR]

    @Initialisation du temps de garde
    @--------------------------------
    mov   r1,#0xa
    str   r1,[r0,#US_TTGR]

    @ Désactivation des interruptions de tout genre
    @----------------------------------------------
    mov   r1,#0x3F
    str   r1,[r0,#US_IDR]
    ldmfd r13!,{r0,r1,r15}

@==================================================================@
@ Sous-programme envoi d'un caractère sur gtkterm                  @
@ -----------------------------------------------                  @
@ Paramètres : code ASCII passé dans r0                            @
@ Valeur de retour : néant                                         @
@==================================================================@
PUTCHAR:
    stmfd r13!,{r1,r2,r14}
    ldr   r1,=USART1_BASE
put_wait:
    ldr   r2,[r1,#US_CSR]
    ands  r2,r2,#US_TXRDY
    beq   put_wait
    @ On place le caractère dans le registre
    @ Transmitter Holding Register ( US_THR)
    strb   r0,[r1,#US_THR]
    ldmfd  r13!,{r1,r2,r15}

@==================================================================@
@ Sous-programme saisie d'un caractère au clavier                  @
@ -----------------------------------------------                  @
@ Paramètres : néant                 	                           @
@ Valeur de retour : code ASCII passé dans r0                      @
@==================================================================@
GETCHAR:
    stmfd r13!,{r1,r2,r14}
    ldr   r1,=USART1_BASE
    @ Attente active de l'arrivée d'un caractère
    @ tapé au clavier
get_wait:
    ldr   r2,[r1,#US_CSR]
    ands  r2,r2,#US_RXRDY
    beq   get_wait

    @ Une fois le caractère saisi, on le place dans r0
    ldrb  r0,[r1,#US_RHR]
    ldmfd r13!,{r1,r2,r15}


tableau:	.byte	1, 3, 7, 15, 0, 15, 0, 15, 0
ft: