-
Notifications
You must be signed in to change notification settings - Fork 1
/
command_parser.cpp
105 lines (102 loc) · 2.34 KB
/
command_parser.cpp
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
#include "command_parser.hpp"
void CommandParser::handleInput(const uint8_t* s, int len) {
const uint8_t* end = s + len;
if(writeFIFOBytesLeft > 0) {
int consume = writeFIFOBytesLeft;
if(consume > len)
consume = len;
handleWriteFIFO(cmdAddress, 0, consume, s);
s += consume;
writeFIFOBytesLeft -= consume;
if(writeFIFOBytesLeft > 0)
return;
}
while(s < end) {
uint8_t c = *s;
if(cmdPhase == 0) {
cmdOpcode = c;
if(cmdOpcode == 0)
goto cont;
if(cmdOpcode == 0x0d) {
send((const uint8_t*) "2", 1);
goto cont;
}
cmdPhase++;
goto cont;
}
if(cmdPhase == 1) {
cmdStartAddress = cmdAddress = c;
if(cmdOpcode == 0x21)
cmdEndAddress = cmdAddress + 2;
if(cmdOpcode == 0x22)
cmdEndAddress = cmdAddress + 4;
if(cmdOpcode == 0x23)
cmdEndAddress = cmdAddress + 8;
// 1-parameter commands
if(cmdOpcode >= 0x10 && cmdOpcode <= 0x12) {
uint8_t* rPtr = registers + (cmdAddress & registersSizeMask);
switch(cmdOpcode) {
case 0x10:
send(rPtr, 1);
break;
case 0x11:
send(rPtr, 2);
break;
case 0x12:
send(rPtr, 4);
break;
}
cmdPhase = 0;
goto cont;
} else {
cmdPhase++;
goto cont;
}
}
// 2 or more parameter commands
switch(cmdOpcode) {
case 0x18:
case 0x13: // FOR TEMPORARY BACKWARDS COMPATIBILITY ONLY. WILL BE REMOVED.
handleReadFIFO(cmdAddress, c);
cmdPhase = 0;
break;
case 0x20:
registers[cmdAddress & registersSizeMask] = c;
cmdPhase = 0;
handleWrite(cmdAddress);
break;
case 0x21:
case 0x22:
case 0x23:
registers[cmdAddress & registersSizeMask] = c;
cmdAddress++;
if(cmdAddress == cmdEndAddress) {
cmdPhase = 0;
handleWrite(cmdStartAddress);
}
break;
case 0x28:
{
int totalBytes = (int) (uint8_t) c;
s++; // move past the size byte
cmdPhase = 0; // resume command processing once data is consumed
int bufBytes = end - s;
if(bufBytes >= totalBytes) {
// all data is in the current buffer
handleWriteFIFO(cmdAddress, totalBytes, totalBytes, s);
s += totalBytes;
continue;
}
// partial data is in the buffer
handleWriteFIFO(cmdAddress, totalBytes, bufBytes, s);
writeFIFOBytesLeft = totalBytes - bufBytes;
return;
}
default:
cmdPhase = 0;
break;
}
cont:
s++;
}
}