| Auteur | : Flyers | : flyers-at-next-touch-dot-com | |
| Ecrit le | : 05/06/2008 | Dernière modification | : 05/06/2008 |
Vous pouvez copier et/ou redistribuer tout ou partie de cet article si le nom et l'email de l'auteur figurent clairement sur les copies.
int dummy(int a, int b, int c, int d)
{
return a+2*b+3*c+4*d;
}
dummy :
; r0 = a
; r1 = b
; r2 = c
; r3 = d
stmfd r13!, {r4-r12,r14} ; sauvegarde des arguments
add r1, r1, r1 ; r1 = r1+r1
add r2,r2,r2,LSL #1 ; r2 = r2+r2*2
add mov r3,r3,LSL #2 ; r3 = r3*4
add r0, r0, r1 ; r0 = r0+r1
add r0, r0, r2 ; r0 = r0+r2
add r0, r0, r3 ; r0 = r0+r3
ldmfd r13!, {r4-r12, r14} ; restauration des arguments

if (a == b)
{
a += b;
}
else
{
b += a;
}
; r0 = a ; r1 = b cmp r0, r1 beq then b else then add r0, r0, r1 ; a += b b end else add r1, r1, r0 ; b += a end
int *ptr = var; ptr = ptr +4 // incrément du pointeur *ptr = 10 // mets 10 en valeur pointée par le pointeur
;;; initialisation du pointeur ldr r0, =var ;; récupération de l'adresse de la variable str r0, ptr ;;; modification du pointeur ldr r0, ptr add r0,r0,#4 str r0,ptr ;;; modification de la valeur pointée ldr r0, ptr mov r1, #10 str r1, [r0]


