-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathserial2ti83.ino
151 lines (131 loc) · 3.61 KB
/
serial2ti83.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
const int TIP = 2; //arduino port where the tip of the stereo jack plug is connected
const int RING = 3; //arduino port where the middle part of the stereo jack plug is connected
const unsigned long TXTIMEOUT = 50; //ms
const unsigned long RXTIMEOUT = 5; //ms
void sendByte(uint8_t byte)
{
unsigned long currentTime;
for (int i = 0; i < 8; ++i)
{
bool bit = byte & 0x01;
byte >>= 1;
//poll both lines until they are both high, which means we're ready to send a bit
currentTime = millis();
while (digitalRead(TIP) == LOW || digitalRead(RING) == LOW)
{
if (millis() - currentTime > TXTIMEOUT)
{
return;
}
}
int ourLine;
int oppositeLine;
if (bit)
{
ourLine = RING;
oppositeLine = TIP;
}
else
{
ourLine = TIP;
oppositeLine = RING;
}
//send a bit by pulling appropriate line low
pinMode(ourLine, OUTPUT);
digitalWrite(ourLine, LOW);
//wait for opposite line to become low
currentTime = millis();
while (digitalRead(oppositeLine) == HIGH)
{
if (millis() - currentTime > TXTIMEOUT)
{
pinMode(ourLine, INPUT_PULLUP);
return;
}
}
//release our line
pinMode(ourLine, INPUT_PULLUP);
//wait for opposite line to become high
currentTime = millis();
while (digitalRead(oppositeLine) == LOW)
{
if (millis() - currentTime > TXTIMEOUT)
{
return;
}
}
}
}
bool getByte(uint8_t& byte)
{
unsigned long currentTime;
uint8_t result = 0;
for (int i = 0; i < 8; ++i)
{
//poll both lines until one of them becomes low
currentTime = millis();
while (digitalRead(TIP) == HIGH && digitalRead(RING) == HIGH)
{
if (millis() - currentTime > RXTIMEOUT)
{
return false;
}
}
int ourLine;
int oppositeLine;
bool bit = (digitalRead(RING) == LOW);
result >>= 1;
if (bit)
{
ourLine = TIP;
oppositeLine = RING;
result |= 0x80; //bits are always transmitted LSb first (least significant bit)
}
else
{
ourLine = RING;
oppositeLine = TIP;
}
//acknowledge a bit by pulling appropriate line low
pinMode(ourLine, OUTPUT);
digitalWrite(ourLine, LOW);
//wait for opposite line to become high
currentTime = millis();
while (digitalRead(oppositeLine) == LOW)
{
if (millis() - currentTime > RXTIMEOUT)
{
pinMode(ourLine, INPUT_PULLUP);
return false;
}
}
//release our line
pinMode(ourLine, INPUT_PULLUP);
}
byte = result;
return true;
}
void setup()
{
//turn off the built-in LED
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(9600);
//configure both lines to be in a high-impedance state and enable pull-up resistors
pinMode(TIP, INPUT_PULLUP);
pinMode(RING, INPUT_PULLUP);
}
void loop()
{
//forward incoming data from PC to the calculator
while (Serial.available() > 0)
{
sendByte(Serial.read());
}
//forward incoming data from calculator to the PC
uint8_t byteFromCalc;
if (getByte(byteFromCalc))
{
Serial.write(byteFromCalc);
}
}