Utilisation d'une TI 84 en terminal
From Eric
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 :
- Le fameux $4 serial link (et d'autres solutions) dont voici le schéma :
- Le modèle de Sami qui utilise un microcontrôleur. Voici le schéma :
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>