J'ai débuté ce projet en faisant des tests de génération de signal vidéo NTSC B/N 320x230. Pourquoi pas 320x240 pour être conforme au standard QVGA?. En principe avec la méthode de scan utilisé on devrait obtenir 240 lignes visibles à l'écran, 262 moins les 20 lignes réservés au vertical retrace. Mais en pratique sur les 2 téléviseurs que j'ai essayé seulement 230 lignes sont visibles à l'écran. Je ne gaspillerai donc pas 400 octets de mémoire RAM pour des lignes qui ne sont pas visibles. Donc le tableau représentant le bitmap vidéo occupe 320x230/8 soit 9200 octets de RAM.
Circuit de test
Voici le circuit utilisé pour faire mes test vidéo. Cette partie du circuit ne devrait pas être modifiée en cours de projet. Le signal vidéo généré est conforme à mes attentes.
La diode D1 n'est pas strictement nécessaire, le circuit fonctionne sans elle, sauf que je constate que la réponse en haute fréquence est meilleure avec cette diode installée. Dans mon image test les lignes verticales les plus étroites se confondent lorsque je l'enlève.
RB7 broche 16 est une entrée de synchronisation pour le signal vidéo généré par un périphérique SPI. Ce signal provient d'un OC en sortie sur la broche 11. Les périphériques SPI sur les PIC32MX peuvent fonctionner en mode frame. Dans ce mode le SPI envoie des octets tant que l'entrée sync est active. Le signal de synchronisation en question est généré par un périphérique OC Output Compare et sert à retarder l'envoie du signal vidéo en début de ligne.
code source
test-NTSC.c
font.h
Les MCU PIC32MX possèdent 4 canaux DMA (Direct Memory AAccess). L'utilisation du DMA pour envoyer les bits vidéo au SPI permet d'accaparer le MCU un temps minimum pour la génération du signal vidéo. En effet le DMA va chercher les octets directement dans la mémoire RAM pour les envoyer au SPI sans intervention du core MCU qui lui pendant ce temps peut s'occuper à d'autres tâches.
Au niveau logiciel ce qui m'a donné de la difficulté c'est d'obtenir un signal avec une bonne synchronisation horizontale. Dans mes premiers essais le démarrage du signal vidéo était déterminer par un délais logiciel. Hors une interruption même au niveau de priorité le plus élevé a un temps de latence variable car le MCU doit compléter l'instruction en cours avant de répondre à l'interruption. Le résultat était des lignes verticales en dent de scie et les caractères étaient déformés. J'ai trouvé la solution de ce problème dans le livre de Lucio Di Jasio, Programming 32-bit Microntrollers in C1. La solution consiste a utiliser le mode frame sur le SPI qui génère le signal vidéo et à déclencher le départ part un signal matériel qui lui ne subit pas de variation temporelle. Pour arriver à ce résultat Jasio utilise la transition montante de l'impulsion de synchronisation horizontale du signal NTSC. Mais comme il doit y avoir un délais d'au minimum 4,7µSec entre la fin de cette impulsion et le début du signal vidéo on doit trouver une façon d'introduire un délais supplémentaire. Pour introduire ce délais Jasio utilise un deuxième canal DMA qui envoie des 0 au SPI. Donc un délais en multiple de 32 bits peut être ajouté en début de ligne avant que le vrai signal vidéo soit envoyé. Sur les PIC32 les canaux DMA peuvent-être mis en chaîne. Donc le premier canal envoie un certain nombre de zéros pour créer un délais et lorsqu'il a terminé sa tâche déclenche le deuxième canal qui lui envoie les vrai bits vidéo au SPI.
Même si le livre de Jasio a été une source d'inspiration j'utilise une méthode différente pour générer le délais. Ma méthode permet une résolution du délais beaucoup plus fine. Cette résolution est en fait celle de la période du signal PBCLK qui alimente le TIMER 2. Donc au lieu d'utiliser un deuxième canal DMA j'utilise un deuxième OC qui est cadencé par le TIMER 2 comme celui qui génère le signal de synchronisation NTSC. J'ai donc 2 signaux de sortie OC en phase, celui sur la broche 14 qui est la synchro NTSC et celui sur la broche 11 qui est la synchro pour déclencher le SPI. Il suffit d'ajuster la constante SPI_DLY pour que la transition montante soit retardée d'au moins 5µsec par rapport à celle de HSYNC pour que le signal vidéo parte au bon moment. Et d'utiliser cette transition montante à la place de celle de HSYNC pour déclencher le SPI.
Avec cette méthode j'obtiens un signal vidéo parfais et je peux ajuster finement la position horizontale simplement en modifiant SPI_DLY. Étant donné la qualité du signal obtenu ce code va probablement demeuré tel quel dans la version finale du projet.
NOTES:
1) Programming 32-bit Microcontrollers in C, Exploring PIC32, Lucio Di Jasio, ed. Newnes
Aucun commentaire:
Publier un commentaire
Remarque : Seuls les membres de ce blogue sont autorisés à publier des commentaires.