EXPORT isr
IMPORT pa9_irq_C_handler
AREA EX2, CODE, READONLY
AIC_BASE EQU 0xFFFFF000
AIC_EOICR EQU 0x130
isr
;/* sauvegarde de l'adresse de retour*/
SUBS lr,lr, #4
STMFD sp!, {r0, lr}
;/* sauvegarde du SPSR */
MRS r0, SPSR
STMFD sp!, {r0}
;/* on réautorise les interruptions et l'on passe en mode svc*/
;/* afin de bénéficier de la pile superviseur */
MRS r0, spsr
BIC r0, r0, #0x80 ; mise à 0 du flag Interruption IRQ
BIC r0, r0, #0x1F ; mise à 0 des flags M4..M0
ORR r0, r0, #0x13 ; mode superviseur activer
MSR cpsr_c, r0
;/* appel de la fonction de traitement*/
STMFD SP!, {r1-r3,r12,lr}
BL pa9_irq_C_handler
LDMFD SP!, {r1-r3,r12,lr}
;/* On repasse en mode irq avec interruption bloquées*/
MRS r0, cpsr
BIC r0, r0, #0x1F ; mise à 0 des flags M4..M0
ORR r0, r0, #0x80 | 0x12 ; mise à 1 du flag Interruption IRQ et passage en mode IRQ
;/* On acquitte l'AIC pour signifier que l'interruption a été traité*/
LDR r0, =AIC_BASE
STR r1, [r0, #AIC_EOICR]
;/* on restore les registres*/
LDMFD sp!, {r0} ; on récupère le SPSR qui avait été sauvegardé
MSR SPSR_cxsf, r0
;/* retour d'interruption*/
LDMFD sp!, {r0, pc}^
END

#include "pio.h"
#include "pioa.h"
#include "piob.h"
#include "apmc55800.h"
#include "stdio.h"
#include "aic.h"
#define PIOA_BASE 0xFFFEC000
#define PIOB_BASE 0xFFFF0000
void InitialiseIRQ (void) ;
void InitialiseBP (void) ;
void InitialiseLED (void) ;
void AfficheLed (unsigned char a) ;
extern void isr (void) ;
StructAIC *AIC ;
StructPIO *PIOA ;
StructPIO *PIOB ;
StructAPMC *APMC ;
unsigned char cpt = 0;
int main (void)
{
AIC = (StructAIC*) AIC_BASE ;
PIOA = (StructPIO*) PIOA_BASE ;
PIOB = (StructPIO*) PIOB_BASE ;
APMC = (StructAPMC*) APMC_BASE ;
InitialiseBP () ;
InitialiseLED () ;
AfficheLed(0);
InitialiseIRQ () ;
while (1)
{
AfficheLed(cpt);
}
return 0;
}
void InitialiseIRQ (void)
{
/* interruption sur niveau et de priorité = 3 */
AIC->AIC_SMR[13] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x03 ;
/* adresse de la routine de traitement des interruption du port A */
AIC->AIC_SVR[13] = (int) isr ;
/* activation des irq du pioa */
AIC->AIC_IECR = (1<<13) ;
/* activation des irq dues à pa9 */
PIOA->PIO_IER = PA9 ;
}
void InitialiseBP (void)
{
/*On active les horloges de périphérique pour pioa et piob*/
APMC->APMC_PCER = 0x6000 ;
/*activation de PA9 en entrée */
PIOA->PIO_PER = PA9 ;
PIOA->PIO_ODR = PA9 ;
}
void InitialiseLED (void)
{
/* Les LED sont attachée au portB PB8 -> PB15 */
/* On active les 8 bits du Port B auxquels sont attachée les led */
PIOB->PIO_PER = 0x0000FF00 ;
/* On met ces 8 bits en sortie */
PIOB->PIO_OER = 0x0000FF00 ;
/* Une led est allumée lorsque la sortie du Port B est à 0 */
/* On les éteint toutes PB8-> PB15 = "0xFF" */
PIOB->PIO_SODR = 0x00FF00 ;
}
void AfficheLed (unsigned char a)
{
/* Constitution du mot permettant de mettre le port à 0 */
/* Les led sont allumées si la sortie est à 0 */
PIOB->PIO_SODR = (~a << 8) & 0x00FF00 ;
/* Constitution du mot permettant de mettre le port à 1 */
/* On inverse les bits 8 à 15 du mot précédent */
PIOB->PIO_CODR = (a << 8) & 0x00FF00 ;
}
void pa9_irq_C_handler(void)
{
/* on acquitte l'irq du périphérique par lecture du registre d'état */
/* on vérifie par la même occasion que l'IRQ est bien due à PA9 */
if ( PIOA->PIO_ISR == (1<< 9) )
{
/* test que c'est un appui */
if ((PIOA->PIO_PDSR & (1<<9) )==0)
/* On incrémente le compteur */
cpt++;
}
else /* interruption non due à PA9 on ne fait rien de spécial*/
{}
}

void write (char *data, unsigned int len)
{
// Attente si transmission déjà en cours
while (flagTX != 1) ;
// Configuration du pointeur de données
USART1->US_TPR = (int) data ;
// Lancement de la transmission avec la longueur de la chaine à transmettre
USART1->US_TCR = (short unsigned int) len ;
// Activation des interruptions sur fin d'émission
USART1->US_IER = US_ENDTX ;
}
int read (char *data, unsigned int len)
{
// Initialisation du flag de lecture
flagRX = 1 ;
// Configuration du pointeur de données
USART1->US_RPR = (int) data ;
// Lancement de la réception avec la longueur de la chaine à recevoir
USART1->US_RCR = (short unsigned int) len ;
// Reset du time-out
USART1->US_CR = US_STTTO ;
// Activation des interruptions sur les différentes erreurs
USART1->US_IER = US_OVRE | US_FRAME | US_TIMEOUT ;
// Paramétrage du time-out
USART1->US_RTOR = 100 ;
// Attente de la fin de la réception ou de la réception d'une erreur
// Tant que la lecture n'est pas finie
// Et qu'il n'y a pas d'erreur de transmission
while (((USART1->US_CSR & US_ENDRX) == 0) && (flagRX == 1)) ;
// Retour du flag de lecture
return flagRX ;
}
void USART1_IRQ (void)
{
// Récupération des flags d'états de l'USART
int CSR = USART1->US_CSR ;
// Si fin de réception
if ((CSR & US_ENDTX) == US_ENDTX)
{
// Modification du flag d'émission
flagTX = 1 ;
// Désactivation des interruptions d'émission
USART1->US_IDR = US_ENDTX ;
}
// Si time-out
if ((CSR & US_TIMEOUT) == US_TIMEOUT)
{
// Modification du flag de réception
flagRX = 2 ;
// Désactivation des interruptions sur time-out
USART1->US_IDR = US_TIMEOUT ;
}
// Si overflow
if ((CSR & US_OVRE) == US_OVRE)
{
// Modification du flag de réception
flagRX = 3 ;
// Désactivation des interruptions sur overflow
USART1->US_IDR = US_OVRE ;
}
// Si framing error
if ((CSR & US_FRAME) == US_FRAME)
{
// Modification du flag de réception
flagRX = 4 ;
// Désactivation des interruptions sur framing error
USART1->US_IDR = US_FRAME ;
}
}
#include "stdio.h"
#include "string.h"
#include "pio.h"
#include "pioa.h"
#include "piob.h"
#include "apmc55800.h"
#include "aic.h"
#include "usart.h"
#define PIOA_BASE 0xFFFEC000
#define USART1_BASE 0xFFFC4000
StructAIC *AIC ;
StructPIO *PIOA ;
StructUSART *USART1 ;
StructAPMC *APMC ;
volatile int flagTX = 1 ;
volatile int flagRX = 1 ;
void Initialise (void) ;
void InitIRQ(void);
void write (char *data, unsigned int len) ;
int read (char *data, unsigned int len) ;
void USART1_IRQ (void) ;
extern void isr (void) ;
int main()
{
char tbuf[] = "test";
char rbuf[15] = "" ;
int retour ;
AIC = (StructAIC*) AIC_BASE ;
PIOA = (StructPIO*)PIOA_BASE ;
USART1 = (StructUSART*)USART1_BASE ;
APMC = (StructAPMC*)APMC_BASE ;
Initialise();
InitIRQ () ;
// Envoi de la chaine de test
write(tbuf, strlen(tbuf)) ;
// Réception de cette même chaine et test du time-out
retour = read(rbuf, strlen(tbuf)+1) ;
// Affichage console du résultat
printf("%d\n%s\n", retour, rbuf) ;
return 0;
}
void Initialise (void)
{
// Activation de l'horloge de l'USART
APMC->APMC_PCER = 1 << 3 ;
// Redirection des pins du PIO sur l'USART
PIOA->PIO_PDR = PA18 | PA19 ;
// Reset de l'USART
USART1->US_CR = US_RSTRX | US_RSTTX ;
// Configuration de la vitesse de transmission 38400
USART1->US_BRGR = 52 ;
// Configuration de l'USART (loopback 8bits sans parité avec bits de stop)
USART1->US_MR = US_CHMODE_LOCAL_LOOPBACK | US_NBSTOP_1 | US_PAR_NO | US_CHRL_8 | US_CLKS_MCK ;
// Activation de l'USART
USART1->US_CR = US_TXEN | US_RXEN ;
}
void InitIRQ(void)
{
// Configuration de la ligne USART de l'AIC
AIC->AIC_SMR[3] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x06 ;
// Paramétrage du handler d'interruption
AIC->AIC_SVR[3] = (int) isr ;
// Activation des interruptions
AIC->AIC_IECR = (1<<3) ;
}
void write (char *data, unsigned int len)
{
// Attente si transmission déjà en cours
while (flagTX != 1) ;
// Configuration du pointeur de données
USART1->US_TPR = (int) data ;
// Lancement de la transmission avec la longueur de la chaine à transmettre
USART1->US_TCR = (short unsigned int) len ;
// Activation des interruptions sur fin d'émission
USART1->US_IER = US_ENDTX ;
}
int read (char *data, unsigned int len)
{
// Initialisation du flag de lecture
flagRX = 1 ;
// Configuration du pointeur de données
USART1->US_RPR = (int) data ;
// Lancement de la réception avec la longueur de la chaine à recevoir
USART1->US_RCR = (short unsigned int) len ;
// Reset du time-out
USART1->US_CR = US_STTTO ;
// Activation des interruptions sur les différentes erreurs
USART1->US_IER = US_OVRE | US_FRAME | US_TIMEOUT ;
// Paramétrage du time-out
USART1->US_RTOR = 100 ;
// Attente de la fin de la réception ou de la réception d'une erreur
// Tant que la lecture n'est pas finie
// Et qu'il n'y a pas d'erreur de transmission
while (((USART1->US_CSR & US_ENDRX) == 0) && (flagRX == 1)) ;
// Retour du flag de lecture
return flagRX ;
}
void USART1_IRQ (void)
{
// Récupération des flags d'états de l'USART
int CSR = USART1->US_CSR ;
// Si fin de réception
if ((CSR & US_ENDTX) == US_ENDTX)
{
// Modification du flag d'émission
flagTX = 1 ;
// Désactivation des interruptions d'émission
USART1->US_IDR = US_ENDTX ;
}
// Si time-out
if ((CSR & US_TIMEOUT) == US_TIMEOUT)
{
// Modification du flag de réception
flagRX = 2 ;
// Désactivation des interruptions sur time-out
USART1->US_IDR = US_TIMEOUT ;
}
// Si overflow
if ((CSR & US_OVRE) == US_OVRE)
{
// Modification du flag de réception
flagRX = 3 ;
// Désactivation des interruptions sur overflow
USART1->US_IDR = US_OVRE ;
}
// Si framing error
if ((CSR & US_FRAME) == US_FRAME)
{
// Modification du flag de réception
flagRX = 4 ;
// Désactivation des interruptions sur framing error
USART1->US_IDR = US_FRAME ;
}
}
