All pastes #823446 Raw Edit

tp8

public text v1 · immutable
·published 2007-12-19 11:25 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


   @ initialisation des leds 
   @ -----------------------
   ldr r1,=PIO_BASE
   ldr r0,=(LED8|LED7|LED6|LED5|LED4|LED2|LED3|LED1)
   str r0,[r1, #PIO_PER] @ Autoriser les ports 
   str r0,[r1, #PIO_OER] @ P6 et P16 en sortie
   @str r0,[r1, #PIO_CODR]@ eteindre les leds 8 et 1 
   @ initialisation du timer1 
   @ -----------------------
   ldr r1,=TC1_BASE
   mov r0,#0b10
   str r0,[r1, #TC_CCR] @ interdire l'horloge du compteur
   mvn r0,#0x0
   str r0,[r1, #TC_IDR] @ interdire la génération d'interruption
   ldr r0,[r1, #TC_SR]  @ lire le SR de TC1
   ldr r0,=0x4004
   str r0,[r1, #TC_CMR] @ TC1 utilise MCK/1024 et redémarrage auto
   mov r0,#1
   str r0,[r1, #TC_CCR] @ Autoriser l'horloge
   mov r0,#0x10
   str r0,[r1, #TC_IER] @ Valider l'interruption de comparaison avec RC
   @ Initialisation AIC 
   @ -----------------------
   ldr r2,=AIC_BASE
   mov r0,#0b100000
   str r0,[r2, #AIC_IDCR]    @ Interdire l'interruption du Timer1 dans l'AIC 
   adr r0,timer1_irq_handler @ Mettre l'adresse de la routine d'interruption
   str r0,[r2, #AIC_SVR5]    @ dans AIC_SVR5 (vecteur relatif à TC1_IRQ)
   mov r0,#0x04              @ Priorité 4 pour l'interruption TC1
   str r0,[r2, #AIC_SMR5]    
   mov r0,#0b100000
   str r0,[r2, #AIC_ICCR]    @ RAZ de l'interruption TC1
   str r0,[r2, #AIC_IECR]    @ Autorise l'interruption TC1

   @ paramètres de timing du timer1 
   @ ----------------------- 
   ldr r0,=64453        @ 64453 * MCK/1024 -> une seconde
   str r0,[r1, #TC_RC]  @ Placer le délai dans le registre C
   mov r0,#0b100        @ Mise à  1 bu bit 2 de CCR
   str r0,[r1, #TC_CCR] @ -> RAZ compteur et démarrage



@ Tâche de fond

boucle:	b	boucle
@ ... 
@ Fin de la tâche de fond
@ ------------------------
exit:
   @ Retour â  Angel par exception (appel systême)
   mov r0, #0x18  
   ldr r1, =0x20026 
   swi  0x123456
@ ===============================================================
@ Fin du programme principal
@ ===============================================================

@ ===============================================================
@ Gestionnaire de l'interruption du timer 1 
@ ===============================================================
timer1_irq_handler:
	@ ------------------------
	@- 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,[r1, #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	r3, r0, r3

	ldr	r0, =LED5|LED6|LED7|LED8
	mov	r4, r2, lsr #1
	and	r4, r4, r0
	orr	r0, r4, r3
	str	r0, [r1, #PIO_CODR]
	
	mvn	r0, r0


	str	r0, [r1, #PIO_SODR]

	@ Fin interruption
	@ ----------------
	cmp	r9, r8
	ldreq	r9, =tableau

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         r0, [r0, #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
	
		

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