1 /*
2  * Copyright (C) 2005-2019 Darron Broad
3  * All rights reserved.
4  *
5  * This file is part of Pickle Microchip PIC ICSP.
6  *
7  * Pickle Microchip PIC ICSP is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as published
9  * by the Free Software Foundation.
10  *
11  * Pickle Microchip PIC ICSP is distributed in the hope that it will be
12  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with Pickle Microchip PIC ICSP. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #define DEBUG
21 
22 #include "pickle.h"
23 
24 /******************************************************************************
25  *
26  * Session
27  *
28  *****************************************************************************/
29 
30 extern struct pickle p;
31 
32 /*******************************************************************************
33  *
34  * STK500V2 emulator
35  *
36  * Only one instance of either a sender or receiver shall exist.
37  *
38  ******************************************************************************/
39 
40 /* I/O descriptor */
41 int stk_fsock = -1;
42 
43 /* I/O buffer */
44 uint8_t stk_msg[STK_LEN + /* Checksum */ 1];
45 
46 /* Packet sequence number */
47 uint8_t stk_seqnum;
48 
49 /* I/O timeout */
50 int stk_timeout;
51 
52 /* I/O data row address */
53 uint32_t stk_addr;
54 
55 /* I/O address size (32-bit extended or 16-bit) */
56 uint8_t stk_addr_size;
57 
58 /* Sign-on signature */
59 uint8_t stk_signon_msg[11] = {
60 	STK_CMD_SIGN_ON, STK_STATUS_CMD_OK,
61 	/* SIG LENGTH   */ 0x08,
62 	/* SIG STK500V2 */ 0x53,0x54,0x4B,0x35,0x30,0x30,0x5F,0x32
63 };
64 
65 /*******************************************************************************
66  *
67  * Open interface
68  */
69 int16_t
stk500v2_open(const char * interface,int port,int flag)70 stk500v2_open(const char *interface, int port, int flag)
71 {
72 	if (interface[0] == '/') {
73 		stk_fsock = serial_open(interface, serial_speed(p.baudrate));
74 	} else {
75 		if (flag == STK_CONNECT) {
76 			stk_fsock = ip_connect(interface, port);
77 		} else { /* STK _LISTEN */
78 			stk_fsock = ip_listen(interface, port);
79 		}
80 	}
81 	return stk_fsock;
82 }
83 
84 /*
85  * Close interface
86  */
87 void
stk500v2_close(const char * interface)88 stk500v2_close(const char *interface)
89 {
90 	if (interface[0] == '/') {
91 		if (stk_fsock >= 0)
92 			serial_close(stk_fsock);
93 	} else {
94 		if (stk_fsock >= 0)
95 			close(stk_fsock);
96 	}
97 	stk_fsock = -1;
98 }
99 
100 /*******************************************************************************
101  *
102  * AVR068: STK500V2 Communication Protocol
103  *
104  *  Receive Packet
105  *
106  * Message Format & Protocol Layer State Table
107  *
108  * 2591C-AVR-06/06 Pages 2 & 3
109  *
110  ******************************************************************************/
111 int16_t
stk500v2_recv(int flag)112 stk500v2_recv(int flag)
113 {
114 	int rc;
115 	uint8_t sum = 0;
116 	uint16_t msgsize, i;
117 
118 	/* Get message start */
119 	rc = rw_get(stk_fsock, (char *)stk_msg, 1, stk_timeout);
120 	if (rc < 0) {
121 		DPRINT("%s:rw_get MESSAGE_START failed\n", __func__);
122 		return rc;
123 	}
124 
125 	/* Validate message start */
126 	if (stk_msg[0] != STK_MESSAGE_START) {
127 		DPRINT("%s:invalid MESSAGE_START\n", __func__);
128 		return STK_PROTOCOL_ERROR;
129 	}
130 
131 	/* Message start checksum */
132 	sum ^= stk_msg[0];
133 
134 	/* Get sequence number */
135 	rc = rw_get(stk_fsock, (char *)stk_msg, 1, stk_timeout);
136 	if (rc < 0) {
137 		DPRINT("%s:rw_get SEQNUM failed\n", __func__);
138 		return rc;
139 	}
140 
141 	/* Echo sequence number */
142 	if (flag == STK_SEQECHO) {
143 		stk_seqnum = stk_msg[0];
144 	}
145 	/* Validate sequence number */
146 	else if (flag == STK_SEQTEST) {
147 		if (stk_msg[0] != stk_seqnum) {
148 			DPRINT("%s:invalid SEQNUM\n", __func__);
149 			return STK_PROTOCOL_ERROR;
150 		}
151 		stk_seqnum++;
152 	}
153 
154 	/* Sequence number checksum */
155 	sum ^= stk_msg[0];
156 
157 	/* Get message size 1/2 */
158 	rc = rw_read(stk_fsock, (char *)stk_msg, 2, stk_timeout);
159 	if (rc < 0) {
160 		DPRINT("%s:rw_read MESSAGE_SIZE failed\n", __func__);
161 		return rc;
162 	}
163 
164 	/* Validate message size */
165 	msgsize = (stk_msg[0] << 8) | stk_msg[1];
166 	if (msgsize > STK_LEN) {
167 		DPRINT("%s:invalid MESSAGE_SIZE\n", __func__);
168 		return STK_PROTOCOL_ERROR;
169 	}
170 
171 	/* Message size checksum */
172 	sum ^= stk_msg[0];
173 	sum ^= stk_msg[1];
174 
175 	/* Get token */
176 	rc = rw_get(stk_fsock, (char *)stk_msg, 1, stk_timeout);
177 	if (rc < 0) {
178 		DPRINT("%s:rw_get TOKEN failed\n", __func__);
179 		return rc;
180 	}
181 
182 	/* Validate token */
183 	if (stk_msg[0] != STK_TOKEN) {
184 		DPRINT("%s:invalid TOKEN\n", __func__);
185 		return STK_PROTOCOL_ERROR;
186 	}
187 
188 	/* Token checksum */
189 	sum ^= stk_msg[0];
190 
191 	/* Get data & checksum */
192 	rc = rw_read(stk_fsock, (char *)stk_msg, ++msgsize, stk_timeout);
193 	if (rc < 0) {
194 		DPRINT("%s:rw_read DATA + CHKSUM failed\n", __func__);
195 		return rc;
196 	}
197 	msgsize--;
198 
199 	/* Message checksum */
200 	for (i = 0; i < msgsize; ++i)
201 		sum ^= stk_msg[i];
202 
203 	/* Validate packet checksum */
204 	if (sum != stk_msg[msgsize]) {
205 		DPRINT("%s:invalid CHKSUM\n", __func__);
206 		return STK_PROTOCOL_ERROR;
207 	}
208 
209 	/* Return with number of bytes in message */
210 	return msgsize;
211 }
212 
213 /*******************************************************************************
214  *
215  * AVR068: STK500V2 Communication Protocol
216  *
217  *  Send Packet
218  *
219  * Message Format & General Commands
220  *
221  * 2591C-AVR-06/06 Pages 2 & 4
222  *
223  ******************************************************************************/
224 int16_t
stk500v2_send(uint16_t msgsize)225 stk500v2_send(uint16_t msgsize)
226 {
227 	int rc;
228 	uint8_t header[5], sum = 0;
229 	uint16_t i;
230 
231 	/* Send header */
232 	header[0] = STK_MESSAGE_START;
233 	header[1] = stk_seqnum;
234 	header[2] = msgsize >> 8;
235 	header[3] = msgsize & 0xFF;
236 	header[4] = STK_TOKEN;
237 	rc = rw_write(stk_fsock, (char *)header, 5, stk_timeout);
238 	if (rc < 0)
239 		return rc;
240 	if (rc != 5)
241 		return -1;
242 
243 	/* Header checksum */
244 	for (i = 0; i < 5; ++i)
245 		sum ^= header[i];
246 
247 	/* Message checksum */
248 	for (i = 0; i < msgsize; ++i)
249 		sum ^= stk_msg[i];
250 
251 	/* Packet checksum */
252 	stk_msg[msgsize] = sum;
253 
254 	/* Send message & Checksum */
255 	rc = rw_write(stk_fsock, (char *)stk_msg, ++msgsize, stk_timeout);
256 	if (rc < 0)
257 		return rc;
258 	if (rc != msgsize--)
259 		return -1;
260 
261 	/* Return with number of bytes in message */
262 	return msgsize;
263 }
264