Utilisation d'une TI 84 en terminal

From Eric

Revision as of 12:04, 16 June 2012 by Ejenn (Talk | contribs)
Jump to: navigation, search

Contents

Objectifs

L'objectif est d'utiliser une calculatrice TI82-stats comme terminal de debug de mes montages à microcontrôleurs, en lieu et place de mon vieux portable.

En pratique, il va s'agir de réaliser une petite interface matérielle et logicielle permettant de transformer un flux au format électrique et logique "texas" en en flux au format RS232 TTL.

Réalisation

Adaptation des signaux électriques

La calculatrice dispose de deux ports bidirectionnels en collecteur ouvert (fil rouge et fil blanc). La transmission d'un bit se fait en positionnant l'un des fils au niveau haut et en récupérant l'accusé de réception sur l'autre fil. Il semble que les niveaux soient TTL.

On trouvera ici une description des signaux. Le protocole physique est le suivant :

<à compléter>


L'interface hardware est chargée de transformer le flux en provenance de la calculatrice en un flux série standard. L'idée est d'utiliser un port d'entrée et un port de sortie par fil (on pourrait n'utiliser qu'un port par fil mais : ça complique vaguement le logiciel et n'importe quel microcontrôleur disposant de voies d'entrées / sorties série dispose aussi d'un nombre plus que suffisant de ports.

L'interface matérielle est la suivante (c'est un peu luxueux, on pourrait faire plus simple) :

Naturellement, on trouve bien des montages sur internet :

Tilink-original.jpg
  • Le fameux $4 serial link (et d'autres solutions) dont voici le schéma :
Tilink-4-dollars.jpg
  • Le modèle de Sami qui utilise un microcontrôleur. Voici le schéma :
Tilink-sami.jpg


Le logiciel

Du côté de la calculatrice, il va s'agir de transmettre et recevoir des flux émis par le micro-contrôleur. La calculatrice dispose de fonctions (en basic) permettant de transmettre une variable, une liste, etc. Cependant, ces données sont transmises selon un protocole particulier qui permet (notamment) de connaître la nature du flux, sa taille, etc. On trouve de l'information sur le format de trames sans avoir à faire trop de rétro-ingénierie, par exemple [<à completer> ici].

Or, si je veux utiliser la calculatrice comme un terminal, je veux pouvoir émettre et recevoir des flux composés uniquement d'octets "utilisateur". La solution consiste à implémenter dans l'interface un bout de logiciel qui va convertir un format dans l'autre. C'est faisable, assez simple, mais il y a plus simple.

On peut en effet piloter directement, "à la main", l'interface matérielle de la calculatrice, mais il faut alors faire un peu d'assembleur Z80. On trouvera dans la rubrique Programmation assembleur de la TI84 Stats quelques explications sur les outils à utiliser et la façon de les utiliser... Le pilotage est assez simple car il se résume à des quelques "in" et "out" sur le port adéquat. Voici, par exemple, le bout d'assembleur Z80 qui réalise les opérations d'émission et de réception d'un octet :

 ;
 ; Link routines taken from Telnet 83,
 ; Sent to me by Scott Dial <homosapian@geocities.com>.
 ; To use them call "ReceiveByte" or "SendByte". You can test the port
 ; (and receive byte if necessary) with "TryReceiveByte".
 ;       LINK PORT WRITE EQUATES
 ;
 #define		D0LD1L                    0C3h
 #define		D0LD1H                    0C1h
 #define		D0HD1L                    0C2h
 #define		D0HD1H                    0C0h
 #define		BPORT                     0
 #define	LINKMASK	12
 TryReceiveByte:

in a,(BPORT) and LINKMASK cp LINKMASK scf ret z

 ReceiveByteCont:

call LinkPrep jr ReceiveCont

 ReceiveByte:

call LinkPrep

 ReceiveBits:

ld de,-1

 WaitRecBit:

call CheckLink jr z,LinkFailed cp LINKMASK jr z,WaitRecBit

 ReceiveCont:

sub LINKMASK/3*2 ld a,LINKMASK/3*2 ld d,D0LD1H jr c,ReceiveLow rra ld d,D0HD1L

 ReceiveLow:

rr c ld (AckBit),a ld a,d out (BPORT),a ld de,-1

 WaitAckRec:

call CheckLink cp 0

 AckBit =$-1

jr nz,WaitAckRec ld a,D0HD1H out (BPORT),a ld d,4

 WaitReadyRec:

dec d jr z,ReadyRec in a,(BPORT) cp LINKMASK jr nz,WaitReadyRec

 ReadyRec:

djnz ReceiveBits jr LinkSuccess

 LinkPrep:

ex (sp),hl push bc push de set indicOnly,(iy+indicflags) ld b,8 jp (hl)

 SendByte:

call LinkPrep ld c,a ;ld a, 255 ;ld (stime), a

 SendBits:

rr c ld a,D0LD1H jr nc,SendLow ld a,D0HD1L

 SendLow:

out (BPORT),a ld de,-1

 WaitAckSend:

call CheckLink jr nz,WaitAckSend

 SendAcked:

ld a,D0HD1H out (BPORT),a ld de,-1

 WaitReadySend:

call CheckLink cp LINKMASK jr nz,WaitReadySend djnz SendBits

 LinkSuccess:

or 0

 .org $-1
 LinkFailed:

scf res indicOnly,(iy+indicflags) ld a,0D0h out (BPORT),a ld a,c pop de pop bc pop hl ret

 CheckLink:

pop hl dec de ld a,d or e jr z,LinkFailed ld a,0BFh ;call stimeout ;cp 0 ;call _readkeypad ;bit 6,a ;jr z,LinkFailed in a,(BPORT) and LINKMASK jp (hl)


Conclusion

Voici le résultat :

<à compléter>

Personal tools