1 /*
2 * Copyright 1996, 1997, 1998, 1999 by Daniel B. Suthers,
3 * Pleasanton Ca. 94588 USA
4 * E-MAIL dbs@tanj.com
5 *
6 */
7
8 /*
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include "eeprom.h"
30 #include "process.h"
31
32 extern int tty;
33 extern int sptty;
34 extern int display();
35 extern int send_buffer ( unsigned char *, int, int, int, int );
36
37 /*-----------------------------------------------------------------+
38 | This function erases the eeprom. |
39 | 0 = 0 |
40 | 1 = 3 (start of macros |
41 | 2 = 0xff (end of timer initiators) |
42 | 3 = 0xff (end of macro initiators) |
43 | |
44 | It does it by writing the value 0xff to all memory positions |
45 | past the 3rd. We start by writing bytes 3 through 18 to 0xff, |
46 | and then byte 0 to 0 and 1 to 3. |
47 | |
48 | We want to avoid having a timer trigger to an invalid position. |
49 | We want all memory to be initialized just in case. |
50 +-----------------------------------------------------------------*/
51
eraseall(void)52 int eraseall ( void )
53 {
54 unsigned char block[20];
55 int blockno;
56 int x;
57 extern void error();
58 extern void remove_record_file();
59 extern int c_setclock();
60
61
62 block[0] = 0;
63 block[1] = 3;
64
65 for ( x = 2; x < 16; x++ )
66 block[x] = (unsigned char) 0xff;
67
68 /* Write the first block */
69 if ( sendpacket(0, block) < 0 ) {
70 error("Erase failed to write the first block\n");
71 }
72 fputc( '.', stdout);
73 fflush(stdout);
74
75 /* fill the block */
76 for(x=0; x < 16; x++)
77 block[x] = (unsigned char) 0xff;
78
79 /* For each 16 byte block... */
80 for ( blockno = 1; blockno < (PROMSIZE / 16); blockno++ ) {
81 if ( sendpacket((blockno * 16) , block) < 0 ) {
82 char tmpstr[100];
83 sprintf( tmpstr, "Erase failed to write block %d\n", blockno);
84 error(tmpstr);
85 }
86 fputc( '.', stdout);
87 fflush(stdout);
88 }
89
90 /*
91 * Delete the X10 Record File and reset the cm11a clock.
92 * (In the absence of record file, the clock is set to
93 * system standard time.)
94 *
95 */
96
97 remove_record_file();
98 (void) c_setclock(1, NULL);
99
100 return 0;
101 }
102
103
104 /*-----------------------------------------------------------------+
105 | sendpacket sends the packet from a 19 byte string and handles |
106 | locking and handshake. |
107 | loc = eeprom address (0 relative ) |
108 | dat = 16 btyes of data. |
109 | Return 0 on success, -1 on error. |
110 +-----------------------------------------------------------------*/
sendpacket(int loc,unsigned char * dat)111 int sendpacket ( int loc, unsigned char *dat)
112 {
113 unsigned char buf[23];
114 extern int xwrite();
115 int rtn;
116 unsigned char sum;
117 int timeout;
118 extern int xwrite(), exread(), check4poll();
119 extern unsigned char checksum();
120
121
122 /* timeout = 10; */
123 timeout = 3;
124
125 buf[0] = (char) 0xfb; /* write to eeprom command */
126 buf[1] = loc / 256; /* hi byte of eeprom address */
127 buf[2] = loc % 256; /* low byte of eeprom address */
128 memcpy(&buf[3], dat, 16);
129
130 rtn = xwrite(tty, buf, 19);
131 if ( rtn < 0 )
132 return rtn;
133
134 /* the checksum covers the data... Not the leading 0xfb */
135 sum = checksum(buf + 1, 18) ;
136
137 /* read back the check sum */
138 rtn = exread(sptty, buf, 1, timeout);
139 if ( rtn < 0 )
140 return rtn;
141
142 if ( sum != buf[0] ) {
143 fprintf(stderr, "Checksum failure sending eeprom command\n");
144 fprintf( stderr, "Expected %0x, got %0x\n", sum, buf[0]);
145 return -2;
146 }
147
148 /* check sums match */
149 rtn= xwrite(tty, "\00" , 1); /* WRMI (we really mean it) */
150 if ( rtn < 0 )
151 return(rtn);
152
153 buf[0] = 0;
154 rtn = exread(sptty, buf, 1, timeout);
155 if ( rtn == 1 ) {
156 if ( buf[0] != 0x55 ) {
157 fprintf(stderr,
158 "Ack after execution = 0x%02x, It should be 0x55)\n", buf[0]);
159 rtn = 0;
160 }
161 }
162
163 if ( rtn != 1 ) {
164 if ( rtn == 0 && sum == 0x5a ) /* Workaround for 0x5a checksum problem */
165 return 0;
166 else {
167 fprintf(stderr,
168 "Interface not ready after sending data for location %0x)\n", loc);
169 fprintf(stderr, "rtn = %0x\n", rtn);
170 return -1;
171 }
172 }
173
174 return 0;
175
176 }
177
178
179 /*-----------------------------------------------------------------+
180 | Upload the 1024 byte memory image 'prommap' to the CM11A EEPROM.|
181 | Start by nulling out the header block. Then upload backwards |
182 | so everything will be in place when the new header block is |
183 | uploaded. |
184 +-----------------------------------------------------------------*/
upload_eeprom_image_old(unsigned char * prommap)185 void upload_eeprom_image_old ( unsigned char *prommap )
186 {
187 unsigned char emptyprom[32];
188 extern int verbose;
189 extern void error();
190 int x;
191
192 /* Zero out the initiators to null the header block */
193
194 emptyprom[0] = (unsigned char)0;
195 emptyprom[1] = (unsigned char)3;
196 for ( x = 2; x < 16; x++)
197 emptyprom[x] = (unsigned char)0xff;
198
199
200 /* erase the old eeprom header information */
201 if ( sendpacket(0 , emptyprom) < 0 ) {
202 (void)error("load_macro() failed to erase initiator block");
203 /* error() exits */
204 }
205
206 /* Copy the data from the array 'prommap' to the CM11A */
207 /* Load backwards
208 * This is so the timers at the end of the eeprom are there when
209 * the initiators are loaded at the start of the eeprom
210 */
211
212 fprintf(stdout, "Uploading %d block memory image to interface.\n",
213 PROMSIZE / 16 );
214
215 for ( x = 0; x < (PROMSIZE/16); x++ )
216 fputc( '.', stdout);
217 fputc( '\r', stdout);
218 fflush(stdout);
219
220 for ( x = (PROMSIZE / 16) - 1; x >= 0; x-- ) {
221 if (verbose)
222 fprintf( stderr, "Loading %d\n", x * 16 );
223
224 if ( sendpacket((x * 16), prommap + (x*16)) < 0 ) {
225 char tmpstr[100];
226 sprintf( tmpstr, "Upload failed to write block %d\n", x);
227 error(tmpstr);
228 }
229 fputc( '#', stdout);
230 fflush(stdout);
231 }
232 fputc('\n', stdout);
233
234 return;
235 }
236
237 /*-----------------------------------------------------------------+
238 | Upload the 1024 byte memory image 'prommap' to the CM11A EEPROM.|
239 | Start by nulling out the header block. Then upload backwards |
240 | so everything will be in place when the new header block is |
241 | uploaded. |
242 +-----------------------------------------------------------------*/
upload_eeprom_image(unsigned char * prommap)243 void upload_eeprom_image ( unsigned char *prommap )
244 {
245 extern int verbose;
246 unsigned char buffer[32];
247 unsigned int loc;
248 int j, k, block, chkoff, result, timeout = 3;
249
250 /* Offset checksum from beginning of buffer - the initial */
251 /* 0xfb is not included in the checksum. */
252 chkoff = 1;
253
254 /* Zero out the initiators to null the header block */
255
256 buffer[0] = 0xfb;
257 buffer[1] = 0x00;
258 buffer[2] = 0x03;
259 for ( j = 3; j < 19; j++)
260 buffer[j] = 0xff;
261
262 /* erase the old eeprom header information */
263 if ( send_buffer(buffer, 19, chkoff, timeout, NO_SYNC) != 0 ) {
264 fprintf(stderr, "upload_eeprom_image() failed to erase initiator block.\n");
265 exit(1);
266 }
267
268 /* Copy the data from the array 'prommap' to the CM11A */
269 /* Load backwards
270 * This is so the timers at the end of the eeprom are there when
271 * the initiators are loaded at the start of the eeprom
272 */
273
274 fprintf(stdout, "Uploading %d block memory image to interface.\n",
275 PROMSIZE / 16 );
276
277 for ( j = 0; j < (PROMSIZE/16); j++ )
278 fputc( '.', stdout);
279 fputc( '\r', stdout);
280 fflush(stdout);
281
282 for ( block = (PROMSIZE / 16) - 1; block >= 0; block-- ) {
283 loc = block * 16;
284
285 buffer[0] = 0xfb;
286 buffer[1] = loc / 256;
287 buffer[2] = loc % 256;
288 memcpy(&buffer[3], prommap + loc, 16);
289
290 result = 0; /* Keep compiler happy */
291 for ( k = 0; k < 3; k++ ) {
292 if (verbose)
293 fprintf(stderr, "Uploading block %d to address 0x%03x\n", block, loc );
294
295 if ( (result = send_buffer(buffer, 19, chkoff, timeout, NO_SYNC)) == 0 )
296 break;
297 sleep(2);
298 }
299 if ( result != 0 ) {
300 fprintf(stderr, "Upload failed to write block %d to address 0x%03x\n", block, loc);
301 exit(1);
302 }
303
304 fputc( '#', stdout);
305 fflush(stdout);
306 }
307 fputc('\n', stdout);
308
309 return;
310 }
311
312