Last active
January 17, 2017 08:55
-
-
Save halferty/d234a3ca9dffd151c572ddc919e414b8 to your computer and use it in GitHub Desktop.
Arduino Apple ADB fun
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c\n" | |
#define BYTE_TO_BINARY(val) \ | |
(val & 0x80 ? '1' : '0'), \ | |
(val & 0x40 ? '1' : '0'), \ | |
(val & 0x20 ? '1' : '0'), \ | |
(val & 0x10 ? '1' : '0'), \ | |
(val & 0x8 ? '1' : '0'), \ | |
(val & 0x4 ? '1' : '0'), \ | |
(val & 0x2 ? '1' : '0'), \ | |
(val & 0x1 ? '1' : '0') | |
void setup() { | |
Serial.begin(9600); | |
pinMode(2, INPUT_PULLUP); | |
} | |
#define NUM 256 | |
unsigned long startTime, endTime, diff; | |
unsigned long diffs[NUM]; | |
unsigned long index = 0; | |
unsigned char command; | |
char printBuffer[64]; | |
boolean waitingForStart = true; | |
unsigned char deviceId = 3; | |
void writeOne() { | |
digitalWrite(2, LOW); | |
delayMicroseconds(35); | |
digitalWrite(2, HIGH); | |
delayMicroseconds(65); | |
} | |
void writeZero() { | |
digitalWrite(2, LOW); | |
delayMicroseconds(65); | |
digitalWrite(2, HIGH); | |
delayMicroseconds(35); | |
} | |
unsigned long readPulse() { | |
while(digitalRead(2)) {} | |
startTime = micros(); | |
while(!digitalRead(2)) {} | |
endTime = micros(); | |
return (endTime - startTime); | |
} | |
boolean isHigh(unsigned long d) { | |
return (d > (35 - 10) && d < (35 + 10)); | |
} | |
boolean isLow(unsigned long d) { | |
return (d > (65 - 10) && d < (65 + 10)); | |
} | |
void loop() { | |
diff = readPulse(); | |
if (diff > 750 && diff < 850) { | |
index = 0; | |
waitingForStart = false; | |
} else if (!waitingForStart) { | |
diffs[index] = diff; | |
index++; | |
if (index == 8) { | |
command = 0; | |
for (index = 0; index < 8; index++) { | |
if (isHigh(diffs[index])) { | |
command |= (1 << (7 - index)); | |
} else if (isLow(diffs[index])) { | |
command &= ~(1 << (7 - index)); | |
} | |
} | |
if (command >> 4 == deviceId) { | |
if (((command >> 2) & 3) == 3) { | |
// Talk command | |
if (command & 3 == 3) { | |
// Register 3 | |
// Respond with some stuff | |
delayMicroseconds(200); | |
pinMode(2, OUTPUT); | |
// '1' Start bit | |
writeOne(); | |
// 15 reserved, 0 | |
writeZero(); | |
// 14 exceptional event, device specific, 1 if unused | |
writeOne(); | |
// 13 service request enable, 1 = enabled | |
writeOne(); | |
// 12 reserved, 0 | |
writeZero(); | |
// 11 | |
// 10 | |
// 9 | |
// 8 address | |
// Send a random address, which is just going to be hardcoded as 6 here, because I'm lazy | |
writeZero(); | |
writeOne(); | |
writeOne(); | |
writeZero(); | |
// 7 | |
// 6 | |
// 5 | |
// 4 | |
// 3 | |
// 2 | |
// 1 | |
// 0 device handler id | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeOne(); | |
// '0' stop bit | |
writeZero(); | |
pinMode(2, INPUT_PULLUP); | |
} else if (command & 3 == 0) { | |
// Register 0 | |
// Respond with some stuff | |
delayMicroseconds(200); | |
pinMode(2, OUTPUT); | |
// '1' Start bit | |
writeOne(); | |
// 15 button status, 0 = down | |
writeOne(); | |
// 14 | |
// 13 | |
// 12 | |
// 11 | |
// 10 | |
// 9 | |
// 8 Y move counts 2's complement form, negative = up | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
// 7 not used (always 0) | |
writeZero(); | |
// 6 | |
// 5 | |
// 4 | |
// 3 | |
// 2 | |
// 1 | |
// 0 X move counts, negative = left | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeZero(); | |
writeOne(); | |
// '0' stop bit | |
writeZero(); | |
pinMode(2, INPUT_PULLUP); | |
} | |
} else if (((command >> 2) & 3) == 2) { | |
// Listen command | |
// Listen Register 3 | |
if (command & 3 == 3) { | |
for(index = 0; index < 19; index++) { | |
diffs[index] = readPulse(); | |
} | |
deviceId = (isHigh(diffs[6]) << 3) | (isHigh(diffs[7]) << 2) | (isHigh(diffs[8]) << 1) | (isHigh(diffs[9])); | |
sprintf(printBuffer, "Going to DeviceId: %d\n", deviceId); | |
Serial.print(printBuffer); | |
for(index = 0; index < 19; index++) { | |
sprintf(printBuffer, "%d\n", (isLow(diffs[index])) ? 0 : (isHigh(diffs[index])) ? 1 : diffs[index]); | |
Serial.print(printBuffer); | |
} | |
Serial.print("Done.\n"); | |
// TODO: The host keeps sending us to different IDs (27 times!) and then polls register 0 very infrequently, so this is probably working wrongly? Or do we just need to do a sysrequest to actually send data? | |
// (That's done by effectively wiping out the stop bit on any host command, holding it low for a total of 300usec. Then it waits to be addressed. If the host addresses some other device instead, do it again). | |
} else { | |
sprintf(printBuffer, BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(command)); | |
Serial.print(printBuffer); | |
Serial.print("Unknown Listen command:\n"); | |
for(index = 0; index < NUM; index++) { | |
diffs[index] = readPulse(); | |
} | |
for(index = 0; index < NUM; index++) { | |
sprintf(printBuffer, "%d\n", (isLow(diffs[index])) ? 0 : (isHigh(diffs[index])) ? 1 : diffs[index]); | |
Serial.print(printBuffer); | |
} | |
Serial.print("Done.\n"); | |
while(1) {} | |
} | |
} | |
sprintf(printBuffer, BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(command)); | |
Serial.print(printBuffer); | |
} | |
index = 0; | |
waitingForStart = true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment