I wrote some communication routines to send bytes from an 84+ calculator to the arduino (not from arduino to calc).
Here is the example code:
z80:
.org $9D93
#define bcall(label) rst 28h \ .dw label
#include "ti83plus.inc"
.db t2ByteTok, tAsmCmp
call USB_Init
bcall(_GetKey)
;send 50
ld b, 50
call USB_SendByte
ret
;------------------------------------------------
; calc-Arduino communication routines trough USB
;------------------------------------------------
USB_Init:
;initializes the USB connection
;turn the USB driver off so we can read and write manually
bcall(810Eh) ;KillUSB
;put the D- line on low
ld a, %00100000
out ($4A), a
ret
USB_SendByte:
;b = the byte to be send
ld c, 0
;c = bitcounter
call Wait
;set D- to high so the arduino knows we will send a byte
ld a, %00011000
out ($4A), a
;wait untill we can start sending the byte
call Wait
SendLoop:
;put the bit we are going to send in carry
rrc b
jr c, sendOne
;send a 0
ld a, %00100000
out ($4A), a
jr endBit
sendOne:
;send a 1
ld a, %00011000
out ($4A), a
endBit:
;increase the bit counter
inc c
;stop sending if all 8 bits were sent
ld a, c
cp 8
jr z, endSend
call Wait
jr sendLoop
endSend:
;set D- low so the arduino won't think we're trying to send an other byte
ld a, %00100000
out ($4A), a
ret
;internally used routine(s)
;--------------------------
wait:
;waits untill you can send a bit
;if the clock is 0: wait untill it's 1
in a, ($4D)
bit 1, a
jr z, Wait
waitLoop2:
;Wait untill the clock is 0, so we can begin writing
in a, ($4D)
bit 1, a
jr nz, WaitLoop2
ret
arduino
//Dp and Dm are the data kables of the USB
const int Dp = 5;
const int Dm = 6;
const int Delay = 1;
int RecievedByte = 0;
int Recieving = 0;
int RecievedBit = 0;
int Recieved = 0;
int ledOn = 0;
void setup(){
pinMode(Dp, OUTPUT);
pinMode(Dm, INPUT);
pinMode(13, OUTPUT);
}
void loop(){
digitalWrite(Dp, HIGH);
//clock = 1 so we'll read a bit
if(Recieving == 0){
//if nothing is being sent, we have to check for a 1
if(digitalRead(Dm) == HIGH){
//1 was send, so we'll have to recieve a byte
Recieving = 1;
RecievedBit = 0;
RecievedByte = 0;
}
} else {
//save the received bit
if(digitalRead(Dm) == HIGH){
bitSet(RecievedByte, RecievedBit);
} else{
bitClear(RecievedByte, RecievedBit);
}
RecievedBit++;
if(RecievedBit == 8){
//if all 8 bits are sent, the byte is complete.
Recieving = 0;
Recieved = 1;
}
}
delay(Delay);
digitalWrite(Dp, LOW);
if(Recieved){
if(RecievedByte == 50){
if(ledOn == 0){
digitalWrite(13, HIGH);
ledOn = 1;
} else {
digitalWrite(13, LOW);
ledOn = 0;
}
RecievedByte = 0;
}
Recieved = 0;
}
delay(Delay);
}
HOW TO USE THE EXAMPLE PROGRAMS:
- BACKUP YOUR PROGRAMS AND OTHER IMPORTANT DATA ON YOUR CALC
- compile the z80 program (I used SPASM) and send it to your calc.
- send the programs to the arduino and the calc.
- if the arduino hasn't got an on-board LED, connect one (and a resistor!) to pin 13.
- cut a USB mini male end of a USB cable (make sure the wire attached to it is long enough, works with both A-type and B-type (both have been tested)).
- connect the white wire of the USB to pin 6, the green wire to pin 5 and the black wire to the GND.
- make sure the arduino is powered and insert the USB cable into the calc's USB port.
- run the assembly program with Asm( on the calc
When you run the program, press a key. The led should now turn on. When you run it and press a key again, the led should turn off. If your calc freezes, make sure the arduino is powered, the black wire is connected to the GND, runs the correct software and is connected to your calc.
What this does is: when you press a key on the calc, it sends a byte with a value of 50 to the arduino. The arduino notices a byte is send and checks if it's 50. If it's 50, pin 13 will toggle.
It may be very unoptimized (especially the arduino part, I learned the language two days ago), but it works. I hope this code can be usefull to anyone.
Also: thank you, Thepenguin77. Without your help, I wouldn't be able to control the USB port.