OpenCores
URL https://opencores.org/ocsvn/adv_debug_sys/adv_debug_sys/trunk

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [trunk/] [Software/] [AdvancedWatchpointControl/] [src/] [advancedWatchpointControl/] [rspCoder.java] - Blame information for rev 51

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 51 nyawn
package advancedWatchpointControl;
2
 
3
import java.io.IOException;
4
 
5
 
6
public class rspCoder {
7
 
8
 
9
 
10
        public enum rcvStateType { WAITING_FOR_START, RECEIVING_DATA, RECEIVING_CSUM1,
11
                RECEIVING_CSUM2, FINISHED }
12
 
13
        private networkSystem netSys = null;
14
        private rcvStateType rcvState = rcvStateType.WAITING_FOR_START;
15
        private StringBuilder rcvPacketStringBuilder = null;
16
 
17
        public rspCoder(networkSystem ns) {
18
                rcvPacketStringBuilder = new StringBuilder();
19
                netSys = ns;
20
        }
21
 
22
        public void Transact(TargetTransaction t) throws IOException {
23
                int retries_remaining = 3;
24
                int rcvchar;
25
                boolean ret = false;
26
 
27
                // Send the packet and look for an RSP ack ("+")
28
                do {
29
                        escapePacketAndSend(t.getDataToSend());
30
                        rcvchar = netSys.getChar(); // Get +/-
31
                        // If -, retry up to 3 times
32
                } while((rcvchar != '+') && ((retries_remaining--) >= 0));
33
 
34
                if(retries_remaining < 0) {
35
                        throw new IOException("Retries exceeded sending data");
36
                }
37
 
38
                retries_remaining = 3;
39
 
40
                do {
41
                        ret = false;
42
                        // Get one complete packet
43
                        String dataPacket = getDataPacket();
44
                        // Unescape, un-RLE, and test the checksum.  Returns null if bad checksum
45
                        String decodedPacket = decodeRSPPacket(dataPacket);
46
                        if(decodedPacket != null) {
47
                                // Let the transaction object parse the specific packet type
48
                                ret = t.receivePacket(decodedPacket);
49
                        }
50
                        if(!ret) {
51
                                sendNak();
52
                        }
53
 
54
                } while ((!ret)&& ((retries_remaining--) >= 0));
55
 
56
                if(retries_remaining < 0) {
57
                        throw new IOException("Retries exceeded parsing data");
58
                }
59
 
60
                sendAck();
61
 
62
        }  // Transact()
63
 
64
 
65
        private boolean escapePacketAndSend(String packetString) {
66
                //System.out.println("Sending packet: \"" + packetString + "\"");
67
                String protocolString = new String("$");
68
 
69
                // Escape the packet data.  '}' is 0x7d, the escape char.
70
                // Escaped char must be XOR'd with 0x20.
71
                packetString.replace("}", "}"+('}'^0x20));  // This must be escaped first!
72
                packetString.replace("#", "}"+('#'^0x20));  // '#' is 0x23
73
                packetString.replace("$", "}"+('$'^0x20));  // '$' is 0x24
74
 
75
                // Add the packet data
76
                protocolString += packetString;
77
 
78
                // Add the separator
79
                protocolString += "#";
80
 
81
                // Create the checksum (from packetString, not protocolString)
82
                int checksum = getChecksum(packetString);
83
 
84
                // Add the checksum
85
                if(checksum < 0x10)
86
                        protocolString += "0";
87
                protocolString += Integer.toHexString(checksum);
88
 
89
                // Send it.
90
                return netSys.sendData(protocolString);
91
        }
92
 
93
 
94
        // This reads one complete data packet from the network, including checksum
95
        public String getDataPacket() throws IOException {
96
                int rcvChar;
97
                rcvState = rcvStateType.WAITING_FOR_START;
98
 
99
                do {
100
                        rcvChar = netSys.getChar();
101
                        //System.out.println("parseData: " + rcvChar);
102
                        switch(rcvState) {
103
                                case WAITING_FOR_START:
104
                                        if(rcvChar == '$') {
105
                                                // discard the '$' character
106
                                                rcvState = rcvStateType.RECEIVING_DATA;
107
                                                rcvPacketStringBuilder = new StringBuilder();
108
                                        }
109
                                        break;
110
                                case RECEIVING_DATA:
111
                                        if(rcvChar == '#') {
112
                                                rcvState = rcvStateType.RECEIVING_CSUM1;
113
                                        }
114
                                        rcvPacketStringBuilder.append((char)rcvChar);
115
                                        break;
116
                                case RECEIVING_CSUM1:
117
                                        rcvPacketStringBuilder.append((char)rcvChar);
118
                                        rcvState = rcvStateType.RECEIVING_CSUM2;
119
                                        break;
120
                                case RECEIVING_CSUM2:
121
                                        rcvPacketStringBuilder.append((char)rcvChar);
122
                                        rcvState = rcvStateType.FINISHED;
123
                                        break;
124
                        }
125
                } while(rcvState != rcvStateType.FINISHED);
126
 
127
                return rcvPacketStringBuilder.toString();
128
        }  // parseData()
129
 
130
 
131
        // This looks like it modifies the input String.  But since a String
132
        // is actually constant, a new String object should be created each
133
        // time we "modify" the String, so the original input parameter
134
        // should remain intact.
135
        private String decodeRSPPacket(String packet) {
136
 
137
                //System.out.println("Parsing packet: \"" + packet + "\"\n");
138
 
139
                // Test the checksum
140
                int checksum = 0;
141
                try {
142
                        //System.out.println("Checksum substring: " + packet.substring(packet.length()-2));
143
                        checksum = Integer.parseInt(packet.substring(packet.length()-2), 16);
144
                } catch (NumberFormatException e) {
145
                        // TODO Log the error
146
                        sendNak();
147
                        System.out.println("Got bad checksum: calculated " + getChecksum(packet) + ", read " + checksum);
148
                        return null;
149
                }
150
                // Cut off the '#' and checksum
151
                packet = packet.substring(0, packet.length()-3);
152
 
153
                if(checksum != getChecksum(packet)) {
154
                        // TODO Log the error
155
                        sendNak();
156
                        System.out.println("Got bad checksum: calculated " + getChecksum(packet) + ", read " + checksum);
157
                        return null;
158
                }
159
 
160
                // Un-escape
161
                packet.replace("}"+('#'^0x20), "#");
162
                packet.replace("}"+('$'^0x20), "$");
163
                packet.replace("}"+('}'^0x20), "}");
164
 
165
                // Undo any run-length encoding.  This code is so ugly.
166
                if(packet.indexOf("*") != -1) {
167
                        StringBuffer sb = new StringBuffer(packet);
168
                        int thisIndex = 0;
169
                        int lastIndex = 0;
170
 
171
                        while(-1 != (thisIndex = sb.indexOf("*", lastIndex))) {
172
                                int runlength = sb.charAt(thisIndex+1) - 28;
173
                                sb.deleteCharAt(thisIndex+1);
174
                                sb.deleteCharAt(thisIndex);
175
                                char c = sb.charAt(thisIndex-1);
176
                                for(int i = 0; i < runlength; i++) {
177
                                        sb.insert(thisIndex, c);
178
                                }
179
                                lastIndex = thisIndex;
180
                        }
181
 
182
                        packet = sb.toString();
183
                }
184
 
185
                return packet;
186
        }  // handleRSPPacket()
187
 
188
 
189
        public void sendAck() {
190
                netSys.sendData("+");
191
        }
192
 
193
        public void sendNak() {
194
                netSys.sendData("-");
195
        }
196
 
197
 
198
        private int getChecksum(String packet) {
199
                int csum = 0;
200
                for(int i = 0; i < packet.length(); i++) {
201
                        csum += packet.charAt(i);
202
                        //System.out.println("checksum adding char: " + packet.charAt(i) + ", checksum " + csum);
203
                }
204
                csum = csum & 0xFF;
205
                //System.out.println("Final checksum: " + csum);
206
                return csum;
207
        }
208
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.