Interface Arduino au port de bande de C64

8

Mise à jour : une implémentation pratique de cela est effectuée dans le projet Tapuino réalisé par Peter Edwards. Vérifiez-le, tout est open source: https://github.com/sweetlilmre/tapuino


Je travaille sur un projet où j'utilise mon Arduino pour diffuser des fichiers de données de bande TAP de mon PC vers le C64. Le côté logiciel du projet se passe bien, mais je suis encore nouveau dans l'électronique et je n'aime pas faire frire mon Commodore. J'ai donc besoin d'une aide pour l'interface matérielle.

Les bandes C64 utilisent la modulation PWM pour stocker le programme sur une cassette et lors de la lecture des données, un déclencheur opamp + schmitt convertit le signal audio en ondes carrées. Chaque transition haut-bas déclenche une interruption dans la machine et la distance entre deux interruptions (qui est la longueur de l'impulsion) représente une partie atomique du flux.

Le brochage du port de cassette ressemble à ceci (le haut et le bas ont les mêmes broches deux fois):

Port de bande du C64

A-1 , GND, masse

B-2 , + 5V, 5 Volt DC

C-3 , MOTEUR, commande moteur, env. Alimentation 6 Volt du moteur

D-4 , LIRE, Entrée de données, lire les données de la base de données

E-5 , ÉCRITURE, sortie de données, écriture de données dans la base de données

F-6 , SENSE, Détection, si l'une des touches PLAY, RECORD, F.FWD ou REW est enfoncée

Mon idée actuelle est la suivante:

Basé sur le livre bleu d'interface C64 (à partir de la page 29), la machine utilise le niveau TTL sur les ports READ et WRITE, donc je suppose que je peux connecter directement une broche PWM de l'Arduino à la broche READ.

J'ai également besoin d'interfacer avec la broche SENSE. Je pense que je peux également connecter directement cela à l'un des PIN numériques et y écrire Digital LOW lorsque j'ai besoin de signaler l'état du bouton pressé. Est-ce exact?

Plus tard, je souhaite détecter la présence d'un signal + 6V sur la broche MOTOR. Certains chargeurs arrêtent le jeu de données au milieu du processus de chargement, je dois donc également le détecter pour émuler la bande correctement. Dois-je utiliser une sorte de résistance pour limiter le courant là-bas ou puis-je simplement le brancher directement? Peut-être que je devrais utiliser un relais là-bas?

NagyI
la source
Le signal PWM de l'Arduino va à la broche WRITE (pas READ).
Telaclavo
J'aime émuler l'ensemble de données avec l'Arduino, donc je dois interfacer avec la broche LIRE car c'est là que le C64 accepte l'entrée.
NagyI
D'après ce que je comprends du format des données, vous ne répétez pas les impulsions comme un signal PWM classique - mais c'est la combinaison d'impulsions longues, moyennes et longues qui transportent les données. L'Arduino peut-il envoyer des signaux PWM comme ça?
Johncl

Réponses:

4

Selon le document que vous avez fourni, le port de la base de données recherche un signal numérique pur avec un rapport cyclique variable (0,75 pour H, 0,25 pour L).

Tant que la broche Arduino peut conduire un courant suffisant (il devrait pouvoir) et fonctionne à 5V, une connexion directe fonctionnera. Vous voudrez peut-être étudier l'utilisation d'un tampon TTL entre l'Arduino et le C64 (le tampon serait alimenté par l'alimentation +5 du port de la base de données et la masse serait commune au C64 et à l'Arduino).

En ce qui concerne le SENSE, il serait plus facile d'utiliser une sortie numérique pour piloter un MOSFET à petit signal (comme un 2N7002) - un niveau logique élevé active le MOSFET, ce qui tire la broche SENSE (connectée au drain) à la masse (connectée à la source) sans que l'Arduino ait à absorber de courant.

La broche MOTOR peut également être utilisée pour entraîner une porte MOSFET. Le drain serait tiré jusqu'à la tension d'alimentation Arduino avec un faible pullup (10k ou plus), la source connectée à la terre. Le drain irait également à une broche logique numérique. Lorsque le MOTEUR est haut, l'entrée logique est basse, et vice versa, et l'Arduino voit un signal logique propre.

Par exemple...

Arduino à C64 V1

Notez l'utilisation de deux portes NAND comme tampon de toutes sortes. (Pouvez-vous dire que j'avais l'habitude de chercher des pièces?)

TTL est assez robuste. Je ne pense pas qu'il y ait beaucoup de chance d'endommager quoi que ce soit.

Adam Lawrence
la source
Wow, de beaux schémas. Je pense que je vais essayer de connecter la broche de sortie PWM d'Arduino directement au D-4 d'abord car il utilise également 5V. En tout cas merci! :)
NagyI
@NagyI Cela devrait fonctionner.
Adam Lawrence
Oh mon Dieu, je n'ai pas accepté cette réponse? Honte sur moi. Quoi qu'il en soit, je viens de commander le connecteur de bord de bande pour essayer cela et ma station de soudage arrive la semaine prochaine. J'espère donc pouvoir tester cela bientôt :)
NagyI
Parce que je n'ai pas pu obtenir un 2N7002, mon collègue m'a suggéré le BS170 à la place. La signalisation sensorielle fonctionne parfaitement. Cependant, la détection du moteur est interrompue. Arduino lit toujours la logique basse. Peu importe que je mette Gate sur Low ou High, Arduino lit toujours la logique basse. Est-ce le problème du BS170 ou quelque chose de différent? Je l'ai essayé avec un autre BS170 mais le problème persiste. Il me semble que BS170 ne peut commuter que GND mais pas la tension.
NagyI
2

