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