TP de traitement du signal en temps réel Carte EZ-Kit – ADSP21061 (Vous utiliserez jusqu’à la section 2 VisualDSP en session simulateur) 1. Première application a. Evaluation Ces TPs sur carte seront évalués par une séance de soutenance sur machine ou vous devrez montrer le bon fonctionnement d’un des exercices demandés ainsi que répondre aux questions posées dans le sujet. Vous passerez en soutenance par binômes durant 15 min (une semaine après la dernière séance). b. Introduction Le développement sur la carte EZ-Kit demande une connaissance large et précise de nombreux aspects à la fois logiciels et matériels : DMA, liaison série, pipeline, boucles câblées, interruptions, alignement mémoire, modes d’adressage, jeu d’instruction, compilation, assemblage, langage C et assembleur et enfin en traitement de signal : filtrage, arithmétique fixe/flottante, échantillonnage, convolution. Si vous n’avez jamais entendu parlé de tout ces termes, il est inutile de commencer le TP. Sortez vos cours et définissez ces termes ! Dans tous les cas, le sujet de TP contient des portions en italique à considérer comme des parties de cours qui vous apporteront les indications pour le développement demandé et pour la partie du futur examen qui sera consacrée à ce sujet. De manière à aborder chaque notion pas à pas nous allons tout d’abord développer une petite application simple tenant en une dizaine de ligne d’assembleur : le clignotement d’une LED régi par l’interruption d’un Timer. Vous l’avez compris, le sujet est complexe avant d’arriver au traitement de signal en temps réel mais vous serez guidé pas à pas dans cet énoncé de 10 pages… Prenez donc le temps de bien comprendre, rien n’est superflu dans ce sujet ! c. Interruptions Le SHARC possède 3 entrées d’interruptions externes (IRQ0, IRQ1, et IRQ2) et de nombreuses autres sources d’interruptions (exceptions arithmétiques, débordement de piles, fin de traitement du DMA…). Toutes ces interruptions sont vectorisées (vecteur donc table). La table IRPTL comporte 32 entrées de 4 instructions chacune. Elle est en mémoire interne au début du bloc B0 (adresse 0x0002 0000). Une interruption est traitée si elle est non masquée et les masquages sont possibles à 2 niveaux : • Globalement, avec le bit IRPTEN du registre MODE 1 (0 : masquée, 1 démasquée) • Individuellement, avec les bits du registre IMASK (sauf le RESET) • Ou encore par une autre interruption en cours, on les appelle alors interruptions imbriquées (NESTED). Lorsqu’une interruption est acceptée : • Le compteur PC est poussé sur la pile, • S’il s’agit d’une interruption IRQi, Timer ou multi-processeur, les registres ASTAT et MODE1 sont empilés, • La demande est effacée en remettant à 0 le bit IRPTL correspondant, • L’instruction lue dans le pipe-line au cycle suivant (fetch) est la première instruction du vecteur d’interruption associé, • Tant que le programme d’interruption est en cours (avant l’instruction RTI de retour d’interruption), le bit associé de IRPTL est forcé à 0 interdisant de mémoriser une nouvelle demande du même niveau d’interruption. (Les interruptions sont traitées par priorité dans l’ordre de la table IRPTL). La Table IRPTL est donnée en annexe A. Q1. Quel est le numéro de l’interruption du Timer dans cette table ? Quel est le nom du registre autorisant la prise en compte d’une interruption ? Et celui dans lequel est mémorisé le déclenchement ? d. Quelques lignes d’assembleur Vous remarquez que les adresses des vecteurs d’interruption sont incrémentés de 4 systématiquement. Le DSP Sharc n’est pourtant pas une architecture basée sur un alignement par octet. Q2. A quel segment le bloc IRPTL est-il associé dans le fichier LDF (reprenez l’ancien fichier LDF du 21061) ? Quelle est la taille des mots adressés dans cet espace adressable ? Finalement, pourquoi un vecteur IR correspond à 4 adresses ? Le second vecteur IR correspond au vecteur de RESET du processeur. C’est donc le point d’entrée de notre programme. Il fera appel à la fonction main de l’application. Q3. Quelle est l’adresse sur 32 bits du vecteur RESET ? e. Le vecteur IRPTL, le vecteur RESET Ouvrez un nouveau projet, ajoutez un nouveau fichier d’extension .asm. Commencer par inclure la lib <def21061.h> qui contient tous les noms de registres, les primitives de l’ISA de ce modèle de DSP. Déclarer ensuite 2 sections successives l’une pour le vecteur d’interruption, l’autre pour le code de l’application. Une section se déclare par .SECTION suivi du bloc mémoire ou doit être placé le contenu et enfin du nom de section (.SECTION/PM nom ou .SECTION/DM _nom). • Faites attention de modifier le nom des sections dans le fichier LDF que vous utilisez. • Remplissez la première section. Pour cela associez une étiquette (label) à chaque vecteur et remplissez ce vecteur d’instructions NOP lorsque le vecteur est réservé et d’instructions de retour d’interruptions (RTI) dans les autres cas. Faites cela jusqu’au vecteur qui déclenchera le clignotement de la LED : celui du Timer. • Remplissez la seconde section de 2 étiquettes (_start et _end). Le label _end correspond à une boucle infinie sur l’instruction IDLE (comme pour la fin de programme _lib_prog_term). • Le corps du programme est terminé, il reste à y placer notre application. Tout d’abord, le vecteur RESET doit faire un saut (JUMP) à la fonction main (_start). Tester à ce stade le programme en session simulateur. Le vecteur RESET fait-il bien appel au main ? Ensuite le vecteur TMZHI doit inverser la valeur qui commande l’allumage de la LED pour la faire clignoter à la fréquence du TIMER puis faire un retour d’interruption (RTI), soit 2 instructions. Le Sharc possède 4 lignes externes nommées FLAG0 à FLAG3 pouvant être programmées comme des entrées ou des sorties logiques. Le mode entrée ou sortie est commandé par les 4 bits FLG0O à FLG3O du registre d’état MODE2 (si champ = 1 => sortie). Le niveau de ces lignes est commandé par les 4 bits FLG0 à FLG3 du registre ASTAT. Pour inverser (complémenter) le niveau de la ligne (nous utiliserons ici FLAG3) utilisez une des instructions binaire du jeu d’instructions du Sharc présentées en annexe B. Compilez pour vérifier le comportement, le vecteur TMZHI ne doit pas s’exécuter puisque l’interruption est pour l’instant masquée. f. Le main(), configuration des registres de contrôle • Enfin vous devez coder le contenu de la fonction principale. Le pseudocode est le suivant : o Placer la ligne FLAG3 en sortie dans MODE2 (cf. paragraphe précédent), o Bloquer le TIMER dans le registre MODE2 (cf. annexe E), o Paramétrer la période du timer et son pas (cf. annexe C), o Démasquer l’interruption TMZHI dans IMASK, o Autoriser les interruptions globales (champs IRPTEN du registre MODE1), o Débloquer le TIMER dans le registre MODE2, o Boucle sans fin (attente d’interruption). Soit 9 instructions au total dans la fonction _start. Placer un breakpoint sur la boucle infinie et tester le programme en mode simulateur. Afficher le contenu des registres ASTAT, TIMERS et IRQs par le menu Registers/Core… pour visualiser si la valeur du bit FLG3 de ASTAT s’alterne bien avec le dépassement du Timer. Que se passe-t-il si l’instruction RTI est placée dans la 4e instruction du vecteur TMZHI ? Pourquoi ? Si le fonctionnement est correct basculez en mode EZ-KIT pour faire tourner l’application sur la carte (passer pour cela à la section suivante). Fermer le projet, puis le logiciel. 2. Le programme à la carte a. Installation Mis à part le mode de chargement du code, le processus de développement d’applications embarquées sur la carte suit les mêmes règles que celles décrites pour le simulateur au premier TP (cf. figure de l’annexe C de l’énoncé 1). La principale différence réside dans la configuration de VisualDSP++. La session doit en effet correspondre à la carte EZ Kit 21061. Le processus de compilation/exécution est ensuite identique à celui déjà rencontré. La communication avec la carte (chargement de code et console de debug) peut se faire soit en utilisant le port série, soit en utilisant l’émulateur branché sur un des slots PCI du PC. Nous allons tout d’abord utiliser la liaison série : • Installer la carte : 1) branchement port série, 2) branchement alimentation. • Lancer le logiciel en appuyant sur la touche CNTRL en continu, • Modifier alors la session. Lorsqu’une fenêtre vous invite à appuyer sur le bouton RESET de la carte, n’en tenez pas compte et cliquez sur la croix (rouge) de fermeture de la fenêtre et attendez quelques instants. Le logiciel doit vous indiquer « Communication success », • Ne jamais appuyer sur le bouton RESET de la carte sans que le logiciel vous le demande (pour recommencer une exécution utiliser restart du menu debug). L’installation est alors terminée et vous pouvez continuer le TP. Note : (La liaison série est lente, aussi à tout moment vous pouvez perdre la synchronisation avec le PC. Si cela arrive trop souvent, vous pouvez utiliser la liaison par émulateur. Pour cela vous vous reporterez alors à l’annexe F). Recompiler et exécuter votre code de première application. Afficher le contenu des registres utiles, vérifier le comportement et faites varier la période du timer. Q4. Modifier le code pour faire clignoter également les LED FLAG2 et FLAG1. Quel problème se pose si on désire faire également clignoter la LED FLAG0 ? Comment remédier à ce problème de manière générale ? Modifier votre code de cette manière. 3. Acquisition / restitution d’un signal a. Introduction – procédure de configuration A partir de cette séance de TP vous allez développer des algorithmes de traitement du signal en temps réel. Pour cela la carte et le processeur doivent être configurés de la manière suivante : • Configuration des vecteurs de reset de la carte pour le lancement de l’application. • Configuration du port série du SHARC. Dans cette configuration est précisée le sens de transmission, le nombre de canaux, la gestion de la transmission par DMA… • Configuration du CODEC serial port AD1847. La spécification de ce circuit est sur le site suivant, observez-y le schéma block-diagram : http://www.datasheetcatalog.net/datasheets_pdf/A/D/1/8/AD1847.shtml Ce circuit intègre un Codec Sigma/Delta dont la fréquence d’échantillonnage va de 5,5KHz à 48KHz. La sortie du circuit vers le DSP fournit en série les échantillons numérisés sur 16 bits en PCM (Pulse Code Modulation). • Configuration des interruptions. b. Programme de boot A l’heure actuelle, la carte est configurée dans sa configuration de base présente dans l’EEPROM, circuit interchangeable situé à côté des boutons poussoirs. Cette config effectue un comptage binaire avec les LEDs et joue sur la sortie audio le thème ‘Peter Gunn’. Le programme utilise l’algorithme de Karplus-Strong (synthèse sonore par cordes pincées) pour simuler le son d’un morceau enregistré. Le DSP génère des échantillons audio numériques correspondant à une table des données du morceau. Ces données sont transmises au codec 1847 à travers un port série. Le codec transforme enfin ce signal numérique en signal analogique. Q5. Retrouver le circuit CODEC sur la carte. Le code assembleur du programme contenu dans la PROM est dans : C:\Program Files\Analog Devices\VisualDSP\21k\EZ-Kits\ADSP21061\Demos\gunn. Observez le. c. Le programme général d’acquisition/restitution Nous allons utiliser un patron de programme en C que vous utiliserez dans les exercices suivants pour y insérer votre code de traitement sans avoir à configurer les mécanismes d’acquisition et de restitution des données en temps réel. Ce programme est sur le site web habituel. Télécharger le et analyser le code. Q2. Faites un schéma de la structure mémoire du Sharc jusqu’à l’adresse 0x0002 7FFF (à partir du fichier LDF). Q3. Ouvrez le fichier assembleur qui correspond à la table d’interruption du processeur (Runtime Header Segment). Faites la correspondance avec la table fournie en annexe. Quelles sont les interruptions qui sont gérées ? Laquelle déclenche le traitement des échantillons ? Q4. Modifier la fréquence d’échantillonnage du CODEC. Le CODEC 1847 est configuré par 16 registres de 8 bits. L’ensemble de la configuration du CODEC est mémorisé dans le tableau regs_1847[16]. Le registre qui configure la fréquence d’échantillonnage est à l’adresse 0xc8x2x1 où x2x1 représente la valeur du registre. Seuls les 4 bits de poids faible x1 codent cette fréquence de la manière suivante : Ce format est celui du Data Format Register que vous retrouverez dans la spec du circuit à la page 15. Q5. Modifier la valeur de x1 en correspondance avec la table des fréquences de cette même page (champ CFSi|CSL) et écouter l’impact sur la qualité du signal de sortie. Quelle propriété du traitement de signal est mise en évidence par cette expérimentation ? Commenter le champ b0-b3 de la case 0xc85c du tableau pour les valeurs indiquées dans le fichier init1847.asm. Pour l’heure votre application de base ne fait que réaliser l’acquisition et la restitution du signal (ce qui comme vous le constatez n’est pas un critère de simplicité). Vous attendrez donc la semaine prochaine pour coder un certain traitement à l’emplacement prévu à cet effet dans le code. Repérer cet emplacement de manière à être prêt la prochaine fois. Ranger soigneusement le matériel. 4. Annexes a. Table d’interruptions de la famille 2106x IRPTL/ IMASK Vector Interrupt Bit # Address* Name** Function 0 0x00 – reserved 1 0x04 RSTI Reset (read-only, non-maskable) HIGHEST PRIORITY 2 0x08 – reserved 3 0x0C SOVFI Status stack or loop stack overflow or PC stack full 4 0x10 TMZHI Timer=0 (high priority option) 5 0x14 VIRPTI Vector Interrupt 6 0x18 IRQ2I IRQ2 asserted 7 0x1C IRQ1I IRQ1 asserted 8 0x20 IRQ0I IRQ0 asserted 9 0x24 – reserved 10 0x28 SPR0I DMA Channel 0 – SPORT0 Receive 11 0x2C SPR1I DMA Channel 1–SPORT1 Receive(or Link Buffer0) 12 0x30 SPT0I DMA Channel 2 – SPORT0 Transmit 13 0x34 SPT1I DMA Channel 3–SPORT1 Transmit(or Link Buff 1) 14 0x38 LP2I DMA Channel 4 – Link Buffer 2 15 0x3C LP3I DMA Channel 5 – Link Buffer 3 16 0x40 EP0I DMA Channel 6–Ext. Port Buff 0 (or Link Buffer 4) 17 0x44 EP1I DMA Channel 7–Ext. Port Buff 1(or Link Buffer 5) 18 0x48 EP2I DMA Channel 8 – Ext. Port Buffer 2 19 0x4C EP3I DMA Channel 9 – Ext. Port Buffer 3 20 0x50 LSRQ Link Port Service Request 21 0x54 CB7I Circular Buffer 7 overflow 22 0x58 CB15I Circular Buffer 15 overflow 23 0x5C TMZLI Timer=0 (low priority option) 24 0x60 FIXI Fixed-point overflow 25 0x64 FLTOI Floating-point overflow exception 26 0x68 FLTUI Floating-point underflow exception 27 0x6C FLTII Floating-point invalid exception 28 0x70 SFT0I User software interrupt 0 29 0x74 SFT1I User software interrupt 1 30 0x78 SFT2I User software interrupt 2 31 0x7C SFT3I User software interrupt 3 LOWEST PRIORITY * Offset from base address: 0x0002 0000 for interrupt vector table in internal memory, 0x0040 0000 for interrupt vector table in external memory ** These IRPTL/IMASK bit names are defined in the def21060.h include file supplied with the ADSP-21000 Family Development Software. b. Instructions binaires L’instruction BIT du jeu d’instruction du SHARC permet de : • Mettre à 1 : paramètre SET • Mettre à Zéro : paramètre CLR • Complémenter : paramètre TGL • Tester : paramètre TST Exemple: BIT CLR mode2 TIMEN. Instruction paramètre registre champ du registre L’équivalent existe en C avec la librairie <sysreg.h> avec les commandes sysreg_bit_set, sysreg_bit_clr, sysreg_bit_tgl… c. Les registres du 21061 Data register File R15-R0 F15-F0 Program sequencer PC PCSTK PCSTKP FADDR DADDR LADDR CURLCNTR LCNTR DATA Address Generator (DAG) I7-I0 M7 – M0 L7-L0 B7-B0 I15 – I8 M15 – M8 L15 – L8 B15 – B8 Timer TPERIOD TCOUNT System Registers MODE1 MODE2 IRPTL IMASK IMASKP ASTAT STKY USTAT1 USTAT2 Register file, fixed-point Register file, flottin-point Top of stack PC stack pointer Fetch address (pipeline) Decode Address (pipeline) Loop address Current Loop Counter Loop Counter (nested loop) DAG1 Index DAG1 Modifier DAG1 Length DAG1 Base DAG2 Index DAG2 Modifier DAG2 Length DAG2 Base Timer period Timer counter Mode Control & Status 1 Mode Control & Status 2 Interrupt latch Interrupt mask Interrupt mask pointer (nested IR) Arithmetic status flags Sticky arithmetic status flags, stack status… User Status Register 1 User Status Register 2 d. Les champs du registre ASTAT e. Les champs du registre MODE2 f. Installation de l’émulateur La communication avec la carte EZ-Kit peut également être réalisée avec l’émulateur. Celui-ci est une carte fille branchée sur un slot PCI de certains PCs de la salle. Cette carte dispose d’une liaison parallèle à brancher sur la connexion JTAG de la carte. • Fermer VisualDSP++, enlever le cordon série. • Réaliser d’abord le branchement à l’émulateur, l’alimentation de la carte étant coupée. • Rebrancher ensuite l’alimentation. Il faut maintenant configurer l’émulateur à l’aide de l’outil Summit-ICE (menu programmes/VisualDSP/). • Il faut configurer l’émulateur en précisant l’adresse du port PCI utilisé. • Une fois que l’adresse est placée, que le test est correct, relancer VisualDSP avec la touche CNTRL appuyée durant le lancement de l’outil. Choisissez une nouvelle session, celle de l’émulateur apparaît alors. Choisissez là, la compilation/exécution sur la carte est alors transparente.