Cela ressemble à un projet intéressant. Si je me souviens bien, le matériel du VIC-20 a envoyé des impulsions de la Datasette dans un circuit de détection de front (j'oublie s'il a détecté des fronts montants ou descendants); les routines de chargement de bande C64 étaient compatibles avec celles du VIC-20, donc je ne pense pas que le chargeur standard aurait pu utiliser des astuces que le VIC-20 ne prendrait pas en charge, bien que des chargeurs personnalisés puissent le faire. Je n'ai jamais suffisamment joué avec des trucs dans la journée pour déterminer si la Datasette elle-même convertissait les fronts montant et descendant en impulsions (par exemple en injectant un signal retardé et non retardé dans une porte XOR). J'ai trouvé une routine pour convertir les données en largeurs d'impulsion, mais je n'ai jamais trouvé comment utiliser le détecteur de bord.

En ce qui concerne l'obtention de données du PC vers le C64, si vous ne souhaitez pas utiliser une carte son (certaines cartes son ont un traitement d'image stéréo et tel que cela pourrait faire des ravages avec la phase de l'audio sortant), il existe deux approches I pourrait suggérer: (1) envoyer des données d'intervalle d'impulsion du PC à l'Arduino, et simplement avoir les impulsions sortantes individuelles de l'heure Arduino. Peut-être encoder le format de données avec deux impulsions par octet, en utilisant quelque chose comme l'encodage suivant:

0000-1100 - Sortie 20us haut suivi de 24-60us bas (par multiples de 3us)
1101 - Sortie 40us basse
1110 - Sortie 80us basse
1111 - Les valeurs d'octet de $ FF seront ignorées
          - D'autres byes avec un nybble égal à 1111 pourraient être utilisés pour simuler
             les boutons du moteur de bande ou indiquent une indication "OK pour faire une pause ici".

Je ne pense pas que les schémas de chargement essaieront de synchroniser les impulsions avec une précision meilleure que 3us, et ce schéma permettrait d'envoyer des données sur un UART à 115200. Le PC devrait ajouter des octets de remplissage 0xFF pour que le débit auquel les données soient envoyées à l'Arduino correspondra raisonnablement bien à la vitesse à laquelle l'Arduino le synchronise. Parce que chaque nybble prendra entre 44 et 80 microsecondes à traiter, l'Arduino n'aurait qu'à interroger son UART entre les nybbles et pourrait désactiver les interruptions vers la fin de chaque impulsion. Si le PC remplit ses données de manière raisonnablement efficace, on pourrait soit (1) faire en sorte que le PC essaie d'envoyer des données légèrement plus rapidement que l'Arduino ne les produirait, et utiliser une négociation matérielle ou logicielle pour les ralentir, ou (2) avoir l'Arduino raser une microseconde sur chaque impulsion lorsque son tampon est presque plein, ou ajouter une microseconde à chaque impulsion lorsque son tampon est presque vide. Pour éviter que des pépins audio ne résultent de hoquets momentanés sur PC, l'Arduino pourrait suspendre la sortie à un octet "OK pour faire une pause ici" si son tampon n'était pas presque plein.

supercat
la source
Merci pour les idées. En fait, je diffuse les données du fichier TAP directement sur l'Arduino. Il spécifie chaque impulsion avec un octet. (voir: c64tapes.org/dokuwiki/doku.php?id=analyzing_loaders ) Pour surmonter les pépins du transfert de données, j'utilise un tampon circulaire d'un Ko sur l'Arduino qui est en train d'être rempli dans la boucle principale. Les données sont consommées par la fonction d'interruption associée à l'événement de correspondance du générateur PWM. Cela s'appelle deux fois par impulsion. C'est là que je modifie le niveau du code PIN et lors de la transition haut-bas, j'écris la nouvelle valeur du registre de correspondance en fonction de l'octet suivant.
NagyI