initial commit after making CF identify work
Stefan Schuermans

Stefan Schuermans commited on 2012-04-15 19:57:57
Showing 166 changed files, with 25630 additions and 0 deletions.

... ...
@@ -0,0 +1,2 @@
1
+*.tar.bz2
2
+*.zip
... ...
@@ -0,0 +1,8 @@
1
+flaneth.calc.ods.pdf
2
+flaneth.net
3
+flaneth.ods.pdf
4
+flaneth.pcb.pdf
5
+flaneth.sch.pdf
6
+flaneth.t2l.pcb
7
+flaneth.t2l.pcb.pdf
8
+gerber
... ...
@@ -0,0 +1,16 @@
1
+0.1.3 2008-06-08
2
+----------------
3
+fixed power connectin in PCB
4
+
5
+0.1.2 2008-02-05
6
+----------------
7
+added option to use LF1S022 instead of FB2022
8
+
9
+0.1.1 2008-02-04
10
+----------------
11
+added capacitor to AREF pin of processor
12
+
13
+0.1 2008-02-03
14
+--------------
15
+first version
16
+
... ...
@@ -0,0 +1,4167 @@
1
+# release: pcb 20070208
2
+# date:    Sun Jun  8 15:50:45 2008
3
+# user:    stefan (Stefan Schuermans)
4
+# host:    stefan1.lan
5
+
6
+PCB["" 433071 433071]
7
+
8
+Grid[3937.007813 0 0 1]
9
+Cursor[0 0 0.000000]
10
+PolyArea[200000000.000000]
11
+Thermal[1.000000]
12
+DRC[700 400 800 800 1500 1000]
13
+Flags(0x0000000000001a51)
14
+Groups("1,c:2,s:3:4:5:6:7:8")
15
+Styles["Signal,2000,4000,2000,1150:Power,4000,6000,3000,1150:Fat,8000,8000,4000,1150:Skinny,1500,3200,1500,1150"]
16
+
17
+Symbol(' ' 18)
18
+(
19
+)
20
+Symbol('!' 12)
21
+(
22
+	SymbolLine(0 45 0 50 8)
23
+	SymbolLine(0 10 0 35 8)
24
+)
25
+Symbol('"' 12)
26
+(
27
+	SymbolLine(0 10 0 20 8)
28
+	SymbolLine(10 10 10 20 8)
29
+)
30
+Symbol('#' 12)
31
+(
32
+	SymbolLine(0 35 20 35 8)
33
+	SymbolLine(0 25 20 25 8)
34
+	SymbolLine(15 20 15 40 8)
35
+	SymbolLine(5 20 5 40 8)
36
+)
37
+Symbol('$' 12)
38
+(
39
+	SymbolLine(15 15 20 20 8)
40
+	SymbolLine(5 15 15 15 8)
41
+	SymbolLine(0 20 5 15 8)
42
+	SymbolLine(0 20 0 25 8)
43
+	SymbolLine(0 25 5 30 8)
44
+	SymbolLine(5 30 15 30 8)
45
+	SymbolLine(15 30 20 35 8)
46
+	SymbolLine(20 35 20 40 8)
47
+	SymbolLine(15 45 20 40 8)
48
+	SymbolLine(5 45 15 45 8)
49
+	SymbolLine(0 40 5 45 8)
50
+	SymbolLine(10 10 10 50 8)
51
+)
52
+Symbol('%' 12)
53
+(
54
+	SymbolLine(0 15 0 20 8)
55
+	SymbolLine(0 15 5 10 8)
56
+	SymbolLine(5 10 10 10 8)
57
+	SymbolLine(10 10 15 15 8)
58
+	SymbolLine(15 15 15 20 8)
59
+	SymbolLine(10 25 15 20 8)
60
+	SymbolLine(5 25 10 25 8)
61
+	SymbolLine(0 20 5 25 8)
62
+	SymbolLine(0 50 40 10 8)
63
+	SymbolLine(35 50 40 45 8)
64
+	SymbolLine(40 40 40 45 8)
65
+	SymbolLine(35 35 40 40 8)
66
+	SymbolLine(30 35 35 35 8)
67
+	SymbolLine(25 40 30 35 8)
68
+	SymbolLine(25 40 25 45 8)
69
+	SymbolLine(25 45 30 50 8)
70
+	SymbolLine(30 50 35 50 8)
71
+)
72
+Symbol('&' 12)
73
+(
74
+	SymbolLine(0 45 5 50 8)
75
+	SymbolLine(0 15 0 25 8)
76
+	SymbolLine(0 15 5 10 8)
77
+	SymbolLine(0 35 15 20 8)
78
+	SymbolLine(5 50 10 50 8)
79
+	SymbolLine(10 50 20 40 8)
80
+	SymbolLine(0 25 25 50 8)
81
+	SymbolLine(5 10 10 10 8)
82
+	SymbolLine(10 10 15 15 8)
83
+	SymbolLine(15 15 15 20 8)
84
+	SymbolLine(0 35 0 45 8)
85
+)
86
+Symbol(''' 12)
87
+(
88
+	SymbolLine(0 20 10 10 8)
89
+)
90
+Symbol('(' 12)
91
+(
92
+	SymbolLine(0 45 5 50 8)
93
+	SymbolLine(0 15 5 10 8)
94
+	SymbolLine(0 15 0 45 8)
95
+)
96
+Symbol(')' 12)
97
+(
98
+	SymbolLine(0 10 5 15 8)
99
+	SymbolLine(5 15 5 45 8)
100
+	SymbolLine(0 50 5 45 8)
101
+)
102
+Symbol('*' 12)
103
+(
104
+	SymbolLine(0 20 20 40 8)
105
+	SymbolLine(0 40 20 20 8)
106
+	SymbolLine(0 30 20 30 8)
107
+	SymbolLine(10 20 10 40 8)
108
+)
109
+Symbol('+' 12)
110
+(
111
+	SymbolLine(0 30 20 30 8)
112
+	SymbolLine(10 20 10 40 8)
113
+)
114
+Symbol(',' 12)
115
+(
116
+	SymbolLine(0 60 10 50 8)
117
+)
118
+Symbol('-' 12)
119
+(
120
+	SymbolLine(0 30 20 30 8)
121
+)
122
+Symbol('.' 12)
123
+(
124
+	SymbolLine(0 50 5 50 8)
125
+)
126
+Symbol('/' 12)
127
+(
128
+	SymbolLine(0 45 30 15 8)
129
+)
130
+Symbol('0' 12)
131
+(
132
+	SymbolLine(0 45 5 50 8)
133
+	SymbolLine(0 15 0 45 8)
134
+	SymbolLine(0 15 5 10 8)
135
+	SymbolLine(5 10 15 10 8)
136
+	SymbolLine(15 10 20 15 8)
137
+	SymbolLine(20 15 20 45 8)
138
+	SymbolLine(15 50 20 45 8)
139
+	SymbolLine(5 50 15 50 8)
140
+	SymbolLine(0 40 20 20 8)
141
+)
142
+Symbol('1' 12)
143
+(
144
+	SymbolLine(5 50 15 50 8)
145
+	SymbolLine(10 10 10 50 8)
146
+	SymbolLine(0 20 10 10 8)
147
+)
148
+Symbol('2' 12)
149
+(
150
+	SymbolLine(0 15 5 10 8)
151
+	SymbolLine(5 10 20 10 8)
152
+	SymbolLine(20 10 25 15 8)
153
+	SymbolLine(25 15 25 25 8)
154
+	SymbolLine(0 50 25 25 8)
155
+	SymbolLine(0 50 25 50 8)
156
+)
157
+Symbol('3' 12)
158
+(
159
+	SymbolLine(0 15 5 10 8)
160
+	SymbolLine(5 10 15 10 8)
161
+	SymbolLine(15 10 20 15 8)
162
+	SymbolLine(20 15 20 45 8)
163
+	SymbolLine(15 50 20 45 8)
164
+	SymbolLine(5 50 15 50 8)
165
+	SymbolLine(0 45 5 50 8)
166
+	SymbolLine(5 30 20 30 8)
167
+)
168
+Symbol('4' 12)
169
+(
170
+	SymbolLine(0 30 20 10 8)
171
+	SymbolLine(0 30 25 30 8)
172
+	SymbolLine(20 10 20 50 8)
173
+)
174
+Symbol('5' 12)
175
+(
176
+	SymbolLine(0 10 20 10 8)
177
+	SymbolLine(0 10 0 30 8)
178
+	SymbolLine(0 30 5 25 8)
179
+	SymbolLine(5 25 15 25 8)
180
+	SymbolLine(15 25 20 30 8)
181
+	SymbolLine(20 30 20 45 8)
182
+	SymbolLine(15 50 20 45 8)
183
+	SymbolLine(5 50 15 50 8)
184
+	SymbolLine(0 45 5 50 8)
185
+)
186
+Symbol('6' 12)
187
+(
188
+	SymbolLine(15 10 20 15 8)
189
+	SymbolLine(5 10 15 10 8)
190
+	SymbolLine(0 15 5 10 8)
191
+	SymbolLine(0 15 0 45 8)
192
+	SymbolLine(0 45 5 50 8)
193
+	SymbolLine(15 30 20 35 8)
194
+	SymbolLine(0 30 15 30 8)
195
+	SymbolLine(5 50 15 50 8)
196
+	SymbolLine(15 50 20 45 8)
197
+	SymbolLine(20 35 20 45 8)
198
+)
199
+Symbol('7' 12)
200
+(
201
+	SymbolLine(0 50 25 25 8)
202
+	SymbolLine(25 10 25 25 8)
203
+	SymbolLine(0 10 25 10 8)
204
+)
205
+Symbol('8' 12)
206
+(
207
+	SymbolLine(0 45 5 50 8)
208
+	SymbolLine(0 35 0 45 8)
209
+	SymbolLine(0 35 5 30 8)
210
+	SymbolLine(5 30 15 30 8)
211
+	SymbolLine(15 30 20 35 8)
212
+	SymbolLine(20 35 20 45 8)
213
+	SymbolLine(15 50 20 45 8)
214
+	SymbolLine(5 50 15 50 8)
215
+	SymbolLine(0 25 5 30 8)
216
+	SymbolLine(0 15 0 25 8)
217
+	SymbolLine(0 15 5 10 8)
218
+	SymbolLine(5 10 15 10 8)
219
+	SymbolLine(15 10 20 15 8)
220
+	SymbolLine(20 15 20 25 8)
221
+	SymbolLine(15 30 20 25 8)
222
+)
223
+Symbol('9' 12)
224
+(
225
+	SymbolLine(0 50 20 30 8)
226
+	SymbolLine(20 15 20 30 8)
227
+	SymbolLine(15 10 20 15 8)
228
+	SymbolLine(5 10 15 10 8)
229
+	SymbolLine(0 15 5 10 8)
230
+	SymbolLine(0 15 0 25 8)
231
+	SymbolLine(0 25 5 30 8)
232
+	SymbolLine(5 30 20 30 8)
233
+)
234
+Symbol(':' 12)
235
+(
236
+	SymbolLine(0 25 5 25 8)
237
+	SymbolLine(0 35 5 35 8)
238
+)
239
+Symbol(';' 12)
240
+(
241
+	SymbolLine(0 50 10 40 8)
242
+	SymbolLine(10 25 10 30 8)
243
+)
244
+Symbol('<' 12)
245
+(
246
+	SymbolLine(0 30 10 20 8)
247
+	SymbolLine(0 30 10 40 8)
248
+)
249
+Symbol('=' 12)
250
+(
251
+	SymbolLine(0 25 20 25 8)
252
+	SymbolLine(0 35 20 35 8)
253
+)
254
+Symbol('>' 12)
255
+(
256
+	SymbolLine(0 20 10 30 8)
257
+	SymbolLine(0 40 10 30 8)
258
+)
259
+Symbol('?' 12)
260
+(
261
+	SymbolLine(10 30 10 35 8)
262
+	SymbolLine(10 45 10 50 8)
263
+	SymbolLine(0 15 0 20 8)
264
+	SymbolLine(0 15 5 10 8)
265
+	SymbolLine(5 10 15 10 8)
266
+	SymbolLine(15 10 20 15 8)
267
+	SymbolLine(20 15 20 20 8)
268
+	SymbolLine(10 30 20 20 8)
269
+)
270
+Symbol('@' 12)
271
+(
272
+	SymbolLine(0 10 0 40 8)
273
+	SymbolLine(0 40 10 50 8)
274
+	SymbolLine(10 50 40 50 8)
275
+	SymbolLine(50 35 50 10 8)
276
+	SymbolLine(50 10 40 0 8)
277
+	SymbolLine(40 0 10 0 8)
278
+	SymbolLine(10 0 0 10 8)
279
+	SymbolLine(15 20 15 30 8)
280
+	SymbolLine(15 30 20 35 8)
281
+	SymbolLine(20 35 30 35 8)
282
+	SymbolLine(30 35 35 30 8)
283
+	SymbolLine(35 30 40 35 8)
284
+	SymbolLine(35 30 35 15 8)
285
+	SymbolLine(35 20 30 15 8)
286
+	SymbolLine(20 15 30 15 8)
287
+	SymbolLine(20 15 15 20 8)
288
+	SymbolLine(40 35 50 35 8)
289
+)
290
+Symbol('A' 12)
291
+(
292
+	SymbolLine(0 15 0 50 8)
293
+	SymbolLine(0 15 5 10 8)
294
+	SymbolLine(5 10 20 10 8)
295
+	SymbolLine(20 10 25 15 8)
296
+	SymbolLine(25 15 25 50 8)
297
+	SymbolLine(0 30 25 30 8)
298
+)
299
+Symbol('B' 12)
300
+(
301
+	SymbolLine(0 50 20 50 8)
302
+	SymbolLine(20 50 25 45 8)
303
+	SymbolLine(25 35 25 45 8)
304
+	SymbolLine(20 30 25 35 8)
305
+	SymbolLine(5 30 20 30 8)
306
+	SymbolLine(5 10 5 50 8)
307
+	SymbolLine(0 10 20 10 8)
308
+	SymbolLine(20 10 25 15 8)
309
+	SymbolLine(25 15 25 25 8)
310
+	SymbolLine(20 30 25 25 8)
311
+)
312
+Symbol('C' 12)
313
+(
314
+	SymbolLine(5 50 20 50 8)
315
+	SymbolLine(0 45 5 50 8)
316
+	SymbolLine(0 15 0 45 8)
317
+	SymbolLine(0 15 5 10 8)
318
+	SymbolLine(5 10 20 10 8)
319
+)
320
+Symbol('D' 12)
321
+(
322
+	SymbolLine(5 10 5 50 8)
323
+	SymbolLine(20 10 25 15 8)
324
+	SymbolLine(25 15 25 45 8)
325
+	SymbolLine(20 50 25 45 8)
326
+	SymbolLine(0 50 20 50 8)
327
+	SymbolLine(0 10 20 10 8)
328
+)
329
+Symbol('E' 12)
330
+(
331
+	SymbolLine(0 30 15 30 8)
332
+	SymbolLine(0 50 20 50 8)
333
+	SymbolLine(0 10 0 50 8)
334
+	SymbolLine(0 10 20 10 8)
335
+)
336
+Symbol('F' 12)
337
+(
338
+	SymbolLine(0 10 0 50 8)
339
+	SymbolLine(0 10 20 10 8)
340
+	SymbolLine(0 30 15 30 8)
341
+)
342
+Symbol('G' 12)
343
+(
344
+	SymbolLine(20 10 25 15 8)
345
+	SymbolLine(5 10 20 10 8)
346
+	SymbolLine(0 15 5 10 8)
347
+	SymbolLine(0 15 0 45 8)
348
+	SymbolLine(0 45 5 50 8)
349
+	SymbolLine(5 50 20 50 8)
350
+	SymbolLine(20 50 25 45 8)
351
+	SymbolLine(25 35 25 45 8)
352
+	SymbolLine(20 30 25 35 8)
353
+	SymbolLine(10 30 20 30 8)
354
+)
355
+Symbol('H' 12)
356
+(
357
+	SymbolLine(0 10 0 50 8)
358
+	SymbolLine(25 10 25 50 8)
359
+	SymbolLine(0 30 25 30 8)
360
+)
361
+Symbol('I' 12)
362
+(
363
+	SymbolLine(0 10 10 10 8)
364
+	SymbolLine(5 10 5 50 8)
365
+	SymbolLine(0 50 10 50 8)
366
+)
367
+Symbol('J' 12)
368
+(
369
+	SymbolLine(0 10 15 10 8)
370
+	SymbolLine(15 10 15 45 8)
371
+	SymbolLine(10 50 15 45 8)
372
+	SymbolLine(5 50 10 50 8)
373
+	SymbolLine(0 45 5 50 8)
374
+)
375
+Symbol('K' 12)
376
+(
377
+	SymbolLine(0 10 0 50 8)
378
+	SymbolLine(0 30 20 10 8)
379
+	SymbolLine(0 30 20 50 8)
380
+)
381
+Symbol('L' 12)
382
+(
383
+	SymbolLine(0 10 0 50 8)
384
+	SymbolLine(0 50 20 50 8)
385
+)
386
+Symbol('M' 12)
387
+(
388
+	SymbolLine(0 10 0 50 8)
389
+	SymbolLine(0 10 15 25 8)
390
+	SymbolLine(15 25 30 10 8)
391
+	SymbolLine(30 10 30 50 8)
392
+)
393
+Symbol('N' 12)
394
+(
395
+	SymbolLine(0 10 0 50 8)
396
+	SymbolLine(0 10 0 15 8)
397
+	SymbolLine(0 15 25 40 8)
398
+	SymbolLine(25 10 25 50 8)
399
+)
400
+Symbol('O' 12)
401
+(
402
+	SymbolLine(0 15 0 45 8)
403
+	SymbolLine(0 15 5 10 8)
404
+	SymbolLine(5 10 15 10 8)
405
+	SymbolLine(15 10 20 15 8)
406
+	SymbolLine(20 15 20 45 8)
407
+	SymbolLine(15 50 20 45 8)
408
+	SymbolLine(5 50 15 50 8)
409
+	SymbolLine(0 45 5 50 8)
410
+)
411
+Symbol('P' 12)
412
+(
413
+	SymbolLine(5 10 5 50 8)
414
+	SymbolLine(0 10 20 10 8)
415
+	SymbolLine(20 10 25 15 8)
416
+	SymbolLine(25 15 25 25 8)
417
+	SymbolLine(20 30 25 25 8)
418
+	SymbolLine(5 30 20 30 8)
419
+)
420
+Symbol('Q' 12)
421
+(
422
+	SymbolLine(0 15 0 45 8)
423
+	SymbolLine(0 15 5 10 8)
424
+	SymbolLine(5 10 15 10 8)
425
+	SymbolLine(15 10 20 15 8)
426
+	SymbolLine(20 15 20 45 8)
427
+	SymbolLine(15 50 20 45 8)
428
+	SymbolLine(5 50 15 50 8)
429
+	SymbolLine(0 45 5 50 8)
430
+	SymbolLine(10 40 20 50 8)
431
+)
432
+Symbol('R' 12)
433
+(
434
+	SymbolLine(0 10 20 10 8)
435
+	SymbolLine(20 10 25 15 8)
436
+	SymbolLine(25 15 25 25 8)
437
+	SymbolLine(20 30 25 25 8)
438
+	SymbolLine(5 30 20 30 8)
439
+	SymbolLine(5 10 5 50 8)
440
+	SymbolLine(5 30 25 50 8)
441
+)
442
+Symbol('S' 12)
443
+(
444
+	SymbolLine(20 10 25 15 8)
445
+	SymbolLine(5 10 20 10 8)
446
+	SymbolLine(0 15 5 10 8)
447
+	SymbolLine(0 15 0 25 8)
448
+	SymbolLine(0 25 5 30 8)
449
+	SymbolLine(5 30 20 30 8)
450
+	SymbolLine(20 30 25 35 8)
451
+	SymbolLine(25 35 25 45 8)
452
+	SymbolLine(20 50 25 45 8)
453
+	SymbolLine(5 50 20 50 8)
454
+	SymbolLine(0 45 5 50 8)
455
+)
456
+Symbol('T' 12)
457
+(
458
+	SymbolLine(0 10 20 10 8)
459
+	SymbolLine(10 10 10 50 8)
460
+)
461
+Symbol('U' 12)
462
+(
463
+	SymbolLine(0 10 0 45 8)
464
+	SymbolLine(0 45 5 50 8)
465
+	SymbolLine(5 50 15 50 8)
466
+	SymbolLine(15 50 20 45 8)
467
+	SymbolLine(20 10 20 45 8)
468
+)
469
+Symbol('V' 12)
470
+(
471
+	SymbolLine(0 10 0 40 8)
472
+	SymbolLine(0 40 10 50 8)
473
+	SymbolLine(10 50 20 40 8)
474
+	SymbolLine(20 10 20 40 8)
475
+)
476
+Symbol('W' 12)
477
+(
478
+	SymbolLine(0 10 0 50 8)
479
+	SymbolLine(0 50 15 35 8)
480
+	SymbolLine(15 35 30 50 8)
481
+	SymbolLine(30 10 30 50 8)
482
+)
483
+Symbol('X' 12)
484
+(
485
+	SymbolLine(0 10 0 15 8)
486
+	SymbolLine(0 15 25 40 8)
487
+	SymbolLine(25 40 25 50 8)
488
+	SymbolLine(0 40 0 50 8)
489
+	SymbolLine(0 40 25 15 8)
490
+	SymbolLine(25 10 25 15 8)
491
+)
492
+Symbol('Y' 12)
493
+(
494
+	SymbolLine(0 10 0 15 8)
495
+	SymbolLine(0 15 10 25 8)
496
+	SymbolLine(10 25 20 15 8)
497
+	SymbolLine(20 10 20 15 8)
498
+	SymbolLine(10 25 10 50 8)
499
+)
500
+Symbol('Z' 12)
501
+(
502
+	SymbolLine(0 10 25 10 8)
503
+	SymbolLine(25 10 25 15 8)
504
+	SymbolLine(0 40 25 15 8)
505
+	SymbolLine(0 40 0 50 8)
506
+	SymbolLine(0 50 25 50 8)
507
+)
508
+Symbol('[' 12)
509
+(
510
+	SymbolLine(0 10 5 10 8)
511
+	SymbolLine(0 10 0 50 8)
512
+	SymbolLine(0 50 5 50 8)
513
+)
514
+Symbol('\' 12)
515
+(
516
+	SymbolLine(0 15 30 45 8)
517
+)
518
+Symbol(']' 12)
519
+(
520
+	SymbolLine(0 10 5 10 8)
521
+	SymbolLine(5 10 5 50 8)
522
+	SymbolLine(0 50 5 50 8)
523
+)
524
+Symbol('^' 12)
525
+(
526
+	SymbolLine(0 15 5 10 8)
527
+	SymbolLine(5 10 10 15 8)
528
+)
529
+Symbol('_' 12)
530
+(
531
+	SymbolLine(0 50 20 50 8)
532
+)
533
+Symbol('a' 12)
534
+(
535
+	SymbolLine(15 30 20 35 8)
536
+	SymbolLine(5 30 15 30 8)
537
+	SymbolLine(0 35 5 30 8)
538
+	SymbolLine(0 35 0 45 8)
539
+	SymbolLine(0 45 5 50 8)
540
+	SymbolLine(20 30 20 45 8)
541
+	SymbolLine(20 45 25 50 8)
542
+	SymbolLine(5 50 15 50 8)
543
+	SymbolLine(15 50 20 45 8)
544
+)
545
+Symbol('b' 12)
546
+(
547
+	SymbolLine(0 10 0 50 8)
548
+	SymbolLine(0 45 5 50 8)
549
+	SymbolLine(5 50 15 50 8)
550
+	SymbolLine(15 50 20 45 8)
551
+	SymbolLine(20 35 20 45 8)
552
+	SymbolLine(15 30 20 35 8)
553
+	SymbolLine(5 30 15 30 8)
554
+	SymbolLine(0 35 5 30 8)
555
+)
556
+Symbol('c' 12)
557
+(
558
+	SymbolLine(5 30 20 30 8)
559
+	SymbolLine(0 35 5 30 8)
560
+	SymbolLine(0 35 0 45 8)
561
+	SymbolLine(0 45 5 50 8)
562
+	SymbolLine(5 50 20 50 8)
563
+)
564
+Symbol('d' 12)
565
+(
566
+	SymbolLine(20 10 20 50 8)
567
+	SymbolLine(15 50 20 45 8)
568
+	SymbolLine(5 50 15 50 8)
569
+	SymbolLine(0 45 5 50 8)
570
+	SymbolLine(0 35 0 45 8)
571
+	SymbolLine(0 35 5 30 8)
572
+	SymbolLine(5 30 15 30 8)
573
+	SymbolLine(15 30 20 35 8)
574
+)
575
+Symbol('e' 12)
576
+(
577
+	SymbolLine(5 50 20 50 8)
578
+	SymbolLine(0 45 5 50 8)
579
+	SymbolLine(0 35 0 45 8)
580
+	SymbolLine(0 35 5 30 8)
581
+	SymbolLine(5 30 15 30 8)
582
+	SymbolLine(15 30 20 35 8)
583
+	SymbolLine(0 40 20 40 8)
584
+	SymbolLine(20 40 20 35 8)
585
+)
586
+Symbol('f' 10)
587
+(
588
+	SymbolLine(5 15 5 50 8)
589
+	SymbolLine(5 15 10 10 8)
590
+	SymbolLine(10 10 15 10 8)
591
+	SymbolLine(0 30 10 30 8)
592
+)
593
+Symbol('g' 12)
594
+(
595
+	SymbolLine(15 30 20 35 8)
596
+	SymbolLine(5 30 15 30 8)
597
+	SymbolLine(0 35 5 30 8)
598
+	SymbolLine(0 35 0 45 8)
599
+	SymbolLine(0 45 5 50 8)
600
+	SymbolLine(5 50 15 50 8)
601
+	SymbolLine(15 50 20 45 8)
602
+	SymbolLine(0 60 5 65 8)
603
+	SymbolLine(5 65 15 65 8)
604
+	SymbolLine(15 65 20 60 8)
605
+	SymbolLine(20 30 20 60 8)
606
+)
607
+Symbol('h' 12)
608
+(
609
+	SymbolLine(0 10 0 50 8)
610
+	SymbolLine(0 35 5 30 8)
611
+	SymbolLine(5 30 15 30 8)
612
+	SymbolLine(15 30 20 35 8)
613
+	SymbolLine(20 35 20 50 8)
614
+)
615
+Symbol('i' 10)
616
+(
617
+	SymbolLine(0 20 0 25 8)
618
+	SymbolLine(0 35 0 50 8)
619
+)
620
+Symbol('j' 10)
621
+(
622
+	SymbolLine(5 20 5 25 8)
623
+	SymbolLine(5 35 5 60 8)
624
+	SymbolLine(0 65 5 60 8)
625
+)
626
+Symbol('k' 12)
627
+(
628
+	SymbolLine(0 10 0 50 8)
629
+	SymbolLine(0 35 15 50 8)
630
+	SymbolLine(0 35 10 25 8)
631
+)
632
+Symbol('l' 10)
633
+(
634
+	SymbolLine(0 10 0 45 8)
635
+	SymbolLine(0 45 5 50 8)
636
+)
637
+Symbol('m' 12)
638
+(
639
+	SymbolLine(5 35 5 50 8)
640
+	SymbolLine(5 35 10 30 8)
641
+	SymbolLine(10 30 15 30 8)
642
+	SymbolLine(15 30 20 35 8)
643
+	SymbolLine(20 35 20 50 8)
644
+	SymbolLine(20 35 25 30 8)
645
+	SymbolLine(25 30 30 30 8)
646
+	SymbolLine(30 30 35 35 8)
647
+	SymbolLine(35 35 35 50 8)
648
+	SymbolLine(0 30 5 35 8)
649
+)
650
+Symbol('n' 12)
651
+(
652
+	SymbolLine(5 35 5 50 8)
653
+	SymbolLine(5 35 10 30 8)
654
+	SymbolLine(10 30 15 30 8)
655
+	SymbolLine(15 30 20 35 8)
656
+	SymbolLine(20 35 20 50 8)
657
+	SymbolLine(0 30 5 35 8)
658
+)
659
+Symbol('o' 12)
660
+(
661
+	SymbolLine(0 35 0 45 8)
662
+	SymbolLine(0 35 5 30 8)
663
+	SymbolLine(5 30 15 30 8)
664
+	SymbolLine(15 30 20 35 8)
665
+	SymbolLine(20 35 20 45 8)
666
+	SymbolLine(15 50 20 45 8)
667
+	SymbolLine(5 50 15 50 8)
668
+	SymbolLine(0 45 5 50 8)
669
+)
670
+Symbol('p' 12)
671
+(
672
+	SymbolLine(5 35 5 65 8)
673
+	SymbolLine(0 30 5 35 8)
674
+	SymbolLine(5 35 10 30 8)
675
+	SymbolLine(10 30 20 30 8)
676
+	SymbolLine(20 30 25 35 8)
677
+	SymbolLine(25 35 25 45 8)
678
+	SymbolLine(20 50 25 45 8)
679
+	SymbolLine(10 50 20 50 8)
680
+	SymbolLine(5 45 10 50 8)
681
+)
682
+Symbol('q' 12)
683
+(
684
+	SymbolLine(20 35 20 65 8)
685
+	SymbolLine(15 30 20 35 8)
686
+	SymbolLine(5 30 15 30 8)
687
+	SymbolLine(0 35 5 30 8)
688
+	SymbolLine(0 35 0 45 8)
689
+	SymbolLine(0 45 5 50 8)
690
+	SymbolLine(5 50 15 50 8)
691
+	SymbolLine(15 50 20 45 8)
692
+)
693
+Symbol('r' 12)
694
+(
695
+	SymbolLine(5 35 5 50 8)
696
+	SymbolLine(5 35 10 30 8)
697
+	SymbolLine(10 30 20 30 8)
698
+	SymbolLine(0 30 5 35 8)
699
+)
700
+Symbol('s' 12)
701
+(
702
+	SymbolLine(5 50 20 50 8)
703
+	SymbolLine(20 50 25 45 8)
704
+	SymbolLine(20 40 25 45 8)
705
+	SymbolLine(5 40 20 40 8)
706
+	SymbolLine(0 35 5 40 8)
707
+	SymbolLine(0 35 5 30 8)
708
+	SymbolLine(5 30 20 30 8)
709
+	SymbolLine(20 30 25 35 8)
710
+	SymbolLine(0 45 5 50 8)
711
+)
712
+Symbol('t' 10)
713
+(
714
+	SymbolLine(5 10 5 45 8)
715
+	SymbolLine(5 45 10 50 8)
716
+	SymbolLine(0 25 10 25 8)
717
+)
718
+Symbol('u' 12)
719
+(
720
+	SymbolLine(0 30 0 45 8)
721
+	SymbolLine(0 45 5 50 8)
722
+	SymbolLine(5 50 15 50 8)
723
+	SymbolLine(15 50 20 45 8)
724
+	SymbolLine(20 30 20 45 8)
725
+)
726
+Symbol('v' 12)
727
+(
728
+	SymbolLine(0 30 0 40 8)
729
+	SymbolLine(0 40 10 50 8)
730
+	SymbolLine(10 50 20 40 8)
731
+	SymbolLine(20 30 20 40 8)
732
+)
733
+Symbol('w' 12)
734
+(
735
+	SymbolLine(0 30 0 45 8)
736
+	SymbolLine(0 45 5 50 8)
737
+	SymbolLine(5 50 10 50 8)
738
+	SymbolLine(10 50 15 45 8)
739
+	SymbolLine(15 30 15 45 8)
740
+	SymbolLine(15 45 20 50 8)
741
+	SymbolLine(20 50 25 50 8)
742
+	SymbolLine(25 50 30 45 8)
743
+	SymbolLine(30 30 30 45 8)
744
+)
745
+Symbol('x' 12)
746
+(
747
+	SymbolLine(0 30 20 50 8)
748
+	SymbolLine(0 50 20 30 8)
749
+)
750
+Symbol('y' 12)
751
+(
752
+	SymbolLine(0 30 0 45 8)
753
+	SymbolLine(0 45 5 50 8)
754
+	SymbolLine(20 30 20 60 8)
755
+	SymbolLine(15 65 20 60 8)
756
+	SymbolLine(5 65 15 65 8)
757
+	SymbolLine(0 60 5 65 8)
758
+	SymbolLine(5 50 15 50 8)
759
+	SymbolLine(15 50 20 45 8)
760
+)
761
+Symbol('z' 12)
762
+(
763
+	SymbolLine(0 30 20 30 8)
764
+	SymbolLine(0 50 20 30 8)
765
+	SymbolLine(0 50 20 50 8)
766
+)
767
+Symbol('{' 12)
768
+(
769
+	SymbolLine(5 15 10 10 8)
770
+	SymbolLine(5 15 5 25 8)
771
+	SymbolLine(0 30 5 25 8)
772
+	SymbolLine(0 30 5 35 8)
773
+	SymbolLine(5 35 5 45 8)
774
+	SymbolLine(5 45 10 50 8)
775
+)
776
+Symbol('|' 12)
777
+(
778
+	SymbolLine(0 10 0 50 8)
779
+)
780
+Symbol('}' 12)
781
+(
782
+	SymbolLine(0 10 5 15 8)
783
+	SymbolLine(5 15 5 25 8)
784
+	SymbolLine(5 25 10 30 8)
785
+	SymbolLine(5 35 10 30 8)
786
+	SymbolLine(5 35 5 45 8)
787
+	SymbolLine(0 50 5 45 8)
788
+)
789
+Symbol('~' 12)
790
+(
791
+	SymbolLine(0 35 5 30 8)
792
+	SymbolLine(5 30 10 30 8)
793
+	SymbolLine(10 30 15 35 8)
794
+	SymbolLine(15 35 20 35 8)
795
+	SymbolLine(20 35 25 30 8)
796
+)
797
+Via[115000 195000 6000 2300 0 3000 "" ""]
798
+Via[115000 232500 4000 2300 0 2000 "" ""]
799
+Via[92500 247500 4000 2300 0 2000 "" ""]
800
+Via[92500 252500 4000 2300 0 2000 "" ""]
801
+Via[115000 227500 4000 2300 0 2000 "" ""]
802
+Via[307500 362500 6000 2300 0 3000 "" ""]
803
+Via[200000 305000 6000 2300 0 3000 "" ""]
804
+Via[202500 290000 6000 2300 0 3000 "" ""]
805
+Via[317500 365000 6000 2300 0 3000 "" ""]
806
+Via[225000 217500 4000 2300 0 2000 "" ""]
807
+Via[322500 265000 6000 2300 0 3000 "" ""]
808
+Via[402500 227500 6000 2300 0 3000 "" ""]
809
+Via[402500 202500 6000 2300 0 3000 "" ""]
810
+Via[366000 381000 4000 2300 0 2000 "" ""]
811
+Via[355000 389000 4000 2300 0 2000 "" ""]
812
+Via[345000 389000 4000 2300 0 2000 "" ""]
813
+Via[335000 342000 4000 2300 0 2000 "" ""]
814
+Via[330000 346000 4000 2300 0 2000 "" ""]
815
+Via[340000 375000 4000 2300 0 2000 "" ""]
816
+Via[279000 378000 4000 2300 0 2000 "" ""]
817
+Via[225000 370000 6000 2300 0 3000 "" ""]
818
+Via[297000 356000 4000 2300 0 2000 "" ""]
819
+Via[297000 350000 4000 2300 0 2000 "" ""]
820
+Via[267000 356000 4000 2300 0 2000 "" ""]
821
+Via[210000 207500 4000 2300 0 2000 "" ""]
822
+Via[220000 217500 4000 2300 0 2000 "" ""]
823
+Via[215000 212500 4000 2300 0 2000 "" ""]
824
+Via[319000 249000 4000 2300 0 2000 "" ""]
825
+Via[305000 227000 4000 2300 0 2000 "" ""]
826
+Via[396000 206000 4000 2300 0 2000 "" ""]
827
+Via[395000 186000 4000 2300 0 2000 "" ""]
828
+Via[358000 161000 4000 2300 0 2000 "" ""]
829
+Via[255000 167500 4000 2300 0 2000 "" ""]
830
+Via[345000 180000 4000 2300 0 2000 "" ""]
831
+Via[232500 385000 4000 2300 0 2000 "" ""]
832
+Via[262500 162500 4000 2300 0 2000 "" ""]
833
+Via[205000 192500 4000 2300 0 2000 "" ""]
834
+Via[210000 192500 4000 2300 0 2000 "" ""]
835
+Via[215000 192500 4000 2300 0 2000 "" ""]
836
+Via[220000 192500 4000 2300 0 2000 "" ""]
837
+Via[225000 192500 4000 2300 0 2000 "" ""]
838
+Via[230000 207500 4000 2300 0 2000 "" ""]
839
+Via[230000 202500 4000 2300 0 2000 "" ""]
840
+Via[230000 197500 4000 2300 0 2000 "" ""]
841
+Via[190000 192500 3200 2300 0 1500 "" ""]
842
+Via[200000 192500 3200 2300 0 1500 "" ""]
843
+Via[195000 192500 3200 2300 0 1500 "" ""]
844
+Via[242000 336000 3200 2300 0 1500 "" ""]
845
+Via[247500 255000 6000 2300 0 3000 "" ""]
846
+Via[255000 262500 6000 2300 0 3000 "" ""]
847
+Via[277500 185000 3200 2300 0 1500 "" ""]
848
+Via[282500 182500 3200 2300 0 1500 "" ""]
849
+Via[407500 167500 6000 2300 0 3000 "" ""]
850
+Via[360000 140000 4000 2300 0 2000 "" ""]
851
+Via[375000 140000 4000 2300 0 2000 "" ""]
852
+Via[325000 227500 4000 2300 0 2000 "" ""]
853
+Via[317500 225000 4000 2300 0 2000 "" ""]
854
+Via[112500 125000 4000 2300 0 2000 "" ""]
855
+Via[105000 132500 4000 2300 0 2000 "" ""]
856
+Via[110000 130000 4000 2300 0 2000 "" ""]
857
+Via[325000 250000 4000 2300 0 2000 "" ""]
858
+Via[330000 252500 4000 2300 0 2000 "" ""]
859
+Via[335000 250000 4000 2300 0 2000 "" ""]
860
+Via[307500 222500 4000 2300 0 2000 "" ""]
861
+Via[310000 217500 4000 2300 0 2000 "" ""]
862
+Via[305000 207500 4000 2300 0 2000 "" ""]
863
+Via[305000 202500 4000 2300 0 2000 "" ""]
864
+Via[305000 197500 4000 2300 0 2000 "" ""]
865
+Via[305000 182500 4000 2300 0 2000 "" ""]
866
+Via[305000 187500 4000 2300 0 2000 "" ""]
867
+Via[305000 192500 4000 2300 0 2000 "" ""]
868
+Via[323000 214000 4000 2300 0 2000 "" ""]
869
+Via[307500 257500 6000 2300 0 3000 "" ""]
870
+Via[286000 273000 4000 2300 0 2000 "" ""]
871
+Via[292000 273000 4000 2300 0 2000 "" ""]
872
+Via[298000 273000 4000 2300 0 2000 "" ""]
873
+Via[170000 357500 4000 2300 0 2000 "" ""]
874
+Via[258000 340000 3200 2300 0 1500 "" ""]
875
+Via[252500 387500 4000 2300 0 2000 "" ""]
876
+Via[320000 192500 4000 2300 0 2000 "" ""]
877
+Via[246000 333000 3200 2300 0 1500 "" ""]
878
+Via[212500 377500 4000 2300 0 2000 "" ""]
879
+Via[338000 159000 4000 2300 0 2000 "" ""]
880
+Via[310000 202500 4000 2300 0 2000 "" ""]
881
+Via[315000 197500 4000 2300 0 2000 "" ""]
882
+Via[253000 340000 3200 2300 0 1500 "" ""]
883
+Via[240000 327000 3200 2300 0 1500 "" ""]
884
+Via[240000 322000 3200 2300 0 1500 "" ""]
885
+Via[240000 317000 3200 2300 0 1500 "" ""]
886
+Via[240000 312000 3200 2300 0 1500 "" ""]
887
+Via[257000 312000 3200 2300 0 1500 "" ""]
888
+Via[259000 316000 3200 2300 0 1500 "" ""]
889
+Via[260000 354000 3200 2300 0 1500 "" ""]
890
+Via[286000 292000 3200 2300 0 1500 "" ""]
891
+Via[290000 295000 3200 2300 0 1500 "" ""]
892
+Via[176000 263000 4000 2300 0 2000 "" ""]
893
+Via[286000 303000 3200 2300 0 1500 "" ""]
894
+Via[272000 306000 3200 2300 0 1500 "" ""]
895
+Via[277000 306000 3200 2300 0 1500 "" ""]
896
+Via[282000 306000 3200 2300 0 1500 "" ""]
897
+Via[296000 284000 3200 2300 0 1500 "" ""]
898
+Via[284000 317000 3200 2300 0 1500 "" ""]
899
+Via[281000 321000 3200 2300 0 1500 "" ""]
900
+Via[240000 307000 3200 2300 0 1500 "" ""]
901
+Via[240000 302000 3200 2300 0 1500 "" ""]
902
+Via[197000 283000 4000 2300 0 2000 "" ""]
903
+Via[192000 273000 4000 2300 0 2000 "" ""]
904
+Via[187000 268000 4000 2300 0 2000 "" ""]
905
+Via[182000 278000 4000 2300 0 2000 "" ""]
906
+Via[176000 258000 4000 2300 0 2000 "" ""]
907
+Via[290000 300000 3200 2300 0 1500 "" ""]
908
+Via[227500 342500 4000 2300 0 2000 "" ""]
909
+Via[215000 302500 4000 2300 0 2000 "" ""]
910
+Via[217500 297500 4000 2300 0 2000 "" ""]
911
+Via[235000 345000 4000 2300 0 2000 "" ""]
912
+Via[160000 250000 4000 2300 0 2000 "" ""]
913
+Via[160000 245000 4000 2300 0 2000 "" ""]
914
+Via[202500 360000 4000 2300 0 2000 "" ""]
915
+Via[215000 370000 4000 2300 0 2000 "" ""]
916
+Via[117500 140000 4000 2300 0 2000 "" ""]
917
+Via[180000 140000 4000 2300 0 2000 "" ""]
918
+Via[162500 140000 4000 2300 0 2000 "" ""]
919
+Via[170000 140000 4000 2300 0 2000 "" ""]
920
+Via[150000 140000 4000 2300 0 2000 "" ""]
921
+Via[82500 152500 6000 2300 0 3000 "" ""]
922
+Via[217500 152500 6000 2300 0 3000 "" ""]
923
+Via[100000 160000 3200 2300 0 1500 "" ""]
924
+Via[105000 160000 3200 2300 0 1500 "" ""]
925
+Via[110000 160000 3200 2300 0 1500 "" ""]
926
+Via[205000 160000 4000 2300 0 2000 "" ""]
927
+Via[185000 160000 4000 2300 0 2000 "" ""]
928
+Via[190000 160000 4000 2300 0 2000 "" ""]
929
+Via[195000 160000 4000 2300 0 2000 "" ""]
930
+Via[200000 160000 4000 2300 0 2000 "" ""]
931
+Via[157500 160000 4000 2300 0 2000 "" ""]
932
+Via[170000 160000 4000 2300 0 2000 "" ""]
933
+Via[410000 150000 4000 2300 0 2000 "" ""]
934
+Via[380000 150000 4000 2300 0 2000 "" ""]
935
+Via[395000 150000 4000 2300 0 2000 "" ""]
936
+Via[350000 92500 4000 2300 0 2000 "" ""]
937
+Via[352500 130000 4000 2300 0 2000 "" ""]
938
+Via[161417 208661 4000 2300 0 2000 "" "thermal(0X,1X)"]
939
+Via[173228 244094 4000 2300 0 2000 "" "thermal(0X,1X)"]
940
+Via[19685 204724 4000 2300 0 2000 "" "thermal(0X,1X)"]
941
+Via[228346 86614 4000 2300 0 2000 "" "thermal(0X,1X)"]
942
+Via[370079 224409 4000 2300 0 2000 "" "thermal(0X,1X)"]
943
+Via[413386 259843 4000 2300 0 2000 "" "thermal(0X,1X)"]
944
+Via[374016 330709 4000 2300 0 2000 "" "thermal(0X,1X)"]
945
+Via[133858 381890 4000 2300 0 2000 "" "thermal(0X,1X)"]
946
+
947
+Element["" "SMD 0805" "R6" "0805" 405000 192500 -5000 -10500 0 100 ""]
948
+(
949
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
950
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
951
+	ElementLine [6000 -4500 6000 4500 1000]
952
+	ElementLine [-6000 -4500 6000 -4500 1000]
953
+	ElementLine [-6000 -4500 -6000 4500 1000]
954
+	ElementLine [-6000 4500 6000 4500 1000]
955
+
956
+	)
957
+
958
+Element["" "SMD 0805" "R4" "0805" 205000 370000 -5000 4500 0 100 ""]
959
+(
960
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
961
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
962
+	ElementLine [-6000 -4500 -6000 4500 1000]
963
+	ElementLine [-6000 4500 6000 4500 1000]
964
+	ElementLine [6000 4500 6000 -4500 1000]
965
+	ElementLine [6000 -4500 -6000 -4500 1000]
966
+
967
+	)
968
+
969
+Element["" "SUB-D 9 pol male" "CON4" "SUBD9m" 40000 110000 -35622 -54356 0 150 ""]
970
+(
971
+	Pin[600 0 6000 3000 6600 3500 "1" "1" "square"]
972
+	Pin[600 10800 6000 3000 6600 3500 "2" "2" ""]
973
+	Pin[600 21600 6000 3000 6600 3500 "3" "3" ""]
974
+	Pin[600 32400 6000 3000 6600 3500 "4" "4" ""]
975
+	Pin[600 43200 6000 3000 6600 3500 "5" "5" ""]
976
+	Pin[-10600 5400 6000 3000 6600 3500 "6" "6" ""]
977
+	Pin[-10600 16200 6000 3000 6600 3500 "7" "7" ""]
978
+	Pin[-10600 27000 6000 3000 6600 3500 "8" "8" ""]
979
+	Pin[-10600 37800 6000 3000 6600 3500 "9" "9" ""]
980
+	Pin[-5000 -27000 25000 3000 25600 12500 "S1" "100" ""]
981
+	Pin[-5000 70200 25000 3000 25600 12500 "S2" "101" ""]
982
+	ElementLine [-41500 -39000 -38500 -39000 1000]
983
+	ElementLine [-38500 -39000 -38500 82200 1000]
984
+	ElementLine [-41500 82200 -38500 82200 1000]
985
+	ElementLine [-41500 -39000 -41500 82200 1000]
986
+	ElementLine [-41500 -33000 -38500 -33000 1000]
987
+	ElementLine [-41500 -21000 -38500 -21000 1000]
988
+	ElementLine [-41500 76200 -38500 76200 1000]
989
+	ElementLine [-41500 64200 -38500 64200 1000]
990
+	ElementLine [-38500 -16000 -28000 -16000 2000]
991
+	ElementLine [-28000 -16000 -28000 59200 2000]
992
+	ElementLine [-38500 59200 -28000 59200 2000]
993
+	ElementLine [-38500 -16000 -38500 59200 1000]
994
+	ElementLine [-28000 0 -3400 0 2000]
995
+	ElementLine [-28000 10800 -3400 10800 2000]
996
+	ElementLine [-28000 21600 -3400 21600 2000]
997
+	ElementLine [-28000 32400 -3400 32400 2000]
998
+	ElementLine [-28000 43200 -3400 43200 2000]
999
+	ElementLine [-28000 5400 -14600 5400 2000]
1000
+	ElementLine [-28000 16200 -14600 16200 2000]
1001
+	ElementLine [-28000 27000 -14600 27000 2000]
1002
+	ElementLine [-28000 37800 -14600 37800 2000]
1003
+
1004
+	)
1005
+
1006
+Element["" "SUB-D 9 pol male" "CON5" "SUBD9m" 40000 270000 -35622 -54356 0 150 ""]
1007
+(
1008
+	Pin[600 0 6000 3000 6600 3500 "1" "1" "square"]
1009
+	Pin[600 10800 6000 3000 6600 3500 "2" "2" ""]
1010
+	Pin[600 21600 6000 3000 6600 3500 "3" "3" ""]
1011
+	Pin[600 32400 6000 3000 6600 3500 "4" "4" ""]
1012
+	Pin[600 43200 6000 3000 6600 3500 "5" "5" ""]
1013
+	Pin[-10600 5400 6000 3000 6600 3500 "6" "6" ""]
1014
+	Pin[-10600 16200 6000 3000 6600 3500 "7" "7" ""]
1015
+	Pin[-10600 27000 6000 3000 6600 3500 "8" "8" ""]
1016
+	Pin[-10600 37800 6000 3000 6600 3500 "9" "9" ""]
1017
+	Pin[-5000 -27000 25000 3000 25600 12500 "S1" "100" ""]
1018
+	Pin[-5000 70200 25000 3000 25600 12500 "S2" "101" ""]
1019
+	ElementLine [-41500 -39000 -38500 -39000 1000]
1020
+	ElementLine [-38500 -39000 -38500 82200 1000]
1021
+	ElementLine [-41500 82200 -38500 82200 1000]
1022
+	ElementLine [-41500 -39000 -41500 82200 1000]
1023
+	ElementLine [-41500 -33000 -38500 -33000 1000]
1024
+	ElementLine [-41500 -21000 -38500 -21000 1000]
1025
+	ElementLine [-41500 76200 -38500 76200 1000]
1026
+	ElementLine [-41500 64200 -38500 64200 1000]
1027
+	ElementLine [-38500 -16000 -28000 -16000 2000]
1028
+	ElementLine [-28000 -16000 -28000 59200 2000]
1029
+	ElementLine [-38500 59200 -28000 59200 2000]
1030
+	ElementLine [-38500 -16000 -38500 59200 1000]
1031
+	ElementLine [-28000 0 -3400 0 2000]
1032
+	ElementLine [-28000 10800 -3400 10800 2000]
1033
+	ElementLine [-28000 21600 -3400 21600 2000]
1034
+	ElementLine [-28000 32400 -3400 32400 2000]
1035
+	ElementLine [-28000 43200 -3400 43200 2000]
1036
+	ElementLine [-28000 5400 -14600 5400 2000]
1037
+	ElementLine [-28000 16200 -14600 16200 2000]
1038
+	ElementLine [-28000 27000 -14600 27000 2000]
1039
+	ElementLine [-28000 37800 -14600 37800 2000]
1040
+
1041
+	)
1042
+
1043
+Element["" "WSL" "CON6" "10G" 405000 300000 -10000 -28500 0 100 ""]
1044
+(
1045
+	Pin[0 0 7000 3000 7600 3500 "1" "1" "square"]
1046
+	Pin[10000 0 7000 3000 7600 3500 "2" "2" ""]
1047
+	Pin[0 10000 7000 3000 7600 3500 "3" "3" ""]
1048
+	Pin[10000 10000 7000 3000 7600 3500 "4" "4" ""]
1049
+	Pin[0 20000 7000 3000 7600 3500 "5" "5" ""]
1050
+	Pin[10000 20000 7000 3000 7600 3500 "6" "6" ""]
1051
+	Pin[0 30000 7000 3000 7600 3500 "7" "7" ""]
1052
+	Pin[10000 30000 7000 3000 7600 3500 "8" "8" ""]
1053
+	Pin[0 40000 7000 3000 7600 3500 "9" "9" ""]
1054
+	Pin[10000 40000 7000 3000 7600 3500 "10" "10" ""]
1055
+	ElementLine [-10000 30000 -10000 60000 2000]
1056
+	ElementLine [-10000 10000 -10000 30000 1000]
1057
+	ElementLine [-10000 -20000 -10000 10000 2000]
1058
+	ElementLine [-10000 60000 20000 60000 2000]
1059
+	ElementLine [20000 -20000 20000 60000 2000]
1060
+	ElementLine [-10000 -20000 20000 -20000 2000]
1061
+
1062
+	)
1063
+
1064
+Element["" "WSL" "CON7" "10G" 180000 405000 -60000 -18500 0 100 ""]
1065
+(
1066
+	Pin[0 0 7000 3000 7600 3500 "1" "1" "square,edge2"]
1067
+	Pin[0 10000 7000 3000 7600 3500 "2" "2" "edge2"]
1068
+	Pin[-10000 0 7000 3000 7600 3500 "3" "3" "edge2"]
1069
+	Pin[-10000 10000 7000 3000 7600 3500 "4" "4" "edge2"]
1070
+	Pin[-20000 0 7000 3000 7600 3500 "5" "5" "edge2"]
1071
+	Pin[-20000 10000 7000 3000 7600 3500 "6" "6" "edge2"]
1072
+	Pin[-30000 0 7000 3000 7600 3500 "7" "7" "edge2"]
1073
+	Pin[-30000 10000 7000 3000 7600 3500 "8" "8" "edge2"]
1074
+	Pin[-40000 0 7000 3000 7600 3500 "9" "9" "edge2"]
1075
+	Pin[-40000 10000 7000 3000 7600 3500 "10" "10" "edge2"]
1076
+	ElementLine [-60000 -10000 -30000 -10000 2000]
1077
+	ElementLine [-30000 -10000 -10000 -10000 1000]
1078
+	ElementLine [-10000 -10000 20000 -10000 2000]
1079
+	ElementLine [-60000 -10000 -60000 20000 2000]
1080
+	ElementLine [-60000 20000 20000 20000 2000]
1081
+	ElementLine [20000 -10000 20000 20000 2000]
1082
+
1083
+	)
1084
+
1085
+Element["" "WSL" "CON8" "10G" 360000 405000 -60000 -18500 0 100 ""]
1086
+(
1087
+	Pin[0 0 7000 3000 7600 3500 "1" "1" "square,edge2"]
1088
+	Pin[0 10000 7000 3000 7600 3500 "2" "2" "edge2"]
1089
+	Pin[-10000 0 7000 3000 7600 3500 "3" "3" "edge2"]
1090
+	Pin[-10000 10000 7000 3000 7600 3500 "4" "4" "edge2"]
1091
+	Pin[-20000 0 7000 3000 7600 3500 "5" "5" "edge2"]
1092
+	Pin[-20000 10000 7000 3000 7600 3500 "6" "6" "edge2"]
1093
+	Pin[-30000 0 7000 3000 7600 3500 "7" "7" "edge2"]
1094
+	Pin[-30000 10000 7000 3000 7600 3500 "8" "8" "edge2"]
1095
+	Pin[-40000 0 7000 3000 7600 3500 "9" "9" "edge2"]
1096
+	Pin[-40000 10000 7000 3000 7600 3500 "10" "10" "edge2"]
1097
+	ElementLine [-60000 -10000 -30000 -10000 2000]
1098
+	ElementLine [-30000 -10000 -10000 -10000 1000]
1099
+	ElementLine [-10000 -10000 20000 -10000 2000]
1100
+	ElementLine [-60000 -10000 -60000 20000 2000]
1101
+	ElementLine [-60000 20000 20000 20000 2000]
1102
+	ElementLine [20000 -10000 20000 20000 2000]
1103
+
1104
+	)
1105
+
1106
+Element["" "WSL" "CON9" "10G" 270000 405000 -60000 -18500 0 100 ""]
1107
+(
1108
+	Pin[0 0 7000 3000 7600 3500 "1" "1" "square,edge2"]
1109
+	Pin[0 10000 7000 3000 7600 3500 "2" "2" "edge2"]
1110
+	Pin[-10000 0 7000 3000 7600 3500 "3" "3" "edge2"]
1111
+	Pin[-10000 10000 7000 3000 7600 3500 "4" "4" "edge2"]
1112
+	Pin[-20000 0 7000 3000 7600 3500 "5" "5" "edge2"]
1113
+	Pin[-20000 10000 7000 3000 7600 3500 "6" "6" "edge2"]
1114
+	Pin[-30000 0 7000 3000 7600 3500 "7" "7" "edge2"]
1115
+	Pin[-30000 10000 7000 3000 7600 3500 "8" "8" "edge2"]
1116
+	Pin[-40000 0 7000 3000 7600 3500 "9" "9" "edge2"]
1117
+	Pin[-40000 10000 7000 3000 7600 3500 "10" "10" "edge2"]
1118
+	ElementLine [-60000 -10000 -30000 -10000 2000]
1119
+	ElementLine [-30000 -10000 -10000 -10000 1000]
1120
+	ElementLine [-10000 -10000 20000 -10000 2000]
1121
+	ElementLine [-60000 -10000 -60000 20000 2000]
1122
+	ElementLine [-60000 20000 20000 20000 2000]
1123
+	ElementLine [20000 -10000 20000 20000 2000]
1124
+
1125
+	)
1126
+
1127
+Element["" "QFP100 rectangular 0.65mm" "IC3" "QFP100_R065" 340000 205000 -50050 -34350 0 100 ""]
1128
+(
1129
+	Pad[37150 -38350 37150 -30250 1500 3000 2100 "1" "1" ""]
1130
+	Pad[34650 -38350 34650 -30250 1500 3000 2100 "2" "2" "square"]
1131
+	Pad[32050 -38350 32050 -30250 1500 3000 2100 "3" "3" "square"]
1132
+	Pad[29550 -38350 29550 -30250 1500 3000 2100 "4" "4" "square"]
1133
+	Pad[26950 -38350 26950 -30250 1500 3000 2100 "5" "5" "square"]
1134
+	Pad[24450 -38350 24450 -30250 1500 3000 2100 "6" "6" "square"]
1135
+	Pad[21850 -38350 21850 -30250 1500 3000 2100 "7" "7" "square"]
1136
+	Pad[19250 -38350 19250 -30250 1500 3000 2100 "8" "8" "square"]
1137
+	Pad[16750 -38350 16750 -30250 1500 3000 2100 "9" "9" "square"]
1138
+	Pad[14150 -38350 14150 -30250 1500 3000 2100 "10" "10" "square"]
1139
+	Pad[11650 -38350 11650 -30250 1500 3000 2100 "11" "11" "square"]
1140
+	Pad[9050 -38350 9050 -30250 1500 3000 2100 "12" "12" "square"]
1141
+	Pad[6450 -38350 6450 -30250 1500 3000 2100 "13" "13" "square"]
1142
+	Pad[3950 -38350 3950 -30250 1500 3000 2100 "14" "14" "square"]
1143
+	Pad[1350 -38350 1350 -30250 1500 3000 2100 "15" "15" "square"]
1144
+	Pad[-1150 -38350 -1150 -30250 1500 3000 2100 "16" "16" "square"]
1145
+	Pad[-3750 -38350 -3750 -30250 1500 3000 2100 "17" "17" "square"]
1146
+	Pad[-6350 -38350 -6350 -30250 1500 3000 2100 "18" "18" "square"]
1147
+	Pad[-8850 -38350 -8850 -30250 1500 3000 2100 "19" "19" "square"]
1148
+	Pad[-11450 -38350 -11450 -30250 1500 3000 2100 "20" "20" "square"]
1149
+	Pad[-13950 -38350 -13950 -30250 1500 3000 2100 "21" "21" "square"]
1150
+	Pad[-16550 -38350 -16550 -30250 1500 3000 2100 "22" "22" "square"]
1151
+	Pad[-19050 -38350 -19050 -30250 1500 3000 2100 "23" "23" "square"]
1152
+	Pad[-21650 -38350 -21650 -30250 1500 3000 2100 "24" "24" "square"]
1153
+	Pad[-24250 -38350 -24250 -30250 1500 3000 2100 "25" "25" "square"]
1154
+	Pad[-26750 -38350 -26750 -30250 1500 3000 2100 "26" "26" "square"]
1155
+	Pad[-29350 -38350 -29350 -30250 1500 3000 2100 "27" "27" "square"]
1156
+	Pad[-31850 -38350 -31850 -30250 1500 3000 2100 "28" "28" "square"]
1157
+	Pad[-34450 -38350 -34450 -30250 1500 3000 2100 "29" "29" "square"]
1158
+	Pad[-37050 -38350 -37050 -30250 1500 3000 2100 "30" "30" "square"]
1159
+	Pad[-50150 -24350 -42050 -24350 1500 3000 2100 "31" "31" "square"]
1160
+	Pad[-50150 -21850 -42050 -21850 1500 3000 2100 "32" "32" "square"]
1161
+	Pad[-50150 -19250 -42050 -19250 1500 3000 2100 "33" "33" "square"]
1162
+	Pad[-50150 -16750 -42050 -16750 1500 3000 2100 "34" "34" "square"]
1163
+	Pad[-50150 -14150 -42050 -14150 1500 3000 2100 "35" "35" "square"]
1164
+	Pad[-50150 -11650 -42050 -11650 1500 3000 2100 "36" "36" "square"]
1165
+	Pad[-50150 -9050 -42050 -9050 1500 3000 2100 "37" "37" "square"]
1166
+	Pad[-50150 -6450 -42050 -6450 1500 3000 2100 "38" "38" "square"]
1167
+	Pad[-50150 -3950 -42050 -3950 1500 3000 2100 "39" "39" "square"]
1168
+	Pad[-50150 -1350 -42050 -1350 1500 3000 2100 "40" "40" "square"]
1169
+	Pad[-50150 1150 -42050 1150 1500 3000 2100 "41" "41" "square"]
1170
+	Pad[-50150 3750 -42050 3750 1500 3000 2100 "42" "42" "square"]
1171
+	Pad[-50150 6350 -42050 6350 1500 3000 2100 "43" "43" "square"]
1172
+	Pad[-50150 8850 -42050 8850 1500 3000 2100 "44" "44" "square"]
1173
+	Pad[-50150 11450 -42050 11450 1500 3000 2100 "45" "45" "square"]
1174
+	Pad[-50150 13950 -42050 13950 1500 3000 2100 "46" "46" "square"]
1175
+	Pad[-50150 16550 -42050 16550 1500 3000 2100 "47" "47" "square"]
1176
+	Pad[-50150 19150 -42050 19150 1500 3000 2100 "48" "48" "square"]
1177
+	Pad[-50150 21650 -42050 21650 1500 3000 2100 "49" "49" "square"]
1178
+	Pad[-50150 24250 -42050 24250 1500 3000 2100 "50" "50" "square"]
1179
+	Pad[-37150 30250 -37150 38350 1500 3000 2100 "51" "51" "square,edge2"]
1180
+	Pad[-34650 30250 -34650 38350 1500 3000 2100 "52" "52" "square,edge2"]
1181
+	Pad[-32050 30250 -32050 38350 1500 3000 2100 "53" "53" "square,edge2"]
1182
+	Pad[-29550 30250 -29550 38350 1500 3000 2100 "54" "54" "square,edge2"]
1183
+	Pad[-26950 30250 -26950 38350 1500 3000 2100 "55" "55" "square,edge2"]
1184
+	Pad[-24450 30250 -24450 38350 1500 3000 2100 "56" "56" "square,edge2"]
1185
+	Pad[-21850 30250 -21850 38350 1500 3000 2100 "57" "57" "square,edge2"]
1186
+	Pad[-19250 30250 -19250 38350 1500 3000 2100 "58" "58" "square,edge2"]
1187
+	Pad[-16750 30250 -16750 38350 1500 3000 2100 "59" "59" "square,edge2"]
1188
+	Pad[-14150 30250 -14150 38350 1500 3000 2100 "60" "60" "square,edge2"]
1189
+	Pad[-11650 30250 -11650 38350 1500 3000 2100 "61" "61" "square,edge2"]
1190
+	Pad[-9050 30250 -9050 38350 1500 3000 2100 "62" "62" "square,edge2"]
1191
+	Pad[-6450 30250 -6450 38350 1500 3000 2100 "63" "63" "square,edge2"]
1192
+	Pad[-3950 30250 -3950 38350 1500 3000 2100 "64" "64" "square,edge2"]
1193
+	Pad[-1350 30250 -1350 38350 1500 3000 2100 "65" "65" "square,edge2"]
1194
+	Pad[1150 30250 1150 38350 1500 3000 2100 "66" "66" "square,edge2"]
1195
+	Pad[3750 30250 3750 38350 1500 3000 2100 "67" "67" "square,edge2"]
1196
+	Pad[6350 30250 6350 38350 1500 3000 2100 "68" "68" "square,edge2"]
1197
+	Pad[8850 30250 8850 38350 1500 3000 2100 "69" "69" "square,edge2"]
1198
+	Pad[11450 30250 11450 38350 1500 3000 2100 "70" "70" "square,edge2"]
1199
+	Pad[13950 30250 13950 38350 1500 3000 2100 "71" "71" "square,edge2"]
1200
+	Pad[16550 30250 16550 38350 1500 3000 2100 "72" "72" "square,edge2"]
1201
+	Pad[19050 30250 19050 38350 1500 3000 2100 "73" "73" "square,edge2"]
1202
+	Pad[21650 30250 21650 38350 1500 3000 2100 "74" "74" "square,edge2"]
1203
+	Pad[24250 30250 24250 38350 1500 3000 2100 "75" "75" "square,edge2"]
1204
+	Pad[26750 30250 26750 38350 1500 3000 2100 "76" "76" "square,edge2"]
1205
+	Pad[29350 30250 29350 38350 1500 3000 2100 "77" "77" "square,edge2"]
1206
+	Pad[31850 30250 31850 38350 1500 3000 2100 "78" "78" "square,edge2"]
1207
+	Pad[34450 30250 34450 38350 1500 3000 2100 "79" "79" "square,edge2"]
1208
+	Pad[37050 30250 37050 38350 1500 3000 2100 "80" "80" "square,edge2"]
1209
+	Pad[42050 24350 50150 24350 1500 3000 2100 "81" "81" "square,edge2"]
1210
+	Pad[42050 21850 50150 21850 1500 3000 2100 "82" "82" "square,edge2"]
1211
+	Pad[42050 19250 50150 19250 1500 3000 2100 "83" "83" "square,edge2"]
1212
+	Pad[42050 16750 50150 16750 1500 3000 2100 "84" "84" "square,edge2"]
1213
+	Pad[42050 14150 50150 14150 1500 3000 2100 "85" "85" "square,edge2"]
1214
+	Pad[42050 11650 50150 11650 1500 3000 2100 "86" "86" "square,edge2"]
1215
+	Pad[42050 9050 50150 9050 1500 3000 2100 "87" "87" "square,edge2"]
1216
+	Pad[42050 6450 50150 6450 1500 3000 2100 "88" "88" "square,edge2"]
1217
+	Pad[42050 3950 50150 3950 1500 3000 2100 "89" "89" "square,edge2"]
1218
+	Pad[42050 1350 50150 1350 1500 3000 2100 "90" "90" "square,edge2"]
1219
+	Pad[42050 -1150 50150 -1150 1500 3000 2100 "91" "91" "square,edge2"]
1220
+	Pad[42050 -3750 50150 -3750 1500 3000 2100 "92" "92" "square,edge2"]
1221
+	Pad[42050 -6350 50150 -6350 1500 3000 2100 "93" "93" "square,edge2"]
1222
+	Pad[42050 -8850 50150 -8850 1500 3000 2100 "94" "94" "square,edge2"]
1223
+	Pad[42050 -11450 50150 -11450 1500 3000 2100 "95" "95" "square,edge2"]
1224
+	Pad[42050 -13950 50150 -13950 1500 3000 2100 "96" "96" "square,edge2"]
1225
+	Pad[42050 -16550 50150 -16550 1500 3000 2100 "97" "97" "square,edge2"]
1226
+	Pad[42050 -19150 50150 -19150 1500 3000 2100 "98" "98" "square,edge2"]
1227
+	Pad[42050 -21650 50150 -21650 1500 3000 2100 "99" "99" "square,edge2"]
1228
+	Pad[42050 -24250 50150 -24250 1500 3000 2100 "100" "100" "square,edge2"]
1229
+	ElementLine [39350 -24750 39350 27550 1000]
1230
+	ElementLine [-39350 27550 39350 27550 1000]
1231
+	ElementLine [-39350 -27550 -39350 27550 1000]
1232
+	ElementLine [-39350 -27550 36550 -27550 1000]
1233
+	ElementLine [36550 -27550 39350 -24750 1000]
1234
+	ElementArc [35850 -24050 1000 1000 270 360 1000]
1235
+
1236
+	)
1237
+
1238
+Element["" "SMD 0805" "C25" "0805" 70000 250000 -15000 -3000 0 100 ""]
1239
+(
1240
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1241
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1242
+	ElementLine [-4500 6000 4500 6000 1000]
1243
+	ElementLine [4500 -6000 4500 6000 1000]
1244
+	ElementLine [-4500 -6000 4500 -6000 1000]
1245
+	ElementLine [-4500 -6000 -4500 6000 1000]
1246
+
1247
+	)
1248
+
1249
+Element["" "SMD 0805" "C9" "0805" 350000 310000 -5000 4500 0 100 ""]
1250
+(
1251
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1252
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1253
+	ElementLine [6000 -4500 6000 4500 1000]
1254
+	ElementLine [-6000 -4500 6000 -4500 1000]
1255
+	ElementLine [-6000 -4500 -6000 4500 1000]
1256
+	ElementLine [-6000 4500 6000 4500 1000]
1257
+
1258
+	)
1259
+
1260
+Element["" "SMD 0805" "R1" "0805" 295000 375000 -5000 4500 0 100 ""]
1261
+(
1262
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1263
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1264
+	ElementLine [6000 -4500 6000 4500 1000]
1265
+	ElementLine [-6000 -4500 6000 -4500 1000]
1266
+	ElementLine [-6000 -4500 -6000 4500 1000]
1267
+	ElementLine [-6000 4500 6000 4500 1000]
1268
+
1269
+	)
1270
+
1271
+Element["" "crystal HC18" "X1" "HC18" 325000 330000 -2500 12000 0 100 ""]
1272
+(
1273
+	Pin[0 0 6000 3000 6600 3000 "1" "1" ""]
1274
+	Pin[0 -20000 6000 3000 6600 3000 "2" "2" ""]
1275
+	ElementLine [-10000 -20000 -10000 0 1000]
1276
+	ElementLine [10000 -20000 10000 0 1000]
1277
+	ElementArc [0 0 10000 10000 0 180 1000]
1278
+	ElementArc [0 -20000 10000 10000 180 180 1000]
1279
+
1280
+	)
1281
+
1282
+Element["" "electrolytic capacitor SMD 4.0mm" "C18" "CAP_EL_SMD_40" 122500 180000 -22500 4400 0 100 ""]
1283
+(
1284
+	Pad[4000 0 10000 0 4000 3000 4600 "+" "1" "square,edge2"]
1285
+	Pad[-10000 0 -4000 0 4000 3000 4600 "-" "2" "square"]
1286
+	ElementLine [7000 10000 12500 7000 1000]
1287
+	ElementLine [-12500 10000 7000 10000 1000]
1288
+	ElementLine [-12500 -10000 -12500 10000 1000]
1289
+	ElementLine [-12500 -10000 7000 -10000 1000]
1290
+	ElementLine [12500 -7000 7000 -10000 1000]
1291
+	ElementLine [12500 -7000 12500 7000 2000]
1292
+
1293
+	)
1294
+
1295
+Element["" "SMD 0805" "R5" "0805" 167500 347500 -6600 5900 0 100 ""]
1296
+(
1297
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "1" "1" "square"]
1298
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "2" "2" "square"]
1299
+	ElementLine [-4500 -6000 4500 -6000 1000]
1300
+	ElementLine [-4500 -6000 -4500 6000 1000]
1301
+	ElementLine [-4500 6000 4500 6000 1000]
1302
+	ElementLine [4500 -6000 4500 6000 1000]
1303
+
1304
+	)
1305
+
1306
+Element["" "SMD 0805" "C12" "0805" 245000 245000 -5000 4500 0 100 ""]
1307
+(
1308
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1309
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1310
+	ElementLine [-6000 -4500 -6000 4500 1000]
1311
+	ElementLine [-6000 4500 6000 4500 1000]
1312
+	ElementLine [6000 4500 6000 -4500 1000]
1313
+	ElementLine [6000 -4500 -6000 -4500 1000]
1314
+
1315
+	)
1316
+
1317
+Element["" "capacitor" "C2" "200" 140000 330000 -23000 -2200 0 100 ""]
1318
+(
1319
+	Pin[10000 0 6300 3000 6900 3150 "" "1" "edge2"]
1320
+	Pin[-10000 0 6300 3000 6900 3150 "" "2" "edge2"]
1321
+	ElementLine [-10000 0 -2500 0 1000]
1322
+	ElementLine [-2500 -4000 -2500 4000 1000]
1323
+	ElementLine [2500 -4000 2500 4000 1000]
1324
+	ElementLine [2500 0 10000 0 1000]
1325
+	ElementLine [14000 -5000 14000 5000 1000]
1326
+	ElementLine [-14000 -5000 14000 -5000 1000]
1327
+	ElementLine [-14000 -5000 -14000 5000 1000]
1328
+	ElementLine [-14000 5000 14000 5000 1000]
1329
+
1330
+	)
1331
+
1332
+Element["" "electrolytic capacitor" "C1" "100" 145000 355000 -20000 12500 0 100 ""]
1333
+(
1334
+	Pin[0 0 6300 3000 6900 3150 "+" "1" "square,edge2"]
1335
+	Pin[-10000 0 6300 3000 6900 3150 "-" "2" "edge2"]
1336
+	ElementLine [2000 4000 2000 8000 1000]
1337
+	ElementLine [0 6000 4000 6000 1000]
1338
+	ElementLine [-10000 0 -6500 0 1000]
1339
+	ElementLine [-6500 -10000 -6500 10000 1000]
1340
+	ElementLine [-3500 -10000 -3500 10000 1000]
1341
+	ElementLine [-3500 0 0 0 1000]
1342
+	ElementArc [-5000 0 15000 15000 180 360 1000]
1343
+
1344
+	)
1345
+
1346
+Element["" "SMD 0805" "C14" "0805" 270000 145000 7500 -3000 0 100 ""]
1347
+(
1348
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1349
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1350
+	ElementLine [-4500 6000 4500 6000 1000]
1351
+	ElementLine [4500 -6000 4500 6000 1000]
1352
+	ElementLine [-4500 -6000 4500 -6000 1000]
1353
+	ElementLine [-4500 -6000 -4500 6000 1000]
1354
+
1355
+	)
1356
+
1357
+Element["" "SMD 0805" "C21" "0805" 105000 205000 7500 -3000 0 100 ""]
1358
+(
1359
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1360
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1361
+	ElementLine [6000 -4500 6000 4500 1000]
1362
+	ElementLine [-6000 -4500 6000 -4500 1000]
1363
+	ElementLine [-6000 -4500 -6000 4500 1000]
1364
+	ElementLine [-6000 4500 6000 4500 1000]
1365
+
1366
+	)
1367
+
1368
+Element["" "PIN" "J2" "3mm5" 401575 94488 15000 10000 0 100 ""]
1369
+(
1370
+	Pin[0 0 29528 3000 30128 13780 "" "1" "thermal(0X,1X)"]
1371
+	ElementArc [0 0 16000 16000 0 360 1000]
1372
+
1373
+	)
1374
+
1375
+Element["" "diode" "D1" "300" 85000 350000 -5000 -12500 0 100 ""]
1376
+(
1377
+	Pin[15000 0 7874 3000 8474 3937 "K" "1" "square,edge2"]
1378
+	Pin[-15000 0 7874 3000 8474 3937 "A" "2" "edge2"]
1379
+	ElementLine [5000 0 15000 0 1000]
1380
+	ElementLine [-15000 0 -5000 0 1000]
1381
+	ElementLine [5000 0 -5000 5000 1000]
1382
+	ElementLine [-5000 -5000 -5000 5000 1000]
1383
+	ElementLine [-5000 -5000 5000 0 1000]
1384
+	ElementLine [5000 -5000 5000 5000 1000]
1385
+	ElementLine [20300 -6000 20300 6000 1000]
1386
+	ElementLine [-20300 -6000 20300 -6000 1000]
1387
+	ElementLine [-20300 -6000 -20300 6000 1000]
1388
+	ElementLine [-20300 6000 20300 6000 1000]
1389
+
1390
+	)
1391
+
1392
+Element["" "SMD 0805" "C7" "0805" 225000 350000 -5200 5000 0 100 ""]
1393
+(
1394
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1395
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1396
+	ElementLine [6000 -4500 6000 4500 1000]
1397
+	ElementLine [-6000 -4500 6000 -4500 1000]
1398
+	ElementLine [-6000 -4500 -6000 4500 1000]
1399
+	ElementLine [-6000 4500 6000 4500 1000]
1400
+
1401
+	)
1402
+
1403
+Element["" "PIN" "J4" "3mm5" 401575 401575 15000 10000 0 100 ""]
1404
+(
1405
+	Pin[0 0 29528 3000 30128 13780 "" "1" "thermal(0X,1X)"]
1406
+	ElementArc [0 0 16000 16000 0 360 1000]
1407
+
1408
+	)
1409
+
1410
+Element["" "SMD 0805" "R11" "0805" 207500 170000 -15000 -3000 0 100 ""]
1411
+(
1412
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1413
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1414
+	ElementLine [-6000 -4500 -6000 4500 1000]
1415
+	ElementLine [-6000 4500 6000 4500 1000]
1416
+	ElementLine [6000 4500 6000 -4500 1000]
1417
+	ElementLine [6000 -4500 -6000 -4500 1000]
1418
+
1419
+	)
1420
+
1421
+Element["" "SMD 0805" "R7" "0805" 367500 140000 -2900 5800 0 100 ""]
1422
+(
1423
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1424
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1425
+	ElementLine [-6000 -4500 -6000 4500 1000]
1426
+	ElementLine [-6000 4500 6000 4500 1000]
1427
+	ElementLine [6000 -4500 6000 4500 1000]
1428
+	ElementLine [-6000 -4500 6000 -4500 1000]
1429
+
1430
+	)
1431
+
1432
+Element["" "SMD 0805" "C13" "0805" 245000 225000 -5000 4500 0 100 ""]
1433
+(
1434
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1435
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1436
+	ElementLine [-6000 -4500 -6000 4500 1000]
1437
+	ElementLine [-6000 4500 6000 4500 1000]
1438
+	ElementLine [6000 4500 6000 -4500 1000]
1439
+	ElementLine [6000 -4500 -6000 -4500 1000]
1440
+
1441
+	)
1442
+
1443
+Element["" "SMD LED 0603" "LED1" "0603" 167500 327500 -6000 -10200 0 100 ""]
1444
+(
1445
+	Pad[-900 -2400 900 -2400 2400 2000 3000 "K" "1" "square"]
1446
+	Pad[-900 2400 900 2400 2400 2000 3000 "A" "2" "square"]
1447
+	ElementLine [-4200 -4200 4200 -4200 1000]
1448
+	ElementLine [-2700 -4200 -4200 4200 1000]
1449
+	ElementLine [-4200 4200 4200 4200 1000]
1450
+	ElementLine [4200 4200 2700 -4200 1000]
1451
+
1452
+	)
1453
+
1454
+Element["" "SMD 0805" "C10" "0805" 402500 212500 -2500 7000 0 100 ""]
1455
+(
1456
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1457
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1458
+	ElementLine [-4500 6000 4500 6000 1000]
1459
+	ElementLine [4500 -6000 4500 6000 1000]
1460
+	ElementLine [-4500 -6000 4500 -6000 1000]
1461
+	ElementLine [-4500 -6000 -4500 6000 1000]
1462
+
1463
+	)
1464
+
1465
+Element["" "SMD 0805" "C15" "0805" 320000 145000 -15000 -3000 0 100 ""]
1466
+(
1467
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1468
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1469
+	ElementLine [-4500 6000 4500 6000 1000]
1470
+	ElementLine [4500 -6000 4500 6000 1000]
1471
+	ElementLine [-4500 -6000 4500 -6000 1000]
1472
+	ElementLine [-4500 -6000 -4500 6000 1000]
1473
+
1474
+	)
1475
+
1476
+Element["" "SO16" "IC4" "" 95000 235000 -4500 21500 0 100 ""]
1477
+(
1478
+	Pad[-13500 -17500 -7000 -17500 2000 3000 2600 "1" "1" "square"]
1479
+	Pad[-13500 -12500 -7000 -12500 2000 3000 2600 "2" "2" "square"]
1480
+	Pad[-13500 -7500 -7000 -7500 2000 3000 2600 "3" "3" "square"]
1481
+	Pad[-13500 -2500 -7000 -2500 2000 3000 2600 "4" "4" "square"]
1482
+	Pad[-13500 2500 -7000 2500 2000 3000 2600 "5" "5" "square"]
1483
+	Pad[-13500 7500 -7000 7500 2000 3000 2600 "6" "6" "square"]
1484
+	Pad[-13500 12500 -7000 12500 2000 3000 2600 "7" "7" "square"]
1485
+	Pad[-13500 17500 -7000 17500 2000 3000 2600 "8" "8" "square"]
1486
+	Pad[7000 17500 13500 17500 2000 3000 2600 "9" "9" "square,edge2"]
1487
+	Pad[7000 12500 13500 12500 2000 3000 2600 "10" "10" "square,edge2"]
1488
+	Pad[7000 7500 13500 7500 2000 3000 2600 "11" "11" "square,edge2"]
1489
+	Pad[7000 2500 13500 2500 2000 3000 2600 "12" "12" "square,edge2"]
1490
+	Pad[7000 -2500 13500 -2500 2000 3000 2600 "13" "13" "square,edge2"]
1491
+	Pad[7000 -7500 13500 -7500 2000 3000 2600 "14" "14" "square,edge2"]
1492
+	Pad[7000 -12500 13500 -12500 2000 3000 2600 "15" "15" "square,edge2"]
1493
+	Pad[7000 -17500 13500 -17500 2000 3000 2600 "16" "16" "square,edge2"]
1494
+	ElementLine [-15500 -19500 -15500 19500 1000]
1495
+	ElementLine [-15500 19500 15500 19500 1000]
1496
+	ElementLine [15500 -19500 15500 19500 1000]
1497
+	ElementLine [-15500 -19500 -2500 -19500 1000]
1498
+	ElementLine [2500 -19500 15500 -19500 1000]
1499
+	ElementArc [0 -19500 2500 2500 0 180 1000]
1500
+
1501
+	)
1502
+
1503
+Element["" "FB2022" "L1" "FB2022" 260000 130000 77000 -500 0 100 ""]
1504
+(
1505
+	Pin[0 0 6300 3000 6900 3150 "1" "1" "square,edge2"]
1506
+	Pin[10000 0 6300 3000 6900 3150 "2" "2" "edge2"]
1507
+	Pin[20000 0 6300 3000 6900 3150 "3" "3" "edge2"]
1508
+	Pin[50000 0 6300 3000 6900 3150 "4" "4" "edge2"]
1509
+	Pin[60000 0 6300 3000 6900 3150 "5" "5" "edge2"]
1510
+	Pin[70000 0 6300 3000 6900 3150 "6" "6" "edge2"]
1511
+	Pin[70000 -30000 6300 3000 6900 3150 "7" "7" "edge2"]
1512
+	Pin[60000 -30000 6300 3000 6900 3150 "8" "8" "edge2"]
1513
+	Pin[50000 -30000 6300 3000 6900 3150 "9" "9" "edge2"]
1514
+	Pin[20000 -30000 6300 3000 6900 3150 "10" "10" "edge2"]
1515
+	Pin[10000 -30000 6300 3000 6900 3150 "11" "11" "edge2"]
1516
+	Pin[0 -30000 6300 3000 6900 3150 "12" "12" "edge2"]
1517
+	ElementLine [-5000 5000 75000 5000 1000]
1518
+	ElementLine [75000 -35000 75000 5000 1000]
1519
+	ElementLine [-5000 -35000 75000 -35000 1000]
1520
+	ElementLine [-5000 -10000 -5000 5000 1000]
1521
+	ElementLine [-5000 -35000 -5000 -20000 1000]
1522
+	ElementArc [-5000 -15000 5000 5000 90 180 1000]
1523
+
1524
+	)
1525
+
1526
+Element["" "SMD 0805" "C16" "0805" 320000 85000 7500 -3000 0 100 ""]
1527
+(
1528
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "1" "1" "square"]
1529
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "2" "2" "square"]
1530
+	ElementLine [-4500 -6000 4500 -6000 1000]
1531
+	ElementLine [-4500 -6000 -4500 6000 1000]
1532
+	ElementLine [-4500 6000 4500 6000 1000]
1533
+	ElementLine [4500 -6000 4500 6000 1000]
1534
+
1535
+	)
1536
+
1537
+Element["" "SMD 0805" "C17" "0805" 270000 85000 7500 -3000 0 100 ""]
1538
+(
1539
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "1" "1" "square"]
1540
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "2" "2" "square"]
1541
+	ElementLine [-4500 -6000 4500 -6000 1000]
1542
+	ElementLine [-4500 -6000 -4500 6000 1000]
1543
+	ElementLine [-4500 6000 4500 6000 1000]
1544
+	ElementLine [4500 -6000 4500 6000 1000]
1545
+
1546
+	)
1547
+
1548
+Element["" "PIN" "J1" "3mm5" 31496 31496 15000 10000 0 100 ""]
1549
+(
1550
+	Pin[0 0 29528 3000 30128 13780 "" "1" "thermal(0X,1X)"]
1551
+	ElementArc [0 0 16000 16000 0 360 1000]
1552
+
1553
+	)
1554
+
1555
+Element["" "SMD 0805" "C24" "0805" 70000 235000 -15000 -3000 0 100 ""]
1556
+(
1557
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1558
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1559
+	ElementLine [-4500 6000 4500 6000 1000]
1560
+	ElementLine [4500 -6000 4500 6000 1000]
1561
+	ElementLine [-4500 -6000 4500 -6000 1000]
1562
+	ElementLine [-4500 -6000 -4500 6000 1000]
1563
+
1564
+	)
1565
+
1566
+Element["" "MEBP8-8G" "CON2" "MEBP8-8G" 295000 60000 -500 12000 0 100 ""]
1567
+(
1568
+	Pin[17500 -10000 6300 3000 6900 3550 "1" "1" "edge2"]
1569
+	Pin[12500 0 6300 3000 6900 3550 "2" "2" "edge2"]
1570
+	Pin[7500 -10000 6300 3000 6900 3550 "3" "3" "edge2"]
1571
+	Pin[2500 0 6300 3000 6900 3550 "4" "4" "edge2"]
1572
+	Pin[-2500 -10000 6300 3000 6900 3550 "5" "5" "edge2"]
1573
+	Pin[-7500 0 6300 3000 6900 3550 "6" "6" "edge2"]
1574
+	Pin[-12500 -10000 6300 3000 6900 3550 "7" "7" "edge2"]
1575
+	Pin[-17500 0 6300 3000 6900 3550 "8" "8" "edge2"]
1576
+	Pin[30492 -22992 10000 3000 10600 6299 "9" "9" "edge2,thermal(0X,1X)"]
1577
+	Pin[-30492 -22992 10000 3000 10600 6299 "10" "10" "edge2,thermal(0X,1X)"]
1578
+	Pin[22500 -35000 12795 3000 13395 12795 "11" "11" "hole,edge2"]
1579
+	Pin[-22500 -35000 12795 3000 13395 12795 "12" "12" "hole,edge2"]
1580
+	ElementLine [-22500 -20000 22500 -20000 1000]
1581
+	ElementLine [-22500 -60000 -22500 -42000 1000]
1582
+	ElementLine [-22500 -28000 -22500 -20000 1000]
1583
+	ElementLine [22500 -60000 22500 -42000 1000]
1584
+	ElementLine [22500 -28000 22500 -20000 1000]
1585
+	ElementLine [-31260 -60000 -31260 10000 1000]
1586
+	ElementLine [31260 -60000 31260 10000 1000]
1587
+	ElementLine [-31260 -60000 31260 -60000 1000]
1588
+	ElementLine [-31260 10000 31260 10000 1000]
1589
+	ElementArc [-22500 -35000 7000 7000 180 360 1000]
1590
+	ElementArc [22500 -35000 7000 7000 180 360 1000]
1591
+
1592
+	)
1593
+
1594
+Element["" "compact flash header" "CF1" "YAMAI_CF050P2" 150000 130000 -94000 26000 0 150 ""]
1595
+(
1596
+	Pin[89370 -98819 5118 3000 5718 5118 "" "NC" "hole,edge2"]
1597
+	Pin[-89370 -98819 5118 3000 5718 5118 "" "NC" "hole,edge2"]
1598
+	Pin[79055 0 6693 3000 7293 6693 "" "NC" "hole,edge2"]
1599
+	Pin[-79055 0 6693 3000 7293 6693 "" "NC" "hole,edge2"]
1600
+	Pin[79055 11811 9055 3000 9655 9055 "" "NC" "hole,edge2"]
1601
+	Pin[-79055 11811 9055 3000 9655 9055 "" "NC" "hole,edge2"]
1602
+	Pad[61250 16929 61250 25197 1575 3000 2175 "1" "1" "edge2"]
1603
+	Pad[58750 16929 58750 25197 1575 3000 2175 "26" "26" "square,edge2"]
1604
+	Pad[56250 16929 56250 25197 1575 3000 2175 "2" "2" "square,edge2"]
1605
+	Pad[53750 16929 53750 25197 1575 3000 2175 "27" "27" "square,edge2"]
1606
+	Pad[51250 16929 51250 25197 1575 3000 2175 "3" "3" "square,edge2"]
1607
+	Pad[48750 16929 48750 25197 1575 3000 2175 "28" "28" "square,edge2"]
1608
+	Pad[46250 16929 46250 25197 1575 3000 2175 "4" "4" "square,edge2"]
1609
+	Pad[43750 16929 43750 25197 1575 3000 2175 "29" "29" "square,edge2"]
1610
+	Pad[41250 16929 41250 25197 1575 3000 2175 "5" "5" "square,edge2"]
1611
+	Pad[38750 16929 38750 25197 1575 3000 2175 "30" "30" "square,edge2"]
1612
+	Pad[36250 16929 36250 25197 1575 3000 2175 "6" "6" "square,edge2"]
1613
+	Pad[33750 16929 33750 25197 1575 3000 2175 "31" "31" "square,edge2"]
1614
+	Pad[31250 16929 31250 25197 1575 3000 2175 "7" "7" "square,edge2"]
1615
+	Pad[28750 16929 28750 25197 1575 3000 2175 "32" "32" "square,edge2"]
1616
+	Pad[26250 16929 26250 25197 1575 3000 2175 "8" "8" "square,edge2"]
1617
+	Pad[23750 16929 23750 25197 1575 3000 2175 "33" "33" "square,edge2"]
1618
+	Pad[21250 16929 21250 25197 1575 3000 2175 "9" "9" "square,edge2"]
1619
+	Pad[18750 16929 18750 25197 1575 3000 2175 "34" "34" "square,edge2"]
1620
+	Pad[16250 16929 16250 25197 1575 3000 2175 "10" "10" "square,edge2"]
1621
+	Pad[13750 16929 13750 25197 1575 3000 2175 "35" "35" "square,edge2"]
1622
+	Pad[11250 16929 11250 25197 1575 3000 2175 "11" "11" "square,edge2"]
1623
+	Pad[8750 16929 8750 25197 1575 3000 2175 "36" "36" "square,edge2"]
1624
+	Pad[6250 16929 6250 25197 1575 3000 2175 "12" "12" "square,edge2"]
1625
+	Pad[3750 16929 3750 25197 1575 3000 2175 "37" "37" "square,edge2"]
1626
+	Pad[1250 16929 1250 25197 1575 3000 2175 "13" "13" "square,edge2"]
1627
+	Pad[-1250 16929 -1250 25197 1575 3000 2175 "38" "38" "square,edge2"]
1628
+	Pad[-3750 16929 -3750 25197 1575 3000 2175 "14" "14" "square,edge2"]
1629
+	Pad[-6250 16929 -6250 25197 1575 3000 2175 "39" "39" "square,edge2"]
1630
+	Pad[-8750 16929 -8750 25197 1575 3000 2175 "15" "15" "square,edge2"]
1631
+	Pad[-11250 16929 -11250 25197 1575 3000 2175 "40" "40" "square,edge2"]
1632
+	Pad[-13750 16929 -13750 25197 1575 3000 2175 "16" "16" "square,edge2"]
1633
+	Pad[-16250 16929 -16250 25197 1575 3000 2175 "41" "41" "square,edge2"]
1634
+	Pad[-18750 16929 -18750 25197 1575 3000 2175 "17" "17" "square,edge2"]
1635
+	Pad[-21250 16929 -21250 25197 1575 3000 2175 "42" "42" "square,edge2"]
1636
+	Pad[-23750 16929 -23750 25197 1575 3000 2175 "18" "18" "square,edge2"]
1637
+	Pad[-26250 16929 -26250 25197 1575 3000 2175 "43" "43" "square,edge2"]
1638
+	Pad[-28750 16929 -28750 25197 1575 3000 2175 "19" "19" "square,edge2"]
1639
+	Pad[-31250 16929 -31250 25197 1575 3000 2175 "44" "44" "square,edge2"]
1640
+	Pad[-33750 16929 -33750 25197 1575 3000 2175 "20" "20" "square,edge2"]
1641
+	Pad[-36250 16929 -36250 25197 1575 3000 2175 "45" "45" "square,edge2"]
1642
+	Pad[-38750 16929 -38750 25197 1575 3000 2175 "21" "21" "square,edge2"]
1643
+	Pad[-41250 16929 -41250 25197 1575 3000 2175 "46" "46" "square,edge2"]
1644
+	Pad[-43750 16929 -43750 25197 1575 3000 2175 "22" "22" "square,edge2"]
1645
+	Pad[-46250 16929 -46250 25197 1575 3000 2175 "47" "47" "square,edge2"]
1646
+	Pad[-48750 16929 -48750 25197 1575 3000 2175 "23" "23" "square,edge2"]
1647
+	Pad[-51250 16929 -51250 25197 1575 3000 2175 "48" "48" "square,edge2"]
1648
+	Pad[-53750 16929 -53750 25197 1575 3000 2175 "24" "24" "square,edge2"]
1649
+	Pad[-56250 16929 -56250 25197 1575 3000 2175 "49" "49" "square,edge2"]
1650
+	Pad[-58750 16929 -58750 25197 1575 3000 2175 "25" "25" "square,edge2"]
1651
+	Pad[-61250 16929 -61250 25197 1575 3000 2175 "50" "50" "square,edge2"]
1652
+	Pad[91732 -87795 91732 -83859 11811 3000 12411 "S1" "100" "square"]
1653
+	Pad[-91732 -87795 -91732 -83859 11811 3000 12411 "S2" "101" "square"]
1654
+	ElementLine [87854 -130669 87854 -113780 1000]
1655
+	ElementLine [81555 -130669 81555 -113780 1000]
1656
+	ElementLine [81555 -130669 87854 -130669 1000]
1657
+	ElementLine [-87854 -130669 -87854 -113780 1000]
1658
+	ElementLine [-81555 -130669 -81555 -113780 1000]
1659
+	ElementLine [-81555 -130669 -87854 -130669 1000]
1660
+	ElementLine [-59055 -31496 59055 -31496 1000]
1661
+	ElementLine [59055 -31496 78740 -113780 1000]
1662
+	ElementLine [-59055 -31496 -78740 -113780 1000]
1663
+	ElementLine [94094 -113780 78740 -113780 1000]
1664
+	ElementLine [-94094 -113780 -78740 -113780 1000]
1665
+	ElementLine [94094 24016 94094 -113780 1000]
1666
+	ElementLine [-94094 24016 -94094 -113780 1000]
1667
+	ElementLine [-68504 7874 68504 7874 1000]
1668
+	ElementLine [68504 24016 68504 7874 1000]
1669
+	ElementLine [-68504 24016 -68504 7874 1000]
1670
+	ElementLine [94094 24016 68504 24016 1000]
1671
+	ElementLine [-94094 24016 -68504 24016 1000]
1672
+
1673
+	)
1674
+
1675
+Element["" "SMD 0805" "R12" "0805" 160000 170000 -5000 4500 0 100 ""]
1676
+(
1677
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1678
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1679
+	ElementLine [-6000 -4500 -6000 4500 1000]
1680
+	ElementLine [-6000 4500 6000 4500 1000]
1681
+	ElementLine [6000 4500 6000 -4500 1000]
1682
+	ElementLine [6000 -4500 -6000 -4500 1000]
1683
+
1684
+	)
1685
+
1686
+Element["" "SMD 0805" "C19" "0805" 77500 165000 -5000 4500 0 100 ""]
1687
+(
1688
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1689
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1690
+	ElementLine [-6000 -4500 -6000 4500 1000]
1691
+	ElementLine [-6000 4500 6000 4500 1000]
1692
+	ElementLine [6000 4500 6000 -4500 1000]
1693
+	ElementLine [6000 -4500 -6000 -4500 1000]
1694
+
1695
+	)
1696
+
1697
+Element["" "SMD 0805" "C20" "0805" 222500 165000 8750 -5303 0 100 ""]
1698
+(
1699
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1700
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1701
+	ElementLine [6000 -4500 6000 4500 1000]
1702
+	ElementLine [-6000 -4500 6000 -4500 1000]
1703
+	ElementLine [-6000 -4500 -6000 4500 1000]
1704
+	ElementLine [-6000 4500 6000 4500 1000]
1705
+
1706
+	)
1707
+
1708
+Element["" "MEBP8-8G" "CON3" "MEBP8-8G" 375000 60000 -500 12000 0 100 ""]
1709
+(
1710
+	Pin[17500 -10000 6300 3000 6900 3550 "1" "1" "edge2"]
1711
+	Pin[12500 0 6300 3000 6900 3550 "2" "2" "edge2"]
1712
+	Pin[7500 -10000 6300 3000 6900 3550 "3" "3" "edge2"]
1713
+	Pin[2500 0 6300 3000 6900 3550 "4" "4" "edge2"]
1714
+	Pin[-2500 -10000 6300 3000 6900 3550 "5" "5" "edge2"]
1715
+	Pin[-7500 0 6300 3000 6900 3550 "6" "6" "edge2"]
1716
+	Pin[-12500 -10000 6300 3000 6900 3550 "7" "7" "edge2"]
1717
+	Pin[-17500 0 6300 3000 6900 3550 "8" "8" "edge2"]
1718
+	Pin[30492 -22992 10000 3000 10600 6299 "9" "9" "edge2,thermal(0X,1X)"]
1719
+	Pin[-30492 -22992 10000 3000 10600 6299 "10" "10" "edge2,thermal(0X,1X)"]
1720
+	Pin[22500 -35000 12795 3000 13395 12795 "11" "11" "hole,edge2"]
1721
+	Pin[-22500 -35000 12795 3000 13395 12795 "12" "12" "hole,edge2"]
1722
+	ElementLine [-22500 -20000 22500 -20000 1000]
1723
+	ElementLine [-22500 -60000 -22500 -42000 1000]
1724
+	ElementLine [-22500 -28000 -22500 -20000 1000]
1725
+	ElementLine [22500 -60000 22500 -42000 1000]
1726
+	ElementLine [22500 -28000 22500 -20000 1000]
1727
+	ElementLine [-31260 -60000 -31260 10000 1000]
1728
+	ElementLine [31260 -60000 31260 10000 1000]
1729
+	ElementLine [-31260 -60000 31260 -60000 1000]
1730
+	ElementLine [-31260 10000 31260 10000 1000]
1731
+	ElementArc [-22500 -35000 7000 7000 180 360 1000]
1732
+	ElementArc [22500 -35000 7000 7000 180 360 1000]
1733
+
1734
+	)
1735
+
1736
+Element["" "SMD 0805" "C5" "0805" 207500 300000 -2500 7000 0 100 ""]
1737
+(
1738
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1739
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1740
+	ElementLine [-4500 6000 4500 6000 1000]
1741
+	ElementLine [4500 -6000 4500 6000 1000]
1742
+	ElementLine [-4500 -6000 4500 -6000 1000]
1743
+	ElementLine [-4500 -6000 -4500 6000 1000]
1744
+
1745
+	)
1746
+
1747
+Element["" "SMD 0805" "C22" "0805" 70000 220000 -15000 -3000 0 100 ""]
1748
+(
1749
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1750
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1751
+	ElementLine [-4500 6000 4500 6000 1000]
1752
+	ElementLine [4500 -6000 4500 6000 1000]
1753
+	ElementLine [-4500 -6000 4500 -6000 1000]
1754
+	ElementLine [-4500 -6000 -4500 6000 1000]
1755
+
1756
+	)
1757
+
1758
+Element["" "SMD 0805" "C23" "0805" 85000 205000 -17500 -3000 0 100 ""]
1759
+(
1760
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1761
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1762
+	ElementLine [6000 -4500 6000 4500 1000]
1763
+	ElementLine [-6000 -4500 6000 -4500 1000]
1764
+	ElementLine [-6000 -4500 -6000 4500 1000]
1765
+	ElementLine [-6000 4500 6000 4500 1000]
1766
+
1767
+	)
1768
+
1769
+Element["" "PIN" "J3" "3mm5" 31496 401575 15000 10000 0 100 ""]
1770
+(
1771
+	Pin[0 0 29528 3000 30128 13780 "" "1" "thermal(0X,1X)"]
1772
+	ElementArc [0 0 16000 16000 0 360 1000]
1773
+
1774
+	)
1775
+
1776
+Element["" "TO220_3" "IC1" "flat" 150000 300000 -56500 23000 0 100 ""]
1777
+(
1778
+	Pin[0 10000 8200 3000 8800 4000 "1" "1" "square,edge2"]
1779
+	Pin[0 0 8200 3000 8800 4000 "2" "2" "edge2"]
1780
+	Pin[0 -10000 8200 3000 8800 4000 "3" "3" "edge2"]
1781
+	Pin[-67000 0 18000 3000 18600 13000 "4" "4" "edge2"]
1782
+	ElementLine [-18000 10000 0 10000 3000]
1783
+	ElementLine [-18000 0 0 0 3000]
1784
+	ElementLine [-18000 -10000 0 -10000 3000]
1785
+	ElementLine [-18000 -20000 -18000 20000 2000]
1786
+	ElementLine [-55500 -20000 -18000 -20000 2000]
1787
+	ElementLine [-55500 -20000 -55500 20000 2000]
1788
+	ElementLine [-55500 20000 -18000 20000 2000]
1789
+	ElementLine [-55500 -20000 -55500 20000 2000]
1790
+	ElementLine [-68000 -20000 -55500 -20000 2000]
1791
+	ElementLine [-68000 -20000 -68000 -18500 2000]
1792
+	ElementLine [-75000 -18500 -68000 -18500 2000]
1793
+	ElementLine [-75000 -20000 -75000 -18500 2000]
1794
+	ElementLine [-79000 -20000 -75000 -20000 2000]
1795
+	ElementLine [-79000 -20000 -79000 20000 2000]
1796
+	ElementLine [-79000 20000 -75000 20000 2000]
1797
+	ElementLine [-75000 18500 -75000 20000 2000]
1798
+	ElementLine [-75000 18500 -68000 18500 2000]
1799
+	ElementLine [-68000 18500 -68000 20000 2000]
1800
+	ElementLine [-68000 20000 -55500 20000 2000]
1801
+
1802
+	)
1803
+
1804
+Element["" "electrolytic capacitor" "C4" "100" 145000 237500 -22500 10000 0 100 ""]
1805
+(
1806
+	Pin[0 0 6300 3000 6900 3150 "+" "1" "square,edge2"]
1807
+	Pin[-10000 0 6300 3000 6900 3150 "-" "2" "edge2"]
1808
+	ElementLine [2000 4000 2000 8000 1000]
1809
+	ElementLine [0 6000 4000 6000 1000]
1810
+	ElementLine [-10000 0 -6500 0 1000]
1811
+	ElementLine [-6500 -10000 -6500 10000 1000]
1812
+	ElementLine [-3500 -10000 -3500 10000 1000]
1813
+	ElementLine [-3500 0 0 0 1000]
1814
+	ElementArc [-5000 0 15000 15000 180 360 1000]
1815
+
1816
+	)
1817
+
1818
+Element["" "capacitor" "C3" "200" 140000 270000 -23000 -2200 0 100 ""]
1819
+(
1820
+	Pin[10000 0 6300 3000 6900 3150 "" "1" "edge2"]
1821
+	Pin[-10000 0 6300 3000 6900 3150 "" "2" "edge2"]
1822
+	ElementLine [-10000 0 -2500 0 1000]
1823
+	ElementLine [-2500 -4000 -2500 4000 1000]
1824
+	ElementLine [2500 -4000 2500 4000 1000]
1825
+	ElementLine [2500 0 10000 0 1000]
1826
+	ElementLine [14000 -5000 14000 5000 1000]
1827
+	ElementLine [-14000 -5000 14000 -5000 1000]
1828
+	ElementLine [-14000 -5000 -14000 5000 1000]
1829
+	ElementLine [-14000 5000 14000 5000 1000]
1830
+
1831
+	)
1832
+
1833
+Element["" "MINIMELF" "D2" "" 185000 295000 -6000 -12100 0 100 ""]
1834
+(
1835
+	Pad[6693 -984 6693 984 4724 3000 5324 "1" "1" "square"]
1836
+	Pad[-6693 -984 -6693 984 4724 3000 5324 "2" "2" "square"]
1837
+	ElementLine [11000 -3000 11000 3000 2000]
1838
+	ElementLine [11000 -3000 7000 -5000 1000]
1839
+	ElementLine [-11000 -5000 7000 -5000 1000]
1840
+	ElementLine [-11000 -5000 -11000 5000 1000]
1841
+	ElementLine [-11000 5000 7000 5000 1000]
1842
+	ElementLine [7000 5000 11000 3000 1000]
1843
+
1844
+	)
1845
+
1846
+Element["" "SMD 0805" "C11" "0805" 317500 257500 -5000 4500 0 100 ""]
1847
+(
1848
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1849
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1850
+	ElementLine [-6000 -4500 -6000 4500 1000]
1851
+	ElementLine [-6000 4500 6000 4500 1000]
1852
+	ElementLine [6000 4500 6000 -4500 1000]
1853
+	ElementLine [6000 -4500 -6000 -4500 1000]
1854
+
1855
+	)
1856
+
1857
+Element["" "SMD 0805" "C6" "0805" 312500 355000 0 4500 0 100 ""]
1858
+(
1859
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1860
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1861
+	ElementLine [6000 -4500 6000 4500 1000]
1862
+	ElementLine [-6000 -4500 6000 -4500 1000]
1863
+	ElementLine [-6000 -4500 -6000 4500 1000]
1864
+	ElementLine [-6000 4500 6000 4500 1000]
1865
+
1866
+	)
1867
+
1868
+Element["" "QFP64 0.8mm" "IC2" "QFP64_08" 265000 315000 29950 27450 0 100 ""]
1869
+(
1870
+	Pad[-23650 30250 -23650 34850 1500 3000 2100 "1" "1" "edge2"]
1871
+	Pad[-20550 30250 -20550 34850 1500 3000 2100 "2" "2" "square,edge2"]
1872
+	Pad[-17450 30250 -17450 34850 1500 3000 2100 "3" "3" "square,edge2"]
1873
+	Pad[-14250 30250 -14250 34850 1500 3000 2100 "4" "4" "square,edge2"]
1874
+	Pad[-11150 30250 -11150 34850 1500 3000 2100 "5" "5" "square,edge2"]
1875
+	Pad[-7950 30250 -7950 34850 1500 3000 2100 "6" "6" "square,edge2"]
1876
+	Pad[-4850 30250 -4850 34850 1500 3000 2100 "7" "7" "square,edge2"]
1877
+	Pad[-1650 30250 -1650 34850 1500 3000 2100 "8" "8" "square,edge2"]
1878
+	Pad[1450 30250 1450 34850 1500 3000 2100 "9" "9" "square,edge2"]
1879
+	Pad[4650 30250 4650 34850 1500 3000 2100 "10" "10" "square,edge2"]
1880
+	Pad[7750 30250 7750 34850 1500 3000 2100 "11" "11" "square,edge2"]
1881
+	Pad[10950 30250 10950 34850 1500 3000 2100 "12" "12" "square,edge2"]
1882
+	Pad[14050 30250 14050 34850 1500 3000 2100 "13" "13" "square,edge2"]
1883
+	Pad[17250 30250 17250 34850 1500 3000 2100 "14" "14" "square,edge2"]
1884
+	Pad[20350 30250 20350 34850 1500 3000 2100 "15" "15" "square,edge2"]
1885
+	Pad[23550 30250 23550 34850 1500 3000 2100 "16" "16" "square,edge2"]
1886
+	Pad[30250 23650 34850 23650 1500 3000 2100 "17" "17" "square,edge2"]
1887
+	Pad[30250 20550 34850 20550 1500 3000 2100 "18" "18" "square,edge2"]
1888
+	Pad[30250 17450 34850 17450 1500 3000 2100 "19" "19" "square,edge2"]
1889
+	Pad[30250 14250 34850 14250 1500 3000 2100 "20" "20" "square,edge2"]
1890
+	Pad[30250 11150 34850 11150 1500 3000 2100 "21" "21" "square,edge2"]
1891
+	Pad[30250 7950 34850 7950 1500 3000 2100 "22" "22" "square,edge2"]
1892
+	Pad[30250 4850 34850 4850 1500 3000 2100 "23" "23" "square,edge2"]
1893
+	Pad[30250 1650 34850 1650 1500 3000 2100 "24" "24" "square,edge2"]
1894
+	Pad[30250 -1450 34850 -1450 1500 3000 2100 "25" "25" "square,edge2"]
1895
+	Pad[30250 -4650 34850 -4650 1500 3000 2100 "26" "26" "square,edge2"]
1896
+	Pad[30250 -7750 34850 -7750 1500 3000 2100 "27" "27" "square,edge2"]
1897
+	Pad[30250 -10950 34850 -10950 1500 3000 2100 "28" "28" "square,edge2"]
1898
+	Pad[30250 -14050 34850 -14050 1500 3000 2100 "29" "29" "square,edge2"]
1899
+	Pad[30250 -17250 34850 -17250 1500 3000 2100 "30" "30" "square,edge2"]
1900
+	Pad[30250 -20350 34850 -20350 1500 3000 2100 "31" "31" "square,edge2"]
1901
+	Pad[30250 -23550 34850 -23550 1500 3000 2100 "32" "32" "square,edge2"]
1902
+	Pad[23650 -34850 23650 -30250 1500 3000 2100 "33" "33" "square"]
1903
+	Pad[20550 -34850 20550 -30250 1500 3000 2100 "34" "34" "square"]
1904
+	Pad[17450 -34850 17450 -30250 1500 3000 2100 "35" "35" "square"]
1905
+	Pad[14250 -34850 14250 -30250 1500 3000 2100 "36" "36" "square"]
1906
+	Pad[11150 -34850 11150 -30250 1500 3000 2100 "37" "37" "square"]
1907
+	Pad[7950 -34850 7950 -30250 1500 3000 2100 "38" "38" "square"]
1908
+	Pad[4850 -34850 4850 -30250 1500 3000 2100 "39" "39" "square"]
1909
+	Pad[1650 -34850 1650 -30250 1500 3000 2100 "40" "40" "square"]
1910
+	Pad[-1450 -34850 -1450 -30250 1500 3000 2100 "41" "41" "square"]
1911
+	Pad[-4650 -34850 -4650 -30250 1500 3000 2100 "42" "42" "square"]
1912
+	Pad[-7750 -34850 -7750 -30250 1500 3000 2100 "43" "43" "square"]
1913
+	Pad[-10950 -34850 -10950 -30250 1500 3000 2100 "44" "44" "square"]
1914
+	Pad[-14050 -34850 -14050 -30250 1500 3000 2100 "45" "45" "square"]
1915
+	Pad[-17250 -34850 -17250 -30250 1500 3000 2100 "46" "46" "square"]
1916
+	Pad[-20350 -34850 -20350 -30250 1500 3000 2100 "47" "47" "square"]
1917
+	Pad[-23550 -34850 -23550 -30250 1500 3000 2100 "48" "48" "square"]
1918
+	Pad[-34850 -23650 -30250 -23650 1500 3000 2100 "49" "49" "square"]
1919
+	Pad[-34850 -20550 -30250 -20550 1500 3000 2100 "50" "50" "square"]
1920
+	Pad[-34850 -17450 -30250 -17450 1500 3000 2100 "51" "51" "square"]
1921
+	Pad[-34850 -14250 -30250 -14250 1500 3000 2100 "52" "52" "square"]
1922
+	Pad[-34850 -11150 -30250 -11150 1500 3000 2100 "53" "53" "square"]
1923
+	Pad[-34850 -7950 -30250 -7950 1500 3000 2100 "54" "54" "square"]
1924
+	Pad[-34850 -4850 -30250 -4850 1500 3000 2100 "55" "55" "square"]
1925
+	Pad[-34850 -1650 -30250 -1650 1500 3000 2100 "56" "56" "square"]
1926
+	Pad[-34850 1450 -30250 1450 1500 3000 2100 "57" "57" "square"]
1927
+	Pad[-34850 4650 -30250 4650 1500 3000 2100 "58" "58" "square"]
1928
+	Pad[-34850 7750 -30250 7750 1500 3000 2100 "59" "59" "square"]
1929
+	Pad[-34850 10950 -30250 10950 1500 3000 2100 "60" "60" "square"]
1930
+	Pad[-34850 14050 -30250 14050 1500 3000 2100 "61" "61" "square"]
1931
+	Pad[-34850 17250 -30250 17250 1500 3000 2100 "62" "62" "square"]
1932
+	Pad[-34850 20350 -30250 20350 1500 3000 2100 "63" "63" "square"]
1933
+	Pad[-34850 23550 -30250 23550 1500 3000 2100 "64" "64" "square"]
1934
+	ElementLine [-27550 -27550 -27550 24750 1000]
1935
+	ElementLine [-27550 -27550 27550 -27550 1000]
1936
+	ElementLine [27550 -27550 27550 27550 1000]
1937
+	ElementLine [-24750 27550 27550 27550 1000]
1938
+	ElementLine [-24750 27550 -27550 24750 1000]
1939
+	ElementArc [-24050 24050 1000 1000 90 360 1000]
1940
+
1941
+	)
1942
+
1943
+Element["" "SMD 0805" "C8" "0805" 350000 330000 -5000 4500 0 100 ""]
1944
+(
1945
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "1" "1" "square"]
1946
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "2" "2" "square"]
1947
+	ElementLine [6000 -4500 6000 4500 1000]
1948
+	ElementLine [-6000 -4500 6000 -4500 1000]
1949
+	ElementLine [-6000 -4500 -6000 4500 1000]
1950
+	ElementLine [-6000 4500 6000 4500 1000]
1951
+
1952
+	)
1953
+
1954
+Element["" "crystal HC18" "X2" "HC18" 270000 245000 -2500 12000 0 100 ""]
1955
+(
1956
+	Pin[0 0 6000 3000 6600 3000 "1" "1" ""]
1957
+	Pin[0 -20000 6000 3000 6600 3000 "2" "2" ""]
1958
+	ElementLine [-10000 -20000 -10000 0 1000]
1959
+	ElementLine [10000 -20000 10000 0 1000]
1960
+	ElementArc [0 0 10000 10000 0 180 1000]
1961
+	ElementArc [0 -20000 10000 10000 180 180 1000]
1962
+
1963
+	)
1964
+
1965
+Element["" "SMD 0805" "R2" "0805" 270000 375000 -2500 7000 0 100 ""]
1966
+(
1967
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
1968
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
1969
+	ElementLine [-4500 6000 4500 6000 1000]
1970
+	ElementLine [4500 -6000 4500 6000 1000]
1971
+	ElementLine [-4500 -6000 4500 -6000 1000]
1972
+	ElementLine [-4500 -6000 -4500 6000 1000]
1973
+
1974
+	)
1975
+
1976
+Element["" "SMD 0805" "R3" "0805" 350000 375000 -5000 4500 0 100 ""]
1977
+(
1978
+	Pad[-3200 -1700 -3200 1700 3600 3000 4200 "1" "1" "square"]
1979
+	Pad[3200 -1700 3200 1700 3600 3000 4200 "2" "2" "square"]
1980
+	ElementLine [-6000 -4500 -6000 4500 1000]
1981
+	ElementLine [-6000 4500 6000 4500 1000]
1982
+	ElementLine [6000 4500 6000 -4500 1000]
1983
+	ElementLine [6000 -4500 -6000 -4500 1000]
1984
+
1985
+	)
1986
+
1987
+Element["" "SMD LED 0603" "LED2" "0603" 385000 125000 -5200 -11200 0 100 ""]
1988
+(
1989
+	Pad[-900 2400 900 2400 2400 2000 3000 "K" "1" "square"]
1990
+	Pad[-900 -2400 900 -2400 2400 2000 3000 "A" "2" "square"]
1991
+	ElementLine [-4200 4200 4200 4200 1000]
1992
+	ElementLine [2700 4200 4200 -4200 1000]
1993
+	ElementLine [-4200 -4200 4200 -4200 1000]
1994
+	ElementLine [-4200 -4200 -2700 4200 1000]
1995
+
1996
+	)
1997
+
1998
+Element["" "SMD LED 0603" "LED3" "0603" 400000 125000 -5200 -11200 0 100 ""]
1999
+(
2000
+	Pad[-900 2400 900 2400 2400 2000 3000 "K" "1" "square"]
2001
+	Pad[-900 -2400 900 -2400 2400 2000 3000 "A" "2" "square"]
2002
+	ElementLine [-4200 4200 4200 4200 1000]
2003
+	ElementLine [2700 4200 4200 -4200 1000]
2004
+	ElementLine [-4200 -4200 4200 -4200 1000]
2005
+	ElementLine [-4200 -4200 -2700 4200 1000]
2006
+
2007
+	)
2008
+
2009
+Element["" "SMD LED 0603" "LED4" "0603" 415000 125000 -5200 -11200 0 100 ""]
2010
+(
2011
+	Pad[-900 2400 900 2400 2400 2000 3000 "K" "1" "square"]
2012
+	Pad[-900 -2400 900 -2400 2400 2000 3000 "A" "2" "square"]
2013
+	ElementLine [-4200 4200 4200 4200 1000]
2014
+	ElementLine [2700 4200 4200 -4200 1000]
2015
+	ElementLine [-4200 -4200 4200 -4200 1000]
2016
+	ElementLine [-4200 -4200 -2700 4200 1000]
2017
+
2018
+	)
2019
+
2020
+Element["" "SMD 0805" "R10" "0805" 415000 140000 -2500 7000 0 100 ""]
2021
+(
2022
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
2023
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
2024
+	ElementLine [-4500 6000 4500 6000 1000]
2025
+	ElementLine [4500 -6000 4500 6000 1000]
2026
+	ElementLine [-4500 -6000 4500 -6000 1000]
2027
+	ElementLine [-4500 -6000 -4500 6000 1000]
2028
+
2029
+	)
2030
+
2031
+Element["" "SMD 0805" "R8" "0805" 385000 140000 -2500 7000 0 100 ""]
2032
+(
2033
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
2034
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
2035
+	ElementLine [-4500 6000 4500 6000 1000]
2036
+	ElementLine [4500 -6000 4500 6000 1000]
2037
+	ElementLine [-4500 -6000 4500 -6000 1000]
2038
+	ElementLine [-4500 -6000 -4500 6000 1000]
2039
+
2040
+	)
2041
+
2042
+Element["" "SMD 0805" "R9" "0805" 400000 140000 -2500 7000 0 100 ""]
2043
+(
2044
+	Pad[-1700 3200 1700 3200 3600 3000 4200 "1" "1" "square"]
2045
+	Pad[-1700 -3200 1700 -3200 3600 3000 4200 "2" "2" "square"]
2046
+	ElementLine [-4500 6000 4500 6000 1000]
2047
+	ElementLine [4500 -6000 4500 6000 1000]
2048
+	ElementLine [-4500 -6000 4500 -6000 1000]
2049
+	ElementLine [-4500 -6000 -4500 6000 1000]
2050
+
2051
+	)
2052
+
2053
+Element["" "DC power connector" "CON1" "HEBW25" 80000 398937 18500 26000 0 150 ""]
2054
+(
2055
+	Pin[0 -24409 18000 3000 18600 11811 "inner" "1" ""]
2056
+	Pin[20472 -12205 16000 3000 16600 9448 "outer" "2" ""]
2057
+	Pin[0 0 16000 3000 16600 9448 "outer" "2" ""]
2058
+	ElementLine [-16000 -24000 16000 -24000 2000]
2059
+	ElementLine [-16000 -24000 -16000 30000 2000]
2060
+	ElementLine [16000 -24000 16000 30000 2000]
2061
+	ElementLine [-16000 30000 16000 30000 2000]
2062
+	ElementLine [-12500 -14000 -12500 30000 1000]
2063
+	ElementLine [12500 -14000 12500 30000 1000]
2064
+	ElementLine [-12500 -14000 12500 -14000 1000]
2065
+	ElementLine [-5000 -14000 -5000 26000 1000]
2066
+	ElementLine [5000 -14000 5000 26000 1000]
2067
+	ElementLine [-5000 26000 5000 26000 1000]
2068
+
2069
+	)
2070
+Layer(1 "component")
2071
+(
2072
+	Line[100000 350000 115000 365000 8000 2300 "clearline"]
2073
+	Line[115000 365000 140000 365000 8000 2300 "clearline"]
2074
+	Line[140000 365000 145000 360000 8000 2300 "clearline"]
2075
+	Line[145000 360000 145000 355000 8000 2300 "clearline"]
2076
+	Line[92500 252500 85000 252500 2000 2300 "clearline"]
2077
+	Line[95000 257500 97500 255000 2000 2300 "clearline"]
2078
+	Line[105000 325000 105000 275000 20000 2300 "clearline,rubberend"]
2079
+	Line[85000 247500 92500 247500 2000 2300 "clearline"]
2080
+	Line[80000 257500 95000 257500 2000 2300 "clearline"]
2081
+	Line[87500 325000 87500 275000 20000 2300 "clearline"]
2082
+	Line[75000 252500 80000 257500 2000 2300 "clearline"]
2083
+	Line[85000 237500 70000 237500 2000 2300 "clearline"]
2084
+	Line[70000 232500 85000 232500 2000 2300 "clearline"]
2085
+	Line[85000 227500 80000 227500 2000 2300 "clearline"]
2086
+	Line[80000 227500 75000 222500 2000 2300 "clearline"]
2087
+	Line[75000 222500 70000 222500 2000 2300 "clearline"]
2088
+	Line[70000 217500 85000 217500 2000 2300 "clearline"]
2089
+	Line[85000 242500 80000 242500 2000 2300 "clearline"]
2090
+	Line[80000 242500 75000 247500 2000 2300 "clearline"]
2091
+	Line[75000 247500 70000 247500 2000 2300 "clearline"]
2092
+	Line[85000 222500 90000 222500 2000 2300 "clearline"]
2093
+	Line[90000 222500 92500 220000 2000 2300 "clearline"]
2094
+	Line[92500 220000 92500 215000 2000 2300 "clearline"]
2095
+	Line[92500 215000 90000 212500 2000 2300 "clearline"]
2096
+	Line[90000 212500 85000 212500 2000 2300 "clearline"]
2097
+	Line[85000 212500 82500 210000 2000 2300 "clearline"]
2098
+	Line[82500 210000 82500 205000 2000 2300 "clearline"]
2099
+	Line[107500 217500 107500 205000 2000 2300 "clearline"]
2100
+	Line[87500 205000 102500 205000 2000 2300 "clearline"]
2101
+	Line[97500 205000 97500 222500 2000 2300 "clearline"]
2102
+	Line[97500 255000 97500 222500 2000 2300 "clearline"]
2103
+	Line[97500 222500 105000 222500 2000 2300 "clearline"]
2104
+	Line[110000 205000 130000 205000 4000 2300 "clearline"]
2105
+	Line[270000 372500 270000 365000 2000 2300 "clearline"]
2106
+	Line[270000 365000 272500 362500 2000 2300 "clearline"]
2107
+	Line[100000 205000 100000 195000 4000 2300 "clearline,rubberend"]
2108
+	Line[145000 237500 145000 220000 8000 2300 "clearline"]
2109
+	Line[272500 362500 272500 355000 2000 2300 "clearline"]
2110
+	Line[272750 349850 272750 354750 1500 2300 "clearline"]
2111
+	Line[272750 354750 272500 355000 1500 2300 "clearline"]
2112
+	Line[70000 252500 75000 252500 2000 2300 "clearline"]
2113
+	Line[70000 275000 70000 325000 20000 2300 "clearline"]
2114
+	Line[70000 275000 105000 275000 20000 2300 "clearline"]
2115
+	Line[105000 325000 70000 325000 20000 2300 "clearline"]
2116
+	Line[115000 195000 77500 195000 4000 2300 "clearline"]
2117
+	Line[115000 232500 105000 232500 2000 2300 "clearline"]
2118
+	Line[105000 227500 115000 227500 2000 2300 "clearline"]
2119
+	Line[35000 180000 62500 180000 4000 2300 "clearline"]
2120
+	Line[62500 180000 77500 195000 4000 2300 "clearline"]
2121
+	Line[112500 125000 115000 125000 2000 2300 "clearline"]
2122
+	Line[115000 117500 110000 117500 4000 2300 "clearline"]
2123
+	Line[320000 142500 320000 130000 2000 2300 "clearline"]
2124
+	Line[320000 87500 320000 102500 2000 2300 "clearline"]
2125
+	Line[135000 162500 133750 161250 1500 2300 "clearline"]
2126
+	Line[110000 130000 114000 130000 2000 2300 "clearline"]
2127
+	Line[185000 207500 157500 180000 2000 2300 "clearline"]
2128
+	Line[130000 132500 115000 117500 4000 2300 "clearline,rubberend"]
2129
+	Line[121250 137250 119000 135000 1500 2300 "clearline"]
2130
+	Line[116250 146929 116250 145250 1500 2300 "clearline"]
2131
+	Line[116250 145250 113000 142000 1500 2300 "clearline"]
2132
+	Line[121250 146929 121250 137250 1500 2300 "clearline"]
2133
+	Line[425000 150000 407500 167500 4000 2300 "clearline"]
2134
+	Line[425000 127500 425000 150000 4000 2300 "clearline"]
2135
+	Line[287500 60000 287500 62500 2000 2300 "clearline"]
2136
+	Line[287500 62500 292500 67500 2000 2300 "clearline"]
2137
+	Line[280750 188250 277500 185000 1500 2300 "clearline"]
2138
+	Line[270000 150000 320000 150000 4000 2300 "clearline"]
2139
+	Line[150000 270000 157500 270000 4000 2300 "clearline"]
2140
+	Line[157500 270000 177500 290000 4000 2300 "clearline"]
2141
+	Line[197500 290000 202500 290000 4000 2300 "clearline"]
2142
+	Line[177500 290000 177500 295000 4000 2300 "clearline"]
2143
+	Line[130000 270000 140000 280000 4000 2300 "clearline"]
2144
+	Line[140000 280000 155000 280000 4000 2300 "clearline"]
2145
+	Line[192500 295000 197500 290000 4000 2300 "clearline"]
2146
+	Line[155000 280000 162500 287500 4000 2300 "clearline"]
2147
+	Line[162500 300000 167500 305000 4000 2300 "clearline"]
2148
+	Line[207500 295000 202500 290000 4000 2300 "clearline"]
2149
+	Line[305550 166650 305550 163050 1500 2300 "clearline"]
2150
+	Line[302950 165450 300000 162500 1500 2300 "clearline"]
2151
+	Line[230150 303850 221350 303850 2000 2300 "clearline"]
2152
+	Line[241350 345150 241350 345250 1500 2300 "clearline"]
2153
+	Line[221350 303850 220000 302500 2000 2300 "clearline"]
2154
+	Line[207500 297500 220000 297500 2000 2300 "clearline"]
2155
+	Line[220000 297500 223250 300750 2000 2300 "clearline"]
2156
+	Line[115000 252500 108500 252500 2000 2300 "clearline"]
2157
+	Line[299850 316650 318350 316650 2000 2300 "clearline"]
2158
+	Line[318350 316650 325000 310000 2000 2300 "clearline"]
2159
+	Line[314850 319850 299850 319850 2000 2300 "clearline"]
2160
+	Line[325000 330000 347500 330000 2000 2300 "clearline"]
2161
+	Line[325000 330000 314850 319850 2000 2300 "clearline"]
2162
+	Line[325000 310000 347500 310000 2000 2300 "clearline"]
2163
+	Line[350000 337500 352500 335000 2000 2300 "clearline"]
2164
+	Line[299850 322950 307950 322950 2000 2300 "clearline"]
2165
+	Line[307950 322950 315000 330000 2000 2300 "clearline"]
2166
+	Line[303650 326150 310000 332500 2000 2300 "clearline"]
2167
+	Line[352500 310000 352500 335000 2000 2300 "clearline"]
2168
+	Line[299850 326150 303650 326150 2000 2300 "clearline"]
2169
+	Line[310000 332500 310000 355000 2000 2300 "clearline"]
2170
+	Line[350000 337500 315000 337500 2000 2300 "clearline"]
2171
+	Line[315000 355000 315000 330000 2000 2300 "clearline"]
2172
+	Line[317500 365000 317500 355000 4000 2300 "clearline"]
2173
+	Line[307500 355000 307500 385000 4000 2300 "clearline"]
2174
+	Line[307500 385000 277500 415000 4000 2300 "clearline"]
2175
+	Line[277500 415000 270000 415000 4000 2300 "clearline"]
2176
+	Line[330000 130000 360000 130000 2000 2300 "clearline"]
2177
+	Line[320000 67500 330000 77500 2000 2300 "clearline"]
2178
+	Line[330000 77500 330000 100000 2000 2300 "clearline"]
2179
+	Line[270000 80000 320000 80000 4000 2300 "clearline"]
2180
+	Line[362500 122500 312500 122500 2000 2300 "clearline"]
2181
+	Line[312500 122500 310000 125000 2000 2300 "clearline"]
2182
+	Line[310000 125000 310000 130000 2000 2300 "clearline"]
2183
+	Line[312500 250000 307500 250000 2000 2300 "clearline"]
2184
+	Line[170500 260000 122500 260000 2000 2300 "clearline"]
2185
+	Line[397500 192500 402500 192500 2000 2300 "clearline"]
2186
+	Line[402500 210000 397500 210000 2000 2300 "clearline"]
2187
+	Line[301200 245000 300000 245000 1500 2300 "clearline,rubberend"]
2188
+	Line[302850 243350 301200 245000 1500 2300 "clearline,rubberend"]
2189
+	Line[286750 229250 285000 227500 1500 2300 "clearline"]
2190
+	Line[289850 229250 286750 229250 1500 2300 "clearline"]
2191
+	Line[395000 222500 395000 216000 2000 2300 "clearline"]
2192
+	Line[407500 215000 410000 212500 2000 2300 "clearline"]
2193
+	Line[410000 212500 410000 195000 2000 2300 "clearline"]
2194
+	Line[410000 195000 407500 192500 2000 2300 "clearline"]
2195
+	Line[217500 277500 202000 262000 2000 2300 "clearline"]
2196
+	Line[217500 290000 217500 277500 2000 2300 "clearline"]
2197
+	Line[230150 294450 226950 294450 2000 2300 "clearline"]
2198
+	Line[225050 297550 217500 290000 2000 2300 "clearline"]
2199
+	Line[223250 300750 230150 300750 2000 2300 "clearline"]
2200
+	Line[230150 297550 225050 297550 2000 2300 "clearline"]
2201
+	Line[305350 247850 307500 250000 1500 2300 "clearline"]
2202
+	Line[305350 243350 305350 247850 1500 2300 "clearline"]
2203
+	Line[173500 263000 170500 260000 2000 2300 "clearline"]
2204
+	Line[122500 260000 115000 252500 2000 2300 "clearline"]
2205
+	Line[320000 267500 322500 265000 4000 2300 "clearline,rubberend"]
2206
+	Line[316000 283000 334000 283000 2000 2300 "clearline"]
2207
+	Line[305150 213850 307000 212000 1500 2300 "clearline"]
2208
+	Line[322500 265000 322500 257500 4000 2300 "clearline,rubberend"]
2209
+	Line[402500 227500 402500 217500 4000 2300 "clearline"]
2210
+	Line[402500 202500 402500 207500 4000 2300 "clearline"]
2211
+	Line[294000 359000 297000 356000 2000 2300 "clearline"]
2212
+	Line[269650 349850 269650 353350 1500 2300 "clearline"]
2213
+	Line[275950 349850 275950 353450 1500 2300 "clearline"]
2214
+	Line[275950 353450 277500 355000 1500 2300 "clearline"]
2215
+	Line[279050 349850 279050 351550 1500 2300 "clearline"]
2216
+	Line[232500 375000 225000 382500 2000 2300 "clearline"]
2217
+	Line[225000 382500 225000 400000 2000 2300 "clearline"]
2218
+	Line[225000 400000 230000 405000 2000 2300 "clearline"]
2219
+	Line[167500 350000 167500 355000 2000 2300 "clearline"]
2220
+	Line[167500 355000 170000 357500 2000 2300 "clearline"]
2221
+	Line[232500 385000 252500 365000 2000 2300 "clearline"]
2222
+	Line[252500 365000 252500 355000 2000 2300 "clearline"]
2223
+	Line[250750 349850 250750 353250 1500 2300 "clearline"]
2224
+	Line[250750 353250 252500 355000 1500 2300 "clearline"]
2225
+	Line[336250 174750 336250 179000 1500 2300 "clearline"]
2226
+	Line[338850 174750 338850 179000 1500 2300 "clearline"]
2227
+	Line[341350 174750 341350 179000 1500 2300 "clearline"]
2228
+	Line[347500 185000 347000 185000 1500 2300 "clearline,rubberend"]
2229
+	Line[331500 182500 334000 185000 2000 2300 "clearline"]
2230
+	Line[347000 185000 334000 185000 2000 2300 "clearline"]
2231
+	Line[329500 187500 331000 189000 2000 2300 "clearline"]
2232
+	Line[348500 189000 348000 189000 1500 2300 "clearline"]
2233
+	Line[331000 189000 348000 189000 2000 2300 "clearline,rubberend"]
2234
+	Line[336250 179000 344000 179000 2000 2300 "clearline"]
2235
+	Line[344000 179000 345000 180000 2000 2300 "clearline"]
2236
+	Line[364450 166650 364450 162450 1500 2300 "clearline"]
2237
+	Line[363000 161000 364000 162000 2000 2300 "clearline"]
2238
+	Line[358000 161000 363000 161000 2000 2300 "clearline"]
2239
+	Line[364000 162000 381000 162000 2000 2300 "clearline"]
2240
+	Line[381000 162000 395000 176000 2000 2300 "clearline"]
2241
+	Line[397000 210000 396000 209000 2000 2300 "clearline"]
2242
+	Line[396000 209000 396000 206000 2000 2300 "clearline"]
2243
+	Line[390000 209000 396000 209000 1500 2300 "clearline"]
2244
+	Line[323000 257000 337000 257000 2000 2300 "clearline"]
2245
+	Line[337000 257000 341000 253000 2000 2300 "clearline"]
2246
+	Line[72500 170000 82500 180000 4000 2300 "clearline"]
2247
+	Line[115000 195000 115000 180000 4000 2300 "clearline"]
2248
+	Line[82500 165000 120000 165000 4000 2300 "clearline"]
2249
+	Line[120000 165000 130000 175000 4000 2300 "clearline"]
2250
+	Line[130000 175000 130000 205000 4000 2300 "clearline"]
2251
+	Line[145000 220000 130000 205000 8000 2300 "clearline"]
2252
+	Line[226950 294450 222500 290000 2000 2300 "clearline"]
2253
+	Line[222500 290000 222500 277500 2000 2300 "clearline"]
2254
+	Line[285000 227500 282500 225000 2000 2300 "clearline"]
2255
+	Line[247500 225000 282500 225000 2000 2300 "clearline"]
2256
+	Line[222500 277500 206000 261000 2000 2300 "clearline"]
2257
+	Line[242500 245000 242500 220000 2000 2300 "clearline"]
2258
+	Line[242500 220000 245000 217500 2000 2300 "clearline"]
2259
+	Line[338650 243350 338650 245650 1500 2300 "clearline"]
2260
+	Line[225000 370000 220000 375000 4000 2300 "clearline"]
2261
+	Line[220000 375000 220000 410000 4000 2300 "clearline"]
2262
+	Line[220000 410000 225000 415000 4000 2300 "clearline"]
2263
+	Line[225000 415000 230000 415000 4000 2300 "clearline"]
2264
+	Line[108500 237500 122500 237500 2000 2300 "clearline"]
2265
+	Line[122500 237500 130000 245000 2000 2300 "clearline"]
2266
+	Line[130000 245000 160000 245000 2000 2300 "clearline"]
2267
+	Line[160000 250000 127500 250000 2000 2300 "clearline"]
2268
+	Line[127500 250000 120000 242500 2000 2300 "clearline"]
2269
+	Line[120000 242500 108500 242500 2000 2300 "clearline"]
2270
+	Line[108500 247500 117500 247500 2000 2300 "clearline"]
2271
+	Line[117500 247500 125000 255000 2000 2300 "clearline"]
2272
+	Line[390150 191050 396050 191050 1500 2300 "clearline"]
2273
+	Line[396050 191050 397500 192500 1500 2300 "clearline"]
2274
+	Line[396000 215000 407500 215000 2000 2300 "clearline"]
2275
+	Line[396000 215000 395000 216000 2000 2300 "clearline"]
2276
+	Line[393250 224250 395000 222500 1500 2300 "clearline"]
2277
+	Line[390150 224250 393250 224250 1500 2300 "clearline"]
2278
+	Line[390150 216650 395000 216650 1500 2300 "clearline"]
2279
+	Line[395000 176000 395000 186000 2000 2300 "clearline"]
2280
+	Line[247500 245000 300000 245000 2000 2300 "clearline"]
2281
+	Line[315000 257500 315000 252500 2000 2300 "clearline"]
2282
+	Line[320000 257500 320000 250000 2000 2300 "clearline"]
2283
+	Line[305000 226000 305000 227000 1500 2300 "clearline"]
2284
+	Line[230150 291350 228850 291350 2000 2300 "clearline"]
2285
+	Line[228850 291350 227500 290000 2000 2300 "clearline"]
2286
+	Line[227500 290000 227500 277500 2000 2300 "clearline"]
2287
+	Line[227500 277500 210000 260000 2000 2300 "clearline"]
2288
+	Line[241450 280150 235150 280150 2000 2300 "clearline"]
2289
+	Line[235150 280150 214000 259000 2000 2300 "clearline"]
2290
+	Line[244650 280150 244650 277150 2000 2300 "clearline"]
2291
+	Line[244650 277150 242500 275000 2000 2300 "clearline"]
2292
+	Line[242500 275000 235000 275000 2000 2300 "clearline"]
2293
+	Line[235000 270000 222000 257000 2000 2300 "clearline,rubberend"]
2294
+	Line[254050 271550 254050 280150 2000 2300 "clearline"]
2295
+	Line[235000 270000 242500 270000 2000 2300 "clearline"]
2296
+	Line[242500 270000 247750 275250 2000 2300 "clearline"]
2297
+	Line[247750 275250 247750 280150 2000 2300 "clearline"]
2298
+	Line[250950 280150 250950 273450 2000 2300 "clearline"]
2299
+	Line[250950 273450 242500 265000 2000 2300 "clearline"]
2300
+	Line[242500 265000 235000 265000 2000 2300 "clearline"]
2301
+	Line[226000 221000 226000 256000 2000 2300 "clearline"]
2302
+	Line[230000 255000 235000 260000 2000 2300 "clearline"]
2303
+	Line[235000 260000 242500 260000 2000 2300 "clearline"]
2304
+	Line[242500 260000 254050 271550 2000 2300 "clearline"]
2305
+	Line[235000 275000 218000 258000 2000 2300 "clearline"]
2306
+	Line[202000 227000 202000 262000 2000 2300 "clearline"]
2307
+	Line[226000 221000 225000 220000 2000 2300 "clearline"]
2308
+	Line[206000 226000 206000 261000 2000 2300 "clearline"]
2309
+	Line[260000 177500 202500 177500 2000 2300 "clearline"]
2310
+	Line[351450 243350 351450 246550 1500 2300 "clearline"]
2311
+	Line[222000 222000 222000 257000 2000 2300 "clearline,rubberend"]
2312
+	Line[341000 253000 341000 248000 2000 2300 "clearline"]
2313
+	Line[205000 192500 205000 195000 2000 2300 "clearline"]
2314
+	Line[273450 195950 267500 190000 1500 2300 "clearline"]
2315
+	Line[289850 193350 275850 193350 1500 2300 "clearline"]
2316
+	Line[289850 195950 273450 195950 1500 2300 "clearline"]
2317
+	Line[260000 197500 266150 203650 1500 2300 "clearline"]
2318
+	Line[289850 198550 271050 198550 1500 2300 "clearline"]
2319
+	Line[263650 206150 260000 202500 1500 2300 "clearline"]
2320
+	Line[302950 166650 302950 165450 1500 2300 "clearline"]
2321
+	Line[289850 203650 266150 203650 1500 2300 "clearline"]
2322
+	Line[289850 206150 263650 206150 1500 2300 "clearline"]
2323
+	Line[267500 190000 260000 182500 2000 2300 "clearline"]
2324
+	Line[289850 208750 261250 208750 1500 2300 "clearline"]
2325
+	Line[271050 198550 262500 190000 1500 2300 "clearline"]
2326
+	Line[260000 207500 261250 208750 1500 2300 "clearline"]
2327
+	Line[268550 201050 260000 192500 1500 2300 "clearline"]
2328
+	Line[289850 211350 268850 211350 1500 2300 "clearline"]
2329
+	Line[268850 211350 258850 211350 1500 2300 "clearline,rubberend"]
2330
+	Line[341000 248000 350000 248000 2000 2300 "clearline"]
2331
+	Line[338650 245650 341000 248000 1500 2300 "clearline"]
2332
+	Line[351450 246550 350000 248000 1500 2300 "clearline"]
2333
+	Line[305350 232650 308000 230000 1500 2300 "clearline"]
2334
+	Line[308000 230000 309000 230000 1500 2300 "clearline"]
2335
+	Line[297950 221550 300550 221550 1500 2300 "clearline"]
2336
+	Line[214000 224000 214000 259000 2000 2300 "clearline"]
2337
+	Line[300550 221550 305000 226000 1500 2300 "clearline"]
2338
+	Line[320000 250000 318000 248000 2000 2300 "clearline"]
2339
+	Line[299850 183150 301000 182000 1500 2300 "clearline"]
2340
+	Line[297950 183150 299850 183150 1500 2300 "clearline"]
2341
+	Line[303000 178000 333000 178000 1500 2300 "clearline"]
2342
+	Line[333000 178000 334000 179000 1500 2300 "clearline"]
2343
+	Line[334000 179000 336000 179000 1500 2300 "clearline"]
2344
+	Line[301000 182000 301000 180000 1500 2300 "clearline"]
2345
+	Line[167500 325000 167500 305000 2000 2300 "clearline"]
2346
+	Line[301000 180000 303000 178000 1500 2300 "clearline"]
2347
+	Line[297950 180650 301000 180650 1500 2300 "clearline"]
2348
+	Line[335000 410000 335000 408000 2000 2300 "clearline"]
2349
+	Line[335000 410000 330000 415000 2000 2300 "clearline"]
2350
+	Line[360000 382000 360000 405000 2000 2300 "clearline"]
2351
+	Line[215000 192500 215000 195000 2000 2300 "clearline"]
2352
+	Line[260000 192500 225000 192500 2000 2300 "clearline"]
2353
+	Line[218000 223000 218000 258000 2000 2300 "clearline"]
2354
+	Line[260000 207500 230000 207500 2000 2300 "clearline"]
2355
+	Line[257500 157500 300000 157500 2000 2300 "clearline"]
2356
+	Line[167500 330000 167500 345000 2000 2300 "clearline"]
2357
+	Line[222500 207500 210000 195000 2000 2300 "clearline"]
2358
+	Line[289850 201050 268550 201050 1500 2300 "clearline"]
2359
+	Line[258850 211350 257500 212500 1500 2300 "clearline,rubberend"]
2360
+	Line[162500 287500 162500 300000 4000 2300 "clearline"]
2361
+	Line[207500 305000 167500 305000 4000 2300 "clearline,rubberend"]
2362
+	Line[300000 162500 262500 162500 2000 2300 "clearline"]
2363
+	Line[305550 163050 300000 157500 1500 2300 "clearline"]
2364
+	Line[260000 202500 222500 202500 2000 2300 "clearline"]
2365
+	Line[272500 190000 260000 177500 2000 2300 "clearline"]
2366
+	Line[262500 190000 260000 187500 2000 2300 "clearline"]
2367
+	Line[275850 193350 272500 190000 1500 2300 "clearline"]
2368
+	Line[260000 182500 202500 182500 2000 2300 "clearline"]
2369
+	Line[260000 187500 202500 187500 2000 2300 "clearline"]
2370
+	Line[220000 195000 222500 197500 2000 2300 "clearline"]
2371
+	Line[335000 408000 335000 402000 1500 2300 "clearline"]
2372
+	Line[330000 405000 330000 346000 2000 2300 "clearline"]
2373
+	Line[282500 355000 290000 355000 2000 2300 "clearline"]
2374
+	Line[290000 355000 295000 350000 2000 2300 "clearline"]
2375
+	Line[255000 167500 255000 160000 2000 2300 "clearline"]
2376
+	Line[255000 160000 257500 157500 2000 2300 "clearline"]
2377
+	Line[230000 212500 230000 255000 2000 2300 "clearline"]
2378
+	Line[230000 207500 222500 207500 2000 2300 "clearline"]
2379
+	Line[220000 192500 220000 195000 2000 2300 "clearline"]
2380
+	Line[295000 350000 297000 350000 2000 2300 "clearline"]
2381
+	Line[257500 212500 222500 212500 2000 2300 "clearline"]
2382
+	Line[260000 197500 222500 197500 2000 2300 "clearline"]
2383
+	Line[205000 195000 222500 212500 2000 2300 "clearline"]
2384
+	Line[210000 195000 210000 192500 2000 2300 "clearline"]
2385
+	Line[215000 195000 222500 202500 2000 2300 "clearline"]
2386
+	Line[197000 222000 197000 204500 2000 2300 "clearline"]
2387
+	Line[205000 202500 200000 197500 2000 2300 "clearline"]
2388
+	Line[220000 220000 220000 217500 2000 2300 "clearline"]
2389
+	Line[200000 190000 202500 187500 2000 2300 "clearline"]
2390
+	Line[202500 182500 195000 190000 2000 2300 "clearline"]
2391
+	Line[215000 220000 215000 212500 2000 2300 "clearline"]
2392
+	Line[351650 162000 308150 162000 2000 2300 "clearline"]
2393
+	Line[210000 220000 210000 207500 2000 2300 "clearline"]
2394
+	Line[206000 226000 201000 221000 2000 2300 "clearline"]
2395
+	Line[190000 190000 202500 177500 2000 2300 "clearline"]
2396
+	Line[277500 355000 277500 356500 2000 2300 "clearline"]
2397
+	Line[202500 172500 185000 190000 2000 2300 "clearline"]
2398
+	Line[277500 356500 280000 359000 2000 2300 "clearline"]
2399
+	Line[180000 197500 180000 190000 2000 2300 "clearline"]
2400
+	Line[280000 359000 294000 359000 2000 2300 "clearline"]
2401
+	Line[269650 353350 268000 355000 1500 2300 "clearline"]
2402
+	Line[268000 355000 267000 356000 2000 2300 "clearline"]
2403
+	Line[299850 329250 301250 329250 1500 2300 "clearline"]
2404
+	Line[301250 329250 304000 332000 1500 2300 "clearline"]
2405
+	Line[304000 332000 304000 346000 2000 2300 "clearline"]
2406
+	Line[304000 346000 302000 348000 2000 2300 "clearline"]
2407
+	Line[302000 348000 302000 359000 2000 2300 "clearline"]
2408
+	Line[292500 380000 292500 368500 2000 2300 "clearline"]
2409
+	Line[114000 130000 119000 135000 2000 2300 "clearline"]
2410
+	Line[185000 190000 185000 197500 2000 2300 "clearline"]
2411
+	Line[180000 170000 180000 190000 2000 2300 "clearline"]
2412
+	Line[157500 170000 157500 180000 2000 2300 "clearline"]
2413
+	Line[115000 125000 122000 132000 2000 2300 "clearline"]
2414
+	Line[133750 161250 133750 155197 1500 2300 "clearline"]
2415
+	Line[307500 362500 304500 362500 2000 2300 "clearline"]
2416
+	Line[313000 228000 313000 221000 2000 2300 "clearline"]
2417
+	Line[304500 362500 298000 369000 2000 2300 "clearline"]
2418
+	Line[323000 214000 315000 214000 2000 2300 "clearline"]
2419
+	Line[298000 369000 298000 375000 2000 2300 "clearline"]
2420
+	Line[279000 378000 270000 378000 2000 2300 "clearline"]
2421
+	Line[340000 375000 347000 375000 2000 2300 "clearline"]
2422
+	Line[353000 375000 360000 382000 2000 2300 "clearline"]
2423
+	Line[335000 402000 335000 342000 2000 2300 "clearline"]
2424
+	Line[366000 381000 367000 382000 2000 2300 "clearline"]
2425
+	Line[363000 422000 367000 418000 2000 2300 "clearline"]
2426
+	Line[350000 405000 350000 394000 2000 2300 "clearline"]
2427
+	Line[350000 394000 345000 389000 2000 2300 "clearline"]
2428
+	Line[360000 415000 355000 410000 2000 2300 "clearline"]
2429
+	Line[245000 217500 282500 217500 2000 2300 "clearline"]
2430
+	Line[282500 217500 285000 215000 2000 2300 "clearline"]
2431
+	Line[285000 215000 286150 213850 1500 2300 "clearline"]
2432
+	Line[286150 213850 289850 213850 1500 2300 "clearline"]
2433
+	Line[315000 219000 315000 214000 2000 2300 "clearline"]
2434
+	Line[313000 212000 315000 214000 2000 2300 "clearline"]
2435
+	Line[305350 235250 305350 232650 1500 2300 "clearline"]
2436
+	Line[249000 336000 260000 336000 1500 2300 "clearline"]
2437
+	Line[335000 230000 335000 226000 2000 2300 "clearline"]
2438
+	Line[370000 140000 370000 130000 2000 2300 "clearline"]
2439
+	Line[195000 190000 195000 197500 2000 2300 "clearline"]
2440
+	Line[205000 220000 205000 202500 2000 2300 "clearline"]
2441
+	Line[193000 205500 193000 223000 2000 2300 "clearline"]
2442
+	Line[195000 197500 201000 203500 2000 2300 "clearline"]
2443
+	Line[189000 206500 189000 224000 2000 2300 "clearline"]
2444
+	Line[197000 204500 190000 197500 2000 2300 "clearline"]
2445
+	Line[181000 208500 181000 226000 2000 2300 "clearline"]
2446
+	Line[210000 225000 205000 220000 2000 2300 "clearline"]
2447
+	Line[170000 197500 181000 208500 2000 2300 "clearline"]
2448
+	Line[201000 221000 201000 203500 2000 2300 "clearline"]
2449
+	Line[355000 400000 355000 389000 2000 2300 "clearline"]
2450
+	Line[202000 227000 197000 222000 2000 2300 "clearline"]
2451
+	Line[355000 410000 355000 400000 1500 2300 "clearline"]
2452
+	Line[200000 197500 200000 190000 2000 2300 "clearline"]
2453
+	Line[235000 265000 226000 256000 2000 2300 "clearline"]
2454
+	Line[222000 222000 220000 220000 2000 2300 "clearline"]
2455
+	Line[218000 223000 215000 220000 2000 2300 "clearline"]
2456
+	Line[214000 224000 210000 220000 2000 2300 "clearline"]
2457
+	Line[225000 220000 225000 217500 2000 2300 "clearline"]
2458
+	Line[190000 197500 190000 190000 2000 2300 "clearline"]
2459
+	Line[185000 197500 193000 205500 2000 2300 "clearline"]
2460
+	Line[180000 197500 189000 206500 2000 2300 "clearline"]
2461
+	Line[170000 197500 135000 162500 2000 2300 "clearline"]
2462
+	Line[185000 207500 185000 225000 2000 2300 "clearline"]
2463
+	Line[248000 337000 249000 336000 1500 2300 "clearline"]
2464
+	Line[243000 337000 248000 337000 1500 2300 "clearline"]
2465
+	Line[350000 415000 350000 418000 2000 2300 "clearline"]
2466
+	Line[210000 225000 210000 260000 2000 2300 "clearline"]
2467
+	Line[241000 302000 240000 302000 1500 2300 "clearline"]
2468
+	Line[197000 227000 193000 223000 2000 2300 "clearline"]
2469
+	Line[197000 227000 197000 283000 2000 2300 "clearline"]
2470
+	Line[192000 227000 189000 224000 2000 2300 "clearline"]
2471
+	Line[192000 227000 192000 273000 2000 2300 "clearline"]
2472
+	Line[187000 227000 185000 225000 2000 2300 "clearline"]
2473
+	Line[187000 227000 187000 268000 2000 2300 "clearline"]
2474
+	Line[182000 227000 181000 226000 2000 2300 "clearline"]
2475
+	Line[313000 221000 315000 219000 2000 2300 "clearline"]
2476
+	Line[307000 212000 313000 212000 2000 2300 "clearline"]
2477
+	Line[297950 213850 305150 213850 1500 2300 "clearline"]
2478
+	Line[336050 231050 335000 230000 1500 2300 "clearline"]
2479
+	Line[311000 230000 313000 228000 2000 2300 "clearline"]
2480
+	Line[312500 257500 307500 257500 4000 2300 "clearline"]
2481
+	Line[260000 255000 247500 255000 4000 2300 "clearline,rubberend"]
2482
+	Line[255000 262500 257500 265000 4000 2300 "clearline,rubberend"]
2483
+	Line[257500 265000 260000 267500 4000 2300 "clearline,rubberend"]
2484
+	Line[260000 267500 320000 267500 4000 2300 "clearline"]
2485
+	Line[260000 255000 265000 260000 4000 2300 "clearline"]
2486
+	Line[318150 248150 318150 243350 1500 2300 "clearline"]
2487
+	Line[307500 257500 305000 260000 4000 2300 "clearline,rubberend"]
2488
+	Line[289850 185750 285750 185750 1500 2300 "clearline"]
2489
+	Line[285750 185750 282500 182500 1500 2300 "clearline"]
2490
+	Line[289850 188250 280750 188250 1500 2300 "clearline"]
2491
+	Line[360000 140000 365000 140000 2000 2300 "clearline"]
2492
+	Line[402500 227500 407500 227500 4000 2300 "clearline"]
2493
+	Line[387500 157500 417500 187500 4000 2300 "clearline"]
2494
+	Line[417500 217500 417500 187500 4000 2300 "clearline"]
2495
+	Line[407500 227500 417500 217500 4000 2300 "clearline"]
2496
+	Line[320000 150000 367500 150000 4000 2300 "clearline"]
2497
+	Line[325000 227500 323250 229250 1500 2300 "clearline"]
2498
+	Line[370000 130000 362500 122500 2000 2300 "clearline"]
2499
+	Line[365000 135000 365000 140000 2000 2300 "clearline"]
2500
+	Line[323250 229250 323250 235250 1500 2300 "clearline"]
2501
+	Line[320750 235250 320750 228250 1500 2300 "clearline"]
2502
+	Line[320750 228250 317500 225000 1500 2300 "clearline"]
2503
+	Line[292500 67500 320000 67500 2000 2300 "clearline"]
2504
+	Line[360000 130000 365000 135000 2000 2300 "clearline"]
2505
+	Line[370000 140000 375000 140000 2000 2300 "clearline"]
2506
+	Line[325000 250000 328350 246650 1500 2300 "clearline"]
2507
+	Line[328350 246650 328350 243350 1500 2300 "clearline"]
2508
+	Line[333550 243350 333550 248550 1500 2300 "clearline"]
2509
+	Line[333550 248550 335000 250000 1500 2300 "clearline"]
2510
+	Line[330950 243350 330950 251550 1500 2300 "clearline"]
2511
+	Line[330950 251550 330000 252500 1500 2300 "clearline"]
2512
+	Line[310000 217500 308950 216450 1500 2300 "clearline"]
2513
+	Line[309000 230000 311000 230000 2000 2300 "clearline"]
2514
+	Line[297950 218950 304000 219000 1500 2300 "clearline"]
2515
+	Line[303950 218950 307500 222500 1500 2300 "clearline,rubberend"]
2516
+	Line[308950 216450 297950 216450 1500 2300 "clearline"]
2517
+	Line[305000 187500 329500 187500 2000 2300 "clearline"]
2518
+	Line[305000 192500 350000 192500 2000 2300 "clearline"]
2519
+	Line[305000 197500 350000 197500 2000 2300 "clearline"]
2520
+	Line[305000 202500 350000 202500 2000 2300 "clearline"]
2521
+	Line[305000 207500 350000 207500 2000 2300 "clearline"]
2522
+	Line[350000 202500 366950 185550 1500 2300 "clearline"]
2523
+	Line[354150 174750 354150 178350 1500 2300 "clearline"]
2524
+	Line[354150 178350 347500 185000 1500 2300 "clearline,rubberend"]
2525
+	Line[356750 174750 356750 180750 1500 2300 "clearline"]
2526
+	Line[356750 180750 348500 189000 1500 2300 "clearline"]
2527
+	Line[359250 174750 359250 183250 1500 2300 "clearline"]
2528
+	Line[359250 183250 350000 192500 1500 2300 "clearline"]
2529
+	Line[361850 174750 361850 185650 1500 2300 "clearline"]
2530
+	Line[361850 185650 350000 197500 1500 2300 "clearline"]
2531
+	Line[369550 187950 369550 174750 1500 2300 "clearline"]
2532
+	Line[366950 174750 366950 185550 1500 2300 "clearline"]
2533
+	Line[350000 207500 369550 187950 1500 2300 "clearline"]
2534
+	Line[305000 182500 331500 182500 2000 2300 "clearline"]
2535
+	Line[343950 166650 343950 162000 1500 2300 "clearline"]
2536
+	Line[308150 166650 308150 162000 1500 2300 "clearline,rubberend"]
2537
+	Line[310650 166650 310650 162000 1500 2300 "clearline,rubberend"]
2538
+	Line[351650 166650 351650 162000 1500 2300 "clearline"]
2539
+	Line[346450 166650 346450 162000 1500 2300 "clearline"]
2540
+	Line[328550 166650 328550 162000 1500 2300 "clearline"]
2541
+	Line[349050 162000 349050 166650 1500 2300 "clearline"]
2542
+	Line[331150 166650 331150 162000 1500 2300 "clearline"]
2543
+	Line[333650 166650 333650 162000 1500 2300 "clearline"]
2544
+	Line[326050 166650 326050 162000 1500 2300 "clearline"]
2545
+	Line[318350 166650 318350 162000 1500 2300 "clearline"]
2546
+	Line[320950 166650 320950 162000 1500 2300 "clearline"]
2547
+	Line[323450 166650 323450 162000 1500 2300 "clearline"]
2548
+	Line[315750 166650 315750 162000 1500 2300 "clearline"]
2549
+	Line[313250 166650 313250 162000 1500 2300 "clearline"]
2550
+	Line[338000 159000 338000 162000 2000 2300 "clearline"]
2551
+	Line[335000 226000 323000 214000 2000 2300 "clearline"]
2552
+	Line[336050 235250 336050 231050 1500 2300 "clearline"]
2553
+	Line[299850 291450 302550 291450 1500 2300 "clearline"]
2554
+	Line[302550 291450 304000 290000 1500 2300 "clearline"]
2555
+	Line[299850 294650 304350 294650 1500 2300 "clearline"]
2556
+	Line[304350 294650 306000 293000 1500 2300 "clearline"]
2557
+	Line[299850 297750 306250 297750 1500 2300 "clearline"]
2558
+	Line[306250 297750 308000 296000 1500 2300 "clearline"]
2559
+	Line[300000 301000 308000 301000 1500 2300 "clearline"]
2560
+	Line[308000 301000 310000 299000 1500 2300 "clearline"]
2561
+	Line[304000 290000 315000 279000 2000 2300 "clearline"]
2562
+	Line[315000 279000 333000 279000 2000 2300 "clearline"]
2563
+	Line[367000 250000 334000 283000 2000 2300 "clearline"]
2564
+	Line[316000 283000 306000 293000 2000 2300 "clearline"]
2565
+	Line[308000 296000 317000 287000 2000 2300 "clearline"]
2566
+	Line[369000 253000 335000 287000 2000 2300 "clearline"]
2567
+	Line[310000 299000 318000 291000 2000 2300 "clearline"]
2568
+	Line[365000 247000 333000 279000 2000 2300 "clearline"]
2569
+	Line[366750 243350 366750 245250 1500 2300 "clearline"]
2570
+	Line[366750 245250 365000 247000 1500 2300 "clearline"]
2571
+	Line[369350 243350 369350 247650 1500 2300 "clearline"]
2572
+	Line[369350 247650 367000 250000 1500 2300 "clearline"]
2573
+	Line[371850 243350 371850 250150 1500 2300 "clearline"]
2574
+	Line[371850 250150 369000 253000 1500 2300 "clearline"]
2575
+	Line[374450 243350 374450 252550 1500 2300 "clearline"]
2576
+	Line[374450 252550 371000 256000 1500 2300 "clearline"]
2577
+	Line[318000 291000 336000 291000 2000 2300 "clearline"]
2578
+	Line[336000 291000 371000 256000 2000 2300 "clearline"]
2579
+	Line[317000 287000 335000 287000 2000 2300 "clearline"]
2580
+	Line[315000 252500 312500 250000 2000 2300 "clearline"]
2581
+	Line[305000 260000 265000 260000 4000 2300 "clearline,rubberend"]
2582
+	Line[286000 273000 262000 273000 2000 2300 "clearline"]
2583
+	Line[262000 273000 259000 276000 2000 2300 "clearline"]
2584
+	Line[257250 280150 257250 277750 1500 2300 "clearline"]
2585
+	Line[257250 277750 259000 276000 1500 2300 "clearline"]
2586
+	Line[285550 280150 285550 278450 1500 2300 "clearline"]
2587
+	Line[285550 278450 287000 277000 1500 2300 "clearline"]
2588
+	Line[287000 277000 290000 277000 1500 2300 "clearline"]
2589
+	Line[290000 277000 292000 275000 1500 2300 "clearline"]
2590
+	Line[292000 275000 292000 273000 1500 2300 "clearline"]
2591
+	Line[288650 280150 290850 280150 1500 2300 "clearline"]
2592
+	Line[290850 280150 298000 273000 1500 2300 "clearline"]
2593
+	Line[263350 339350 263350 345250 1500 2300 "clearline"]
2594
+	Line[350000 418000 354000 422000 2000 2300 "clearline"]
2595
+	Line[266450 338450 261000 333000 1500 2300 "clearline"]
2596
+	Line[242000 336000 243000 337000 1500 2300 "clearline"]
2597
+	Line[260000 336000 263350 339350 1500 2300 "clearline"]
2598
+	Line[257050 345250 257050 340950 1500 2300 "clearline"]
2599
+	Line[257050 340950 258000 340000 1500 2300 "clearline"]
2600
+	Line[354000 422000 363000 422000 2000 2300 "clearline"]
2601
+	Line[253850 345250 253850 340850 1500 2300 "clearline"]
2602
+	Line[266450 345250 266450 338450 1500 2300 "clearline"]
2603
+	Line[253850 340850 253000 340000 1500 2300 "clearline"]
2604
+	Line[261000 333000 246000 333000 1500 2300 "clearline"]
2605
+	Line[367000 382000 367000 418000 2000 2300 "clearline"]
2606
+	Line[240000 327000 242000 329000 1500 2300 "clearline"]
2607
+	Line[242000 329000 261000 329000 1500 2300 "clearline"]
2608
+	Line[261000 329000 272000 340000 1500 2300 "clearline"]
2609
+	Line[272000 340000 280000 340000 1500 2300 "clearline"]
2610
+	Line[280000 340000 282250 342250 1500 2300 "clearline"]
2611
+	Line[282250 342250 282250 345250 1500 2300 "clearline"]
2612
+	Line[285350 345250 285350 341350 1500 2300 "clearline"]
2613
+	Line[285350 341350 281000 337000 1500 2300 "clearline"]
2614
+	Line[281000 337000 273000 337000 1500 2300 "clearline"]
2615
+	Line[273000 337000 262000 326000 1500 2300 "clearline"]
2616
+	Line[262000 326000 246000 326000 1500 2300 "clearline"]
2617
+	Line[246000 326000 242000 322000 1500 2300 "clearline"]
2618
+	Line[242000 322000 240000 322000 1500 2300 "clearline"]
2619
+	Line[240000 317000 242000 317000 1500 2300 "clearline"]
2620
+	Line[242000 317000 248000 323000 1500 2300 "clearline"]
2621
+	Line[248000 323000 263000 323000 1500 2300 "clearline"]
2622
+	Line[263000 323000 274000 334000 1500 2300 "clearline"]
2623
+	Line[274000 334000 282000 334000 1500 2300 "clearline"]
2624
+	Line[282000 334000 288550 340550 1500 2300 "clearline"]
2625
+	Line[288550 340550 288550 345250 1500 2300 "clearline"]
2626
+	Line[240000 312000 242000 312000 1500 2300 "clearline"]
2627
+	Line[242000 312000 250000 320000 1500 2300 "clearline"]
2628
+	Line[250000 320000 264000 320000 1500 2300 "clearline"]
2629
+	Line[264000 320000 275000 331000 1500 2300 "clearline"]
2630
+	Line[275000 331000 283000 331000 1500 2300 "clearline"]
2631
+	Line[283000 331000 290650 338650 1500 2300 "clearline"]
2632
+	Line[290650 338650 295250 338650 1500 2300 "clearline"]
2633
+	Line[295250 335550 291550 335550 1500 2300 "clearline"]
2634
+	Line[291550 335550 284000 328000 1500 2300 "clearline"]
2635
+	Line[284000 328000 276000 328000 1500 2300 "clearline"]
2636
+	Line[276000 328000 265000 317000 1500 2300 "clearline"]
2637
+	Line[260000 317000 259000 316000 1500 2300 "clearline"]
2638
+	Line[295250 332450 292450 332450 1500 2300 "clearline"]
2639
+	Line[292450 332450 285000 325000 1500 2300 "clearline"]
2640
+	Line[285000 325000 277000 325000 1500 2300 "clearline"]
2641
+	Line[277000 325000 264000 312000 1500 2300 "clearline"]
2642
+	Line[265000 317000 260000 317000 1500 2300 "clearline"]
2643
+	Line[269000 313000 264000 308000 1500 2300 "clearline"]
2644
+	Line[270000 310000 265000 305000 1500 2300 "clearline"]
2645
+	Line[264000 312000 257000 312000 1500 2300 "clearline"]
2646
+	Line[260000 354000 260150 353850 1500 2300 "clearline"]
2647
+	Line[260150 353850 260150 349850 1500 2300 "clearline"]
2648
+	Line[295250 307250 291750 307250 1500 2300 "clearline"]
2649
+	Line[284000 288000 292000 288000 1500 2300 "clearline"]
2650
+	Line[291750 307250 286000 313000 1500 2300 "clearline"]
2651
+	Line[295250 304050 290950 304050 1500 2300 "clearline"]
2652
+	Line[296000 284000 292000 288000 1500 2300 "clearline,rubberend"]
2653
+	Line[290950 304050 285000 310000 1500 2300 "clearline"]
2654
+	Line[286000 313000 269000 313000 1500 2300 "clearline"]
2655
+	Line[240000 307000 241000 308000 1500 2300 "clearline"]
2656
+	Line[264000 308000 241000 308000 1500 2300 "clearline"]
2657
+	Line[285000 310000 270000 310000 1500 2300 "clearline"]
2658
+	Line[286000 303000 283000 303000 1500 2300 "clearline"]
2659
+	Line[277000 306000 273000 302000 1500 2300 "clearline"]
2660
+	Line[279250 287250 284000 292000 1500 2300 "clearline"]
2661
+	Line[272950 284750 272950 288950 1500 2300 "clearline"]
2662
+	Line[290000 300000 289000 299000 1500 2300 "clearline"]
2663
+	Line[272000 306000 270000 306000 1500 2300 "clearline"]
2664
+	Line[277000 293000 272950 288950 1500 2300 "clearline"]
2665
+	Line[270000 306000 260350 296350 1500 2300 "clearline"]
2666
+	Line[260350 296350 260350 284750 1500 2300 "clearline"]
2667
+	Line[273000 302000 270000 302000 1500 2300 "clearline"]
2668
+	Line[270000 302000 263550 295550 1500 2300 "clearline"]
2669
+	Line[263550 295550 263550 284750 1500 2300 "clearline"]
2670
+	Line[266650 284750 266650 294650 1500 2300 "clearline"]
2671
+	Line[266650 294650 271000 299000 1500 2300 "clearline"]
2672
+	Line[271000 299000 275000 299000 1500 2300 "clearline"]
2673
+	Line[275000 299000 282000 306000 1500 2300 "clearline"]
2674
+	Line[283000 303000 276000 296000 1500 2300 "clearline"]
2675
+	Line[276000 296000 272000 296000 1500 2300 "clearline"]
2676
+	Line[272000 296000 269850 293850 1500 2300 "clearline"]
2677
+	Line[269850 293850 269850 284750 1500 2300 "clearline"]
2678
+	Line[289000 299000 283000 299000 1500 2300 "clearline"]
2679
+	Line[283000 299000 277000 293000 1500 2300 "clearline"]
2680
+	Line[290000 295000 289000 296000 1500 2300 "clearline"]
2681
+	Line[284000 296000 276150 288150 1500 2300 "clearline"]
2682
+	Line[276150 288150 276150 284750 1500 2300 "clearline"]
2683
+	Line[279250 284750 279250 287250 1500 2300 "clearline"]
2684
+	Line[286000 292000 284000 292000 1500 2300 "clearline"]
2685
+	Line[289000 296000 284000 296000 1500 2300 "clearline"]
2686
+	Line[282450 284750 282450 286450 1500 2300 "clearline"]
2687
+	Line[282450 286450 284000 288000 1500 2300 "clearline"]
2688
+	Line[295250 310350 292650 310350 1500 2300 "clearline"]
2689
+	Line[286000 317000 284000 317000 1500 2300 "clearline"]
2690
+	Line[295250 313550 293450 313550 1500 2300 "clearline"]
2691
+	Line[293450 313550 286000 321000 1500 2300 "clearline"]
2692
+	Line[292650 310350 286000 317000 1500 2300 "clearline"]
2693
+	Line[286000 321000 281000 321000 1500 2300 "clearline"]
2694
+	Line[265000 305000 244000 305000 1500 2300 "clearline"]
2695
+	Line[244000 305000 241000 302000 1500 2300 "clearline"]
2696
+	Line[182000 227000 182000 278000 2000 2300 "clearline"]
2697
+	Line[176000 263000 173500 263000 2000 2300 "clearline"]
2698
+	Line[125000 255000 173000 255000 2000 2300 "clearline"]
2699
+	Line[173000 255000 176000 258000 2000 2300 "clearline"]
2700
+	Line[230000 307000 217000 307000 1500 2300 "clearline"]
2701
+	Line[179000 359000 179000 349000 1500 2300 "clearline"]
2702
+	Line[230150 310150 217850 310150 1500 2300 "clearline"]
2703
+	Line[217850 310150 179000 349000 1500 2300 "clearline"]
2704
+	Line[230150 313350 218650 313350 1500 2300 "clearline"]
2705
+	Line[235250 345250 241350 345250 1500 2300 "clearline"]
2706
+	Line[185000 361000 185000 351000 1500 2300 "clearline"]
2707
+	Line[219550 316450 230150 316450 1500 2300 "clearline"]
2708
+	Line[230150 319650 220350 319650 1500 2300 "clearline"]
2709
+	Line[219550 316450 185000 351000 1500 2300 "clearline"]
2710
+	Line[191000 363000 191000 353000 1500 2300 "clearline"]
2711
+	Line[221250 322750 230150 322750 1500 2300 "clearline"]
2712
+	Line[230150 325950 222050 325950 1500 2300 "clearline"]
2713
+	Line[221250 322750 191000 353000 1500 2300 "clearline"]
2714
+	Line[230150 329050 222950 329050 1500 2300 "clearline"]
2715
+	Line[197000 366000 197000 355000 1500 2300 "clearline"]
2716
+	Line[230150 332250 225250 332250 1500 2300 "clearline"]
2717
+	Line[225250 332250 222500 335000 1500 2300 "clearline"]
2718
+	Line[225000 340000 227500 342500 2000 2300 "clearline"]
2719
+	Line[227150 335350 225000 337500 1500 2300 "clearline"]
2720
+	Line[225000 337500 225000 340000 1500 2300 "clearline"]
2721
+	Line[230150 335350 227150 335350 1500 2300 "clearline"]
2722
+	Line[220000 337500 222500 335000 2000 2300 "clearline"]
2723
+	Line[220000 337500 220000 347500 2000 2300 "clearline"]
2724
+	Line[220000 347500 222500 350000 2000 2300 "clearline"]
2725
+	Line[227500 342500 227500 350000 2000 2300 "clearline"]
2726
+	Line[220000 302500 207500 302500 2000 2300 "clearline"]
2727
+	Line[234750 338550 234750 344750 1500 2300 "clearline"]
2728
+	Line[234750 344750 235250 345250 1500 2300 "clearline"]
2729
+	Line[217000 307000 176000 348000 1500 2300 "clearline"]
2730
+	Line[176000 348000 176000 358000 1500 2300 "clearline"]
2731
+	Line[150000 388000 150000 405000 1500 2300 "clearline"]
2732
+	Line[160000 386000 160000 405000 1500 2300 "clearline"]
2733
+	Line[218650 313350 182000 350000 1500 2300 "clearline"]
2734
+	Line[182000 350000 182000 360000 1500 2300 "clearline"]
2735
+	Line[155000 410000 155000 387000 1500 2300 "clearline"]
2736
+	Line[191000 363000 170000 384000 1500 2300 "clearline"]
2737
+	Line[220350 319650 188000 352000 1500 2300 "clearline"]
2738
+	Line[188000 352000 188000 362000 1500 2300 "clearline"]
2739
+	Line[182000 360000 155000 387000 1500 2300 "clearline"]
2740
+	Line[170000 405000 170000 384000 1500 2300 "clearline"]
2741
+	Line[222050 325950 194000 354000 1500 2300 "clearline"]
2742
+	Line[194000 354000 194000 364000 1500 2300 "clearline"]
2743
+	Line[175000 410000 175000 383000 1500 2300 "clearline"]
2744
+	Line[180000 383000 197000 366000 1500 2300 "clearline"]
2745
+	Line[222950 329050 197000 355000 1500 2300 "clearline"]
2746
+	Line[180000 383000 180000 405000 1500 2300 "clearline"]
2747
+	Line[185000 361000 160000 386000 1500 2300 "clearline"]
2748
+	Line[179000 359000 150000 388000 1500 2300 "clearline"]
2749
+	Line[176000 358000 145000 389000 1500 2300 "clearline"]
2750
+	Line[145000 389000 145000 410000 1500 2300 "clearline"]
2751
+	Line[165000 385000 165000 410000 1500 2300 "clearline"]
2752
+	Line[194000 364000 175000 383000 1500 2300 "clearline"]
2753
+	Line[188000 362000 165000 385000 1500 2300 "clearline"]
2754
+	Line[145000 410000 150000 415000 1500 2300 "clearline"]
2755
+	Line[160000 415000 155000 410000 1500 2300 "clearline"]
2756
+	Line[165000 410000 170000 415000 1500 2300 "clearline"]
2757
+	Line[175000 410000 180000 415000 1500 2300 "clearline"]
2758
+	Line[202500 360000 202500 370000 2000 2300 "clearline"]
2759
+	Line[215000 370000 222500 362500 2000 2300 "clearline"]
2760
+	Line[242500 362500 247500 357500 2000 2300 "clearline"]
2761
+	Line[212500 377500 207500 372500 2000 2300 "clearline"]
2762
+	Line[207500 365000 215000 357500 2000 2300 "clearline"]
2763
+	Line[232500 362500 232500 375000 2000 2300 "clearline"]
2764
+	Line[279050 351550 282500 355000 1500 2300 "clearline"]
2765
+	Line[222500 362500 242500 362500 2000 2300 "clearline"]
2766
+	Line[215000 357500 240000 357500 2000 2300 "clearline"]
2767
+	Line[240000 357500 242500 355000 2000 2300 "clearline"]
2768
+	Line[270000 405000 270000 395000 2000 2300 "clearline"]
2769
+	Line[270000 395000 262500 387500 2000 2300 "clearline"]
2770
+	Line[247500 357500 247550 357450 1500 2300 "clearline"]
2771
+	Line[247550 357450 247550 349850 1500 2300 "clearline"]
2772
+	Line[244450 349850 244450 353050 1500 2300 "clearline"]
2773
+	Line[244450 353050 242500 355000 1500 2300 "clearline"]
2774
+	Line[207500 365000 207500 372500 2000 2300 "clearline"]
2775
+	Line[252500 387500 262500 387500 2000 2300 "clearline"]
2776
+	Line[270000 377500 247500 377500 2000 2300 "clearline"]
2777
+	Line[247500 377500 240000 385000 2000 2300 "clearline"]
2778
+	Line[240000 385000 240000 405000 2000 2300 "clearline"]
2779
+	Line[250000 405000 247500 402500 2000 2300 "clearline"]
2780
+	Line[247500 402500 247500 385000 2000 2300 "clearline"]
2781
+	Line[247500 385000 250000 382500 2000 2300 "clearline"]
2782
+	Line[250000 382500 290000 382500 2000 2300 "clearline"]
2783
+	Line[290000 382500 292500 380000 2000 2300 "clearline"]
2784
+	Line[302000 359000 292500 368500 2000 2300 "clearline"]
2785
+	Line[80000 145000 80000 122500 4000 2300 "clearline"]
2786
+	Line[80000 122500 57500 100000 4000 2300 "clearline"]
2787
+	Line[57500 100000 57500 47500 4000 2300 "clearline"]
2788
+	Line[220000 145000 220000 122500 4000 2300 "clearline"]
2789
+	Line[242500 47500 242500 100000 4000 2300 "clearline,rubberend"]
2790
+	Line[131250 146929 131250 132500 1500 2300 "clearline"]
2791
+	Line[118750 146929 118750 141250 1500 2300 "clearline"]
2792
+	Line[118750 141250 117500 140000 1500 2300 "clearline"]
2793
+	Line[148750 146929 151250 146929 1500 2300 "clearline"]
2794
+	Line[150000 146929 150000 140000 1500 2300 "clearline"]
2795
+	Line[163750 146929 163750 141250 1500 2300 "clearline"]
2796
+	Line[163750 141250 162500 140000 1500 2300 "clearline"]
2797
+	Line[170000 140000 168750 141250 1500 2300 "clearline"]
2798
+	Line[168750 141250 168750 146929 1500 2300 "clearline"]
2799
+	Line[178750 146929 178750 141250 1500 2300 "clearline"]
2800
+	Line[178750 141250 180000 140000 1500 2300 "clearline"]
2801
+	Line[88750 146929 88750 132500 1500 2300 "clearline"]
2802
+	Line[156250 142500 158500 142500 1500 2300 "clearline"]
2803
+	Line[161250 145250 158500 142500 1500 2300 "clearline,rubberend"]
2804
+	Line[211250 146929 211250 132500 1500 2300 "clearline"]
2805
+	Line[135000 142500 131250 142500 1500 2300 "clearline"]
2806
+	Line[141250 146929 146250 146929 1500 2300 "clearline"]
2807
+	Line[143750 146929 143750 132500 1500 2300 "clearline"]
2808
+	Line[166250 146929 166250 132500 1500 2300 "clearline"]
2809
+	Line[176250 146929 176250 132500 1500 2300 "clearline"]
2810
+	Line[161250 146929 161250 145250 1500 2300 "clearline"]
2811
+	Line[136250 146929 136250 143750 1500 2300 "clearline"]
2812
+	Line[136250 143750 135000 142500 1500 2300 "clearline"]
2813
+	Line[156250 146929 156250 132500 1500 2300 "clearline"]
2814
+	Line[217500 165000 217500 152500 4000 2300 "clearline"]
2815
+	Line[227500 165000 227500 152500 4000 2300 "clearline"]
2816
+	Line[227500 152500 220000 145000 4000 2300 "clearline"]
2817
+	Line[242500 100000 220000 122500 4000 2300 "clearline"]
2818
+	Line[220000 132500 130000 132500 4000 2300 "clearline"]
2819
+	Line[82500 165000 82500 152500 4000 2300 "clearline"]
2820
+	Line[80000 145000 72500 152500 4000 2300 "clearline"]
2821
+	Line[72500 152500 72500 170000 4000 2300 "clearline"]
2822
+	Line[105000 134000 105000 132500 2000 2300 "clearline"]
2823
+	Line[95000 132500 80000 132500 4000 2300 "clearline"]
2824
+	Line[206250 158750 205000 160000 1500 2300 "clearline"]
2825
+	Line[201250 158750 201250 155197 1500 2300 "clearline"]
2826
+	Line[100000 160000 101250 158750 1500 2300 "clearline"]
2827
+	Line[101250 158750 101250 155197 1500 2300 "clearline"]
2828
+	Line[105000 160000 106250 158750 1500 2300 "clearline"]
2829
+	Line[106250 158750 106250 155197 1500 2300 "clearline"]
2830
+	Line[110000 160000 111250 158750 1500 2300 "clearline"]
2831
+	Line[111250 158750 111250 155197 1500 2300 "clearline"]
2832
+	Line[206250 155197 206250 158750 1500 2300 "clearline"]
2833
+	Line[186250 155197 186250 158750 1500 2300 "clearline"]
2834
+	Line[186250 158750 185000 160000 1500 2300 "clearline"]
2835
+	Line[190000 160000 191250 158750 1500 2300 "clearline"]
2836
+	Line[191250 158750 191250 155197 1500 2300 "clearline"]
2837
+	Line[196250 155197 196250 158750 1500 2300 "clearline"]
2838
+	Line[196250 158750 195000 160000 1500 2300 "clearline"]
2839
+	Line[200000 160000 201250 158750 1500 2300 "clearline"]
2840
+	Line[205000 170000 205000 167500 2000 2300 "clearline"]
2841
+	Line[210000 170000 212500 170000 2000 2300 "clearline"]
2842
+	Line[208750 155197 208750 163750 1500 2300 "clearline"]
2843
+	Line[208750 163750 207500 165000 1500 2300 "clearline"]
2844
+	Line[212500 170000 217500 165000 2000 2300 "clearline"]
2845
+	Line[157500 160000 158750 158750 1500 2300 "clearline"]
2846
+	Line[158750 158750 158750 155197 1500 2300 "clearline"]
2847
+	Line[171250 155197 171250 158750 1500 2300 "clearline"]
2848
+	Line[171250 158750 170000 160000 1500 2300 "clearline"]
2849
+	Line[205000 167500 207500 165000 2000 2300 "clearline"]
2850
+	Line[82500 180000 115000 180000 4000 2300 "clearline"]
2851
+	Line[180000 160000 180000 170000 2000 2300 "clearline"]
2852
+	Line[162500 170000 162500 160000 2000 2300 "clearline"]
2853
+	Line[157500 170000 152500 165000 2000 2300 "clearline"]
2854
+	Line[152500 165000 152500 160000 2000 2300 "clearline"]
2855
+	Line[153750 155197 153750 158750 1500 2300 "clearline"]
2856
+	Line[153750 158750 152500 160000 1500 2300 "clearline"]
2857
+	Line[162500 160000 163750 158750 1500 2300 "clearline"]
2858
+	Line[163750 158750 163750 155197 1500 2300 "clearline"]
2859
+	Line[181250 155197 181250 158750 1500 2300 "clearline"]
2860
+	Line[181250 158750 180000 160000 1500 2300 "clearline"]
2861
+	Line[110000 117500 95000 132500 4000 2300 "clearline"]
2862
+	Line[113000 142000 105000 134000 2000 2300 "clearline"]
2863
+	Line[126250 136250 122000 132000 1500 2300 "clearline"]
2864
+	Line[126250 146929 126250 136250 1500 2300 "clearline"]
2865
+	Line[280000 112500 270000 102500 2000 2300 "clearline"]
2866
+	Line[325000 107500 320000 102500 2000 2300 "clearline"]
2867
+	Line[385000 137500 385000 127500 2000 2300 "clearline"]
2868
+	Line[410000 150000 415000 145000 2000 2300 "clearline"]
2869
+	Line[380000 150000 385000 145000 2000 2300 "clearline"]
2870
+	Line[400000 142500 400000 145000 2000 2300 "clearline,rubberend"]
2871
+	Line[415000 145000 415000 142500 2000 2300 "clearline"]
2872
+	Line[400000 137500 400000 127500 2000 2300 "clearline"]
2873
+	Line[415000 127500 415000 137500 2000 2300 "clearline"]
2874
+	Line[367500 150000 375000 157500 4000 2300 "clearline"]
2875
+	Line[375000 157500 387500 157500 4000 2300 "clearline"]
2876
+	Line[385000 145000 385000 142500 2000 2300 "clearline"]
2877
+	Line[400000 145000 395000 150000 2000 2300 "clearline,rubberend"]
2878
+	Line[385000 122500 420000 122500 4000 2300 "clearline"]
2879
+	Line[420000 122500 425000 127500 4000 2300 "clearline"]
2880
+	Line[270000 80000 264508 74508 4000 2300 "clearline"]
2881
+	Line[264508 74508 264508 37008 4000 2300 "clearline"]
2882
+	Line[395000 62500 345000 112500 2000 2300 "clearline"]
2883
+	Line[350000 92500 377500 65000 2000 2300 "clearline"]
2884
+	Line[377500 65000 377500 60000 2000 2300 "clearline"]
2885
+	Line[387500 60000 387500 62500 2000 2300 "clearline"]
2886
+	Line[387500 62500 342500 107500 2000 2300 "clearline"]
2887
+	Line[270000 87500 270000 102500 2000 2300 "clearline"]
2888
+	Line[345000 112500 280000 112500 2000 2300 "clearline,rubberend"]
2889
+	Line[342500 107500 325000 107500 2000 2300 "clearline"]
2890
+	Line[270000 142500 270000 127500 2000 2300 "clearline"]
2891
+	Line[270000 127500 280000 117500 2000 2300 "clearline"]
2892
+	Line[280000 117500 347500 117500 2000 2300 "clearline"]
2893
+	Line[347500 117500 400000 65000 2000 2300 "clearline"]
2894
+	Line[400000 65000 400000 47500 2000 2300 "clearline"]
2895
+	Line[400000 47500 395000 42500 2000 2300 "clearline"]
2896
+	Line[395000 42500 387500 42500 2000 2300 "clearline"]
2897
+	Line[387500 42500 382500 47500 2000 2300 "clearline"]
2898
+	Line[382500 47500 382500 50000 2000 2300 "clearline"]
2899
+	Line[392500 50000 395000 52500 2000 2300 "clearline"]
2900
+	Line[395000 52500 395000 62500 2000 2300 "clearline,rubberend"]
2901
+	Text[362205 342520 0 200 "TOP" ""]
2902
+	Text[11811 358268 0 200 "flaneth" ""]
2903
+	Text[11811 370079 0 200 "0.1.2" ""]
2904
+	Text[90551 7874 0 100 "flaneth - flash and ethernet" ""]
2905
+	Text[90551 15748 0 100 "version 0.1.2 date 2008-02-05" ""]
2906
+	Text[90551 24685 0 100 "Copyright (C) 2007-2008 Stefan Schuermans" ""]
2907
+	Text[90551 33622 0 100 "Copyleft: GNU public license V2" ""]
2908
+	Text[90551 42559 0 100 "a blinkenarea.org project" ""]
2909
+	Polygon("clearpoly,fullpoly")
2910
+	(
2911
+		[255906 0] [255906 114173] [354331 114173] [413386 55118] [413386 0] 
2912
+	)
2913
+	Polygon("clearpoly,fullpoly")
2914
+	(
2915
+		[0 0] [251969 0] [251969 118110] [354331 118110] [417323 55118] 
2916
+		[417323 0] [433071 0] [433071 433071] [0 433071] 
2917
+	)
2918
+)
2919
+Layer(2 "solder")
2920
+(
2921
+	Line[5000 375079 57421 427500 8000 2300 "clearline,rubberend"]
2922
+	Line[80000 398937 80000 427500 8000 2300 "clearline"]
2923
+	Line[375650 427500 57421 427500 8000 2300 "clearline"]
2924
+	Line[145000 355000 150000 350000 8000 2300 "clearline"]
2925
+	Line[320000 132500 320000 130000 2000 2300 "clearline"]
2926
+	Line[327500 140000 320000 132500 2000 2300 "clearline"]
2927
+	Line[130000 357500 100472 386732 8000 2300 "clearline"]
2928
+	Line[130000 355000 135000 355000 8000 2300 "clearline"]
2929
+	Line[415000 340000 427500 340000 4000 2300 "clearline"]
2930
+	Line[150000 350000 150000 310000 8000 2300 "clearline"]
2931
+	Line[52500 282500 52500 265000 2000 2300 "clearline"]
2932
+	Line[130000 300000 150000 300000 8000 2300 "clearline"]
2933
+	Line[47500 262500 57500 252500 2000 2300 "clearline"]
2934
+	Line[47500 277500 47500 262500 2000 2300 "clearline"]
2935
+	Line[105000 275000 105000 325000 20000 2300 "clearline"]
2936
+	Line[44200 280800 47500 277500 2000 2300 "clearline"]
2937
+	Line[70000 325000 70000 275000 20000 2300 "clearline"]
2938
+	Line[130000 357500 130000 242500 8000 2300 "clearline"]
2939
+	Line[340000 415000 340000 427500 4000 2300 "clearline"]
2940
+	Line[150000 290000 150000 242500 8000 2300 "clearline"]
2941
+	Line[135000 237500 135000 215000 8000 2300 "clearline"]
2942
+	Line[29400 286200 29400 297000 2000 2300 "clearline"]
2943
+	Line[40600 302400 24900 302400 2000 2300 "clearline"]
2944
+	Line[24900 302400 22500 300000 2000 2300 "clearline"]
2945
+	Line[29400 275400 22500 282300 2000 2300 "clearline"]
2946
+	Line[22500 300000 22500 282300 2000 2300 "clearline"]
2947
+	Line[15000 307500 15000 275000 4000 2300 "clearline"]
2948
+	Line[38800 315000 40600 313200 4000 2300 "clearline"]
2949
+	Line[15000 307500 22500 315000 4000 2300 "clearline"]
2950
+	Line[22500 315000 38800 315000 4000 2300 "clearline"]
2951
+	Line[15000 275000 22500 267500 4000 2300 "clearline"]
2952
+	Line[22500 267500 38100 267500 4000 2300 "clearline"]
2953
+	Line[38100 267500 40600 270000 4000 2300 "clearline"]
2954
+	Line[35000 155000 35000 180000 4000 2300 "clearline"]
2955
+	Line[35000 315000 35000 340000 4000 2300 "clearline"]
2956
+	Line[29400 126200 29400 137000 2000 2300 "clearline"]
2957
+	Line[40600 142400 24900 142400 2000 2300 "clearline"]
2958
+	Line[24900 142400 22500 140000 2000 2300 "clearline"]
2959
+	Line[29400 115400 22500 122300 2000 2300 "clearline"]
2960
+	Line[22500 140000 22500 122300 2000 2300 "clearline"]
2961
+	Line[15000 147500 15000 115000 4000 2300 "clearline"]
2962
+	Line[38800 155000 40600 153200 4000 2300 "clearline"]
2963
+	Line[15000 147500 22500 155000 4000 2300 "clearline"]
2964
+	Line[22500 155000 38800 155000 4000 2300 "clearline"]
2965
+	Line[15000 115000 22500 107500 4000 2300 "clearline"]
2966
+	Line[22500 107500 38100 107500 4000 2300 "clearline"]
2967
+	Line[38100 107500 40600 110000 4000 2300 "clearline"]
2968
+	Line[35000 107500 35000 82500 4000 2300 "clearline"]
2969
+	Line[35000 267500 35000 180000 4000 2300 "clearline"]
2970
+	Line[105000 275000 70000 275000 20000 2300 "clearline"]
2971
+	Line[70000 325000 105000 325000 20000 2300 "clearline"]
2972
+	Line[87500 275000 87500 325000 20000 2300 "clearline"]
2973
+	Line[92500 247500 95000 247500 2000 2300 "clearline"]
2974
+	Line[95000 247500 97500 250000 2000 2300 "clearline"]
2975
+	Line[97500 250000 97500 255000 2000 2300 "clearline"]
2976
+	Line[97500 255000 95000 257500 2000 2300 "clearline"]
2977
+	Line[95000 257500 60000 257500 2000 2300 "clearline"]
2978
+	Line[60000 257500 52500 265000 2000 2300 "clearline"]
2979
+	Line[92500 252500 57500 252500 2000 2300 "clearline"]
2980
+	Line[40600 280800 44200 280800 2000 2300 "clearline"]
2981
+	Line[40600 291600 43400 291600 2000 2300 "clearline"]
2982
+	Line[43400 291600 52500 282500 2000 2300 "clearline"]
2983
+	Line[40600 131600 44100 131600 2000 2300 "clearline"]
2984
+	Line[44100 131600 50000 137500 2000 2300 "clearline"]
2985
+	Line[50000 137500 50000 162500 2000 2300 "clearline"]
2986
+	Line[40600 120800 43300 120800 2000 2300 "clearline"]
2987
+	Line[43300 120800 55000 132500 2000 2300 "clearline"]
2988
+	Line[55000 132500 55000 160000 2000 2300 "clearline"]
2989
+	Line[55000 160000 120000 225000 2000 2300 "clearline"]
2990
+	Line[115000 227500 50000 162500 2000 2300 "clearline"]
2991
+	Line[120000 225000 120000 230000 2000 2300 "clearline"]
2992
+	Line[120000 230000 117500 232500 2000 2300 "clearline"]
2993
+	Line[117500 232500 115000 232500 2000 2300 "clearline"]
2994
+	Line[105000 157500 107500 155000 2000 2300 "clearline"]
2995
+	Line[122500 115000 112500 125000 2000 2300 "clearline"]
2996
+	Line[105000 150000 135000 150000 2000 2300 "clearline"]
2997
+	Line[165000 187500 192500 187500 2000 2300 "clearline"]
2998
+	Line[205000 187500 185000 167500 2000 2300 "clearline"]
2999
+	Line[205000 160000 205000 167500 2000 2300 "clearline"]
3000
+	Line[107500 135000 105000 132500 2000 2300 "clearline"]
3001
+	Line[129000 123000 117000 135000 2000 2300 "clearline"]
3002
+	Line[127000 119000 235000 119000 2000 2300 "clearline"]
3003
+	Line[117000 135000 107500 135000 2000 2300 "clearline"]
3004
+	Line[116000 130000 127000 119000 2000 2300 "clearline"]
3005
+	Line[185000 167500 185000 160000 2000 2300 "clearline"]
3006
+	Line[190000 160000 190000 167500 2000 2300 "clearline"]
3007
+	Line[190000 167500 210000 187500 2000 2300 "clearline"]
3008
+	Line[195000 160000 195000 167500 2000 2300 "clearline"]
3009
+	Line[195000 167500 215000 187500 2000 2300 "clearline"]
3010
+	Line[122500 115000 236000 115000 2000 2300 "clearline"]
3011
+	Line[220000 167500 255000 167500 2000 2300 "clearline"]
3012
+	Line[220000 187500 200000 167500 2000 2300 "clearline"]
3013
+	Line[200000 167500 200000 160000 2000 2300 "clearline"]
3014
+	Line[107500 155000 132500 155000 2000 2300 "clearline"]
3015
+	Line[129000 123000 234000 123000 2000 2300 "clearline"]
3016
+	Line[5000 57992 31496 31496 8000 2300 "clearline"]
3017
+	Line[5000 57992 5000 375079 8000 2300 "clearline"]
3018
+	Line[100472 386732 88267 398937 8000 2300 "clearline"]
3019
+	Line[375650 427500 427500 375650 8000 2300 "clearline,rubberend"]
3020
+	Line[427500 375650 427500 120413 8000 2300 "clearline,rubberend"]
3021
+	Line[289000 152000 254000 152000 2000 2300 "clearline"]
3022
+	Line[307500 362500 230000 362500 4000 2300 "clearline"]
3023
+	Line[230000 362500 207500 340000 4000 2300 "clearline"]
3024
+	Line[207500 340000 207500 295000 4000 2300 "clearline"]
3025
+	Line[207500 295000 202500 290000 4000 2300 "clearline"]
3026
+	Line[200000 305000 200000 345000 4000 2300 "clearline"]
3027
+	Line[200000 345000 225000 370000 4000 2300 "clearline"]
3028
+	Line[225000 370000 312500 370000 4000 2300 "clearline"]
3029
+	Line[312500 370000 317500 365000 4000 2300 "clearline"]
3030
+	Line[305000 235000 305000 227000 2000 2300 "clearline"]
3031
+	Line[281000 321000 304000 344000 2000 2300 "clearline"]
3032
+	Line[135000 215000 115000 195000 8000 2300 "clearline"]
3033
+	Line[260000 405000 260000 400000 4000 2300 "clearline"]
3034
+	Line[260000 400000 265000 395000 4000 2300 "clearline"]
3035
+	Line[265000 395000 275000 395000 4000 2300 "clearline"]
3036
+	Line[275000 395000 280000 400000 4000 2300 "clearline"]
3037
+	Line[280000 400000 280000 410000 4000 2300 "clearline"]
3038
+	Line[280000 410000 275000 415000 4000 2300 "clearline"]
3039
+	Line[275000 415000 270000 415000 4000 2300 "clearline"]
3040
+	Line[377500 267500 410000 235000 4000 2300 "clearline,rubberend"]
3041
+	Line[410000 210000 410000 235000 4000 2300 "clearline"]
3042
+	Line[377500 267500 325000 267500 4000 2300 "clearline"]
3043
+	Line[375000 260000 402500 232500 4000 2300 "clearline"]
3044
+	Line[402500 232500 402500 227500 4000 2300 "clearline"]
3045
+	Line[402500 202500 410000 210000 4000 2300 "clearline"]
3046
+	Line[375000 260000 327500 260000 4000 2300 "clearline,rubberend"]
3047
+	Line[333000 340000 335000 342000 2000 2300 "clearline"]
3048
+	Line[247500 255000 220000 227500 4000 2300 "clearline"]
3049
+	Line[284000 317000 284000 318000 2000 2300 "clearline"]
3050
+	Line[284000 318000 306000 340000 2000 2300 "clearline"]
3051
+	Line[328000 344000 330000 346000 2000 2300 "clearline"]
3052
+	Line[230000 415000 260000 415000 4000 2300 "clearline"]
3053
+	Line[150000 290000 157500 290000 4000 2300 "clearline"]
3054
+	Line[157500 290000 162500 295000 4000 2300 "clearline"]
3055
+	Line[162500 295000 162500 395000 4000 2300 "clearline"]
3056
+	Line[140000 405000 140000 400000 4000 2300 "clearline"]
3057
+	Line[140000 400000 145000 395000 4000 2300 "clearline"]
3058
+	Line[145000 395000 255000 395000 4000 2300 "clearline"]
3059
+	Line[255000 395000 262500 387500 4000 2300 "clearline"]
3060
+	Line[262500 387500 277500 387500 4000 2300 "clearline"]
3061
+	Line[277500 387500 285000 395000 4000 2300 "clearline"]
3062
+	Line[320000 395000 320000 405000 4000 2300 "clearline"]
3063
+	Line[285000 395000 362500 395000 4000 2300 "clearline"]
3064
+	Line[340000 405000 340000 395000 4000 2300 "clearline"]
3065
+	Line[362500 395000 405000 352500 4000 2300 "clearline"]
3066
+	Line[405000 352500 405000 340000 4000 2300 "clearline"]
3067
+	Line[140000 415000 140000 427500 4000 2300 "clearline"]
3068
+	Line[320000 415000 320000 427500 4000 2300 "clearline"]
3069
+	Line[130000 242500 135000 237500 8000 2300 "clearline"]
3070
+	Line[150000 242500 145000 237500 8000 2300 "clearline"]
3071
+	Line[227500 202500 220000 210000 2000 2300 "clearline"]
3072
+	Line[220000 210000 220000 217500 2000 2300 "clearline"]
3073
+	Line[212500 207500 210000 207500 2000 2300 "clearline"]
3074
+	Line[230000 202500 227500 202500 2000 2300 "clearline"]
3075
+	Line[225000 210000 227500 207500 2000 2300 "clearline"]
3076
+	Line[227500 207500 230000 207500 2000 2300 "clearline"]
3077
+	Line[227500 197500 230000 197500 2000 2300 "clearline"]
3078
+	Line[220000 192500 220000 187500 2000 2300 "clearline"]
3079
+	Line[215000 187500 215000 192500 2000 2300 "clearline"]
3080
+	Line[267000 356000 278000 345000 2000 2300 "clearline"]
3081
+	Line[210000 192500 210000 187500 2000 2300 "clearline"]
3082
+	Line[278000 345000 299000 345000 2000 2300 "clearline"]
3083
+	Line[299000 345000 302000 348000 2000 2300 "clearline"]
3084
+	Line[345000 372000 345000 389000 2000 2300 "clearline"]
3085
+	Line[297000 350000 299000 350000 2000 2300 "clearline"]
3086
+	Line[299000 350000 301000 352000 2000 2300 "clearline"]
3087
+	Line[297000 356000 321000 356000 2000 2300 "clearline"]
3088
+	Line[110000 130000 116000 130000 2000 2300 "clearline"]
3089
+	Line[337000 378000 340000 375000 2000 2300 "clearline"]
3090
+	Line[215000 212500 215000 210000 2000 2300 "clearline"]
3091
+	Line[225000 195000 212500 207500 2000 2300 "clearline"]
3092
+	Line[215000 210000 227500 197500 2000 2300 "clearline"]
3093
+	Line[225000 217500 225000 210000 2000 2300 "clearline"]
3094
+	Line[225000 187500 225000 195000 2000 2300 "clearline"]
3095
+	Line[279000 378000 337000 378000 2000 2300 "clearline"]
3096
+	Line[304000 344000 328000 344000 2000 2300 "clearline"]
3097
+	Line[145000 237500 150000 237500 4000 2300 "clearline"]
3098
+	Line[150000 237500 152500 235000 4000 2300 "clearline"]
3099
+	Line[162500 192500 190000 192500 2000 2300 "clearline"]
3100
+	Line[130000 160000 162500 192500 2000 2300 "clearline"]
3101
+	Line[306000 340000 333000 340000 2000 2300 "clearline"]
3102
+	Line[302000 348000 325000 348000 2000 2300 "clearline"]
3103
+	Line[325000 348000 328000 351000 2000 2300 "clearline"]
3104
+	Line[301000 352000 323000 352000 2000 2300 "clearline"]
3105
+	Line[132500 155000 165000 187500 2000 2300 "clearline"]
3106
+	Line[205000 187500 205000 192500 2000 2300 "clearline"]
3107
+	Line[192500 187500 195000 190000 2000 2300 "clearline"]
3108
+	Line[195000 190000 195000 192500 2000 2300 "clearline"]
3109
+	Line[200000 192500 200000 190000 2000 2300 "clearline"]
3110
+	Line[200000 190000 192500 182500 2000 2300 "clearline"]
3111
+	Line[192500 182500 167500 182500 2000 2300 "clearline"]
3112
+	Line[167500 182500 135000 150000 2000 2300 "clearline"]
3113
+	Line[152500 235000 215000 235000 4000 2300 "clearline"]
3114
+	Line[215000 235000 242500 262500 4000 2300 "clearline"]
3115
+	Line[242500 262500 255000 262500 4000 2300 "clearline"]
3116
+	Line[135000 227500 220000 227500 4000 2300 "clearline,rubberend"]
3117
+	Line[265000 257000 265000 269000 2000 2300 "clearline"]
3118
+	Line[261000 259000 255000 253000 2000 2300 "clearline,rubberend"]
3119
+	Line[257000 312000 256000 311000 1500 2300 "clearline"]
3120
+	Line[255000 253000 255000 167500 2000 2300 "clearline"]
3121
+	Line[259000 251000 265000 257000 2000 2300 "clearline"]
3122
+	Line[269000 255000 269000 270000 2000 2300 "clearline"]
3123
+	Line[273000 255000 273000 271000 2000 2300 "clearline"]
3124
+	Line[269000 255000 263000 249000 2000 2300 "clearline"]
3125
+	Line[262500 168500 262500 162500 2000 2300 "clearline"]
3126
+	Line[305000 197500 301500 197500 2000 2300 "clearline"]
3127
+	Line[273000 255000 277000 251000 2000 2300 "clearline"]
3128
+	Line[275000 180000 280000 180000 2000 2300 "clearline"]
3129
+	Line[298500 182500 281000 200000 2000 2300 "clearline"]
3130
+	Line[305000 192500 300500 192500 2000 2300 "clearline"]
3131
+	Line[300500 192500 289000 204000 2000 2300 "clearline"]
3132
+	Line[305000 182500 298500 182500 2000 2300 "clearline"]
3133
+	Line[281000 253000 281000 200000 2000 2300 "clearline"]
3134
+	Line[299500 187500 285000 202000 2000 2300 "clearline"]
3135
+	Line[305000 187500 299500 187500 2000 2300 "clearline"]
3136
+	Line[289000 257000 289000 204000 2000 2300 "clearline"]
3137
+	Line[285000 255000 285000 202000 2000 2300 "clearline"]
3138
+	Line[301500 197500 293000 206000 2000 2300 "clearline"]
3139
+	Line[338000 159000 338000 199000 2000 2300 "clearline"]
3140
+	Line[259000 251000 259000 172000 2000 2300 "clearline"]
3141
+	Line[259000 172000 262500 168500 2000 2300 "clearline"]
3142
+	Line[277000 185500 277500 185000 2000 2300 "clearline"]
3143
+	Line[407500 167500 402500 172500 4000 2300 "clearline"]
3144
+	Line[280000 180000 282500 182500 2000 2300 "clearline"]
3145
+	Line[263000 192000 275000 180000 2000 2300 "clearline"]
3146
+	Line[263000 249000 263000 192000 2000 2300 "clearline"]
3147
+	Line[293000 268000 293000 206000 2000 2300 "clearline,rubberend"]
3148
+	Line[291000 148000 256000 148000 2000 2300 "clearline"]
3149
+	Line[365000 190000 332500 222500 2000 2300 "clearline"]
3150
+	Line[260000 135000 267500 142500 2000 2300 "clearline"]
3151
+	Line[365000 145000 360000 140000 2000 2300 "clearline"]
3152
+	Line[370000 190000 332500 227500 2000 2300 "clearline"]
3153
+	Line[402500 172500 402500 202500 4000 2300 "clearline"]
3154
+	Line[332500 227500 325000 227500 2000 2300 "clearline,rubberend"]
3155
+	Line[317500 225000 320000 222500 2000 2300 "clearline"]
3156
+	Line[320000 222500 332500 222500 2000 2300 "clearline"]
3157
+	Line[280000 135000 280000 130000 2000 2300 "clearline,rubberend"]
3158
+	Line[380000 185000 325000 240000 2000 2300 "clearline"]
3159
+	Line[395000 150000 385000 160000 2000 2300 "clearline"]
3160
+	Line[325000 170000 297500 142500 2000 2300 "clearline"]
3161
+	Line[287500 122500 280000 130000 2000 2300 "clearline"]
3162
+	Line[315000 197500 314000 196500 2000 2300 "clearline"]
3163
+	Line[427500 120413 401575 94488 8000 2300 "clearline"]
3164
+	Line[403484 35000 405492 37008 4000 2300 "clearline"]
3165
+	Line[380000 150000 380000 185000 2000 2300 "clearline"]
3166
+	Line[254000 152000 243000 141000 2000 2300 "clearline"]
3167
+	Line[252000 156000 239000 143000 2000 2300 "clearline"]
3168
+	Line[267500 142500 297500 142500 2000 2300 "clearline"]
3169
+	Line[287000 156000 252000 156000 2000 2300 "clearline"]
3170
+	Line[350000 65000 360000 75000 2000 2300 "clearline"]
3171
+	Line[302500 202500 297000 208000 2000 2300 "clearline,rubberend"]
3172
+	Line[325000 250000 325000 240000 2000 2300 "clearline"]
3173
+	Line[329000 168000 298500 137500 2000 2300 "clearline"]
3174
+	Line[385000 185000 330000 240000 2000 2300 "clearline"]
3175
+	Line[312500 222500 318000 217000 2000 2300 "clearline"]
3176
+	Line[305000 207500 301000 211500 2000 2300 "clearline"]
3177
+	Line[330000 240000 330000 252500 2000 2300 "clearline"]
3178
+	Line[335000 250000 335000 240000 2000 2300 "clearline"]
3179
+	Line[335000 240000 390000 185000 2000 2300 "clearline"]
3180
+	Line[282500 137500 298500 137500 2000 2300 "clearline"]
3181
+	Line[325000 267500 322500 265000 4000 2300 "clearline"]
3182
+	Line[327500 260000 325000 257500 4000 2300 "clearline,rubberend"]
3183
+	Line[325000 257500 307500 257500 4000 2300 "clearline"]
3184
+	Line[310000 217500 310000 214000 2000 2300 "clearline"]
3185
+	Line[318000 217000 318000 212000 2000 2300 "clearline"]
3186
+	Line[307500 222500 312500 222500 2000 2300 "clearline,rubberend"]
3187
+	Line[256000 148000 247000 139000 2000 2300 "clearline"]
3188
+	Line[301000 266000 301000 211500 2000 2300 "clearline"]
3189
+	Line[305000 202500 302500 202500 2000 2300 "clearline"]
3190
+	Line[297000 268000 297000 208000 2000 2300 "clearline"]
3191
+	Line[273000 271000 254000 290000 2000 2300 "clearline"]
3192
+	Line[277000 251000 277000 185500 2000 2300 "clearline"]
3193
+	Line[281000 253000 277000 257000 2000 2300 "clearline"]
3194
+	Line[260000 295000 281000 274000 2000 2300 "clearline"]
3195
+	Line[286000 260000 289000 257000 2000 2300 "clearline"]
3196
+	Line[281000 259000 285000 255000 2000 2300 "clearline"]
3197
+	Line[286000 273000 286000 260000 2000 2300 "clearline"]
3198
+	Line[261000 259000 261000 267000 2000 2300 "clearline"]
3199
+	Line[292000 273000 292000 269000 2000 2300 "clearline"]
3200
+	Line[292000 269000 293000 268000 2000 2300 "clearline"]
3201
+	Line[301000 266000 303000 268000 2000 2300 "clearline"]
3202
+	Line[303000 268000 303000 274000 2000 2300 "clearline"]
3203
+	Line[298000 273000 298000 269000 2000 2300 "clearline"]
3204
+	Line[298000 269000 297000 268000 2000 2300 "clearline"]
3205
+	Line[261000 267000 245000 283000 2000 2300 "clearline"]
3206
+	Line[242000 331000 242000 336000 1500 2300 "clearline"]
3207
+	Line[323000 352000 326000 355000 2000 2300 "clearline"]
3208
+	Line[247000 287000 248000 286000 1500 2300 "clearline"]
3209
+	Line[265000 269000 248000 286000 2000 2300 "clearline"]
3210
+	Line[253000 340000 250000 337000 1500 2300 "clearline"]
3211
+	Line[269000 270000 251000 288000 2000 2300 "clearline"]
3212
+	Line[277000 257000 277000 272000 2000 2300 "clearline"]
3213
+	Line[277000 272000 257000 292000 2000 2300 "clearline"]
3214
+	Line[281000 259000 281000 274000 2000 2300 "clearline"]
3215
+	Line[326000 355000 334000 355000 2000 2300 "clearline"]
3216
+	Line[246000 333000 247000 332000 1500 2300 "clearline"]
3217
+	Line[253000 291000 254000 290000 1500 2300 "clearline"]
3218
+	Line[250000 289000 250000 337000 1500 2300 "clearline"]
3219
+	Line[332000 359000 324000 359000 2000 2300 "clearline"]
3220
+	Line[324000 359000 321000 356000 2000 2300 "clearline"]
3221
+	Line[251000 288000 250000 289000 1500 2300 "clearline"]
3222
+	Line[256000 293000 257000 292000 1500 2300 "clearline"]
3223
+	Line[264000 309000 264000 350000 1500 2300 "clearline"]
3224
+	Line[338000 199000 323000 214000 2000 2300 "clearline"]
3225
+	Line[310000 179000 287000 156000 2000 2300 "clearline"]
3226
+	Line[329000 201000 329000 168000 2000 2300 "clearline"]
3227
+	Line[318000 212000 329000 201000 2000 2300 "clearline"]
3228
+	Line[325000 199000 325000 170000 2000 2300 "clearline"]
3229
+	Line[310000 214000 325000 199000 2000 2300 "clearline"]
3230
+	Line[282500 137500 280000 135000 2000 2300 "clearline,rubberend"]
3231
+	Line[355000 389000 355000 376000 2000 2300 "clearline"]
3232
+	Line[318000 190500 320000 192500 2000 2300 "clearline"]
3233
+	Line[310000 179000 310000 202500 2000 2300 "clearline"]
3234
+	Line[314000 196500 314000 177000 2000 2300 "clearline"]
3235
+	Line[314000 177000 289000 152000 2000 2300 "clearline"]
3236
+	Line[355000 376000 334000 355000 2000 2300 "clearline"]
3237
+	Line[318000 190500 318000 175000 2000 2300 "clearline"]
3238
+	Line[318000 175000 291000 148000 2000 2300 "clearline"]
3239
+	Line[332000 359000 345000 372000 2000 2300 "clearline"]
3240
+	Line[328000 351000 336000 351000 2000 2300 "clearline"]
3241
+	Line[336000 351000 366000 381000 2000 2300 "clearline"]
3242
+	Line[245000 283000 244000 284000 1500 2300 "clearline"]
3243
+	Line[258000 339000 258000 340000 1500 2300 "clearline"]
3244
+	Line[253000 291000 253000 334000 1500 2300 "clearline"]
3245
+	Line[253000 334000 258000 339000 1500 2300 "clearline"]
3246
+	Line[247000 287000 247000 332000 1500 2300 "clearline"]
3247
+	Line[244000 284000 244000 329000 1500 2300 "clearline"]
3248
+	Line[244000 329000 242000 331000 1500 2300 "clearline"]
3249
+	Line[256000 293000 256000 311000 1500 2300 "clearline"]
3250
+	Line[300000 277000 283000 277000 1500 2300 "clearline"]
3251
+	Line[264000 350000 260000 354000 1500 2300 "clearline"]
3252
+	Line[283000 277000 262000 298000 1500 2300 "clearline"]
3253
+	Line[261000 314000 259000 316000 1500 2300 "clearline"]
3254
+	Line[303000 274000 300000 277000 1500 2300 "clearline"]
3255
+	Line[262000 298000 262000 307000 1500 2300 "clearline"]
3256
+	Line[261000 310000 261000 314000 1500 2300 "clearline"]
3257
+	Line[261000 310000 259000 308000 1500 2300 "clearline"]
3258
+	Line[259000 308000 259000 296000 1500 2300 "clearline"]
3259
+	Line[259000 296000 260000 295000 1500 2300 "clearline"]
3260
+	Line[262000 307000 264000 309000 1500 2300 "clearline"]
3261
+	Line[240000 302000 239000 301000 1500 2300 "clearline"]
3262
+	Line[236000 304000 236000 277000 1500 2300 "clearline"]
3263
+	Line[240000 307000 239000 307000 1500 2300 "clearline"]
3264
+	Line[239000 307000 236000 304000 1500 2300 "clearline"]
3265
+	Line[235000 276000 236000 277000 1500 2300 "clearline"]
3266
+	Line[240000 312000 239000 312000 1500 2300 "clearline"]
3267
+	Line[239000 312000 233000 306000 1500 2300 "clearline"]
3268
+	Line[230000 308000 230000 283000 1500 2300 "clearline"]
3269
+	Line[240000 317000 239000 317000 1500 2300 "clearline"]
3270
+	Line[239000 317000 230000 308000 1500 2300 "clearline"]
3271
+	Line[229000 282000 230000 283000 1500 2300 "clearline"]
3272
+	Line[240000 322000 239000 322000 1500 2300 "clearline"]
3273
+	Line[239000 322000 227000 310000 1500 2300 "clearline"]
3274
+	Line[224000 289000 223000 288000 1500 2300 "clearline"]
3275
+	Line[240000 327000 239000 327000 1500 2300 "clearline"]
3276
+	Line[239000 327000 224000 312000 1500 2300 "clearline"]
3277
+	Line[220000 273000 229000 282000 2000 2300 "clearline"]
3278
+	Line[239000 274000 238000 273000 1500 2300 "clearline"]
3279
+	Line[218000 283000 223000 288000 2000 2300 "clearline"]
3280
+	Line[219000 278000 226000 285000 2000 2300 "clearline"]
3281
+	Line[218000 283000 197000 283000 2000 2300 "clearline"]
3282
+	Line[220000 273000 192000 273000 2000 2300 "clearline"]
3283
+	Line[223000 258000 176000 258000 2000 2300 "clearline"]
3284
+	Line[221000 268000 187000 268000 2000 2300 "clearline"]
3285
+	Line[222000 263000 176000 263000 2000 2300 "clearline"]
3286
+	Line[223000 258000 238000 273000 2000 2300 "clearline"]
3287
+	Line[222000 263000 235000 276000 2000 2300 "clearline"]
3288
+	Line[221000 268000 232000 279000 2000 2300 "clearline"]
3289
+	Line[224000 312000 224000 289000 1500 2300 "clearline"]
3290
+	Line[227000 310000 227000 286000 1500 2300 "clearline"]
3291
+	Line[227000 286000 226000 285000 1500 2300 "clearline"]
3292
+	Line[233000 306000 233000 280000 1500 2300 "clearline"]
3293
+	Line[233000 280000 232000 279000 1500 2300 "clearline"]
3294
+	Line[239000 301000 239000 274000 1500 2300 "clearline"]
3295
+	Line[219000 278000 182000 278000 2000 2300 "clearline"]
3296
+	Line[272000 306000 272000 310000 1500 2300 "clearline"]
3297
+	Line[272000 310000 275000 313000 1500 2300 "clearline"]
3298
+	Line[315000 289000 309000 295000 1500 2300 "clearline"]
3299
+	Line[319000 301000 310000 310000 1500 2300 "clearline"]
3300
+	Line[279000 310000 277000 308000 1500 2300 "clearline"]
3301
+	Line[277000 308000 277000 306000 1500 2300 "clearline"]
3302
+	Line[282000 306000 283000 307000 1500 2300 "clearline"]
3303
+	Line[279000 310000 310000 310000 1500 2300 "clearline"]
3304
+	Line[317000 295000 308000 304000 1500 2300 "clearline"]
3305
+	Line[287000 304000 286000 303000 1500 2300 "clearline"]
3306
+	Line[400000 310000 379000 289000 1500 2300 "clearline"]
3307
+	Line[401000 315000 378000 292000 1500 2300 "clearline"]
3308
+	Line[309000 295000 291000 295000 1500 2300 "clearline"]
3309
+	Line[309000 291000 314000 286000 1500 2300 "clearline"]
3310
+	Line[291000 295000 290000 295000 1500 2300 "clearline"]
3311
+	Line[286000 292000 287000 291000 1500 2300 "clearline"]
3312
+	Line[400000 305000 381000 286000 1500 2300 "clearline"]
3313
+	Line[287000 304000 308000 304000 1500 2300 "clearline"]
3314
+	Line[287000 291000 309000 291000 1500 2300 "clearline"]
3315
+	Line[297000 283000 296000 284000 1500 2300 "clearline"]
3316
+	Line[275000 313000 311000 313000 1500 2300 "clearline"]
3317
+	Line[311000 313000 320000 304000 1500 2300 "clearline"]
3318
+	Line[400000 335000 369000 304000 1500 2300 "clearline"]
3319
+	Line[400000 330000 371000 301000 1500 2300 "clearline"]
3320
+	Line[283000 307000 309000 307000 1500 2300 "clearline"]
3321
+	Line[309000 307000 318000 298000 1500 2300 "clearline"]
3322
+	Line[316000 292000 378000 292000 1500 2300 "clearline"]
3323
+	Line[315000 289000 379000 289000 1500 2300 "clearline"]
3324
+	Line[290000 300000 308000 300000 1500 2300 "clearline"]
3325
+	Line[308000 300000 316000 292000 1500 2300 "clearline"]
3326
+	Line[297000 283000 383000 283000 1500 2300 "clearline"]
3327
+	Line[383000 283000 400000 300000 1500 2300 "clearline"]
3328
+	Line[400000 300000 405000 300000 1500 2300 "clearline"]
3329
+	Line[405000 310000 400000 310000 1500 2300 "clearline"]
3330
+	Line[317000 295000 375000 295000 1500 2300 "clearline"]
3331
+	Line[375000 295000 400000 320000 1500 2300 "clearline"]
3332
+	Line[400000 320000 405000 320000 1500 2300 "clearline"]
3333
+	Line[405000 330000 400000 330000 1500 2300 "clearline"]
3334
+	Line[319000 301000 371000 301000 1500 2300 "clearline"]
3335
+	Line[314000 286000 381000 286000 1500 2300 "clearline"]
3336
+	Line[400000 305000 410000 305000 1500 2300 "clearline"]
3337
+	Line[410000 305000 415000 300000 1500 2300 "clearline"]
3338
+	Line[415000 310000 410000 315000 1500 2300 "clearline"]
3339
+	Line[410000 325000 400000 325000 1500 2300 "clearline"]
3340
+	Line[415000 320000 410000 325000 1500 2300 "clearline"]
3341
+	Line[410000 335000 400000 335000 1500 2300 "clearline"]
3342
+	Line[415000 330000 410000 335000 1500 2300 "clearline"]
3343
+	Line[410000 315000 401000 315000 1500 2300 "clearline"]
3344
+	Line[318000 298000 373000 298000 1500 2300 "clearline"]
3345
+	Line[373000 298000 400000 325000 1500 2300 "clearline"]
3346
+	Line[320000 304000 369000 304000 1500 2300 "clearline"]
3347
+	Line[227500 342500 215000 330000 2000 2300 "clearline"]
3348
+	Line[215000 330000 215000 302500 2000 2300 "clearline"]
3349
+	Line[217500 297500 220000 300000 2000 2300 "clearline"]
3350
+	Line[220000 300000 220000 327500 2000 2300 "clearline"]
3351
+	Line[220000 327500 235000 342500 2000 2300 "clearline"]
3352
+	Line[235000 342500 235000 345000 2000 2300 "clearline"]
3353
+	Line[160000 250000 165000 255000 2000 2300 "clearline"]
3354
+	Line[165000 255000 165000 285000 2000 2300 "clearline"]
3355
+	Line[165000 285000 182500 302500 2000 2300 "clearline"]
3356
+	Line[200000 360000 202500 360000 2000 2300 "clearline"]
3357
+	Line[162500 245000 160000 245000 2000 2300 "clearline"]
3358
+	Line[187500 300000 170000 282500 2000 2300 "clearline"]
3359
+	Line[170000 282500 170000 252500 2000 2300 "clearline"]
3360
+	Line[170000 252500 162500 245000 2000 2300 "clearline"]
3361
+	Line[187500 300000 187500 347500 2000 2300 "clearline"]
3362
+	Line[187500 347500 200000 360000 2000 2300 "clearline"]
3363
+	Line[182500 302500 182500 350000 2000 2300 "clearline"]
3364
+	Line[182500 350000 202500 370000 2000 2300 "clearline"]
3365
+	Line[202500 370000 215000 370000 2000 2300 "clearline"]
3366
+	Line[212500 377500 242500 377500 2000 2300 "clearline"]
3367
+	Line[242500 377500 252500 387500 2000 2300 "clearline"]
3368
+	Line[170000 357500 197500 385000 2000 2300 "clearline"]
3369
+	Line[197500 385000 232500 385000 2000 2300 "clearline"]
3370
+	Line[345000 180000 345000 173000 2000 2300 "clearline"]
3371
+	Line[345000 173000 358000 161000 2000 2300 "clearline"]
3372
+	Line[396000 206000 395000 205000 2000 2300 "clearline"]
3373
+	Line[395000 186000 395000 205000 2000 2300 "clearline"]
3374
+	Line[319000 249000 305000 235000 2000 2300 "clearline"]
3375
+	Line[217500 145000 217500 152500 4000 2300 "clearline"]
3376
+	Line[212500 140000 217500 145000 4000 2300 "clearline"]
3377
+	Line[105000 150000 100000 155000 2000 2300 "clearline"]
3378
+	Line[87500 140000 212500 140000 4000 2300 "clearline"]
3379
+	Line[82500 152500 82500 145000 4000 2300 "clearline"]
3380
+	Line[82500 145000 87500 140000 4000 2300 "clearline"]
3381
+	Line[220000 162500 262500 162500 2000 2300 "clearline"]
3382
+	Line[167500 150000 207500 150000 2000 2300 "clearline"]
3383
+	Line[207500 155000 220000 167500 2000 2300 "clearline"]
3384
+	Line[170000 160000 175000 155000 2000 2300 "clearline"]
3385
+	Line[175000 155000 207500 155000 2000 2300 "clearline"]
3386
+	Line[207500 150000 220000 162500 2000 2300 "clearline,rubberend"]
3387
+	Line[110000 160000 130000 160000 2000 2300 "clearline"]
3388
+	Line[157500 160000 167500 150000 2000 2300 "clearline"]
3389
+	Line[100000 155000 100000 160000 2000 2300 "clearline"]
3390
+	Line[205000 167500 225000 187500 2000 2300 "clearline"]
3391
+	Line[105000 160000 105000 157500 2000 2300 "clearline"]
3392
+	Line[307500 65000 280000 92500 2000 2300 "clearline"]
3393
+	Line[280000 92500 280000 100000 2000 2300 "clearline"]
3394
+	Line[315000 65000 287500 92500 2000 2300 "clearline"]
3395
+	Line[287500 92500 287500 102500 2000 2300 "clearline"]
3396
+	Line[287500 102500 282500 107500 2000 2300 "clearline"]
3397
+	Line[282500 107500 265000 107500 2000 2300 "clearline"]
3398
+	Line[265000 107500 260000 102500 2000 2300 "clearline"]
3399
+	Line[260000 102500 260000 100000 2000 2300 "clearline"]
3400
+	Line[320000 67500 310000 77500 2000 2300 "clearline"]
3401
+	Line[310000 77500 310000 100000 2000 2300 "clearline"]
3402
+	Line[307500 60000 307500 65000 2000 2300 "clearline"]
3403
+	Line[312500 50000 315000 52500 2000 2300 "clearline"]
3404
+	Line[315000 52500 315000 65000 2000 2300 "clearline"]
3405
+	Line[302500 50000 302500 47500 2000 2300 "clearline"]
3406
+	Line[302500 47500 307500 42500 2000 2300 "clearline"]
3407
+	Line[307500 42500 317500 42500 2000 2300 "clearline"]
3408
+	Line[317500 42500 320000 45000 2000 2300 "clearline"]
3409
+	Line[320000 45000 320000 67500 2000 2300 "clearline"]
3410
+	Line[265000 37500 265492 37008 4000 2300 "clearline,rubberend"]
3411
+	Line[325000 37500 322500 35000 4000 2300 "clearline"]
3412
+	Line[322500 35000 267500 35000 4000 2300 "clearline,rubberend"]
3413
+	Line[267500 35000 265000 37500 4000 2300 "clearline,rubberend"]
3414
+	Line[239000 143000 239000 128000 2000 2300 "clearline"]
3415
+	Line[243000 141000 243000 127000 2000 2300 "clearline"]
3416
+	Line[247000 139000 247000 126000 2000 2300 "clearline"]
3417
+	Line[247000 126000 236000 115000 2000 2300 "clearline"]
3418
+	Line[243000 127000 235000 119000 2000 2300 "clearline"]
3419
+	Line[239000 128000 234000 123000 2000 2300 "clearline"]
3420
+	Line[375000 140000 370000 140000 2000 2300 "clearline,rubberend"]
3421
+	Line[390000 185000 390000 170000 2000 2300 "clearline"]
3422
+	Line[390000 170000 410000 150000 2000 2300 "clearline"]
3423
+	Line[385000 185000 385000 160000 2000 2300 "clearline"]
3424
+	Line[325492 37008 344508 37008 4000 2300 "clearline"]
3425
+	Line[344508 37008 346516 35000 4000 2300 "clearline"]
3426
+	Line[346516 35000 403484 35000 4000 2300 "clearline"]
3427
+	Line[370000 190000 370000 70000 2000 2300 "clearline"]
3428
+	Line[370000 70000 367500 67500 2000 2300 "clearline"]
3429
+	Line[367500 67500 367500 60000 2000 2300 "clearline"]
3430
+	Line[362500 50000 352500 50000 2000 2300 "clearline"]
3431
+	Line[352500 50000 350000 52500 2000 2300 "clearline"]
3432
+	Line[350000 52500 350000 65000 2000 2300 "clearline"]
3433
+	Line[365000 190000 365000 145000 2000 2300 "clearline"]
3434
+	Line[372500 50000 372500 47500 2000 2300 "clearline"]
3435
+	Line[372500 47500 367500 42500 2000 2300 "clearline"]
3436
+	Line[367500 42500 352500 42500 2000 2300 "clearline"]
3437
+	Line[352500 42500 345000 50000 2000 2300 "clearline"]
3438
+	Line[345000 50000 345000 67500 2000 2300 "clearline"]
3439
+	Line[355000 102500 335000 122500 2000 2300 "clearline"]
3440
+	Line[335000 122500 287500 122500 2000 2300 "clearline"]
3441
+	Line[260000 135000 260000 127500 2000 2300 "clearline"]
3442
+	Line[260000 127500 270000 117500 2000 2300 "clearline"]
3443
+	Line[270000 117500 332500 117500 2000 2300 "clearline"]
3444
+	Line[332500 117500 350000 100000 2000 2300 "clearline"]
3445
+	Line[355000 77500 355000 102500 2000 2300 "clearline"]
3446
+	Line[345000 67500 355000 77500 2000 2300 "clearline"]
3447
+	Line[350000 100000 350000 92500 2000 2300 "clearline"]
3448
+	Line[360000 122500 360000 75000 2000 2300 "clearline"]
3449
+	Line[352500 130000 360000 122500 2000 2300 "clearline"]
3450
+	Line[357500 60000 357500 65000 2000 2300 "clearline"]
3451
+	Line[357500 65000 365000 72500 2000 2300 "clearline"]
3452
+	Line[365000 72500 365000 127500 2000 2300 "clearline"]
3453
+	Line[365000 127500 352500 140000 2000 2300 "clearline"]
3454
+	Line[352500 140000 327500 140000 2000 2300 "clearline"]
3455
+	Line[88267 398937 80000 398937 8000 2300 "clearline"]
3456
+	Line[70000 365000 80000 375000 8000 2300 "clearline"]
3457
+	Line[70000 350000 70000 365000 8000 2300 "clearline"]
3458
+	Text[389764 342520 2 200 "BOTTOM" "auto"]
3459
+	Polygon("clearpoly,fullpoly")
3460
+	(
3461
+		[255906 0] [255906 114173] [354331 114173] [413386 55118] [413386 0] 
3462
+	)
3463
+	Polygon("clearpoly,fullpoly")
3464
+	(
3465
+		[0 0] [251969 0] [251969 118110] [354331 118110] [417323 55118] 
3466
+		[417323 0] [433071 0] [433071 433071] [0 433071] 
3467
+	)
3468
+)
3469
+Layer(3 "GND")
3470
+(
3471
+)
3472
+Layer(4 "power")
3473
+(
3474
+)
3475
+Layer(5 "signal1")
3476
+(
3477
+)
3478
+Layer(6 "signal2")
3479
+(
3480
+)
3481
+Layer(7 "signal3")
3482
+(
3483
+)
3484
+Layer(8 "signal4")
3485
+(
3486
+)
3487
+Layer(9 "silk")
3488
+(
3489
+)
3490
+Layer(10 "silk")
3491
+(
3492
+)
3493
+NetList()
3494
+(
3495
+	Net("GND" "(unknown)")
3496
+	(
3497
+		Connect("C1-2")
3498
+		Connect("C2-2")
3499
+		Connect("C3-2")
3500
+		Connect("C4-2")
3501
+		Connect("C5-1")
3502
+		Connect("C6-1")
3503
+		Connect("C7-1")
3504
+		Connect("C8-1")
3505
+		Connect("C9-1")
3506
+		Connect("C10-1")
3507
+		Connect("C11-1")
3508
+		Connect("C12-1")
3509
+		Connect("C13-1")
3510
+		Connect("C14-1")
3511
+		Connect("C15-1")
3512
+		Connect("C18-2")
3513
+		Connect("C19-1")
3514
+		Connect("C20-1")
3515
+		Connect("C21-2")
3516
+		Connect("C23-1")
3517
+		Connect("C25-1")
3518
+		Connect("CF1-1")
3519
+		Connect("CF1-8")
3520
+		Connect("CF1-10")
3521
+		Connect("CF1-11")
3522
+		Connect("CF1-12")
3523
+		Connect("CF1-14")
3524
+		Connect("CF1-15")
3525
+		Connect("CF1-16")
3526
+		Connect("CF1-17")
3527
+		Connect("CF1-39")
3528
+		Connect("CF1-50")
3529
+		Connect("CF1-100")
3530
+		Connect("CF1-101")
3531
+		Connect("CON1-2")
3532
+		Connect("CON4-1")
3533
+		Connect("CON4-5")
3534
+		Connect("CON4-100")
3535
+		Connect("CON4-101")
3536
+		Connect("CON5-1")
3537
+		Connect("CON5-5")
3538
+		Connect("CON5-100")
3539
+		Connect("CON5-101")
3540
+		Connect("CON6-10")
3541
+		Connect("CON7-10")
3542
+		Connect("CON8-6")
3543
+		Connect("CON8-10")
3544
+		Connect("CON9-4")
3545
+		Connect("CON9-6")
3546
+		Connect("CON9-8")
3547
+		Connect("CON9-10")
3548
+		Connect("IC1-2")
3549
+		Connect("IC2-22")
3550
+		Connect("IC2-53")
3551
+		Connect("IC2-63")
3552
+		Connect("IC3-11")
3553
+		Connect("IC3-12")
3554
+		Connect("IC3-13")
3555
+		Connect("IC3-14")
3556
+		Connect("IC3-18")
3557
+		Connect("IC3-19")
3558
+		Connect("IC3-20")
3559
+		Connect("IC3-21")
3560
+		Connect("IC3-22")
3561
+		Connect("IC3-23")
3562
+		Connect("IC3-24")
3563
+		Connect("IC3-25")
3564
+		Connect("IC3-26")
3565
+		Connect("IC3-27")
3566
+		Connect("IC3-28")
3567
+		Connect("IC3-44")
3568
+		Connect("IC3-52")
3569
+		Connect("IC3-64")
3570
+		Connect("IC3-83")
3571
+		Connect("IC3-86")
3572
+		Connect("IC4-15")
3573
+		Connect("J1-1")
3574
+		Connect("J2-1")
3575
+		Connect("J3-1")
3576
+		Connect("J4-1")
3577
+		Connect("LED1-1")
3578
+		Connect("R6-1")
3579
+	)
3580
+	Net("unnamed_net1" "(unknown)")
3581
+	(
3582
+		Connect("CON9-5")
3583
+		Connect("IC2-20")
3584
+		Connect("R1-2")
3585
+	)
3586
+	Net("unnamed_net2" "(unknown)")
3587
+	(
3588
+		Connect("CON7-8")
3589
+		Connect("IC2-54")
3590
+	)
3591
+	Net("unnamed_net3" "(unknown)")
3592
+	(
3593
+		Connect("CON9-1")
3594
+		Connect("IC2-2")
3595
+		Connect("R4-2")
3596
+	)
3597
+	Net("unnamed_net4" "(unknown)")
3598
+	(
3599
+		Connect("C9-2")
3600
+		Connect("IC2-24")
3601
+		Connect("X1-2")
3602
+	)
3603
+	Net("unnamed_net5" "(unknown)")
3604
+	(
3605
+		Connect("C8-2")
3606
+		Connect("IC2-23")
3607
+		Connect("X1-1")
3608
+	)
3609
+	Net("unnamed_net6" "(unknown)")
3610
+	(
3611
+		Connect("C7-2")
3612
+		Connect("IC2-62")
3613
+	)
3614
+	Net("unnamed_net7" "(unknown)")
3615
+	(
3616
+		Connect("C5-2")
3617
+		Connect("C6-2")
3618
+		Connect("CON9-2")
3619
+		Connect("CON9-3")
3620
+		Connect("D2-1")
3621
+		Connect("IC2-1")
3622
+		Connect("IC2-21")
3623
+		Connect("IC2-52")
3624
+		Connect("IC2-64")
3625
+		Connect("R1-1")
3626
+	)
3627
+	Net("unnamed_net8" "(unknown)")
3628
+	(
3629
+		Connect("IC2-19")
3630
+		Connect("IC3-10")
3631
+	)
3632
+	Net("unnamed_net9" "(unknown)")
3633
+	(
3634
+		Connect("IC2-18")
3635
+		Connect("IC3-9")
3636
+	)
3637
+	Net("unnamed_net10" "(unknown)")
3638
+	(
3639
+		Connect("CF1-18")
3640
+		Connect("IC2-43")
3641
+		Connect("IC3-8")
3642
+	)
3643
+	Net("unnamed_net11" "(unknown)")
3644
+	(
3645
+		Connect("CF1-19")
3646
+		Connect("IC2-34")
3647
+		Connect("IC3-7")
3648
+	)
3649
+	Net("unnamed_net12" "(unknown)")
3650
+	(
3651
+		Connect("CF1-20")
3652
+		Connect("IC2-33")
3653
+		Connect("IC3-5")
3654
+	)
3655
+	Net("unnamed_net13" "(unknown)")
3656
+	(
3657
+		Connect("CON7-7")
3658
+		Connect("IC2-55")
3659
+	)
3660
+	Net("unnamed_net14" "(unknown)")
3661
+	(
3662
+		Connect("CON7-6")
3663
+		Connect("IC2-56")
3664
+	)
3665
+	Net("unnamed_net15" "(unknown)")
3666
+	(
3667
+		Connect("CON7-5")
3668
+		Connect("IC2-57")
3669
+	)
3670
+	Net("unnamed_net16" "(unknown)")
3671
+	(
3672
+		Connect("CON7-4")
3673
+		Connect("IC2-58")
3674
+	)
3675
+	Net("unnamed_net17" "(unknown)")
3676
+	(
3677
+		Connect("CON7-3")
3678
+		Connect("IC2-59")
3679
+	)
3680
+	Net("unnamed_net18" "(unknown)")
3681
+	(
3682
+		Connect("CON7-2")
3683
+		Connect("IC2-60")
3684
+	)
3685
+	Net("unnamed_net19" "(unknown)")
3686
+	(
3687
+		Connect("CON7-1")
3688
+		Connect("IC2-61")
3689
+	)
3690
+	Net("unnamed_net20" "(unknown)")
3691
+	(
3692
+		Connect("CON9-9")
3693
+		Connect("IC2-3")
3694
+		Connect("IC4-11")
3695
+	)
3696
+	Net("unnamed_net21" "(unknown)")
3697
+	(
3698
+		Connect("IC2-4")
3699
+		Connect("R5-2")
3700
+	)
3701
+	Net("unnamed_net22" "(unknown)")
3702
+	(
3703
+		Connect("IC2-5")
3704
+		Connect("IC3-33")
3705
+	)
3706
+	Net("unnamed_net23" "(unknown)")
3707
+	(
3708
+		Connect("IC2-6")
3709
+		Connect("IC3-34")
3710
+	)
3711
+	Net("unnamed_net24" "(unknown)")
3712
+	(
3713
+		Connect("IC2-7")
3714
+		Connect("IC3-4")
3715
+	)
3716
+	Net("unnamed_net25" "(unknown)")
3717
+	(
3718
+		Connect("CF1-9")
3719
+		Connect("IC2-8")
3720
+		Connect("IC3-29")
3721
+	)
3722
+	Net("unnamed_net26" "(unknown)")
3723
+	(
3724
+		Connect("CF1-36")
3725
+		Connect("IC2-9")
3726
+		Connect("IC3-30")
3727
+	)
3728
+	Net("unnamed_net27" "(unknown)")
3729
+	(
3730
+		Connect("CON8-7")
3731
+		Connect("IC2-25")
3732
+	)
3733
+	Net("unnamed_net28" "(unknown)")
3734
+	(
3735
+		Connect("CON8-8")
3736
+		Connect("IC2-26")
3737
+	)
3738
+	Net("unnamed_net29" "(unknown)")
3739
+	(
3740
+		Connect("IC2-27")
3741
+		Connect("IC4-9")
3742
+	)
3743
+	Net("unnamed_net30" "(unknown)")
3744
+	(
3745
+		Connect("IC2-28")
3746
+		Connect("IC4-10")
3747
+	)
3748
+	Net("unnamed_net31" "(unknown)")
3749
+	(
3750
+		Connect("IC2-29")
3751
+		Connect("IC3-79")
3752
+	)
3753
+	Net("unnamed_net32" "(unknown)")
3754
+	(
3755
+		Connect("IC2-30")
3756
+		Connect("IC3-78")
3757
+	)
3758
+	Net("unnamed_net33" "(unknown)")
3759
+	(
3760
+		Connect("IC2-31")
3761
+		Connect("IC3-77")
3762
+	)
3763
+	Net("unnamed_net34" "(unknown)")
3764
+	(
3765
+		Connect("IC2-32")
3766
+		Connect("IC3-76")
3767
+	)
3768
+	Net("unnamed_net35" "(unknown)")
3769
+	(
3770
+		Connect("CON6-1")
3771
+		Connect("IC2-35")
3772
+	)
3773
+	Net("unnamed_net36" "(unknown)")
3774
+	(
3775
+		Connect("CON6-2")
3776
+		Connect("IC2-36")
3777
+	)
3778
+	Net("unnamed_net37" "(unknown)")
3779
+	(
3780
+		Connect("CON6-3")
3781
+		Connect("IC2-37")
3782
+	)
3783
+	Net("unnamed_net38" "(unknown)")
3784
+	(
3785
+		Connect("CON6-4")
3786
+		Connect("IC2-38")
3787
+	)
3788
+	Net("unnamed_net39" "(unknown)")
3789
+	(
3790
+		Connect("CON6-5")
3791
+		Connect("IC2-39")
3792
+	)
3793
+	Net("unnamed_net40" "(unknown)")
3794
+	(
3795
+		Connect("CON6-6")
3796
+		Connect("IC2-40")
3797
+	)
3798
+	Net("unnamed_net41" "(unknown)")
3799
+	(
3800
+		Connect("CON6-7")
3801
+		Connect("IC2-41")
3802
+	)
3803
+	Net("unnamed_net42" "(unknown)")
3804
+	(
3805
+		Connect("CON6-8")
3806
+		Connect("IC2-42")
3807
+	)
3808
+	Net("unnamed_net43" "(unknown)")
3809
+	(
3810
+		Connect("CON8-4")
3811
+		Connect("IC2-10")
3812
+	)
3813
+	Net("unnamed_net44" "(unknown)")
3814
+	(
3815
+		Connect("IC2-11")
3816
+		Connect("R2-2")
3817
+	)
3818
+	Net("unnamed_net45" "(unknown)")
3819
+	(
3820
+		Connect("CON8-3")
3821
+		Connect("IC2-12")
3822
+	)
3823
+	Net("unnamed_net46" "(unknown)")
3824
+	(
3825
+		Connect("CON8-2")
3826
+		Connect("IC2-13")
3827
+	)
3828
+	Net("unnamed_net47" "(unknown)")
3829
+	(
3830
+		Connect("CF1-26")
3831
+		Connect("IC2-14")
3832
+		Connect("R11-1")
3833
+	)
3834
+	Net("unnamed_net48" "(unknown)")
3835
+	(
3836
+		Connect("CF1-41")
3837
+		Connect("IC2-15")
3838
+	)
3839
+	Net("unnamed_net49" "(unknown)")
3840
+	(
3841
+		Connect("CF1-7")
3842
+		Connect("IC2-16")
3843
+	)
3844
+	Net("unnamed_net50" "(unknown)")
3845
+	(
3846
+		Connect("CF1-37")
3847
+		Connect("IC2-17")
3848
+		Connect("R12-1")
3849
+	)
3850
+	Net("unnamed_net51" "(unknown)")
3851
+	(
3852
+		Connect("CF1-21")
3853
+		Connect("IC2-51")
3854
+		Connect("IC3-36")
3855
+	)
3856
+	Net("unnamed_net52" "(unknown)")
3857
+	(
3858
+		Connect("CF1-22")
3859
+		Connect("IC2-50")
3860
+		Connect("IC3-37")
3861
+	)
3862
+	Net("unnamed_net53" "(unknown)")
3863
+	(
3864
+		Connect("CF1-23")
3865
+		Connect("IC2-49")
3866
+		Connect("IC3-38")
3867
+	)
3868
+	Net("unnamed_net54" "(unknown)")
3869
+	(
3870
+		Connect("CF1-2")
3871
+		Connect("IC2-48")
3872
+		Connect("IC3-39")
3873
+	)
3874
+	Net("unnamed_net55" "(unknown)")
3875
+	(
3876
+		Connect("CF1-3")
3877
+		Connect("IC2-47")
3878
+		Connect("IC3-40")
3879
+	)
3880
+	Net("unnamed_net56" "(unknown)")
3881
+	(
3882
+		Connect("CF1-4")
3883
+		Connect("IC2-46")
3884
+		Connect("IC3-41")
3885
+	)
3886
+	Net("unnamed_net57" "(unknown)")
3887
+	(
3888
+		Connect("CF1-5")
3889
+		Connect("IC2-45")
3890
+		Connect("IC3-42")
3891
+	)
3892
+	Net("unnamed_net58" "(unknown)")
3893
+	(
3894
+		Connect("CF1-6")
3895
+		Connect("IC2-44")
3896
+		Connect("IC3-43")
3897
+	)
3898
+	Net("unnamed_net59" "(unknown)")
3899
+	(
3900
+		Connect("IC3-96")
3901
+		Connect("R6-2")
3902
+	)
3903
+	Net("unnamed_net60" "(unknown)")
3904
+	(
3905
+		Connect("C12-2")
3906
+		Connect("IC3-51")
3907
+		Connect("X2-1")
3908
+	)
3909
+	Net("unnamed_net61" "(unknown)")
3910
+	(
3911
+		Connect("C13-2")
3912
+		Connect("IC3-50")
3913
+		Connect("X2-2")
3914
+	)
3915
+	Net("unnamed_net62" "(unknown)")
3916
+	(
3917
+		Connect("IC3-63")
3918
+		Connect("R10-1")
3919
+	)
3920
+	Net("unnamed_net63" "(unknown)")
3921
+	(
3922
+		Connect("IC3-62")
3923
+		Connect("R9-1")
3924
+	)
3925
+	Net("unnamed_net64" "(unknown)")
3926
+	(
3927
+		Connect("IC3-61")
3928
+		Connect("R8-1")
3929
+	)
3930
+	Net("unnamed_net65" "(unknown)")
3931
+	(
3932
+		Connect("CON3-4")
3933
+		Connect("IC3-45")
3934
+		Connect("L1-1")
3935
+	)
3936
+	Net("unnamed_net66" "(unknown)")
3937
+	(
3938
+		Connect("CON3-5")
3939
+		Connect("IC3-46")
3940
+		Connect("L1-3")
3941
+	)
3942
+	Net("unnamed_net67" "(unknown)")
3943
+	(
3944
+		Connect("CON3-6")
3945
+		Connect("IC3-59")
3946
+		Connect("L1-4")
3947
+		Connect("R7-2")
3948
+	)
3949
+	Net("unnamed_net68" "(unknown)")
3950
+	(
3951
+		Connect("CON3-7")
3952
+		Connect("IC3-58")
3953
+		Connect("L1-6")
3954
+		Connect("R7-1")
3955
+	)
3956
+	Net("unnamed_net69" "(unknown)")
3957
+	(
3958
+		Connect("CON2-1")
3959
+		Connect("L1-12")
3960
+	)
3961
+	Net("unnamed_net70" "(unknown)")
3962
+	(
3963
+		Connect("C14-2")
3964
+		Connect("CON3-3")
3965
+		Connect("L1-2")
3966
+	)
3967
+	Net("unnamed_net71" "(unknown)")
3968
+	(
3969
+		Connect("C17-2")
3970
+		Connect("CON3-1")
3971
+		Connect("L1-11")
3972
+	)
3973
+	Net("unnamed_net72" "(unknown)")
3974
+	(
3975
+		Connect("CON2-2")
3976
+		Connect("L1-10")
3977
+	)
3978
+	Net("unnamed_net73" "(unknown)")
3979
+	(
3980
+		Connect("CON2-3")
3981
+		Connect("L1-9")
3982
+	)
3983
+	Net("unnamed_net74" "(unknown)")
3984
+	(
3985
+		Connect("C15-2")
3986
+		Connect("CON3-8")
3987
+		Connect("L1-5")
3988
+	)
3989
+	Net("unnamed_net75" "(unknown)")
3990
+	(
3991
+		Connect("C16-2")
3992
+		Connect("CON3-2")
3993
+		Connect("L1-8")
3994
+	)
3995
+	Net("unnamed_net76" "(unknown)")
3996
+	(
3997
+		Connect("CON2-6")
3998
+		Connect("L1-7")
3999
+	)
4000
+	Net("unnamed_net77" "(unknown)")
4001
+	(
4002
+		Connect("C16-1")
4003
+		Connect("C17-1")
4004
+		Connect("CON2-9")
4005
+		Connect("CON2-10")
4006
+		Connect("CON3-9")
4007
+		Connect("CON3-10")
4008
+	)
4009
+	Net("unnamed_net78" "(unknown)")
4010
+	(
4011
+		Connect("LED2-1")
4012
+		Connect("R8-2")
4013
+	)
4014
+	Net("unnamed_net79" "(unknown)")
4015
+	(
4016
+		Connect("LED3-1")
4017
+		Connect("R9-2")
4018
+	)
4019
+	Net("unnamed_net80" "(unknown)")
4020
+	(
4021
+		Connect("LED4-1")
4022
+		Connect("R10-2")
4023
+	)
4024
+	Net("unnamed_net81" "(unknown)")
4025
+	(
4026
+		Connect("CON9-7")
4027
+		Connect("R2-1")
4028
+		Connect("R3-1")
4029
+	)
4030
+	Net("unnamed_net82" "(unknown)")
4031
+	(
4032
+		Connect("LED1-2")
4033
+		Connect("R5-1")
4034
+	)
4035
+	Net("unnamed_net83" "(unknown)")
4036
+	(
4037
+		Connect("C1-1")
4038
+		Connect("C2-1")
4039
+		Connect("D1-1")
4040
+		Connect("IC1-1")
4041
+	)
4042
+	Net("unnamed_net84" "(unknown)")
4043
+	(
4044
+		Connect("CON1-1")
4045
+		Connect("D1-2")
4046
+	)
4047
+	Net("unnamed_net85" "(unknown)")
4048
+	(
4049
+		Connect("IC4-12")
4050
+		Connect("R4-1")
4051
+	)
4052
+	Net("unnamed_net86" "(unknown)")
4053
+	(
4054
+		Connect("CON8-1")
4055
+		Connect("R3-2")
4056
+	)
4057
+	Net("unnamed_net87" "(unknown)")
4058
+	(
4059
+		Connect("C22-2")
4060
+		Connect("IC4-1")
4061
+	)
4062
+	Net("unnamed_net88" "(unknown)")
4063
+	(
4064
+		Connect("CON5-2")
4065
+		Connect("IC4-8")
4066
+	)
4067
+	Net("unnamed_net89" "(unknown)")
4068
+	(
4069
+		Connect("C23-2")
4070
+		Connect("IC4-2")
4071
+	)
4072
+	Net("unnamed_net90" "(unknown)")
4073
+	(
4074
+		Connect("C22-1")
4075
+		Connect("IC4-3")
4076
+	)
4077
+	Net("unnamed_net91" "(unknown)")
4078
+	(
4079
+		Connect("C24-2")
4080
+		Connect("IC4-4")
4081
+	)
4082
+	Net("unnamed_net92" "(unknown)")
4083
+	(
4084
+		Connect("C24-1")
4085
+		Connect("IC4-5")
4086
+	)
4087
+	Net("unnamed_net93" "(unknown)")
4088
+	(
4089
+		Connect("CON4-3")
4090
+		Connect("IC4-14")
4091
+	)
4092
+	Net("unnamed_net94" "(unknown)")
4093
+	(
4094
+		Connect("C25-2")
4095
+		Connect("IC4-6")
4096
+	)
4097
+	Net("unnamed_net95" "(unknown)")
4098
+	(
4099
+		Connect("CON4-2")
4100
+		Connect("IC4-13")
4101
+	)
4102
+	Net("unnamed_net96" "(unknown)")
4103
+	(
4104
+		Connect("CON5-3")
4105
+		Connect("IC4-7")
4106
+	)
4107
+	Net("unnamed_net97" "(unknown)")
4108
+	(
4109
+		Connect("CON5-4")
4110
+		Connect("CON5-6")
4111
+	)
4112
+	Net("unnamed_net98" "(unknown)")
4113
+	(
4114
+		Connect("CON5-7")
4115
+		Connect("CON5-8")
4116
+	)
4117
+	Net("unnamed_net99" "(unknown)")
4118
+	(
4119
+		Connect("CON4-4")
4120
+		Connect("CON4-6")
4121
+	)
4122
+	Net("unnamed_net100" "(unknown)")
4123
+	(
4124
+		Connect("CON4-7")
4125
+		Connect("CON4-8")
4126
+	)
4127
+	Net("VDD5" "(unknown)")
4128
+	(
4129
+		Connect("C3-1")
4130
+		Connect("C4-1")
4131
+		Connect("C10-2")
4132
+		Connect("C11-2")
4133
+		Connect("C18-1")
4134
+		Connect("C19-2")
4135
+		Connect("C20-2")
4136
+		Connect("C21-1")
4137
+		Connect("CF1-13")
4138
+		Connect("CF1-32")
4139
+		Connect("CF1-34")
4140
+		Connect("CF1-35")
4141
+		Connect("CF1-38")
4142
+		Connect("CF1-44")
4143
+		Connect("CON6-9")
4144
+		Connect("CON7-9")
4145
+		Connect("CON8-5")
4146
+		Connect("CON8-9")
4147
+		Connect("D2-2")
4148
+		Connect("IC1-3")
4149
+		Connect("IC3-6")
4150
+		Connect("IC3-15")
4151
+		Connect("IC3-16")
4152
+		Connect("IC3-17")
4153
+		Connect("IC3-31")
4154
+		Connect("IC3-32")
4155
+		Connect("IC3-47")
4156
+		Connect("IC3-57")
4157
+		Connect("IC3-65")
4158
+		Connect("IC3-70")
4159
+		Connect("IC3-89")
4160
+		Connect("IC4-16")
4161
+		Connect("LED2-2")
4162
+		Connect("LED3-2")
4163
+		Connect("LED4-2")
4164
+		Connect("R11-2")
4165
+		Connect("R12-2")
4166
+	)
4167
+)
... ...
@@ -0,0 +1,6882 @@
1
+v 20061020 1
2
+C 7300 11400 1 0 0 EMBEDDEDATMEGA128.sym
3
+[
4
+P 7300 20400 7600 20400 1 0 0
5
+{
6
+T 7500 20450 5 8 1 1 0 6 1
7
+pinnumber=20
8
+T 7500 20350 5 8 0 1 0 8 1
9
+pinseq=20
10
+T 7650 20400 9 8 1 1 0 0 1
11
+pinlabel=nRESET
12
+T 7650 20400 5 8 0 1 0 2 1
13
+pintype=in
14
+}
15
+P 7300 13200 7600 13200 1 0 0
16
+{
17
+T 7500 13250 5 8 1 1 0 6 1
18
+pinnumber=54
19
+T 7500 13150 5 8 0 1 0 8 1
20
+pinseq=54
21
+T 7650 13200 9 8 1 1 0 0 1
22
+pinlabel=PF7 (ADC7/TDI)
23
+T 7650 13200 5 8 0 1 0 2 1
24
+pintype=io
25
+}
26
+P 11100 11800 10800 11800 1 0 0
27
+{
28
+T 10900 11850 5 8 1 1 0 0 1
29
+pinnumber=2
30
+T 10900 11750 5 8 0 1 0 2 1
31
+pinseq=2
32
+T 10750 11800 9 8 1 1 0 6 1
33
+pinlabel=PE0 (RXD0/PDI)
34
+T 10750 11800 5 8 0 1 0 8 1
35
+pintype=io
36
+}
37
+B 7600 11400 3200 9400 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
38
+T 7700 18450 5 10 0 0 0 0 1
39
+numslots=0
40
+P 7300 19000 7600 19000 1 0 0
41
+{
42
+T 7500 19050 5 8 1 1 0 6 1
43
+pinnumber=24
44
+T 7500 18950 5 8 0 1 0 8 1
45
+pinseq=24
46
+T 7650 19000 9 8 1 1 0 0 1
47
+pinlabel=XTAL1
48
+T 7650 19000 5 8 0 1 0 2 1
49
+pintype=in
50
+}
51
+P 7300 19600 7600 19600 1 0 0
52
+{
53
+T 7500 19650 5 8 1 1 0 6 1
54
+pinnumber=23
55
+T 7500 19550 5 8 0 1 0 8 1
56
+pinseq=23
57
+T 7650 19600 9 8 1 1 0 0 1
58
+pinlabel=XTAL2
59
+T 7650 19600 5 8 0 1 0 2 1
60
+pintype=out
61
+}
62
+P 7300 18400 7600 18400 1 0 0
63
+{
64
+T 7500 18450 5 8 1 1 0 6 1
65
+pinnumber=62
66
+T 7500 18350 5 8 0 1 0 8 1
67
+pinseq=62
68
+T 7650 18400 9 8 1 1 0 0 1
69
+pinlabel=AREF
70
+T 7650 18400 5 8 0 1 0 2 1
71
+pintype=in
72
+}
73
+P 7300 18200 7600 18200 1 0 0
74
+{
75
+T 7500 18250 5 8 1 1 0 6 1
76
+pinnumber=64
77
+T 7500 18150 5 8 0 1 0 8 1
78
+pinseq=64
79
+T 7650 18200 9 8 1 1 0 0 1
80
+pinlabel=AVCC
81
+T 7650 18200 5 8 0 1 0 2 1
82
+pintype=pwr
83
+}
84
+P 7300 18000 7600 18000 1 0 0
85
+{
86
+T 7500 18050 5 8 1 1 0 6 1
87
+pinnumber=63
88
+T 7500 17950 5 8 0 1 0 8 1
89
+pinseq=63
90
+T 7650 18000 9 8 1 1 0 0 1
91
+pinlabel=AGND
92
+T 7650 18000 5 8 0 1 0 2 1
93
+pintype=pwr
94
+}
95
+P 7300 17400 7600 17400 1 0 0
96
+{
97
+T 7500 17450 5 8 1 1 0 6 1
98
+pinnumber=21
99
+T 7500 17350 5 8 0 1 0 8 1
100
+pinseq=21
101
+T 7650 17400 9 8 1 1 0 0 1
102
+pinlabel=VCC1
103
+T 7650 17400 5 8 0 1 0 2 1
104
+pintype=pwr
105
+}
106
+P 7300 17200 7600 17200 1 0 0
107
+{
108
+T 7500 17250 5 8 1 1 0 6 1
109
+pinnumber=52
110
+T 7500 17150 5 8 0 1 0 8 1
111
+pinseq=52
112
+T 7650 17200 9 8 1 1 0 0 1
113
+pinlabel=VCC2
114
+T 7650 17200 5 8 0 1 0 2 1
115
+pintype=pwr
116
+}
117
+P 7300 17000 7600 17000 1 0 0
118
+{
119
+T 7500 17050 5 8 1 1 0 6 1
120
+pinnumber=22
121
+T 7500 16950 5 8 0 1 0 8 1
122
+pinseq=22
123
+T 7650 17000 9 8 1 1 0 0 1
124
+pinlabel=GND1
125
+T 7650 17000 5 8 0 1 0 2 1
126
+pintype=pwr
127
+}
128
+P 7300 16800 7600 16800 1 0 0
129
+{
130
+T 7500 16850 5 8 1 1 0 6 1
131
+pinnumber=53
132
+T 7500 16750 5 8 0 1 0 8 1
133
+pinseq=53
134
+T 7650 16800 9 8 1 1 0 0 1
135
+pinlabel=GND2
136
+T 7650 16800 5 8 0 1 0 2 1
137
+pintype=pwr
138
+}
139
+P 7300 16200 7600 16200 1 0 0
140
+{
141
+T 7500 16250 5 8 1 1 0 6 1
142
+pinnumber=19
143
+T 7500 16150 5 8 0 1 0 8 1
144
+pinseq=19
145
+T 7650 16200 9 8 1 1 0 0 1
146
+pinlabel=PG4 (TOSC1)
147
+T 7650 16200 5 8 0 1 0 2 1
148
+pintype=io
149
+}
150
+P 7300 16000 7600 16000 1 0 0
151
+{
152
+T 7500 16050 5 8 1 1 0 6 1
153
+pinnumber=18
154
+T 7500 15950 5 8 0 1 0 8 1
155
+pinseq=18
156
+T 7650 16000 9 8 1 1 0 0 1
157
+pinlabel=PG3 (TOSC2)
158
+T 7650 16000 5 8 0 1 0 2 1
159
+pintype=io
160
+}
161
+P 7300 15800 7600 15800 1 0 0
162
+{
163
+T 7500 15850 5 8 1 1 0 6 1
164
+pinnumber=43
165
+T 7500 15750 5 8 0 1 0 8 1
166
+pinseq=43
167
+T 7650 15800 9 8 1 1 0 0 1
168
+pinlabel=PG2 (ALE)
169
+T 7650 15800 5 8 0 1 0 2 1
170
+pintype=io
171
+}
172
+P 7300 15600 7600 15600 1 0 0
173
+{
174
+T 7500 15650 5 8 1 1 0 6 1
175
+pinnumber=34
176
+T 7500 15550 5 8 0 1 0 8 1
177
+pinseq=34
178
+T 7650 15600 9 8 1 1 0 0 1
179
+pinlabel=PG1 (nRD)
180
+T 7650 15600 5 8 0 1 0 2 1
181
+pintype=io
182
+}
183
+P 7300 15400 7600 15400 1 0 0
184
+{
185
+T 7500 15450 5 8 1 1 0 6 1
186
+pinnumber=33
187
+T 7500 15350 5 8 0 1 0 8 1
188
+pinseq=33
189
+T 7650 15400 9 8 1 1 0 0 1
190
+pinlabel=PG0 (nWR)
191
+T 7650 15400 5 8 0 1 0 2 1
192
+pintype=io
193
+}
194
+P 7300 14800 7600 14800 1 0 0
195
+{
196
+T 7500 14850 5 8 1 1 0 6 1
197
+pinnumber=1
198
+T 7500 14750 5 8 0 1 0 8 1
199
+pinseq=1
200
+T 7650 14800 9 8 1 1 0 0 1
201
+pinlabel=nPEN
202
+T 7650 14800 5 8 0 1 0 2 1
203
+pintype=in
204
+}
205
+P 7300 13000 7600 13000 1 0 0
206
+{
207
+T 7500 13050 5 8 1 1 0 6 1
208
+pinnumber=55
209
+T 7500 12950 5 8 0 1 0 8 1
210
+pinseq=55
211
+T 7650 13000 9 8 1 1 0 0 1
212
+pinlabel=PF6 (ADC6/TDO)
213
+T 7650 13000 5 8 0 1 0 2 1
214
+pintype=io
215
+}
216
+P 7300 12800 7600 12800 1 0 0
217
+{
218
+T 7500 12850 5 8 1 1 0 6 1
219
+pinnumber=56
220
+T 7500 12750 5 8 0 1 0 8 1
221
+pinseq=56
222
+T 7650 12800 9 8 1 1 0 0 1
223
+pinlabel=PF5 (ADC5/TMS)
224
+T 7650 12800 5 8 0 1 0 2 1
225
+pintype=io
226
+}
227
+P 7300 12600 7600 12600 1 0 0
228
+{
229
+T 7500 12650 5 8 1 1 0 6 1
230
+pinnumber=57
231
+T 7500 12550 5 8 0 1 0 8 1
232
+pinseq=57
233
+T 7650 12600 9 8 1 1 0 0 1
234
+pinlabel=PF4 (ADC4/TCK)
235
+T 7650 12600 5 8 0 1 0 2 1
236
+pintype=io
237
+}
238
+P 7300 12400 7600 12400 1 0 0
239
+{
240
+T 7500 12450 5 8 1 1 0 6 1
241
+pinnumber=58
242
+T 7500 12350 5 8 0 1 0 8 1
243
+pinseq=58
244
+T 7650 12400 9 8 1 1 0 0 1
245
+pinlabel=PF3 (ADC3)
246
+T 7650 12400 5 8 0 1 0 2 1
247
+pintype=io
248
+}
249
+P 7300 12200 7600 12200 1 0 0
250
+{
251
+T 7500 12250 5 8 1 1 0 6 1
252
+pinnumber=59
253
+T 7500 12150 5 8 0 1 0 8 1
254
+pinseq=59
255
+T 7650 12200 9 8 1 1 0 0 1
256
+pinlabel=PF2 (ADC2)
257
+T 7650 12200 5 8 0 1 0 2 1
258
+pintype=io
259
+}
260
+P 7300 12000 7600 12000 1 0 0
261
+{
262
+T 7500 12050 5 8 1 1 0 6 1
263
+pinnumber=60
264
+T 7500 11950 5 8 0 1 0 8 1
265
+pinseq=60
266
+T 7650 12000 9 8 1 1 0 0 1
267
+pinlabel=PF1 (ADC1)
268
+T 7650 12000 5 8 0 1 0 2 1
269
+pintype=io
270
+}
271
+P 7300 11800 7600 11800 1 0 0
272
+{
273
+T 7500 11850 5 8 1 1 0 6 1
274
+pinnumber=61
275
+T 7500 11750 5 8 0 1 0 8 1
276
+pinseq=61
277
+T 7650 11800 9 8 1 1 0 0 1
278
+pinlabel=PF0 (ADC0)
279
+T 7650 11800 5 8 0 1 0 2 1
280
+pintype=io
281
+}
282
+P 11100 12000 10800 12000 1 0 0
283
+{
284
+T 10900 12050 5 8 1 1 0 0 1
285
+pinnumber=3
286
+T 10900 11950 5 8 0 1 0 2 1
287
+pinseq=3
288
+T 10750 12000 9 8 1 1 0 6 1
289
+pinlabel=PE1 (TXD0/PDO)
290
+T 10750 12000 5 8 0 1 0 8 1
291
+pintype=io
292
+}
293
+P 11100 12200 10800 12200 1 0 0
294
+{
295
+T 10900 12250 5 8 1 1 0 0 1
296
+pinnumber=4
297
+T 10900 12150 5 8 0 1 0 2 1
298
+pinseq=4
299
+T 10750 12200 9 8 1 1 0 6 1
300
+pinlabel=PE2 (XCK0/AIN0)
301
+T 10750 12200 5 8 0 1 0 8 1
302
+pintype=io
303
+}
304
+P 11100 12400 10800 12400 1 0 0
305
+{
306
+T 10900 12450 5 8 1 1 0 0 1
307
+pinnumber=5
308
+T 10900 12350 5 8 0 1 0 2 1
309
+pinseq=5
310
+T 10750 12400 9 8 1 1 0 6 1
311
+pinlabel=PE3 (OC3A/AIN1)
312
+T 10750 12400 5 8 0 1 0 8 1
313
+pintype=io
314
+}
315
+P 11100 12600 10800 12600 1 0 0
316
+{
317
+T 10900 12650 5 8 1 1 0 0 1
318
+pinnumber=6
319
+T 10900 12550 5 8 0 1 0 2 1
320
+pinseq=6
321
+T 10750 12600 9 8 1 1 0 6 1
322
+pinlabel=PE4 (OC3B/INT4)
323
+T 10750 12600 5 8 0 1 0 8 1
324
+pintype=io
325
+}
326
+P 11100 12800 10800 12800 1 0 0
327
+{
328
+T 10900 12850 5 8 1 1 0 0 1
329
+pinnumber=7
330
+T 10900 12750 5 8 0 1 0 2 1
331
+pinseq=7
332
+T 10750 12800 9 8 1 1 0 6 1
333
+pinlabel=PE5 (OC3C/INT5)
334
+T 10750 12800 5 8 0 1 0 8 1
335
+pintype=io
336
+}
337
+P 11100 13000 10800 13000 1 0 0
338
+{
339
+T 10900 13050 5 8 1 1 0 0 1
340
+pinnumber=8
341
+T 10900 12950 5 8 0 1 0 2 1
342
+pinseq=8
343
+T 10750 13000 9 8 1 1 0 6 1
344
+pinlabel=PE6 (T3/INT6)
345
+T 10750 13000 5 8 0 1 0 8 1
346
+pintype=io
347
+}
348
+P 11100 13200 10800 13200 1 0 0
349
+{
350
+T 10900 13250 5 8 1 1 0 0 1
351
+pinnumber=9
352
+T 10900 13150 5 8 0 1 0 2 1
353
+pinseq=9
354
+T 10750 13200 9 8 1 1 0 6 1
355
+pinlabel=PE7 (ICP3/INT7)
356
+T 10750 13200 5 8 0 1 0 8 1
357
+pintype=io
358
+}
359
+P 11100 13600 10800 13600 1 0 0
360
+{
361
+T 10900 13650 5 8 1 1 0 0 1
362
+pinnumber=25
363
+T 10900 13550 5 8 0 1 0 2 1
364
+pinseq=25
365
+T 10750 13600 9 8 1 1 0 6 1
366
+pinlabel=PD0 (SCL/INT0)
367
+T 10750 13600 5 8 0 1 0 8 1
368
+pintype=io
369
+}
370
+P 11100 13800 10800 13800 1 0 0
371
+{
372
+T 10900 13850 5 8 1 1 0 0 1
373
+pinnumber=26
374
+T 10900 13750 5 8 0 1 0 2 1
375
+pinseq=26
376
+T 10750 13800 9 8 1 1 0 6 1
377
+pinlabel=PD1 (SDA/INT1)
378
+T 10750 13800 5 8 0 1 0 8 1
379
+pintype=io
380
+}
381
+P 11100 14000 10800 14000 1 0 0
382
+{
383
+T 10900 14050 5 8 1 1 0 0 1
384
+pinnumber=27
385
+T 10900 13950 5 8 0 1 0 2 1
386
+pinseq=27
387
+T 10750 14000 9 8 1 1 0 6 1
388
+pinlabel=PD2 (RXD1/INT2)
389
+T 10750 14000 5 8 0 1 0 8 1
390
+pintype=io
391
+}
392
+P 11100 14200 10800 14200 1 0 0
393
+{
394
+T 10900 14250 5 8 1 1 0 0 1
395
+pinnumber=28
396
+T 10900 14150 5 8 0 1 0 2 1
397
+pinseq=28
398
+T 10750 14200 9 8 1 1 0 6 1
399
+pinlabel=PD3 (TXD1/INT3)
400
+T 10750 14200 5 8 0 1 0 8 1
401
+pintype=io
402
+}
403
+P 11100 14400 10800 14400 1 0 0
404
+{
405
+T 10900 14450 5 8 1 1 0 0 1
406
+pinnumber=29
407
+T 10900 14350 5 8 0 1 0 2 1
408
+pinseq=29
409
+T 10750 14400 9 8 1 1 0 6 1
410
+pinlabel=PD4 (ICP1)
411
+T 10750 14400 5 8 0 1 0 8 1
412
+pintype=io
413
+}
414
+P 11100 14600 10800 14600 1 0 0
415
+{
416
+T 10900 14650 5 8 1 1 0 0 1
417
+pinnumber=30
418
+T 10900 14550 5 8 0 1 0 2 1
419
+pinseq=30
420
+T 10750 14600 9 8 1 1 0 6 1
421
+pinlabel=PD5 (XCK1)
422
+T 10750 14600 5 8 0 1 0 8 1
423
+pintype=io
424
+}
425
+P 11100 14800 10800 14800 1 0 0
426
+{
427
+T 10900 14850 5 8 1 1 0 0 1
428
+pinnumber=31
429
+T 10900 14750 5 8 0 1 0 2 1
430
+pinseq=31
431
+T 10750 14800 9 8 1 1 0 6 1
432
+pinlabel=PD6 (T1)
433
+T 10750 14800 5 8 0 1 0 8 1
434
+pintype=io
435
+}
436
+P 11100 15000 10800 15000 1 0 0
437
+{
438
+T 10900 15050 5 8 1 1 0 0 1
439
+pinnumber=32
440
+T 10900 14950 5 8 0 1 0 2 1
441
+pinseq=32
442
+T 10750 15000 9 8 1 1 0 6 1
443
+pinlabel=PD7 (T2)
444
+T 10750 15000 5 8 0 1 0 8 1
445
+pintype=io
446
+}
447
+P 11100 15400 10800 15400 1 0 0
448
+{
449
+T 10900 15450 5 8 1 1 0 0 1
450
+pinnumber=35
451
+T 10900 15350 5 8 0 1 0 2 1
452
+pinseq=35
453
+T 10750 15400 9 8 1 1 0 6 1
454
+pinlabel=PC0 (A8)
455
+T 10750 15400 5 8 0 1 0 8 1
456
+pintype=io
457
+}
458
+P 11100 15600 10800 15600 1 0 0
459
+{
460
+T 10900 15650 5 8 1 1 0 0 1
461
+pinnumber=36
462
+T 10900 15550 5 8 0 1 0 2 1
463
+pinseq=36
464
+T 10750 15600 9 8 1 1 0 6 1
465
+pinlabel=PC1 (A9)
466
+T 10750 15600 5 8 0 1 0 8 1
467
+pintype=io
468
+}
469
+P 11100 15800 10800 15800 1 0 0
470
+{
471
+T 10900 15850 5 8 1 1 0 0 1
472
+pinnumber=37
473
+T 10900 15750 5 8 0 1 0 2 1
474
+pinseq=37
475
+T 10750 15800 9 8 1 1 0 6 1
476
+pinlabel=PC2 (A10)
477
+T 10750 15800 5 8 0 1 0 8 1
478
+pintype=io
479
+}
480
+P 11100 16000 10800 16000 1 0 0
481
+{
482
+T 10900 16050 5 8 1 1 0 0 1
483
+pinnumber=38
484
+T 10900 15950 5 8 0 1 0 2 1
485
+pinseq=38
486
+T 10750 16000 9 8 1 1 0 6 1
487
+pinlabel=PC3 (A11)
488
+T 10750 16000 5 8 0 1 0 8 1
489
+pintype=io
490
+}
491
+P 11100 16200 10800 16200 1 0 0
492
+{
493
+T 10900 16250 5 8 1 1 0 0 1
494
+pinnumber=39
495
+T 10900 16150 5 8 0 1 0 2 1
496
+pinseq=39
497
+T 10750 16200 9 8 1 1 0 6 1
498
+pinlabel=PC4 (A12)
499
+T 10750 16200 5 8 0 1 0 8 1
500
+pintype=io
501
+}
502
+P 11100 16400 10800 16400 1 0 0
503
+{
504
+T 10900 16450 5 8 1 1 0 0 1
505
+pinnumber=40
506
+T 10900 16350 5 8 0 1 0 2 1
507
+pinseq=40
508
+T 10750 16400 9 8 1 1 0 6 1
509
+pinlabel=PC5 (A13)
510
+T 10750 16400 5 8 0 1 0 8 1
511
+pintype=io
512
+}
513
+P 11100 16600 10800 16600 1 0 0
514
+{
515
+T 10900 16650 5 8 1 1 0 0 1
516
+pinnumber=41
517
+T 10900 16550 5 8 0 1 0 2 1
518
+pinseq=41
519
+T 10750 16600 9 8 1 1 0 6 1
520
+pinlabel=PC6 (A14)
521
+T 10750 16600 5 8 0 1 0 8 1
522
+pintype=io
523
+}
524
+P 11100 16800 10800 16800 1 0 0
525
+{
526
+T 10900 16850 5 8 1 1 0 0 1
527
+pinnumber=42
528
+T 10900 16750 5 8 0 1 0 2 1
529
+pinseq=42
530
+T 10750 16800 9 8 1 1 0 6 1
531
+pinlabel=PC7 (A15)
532
+T 10750 16800 5 8 0 1 0 8 1
533
+pintype=io
534
+}
535
+P 11100 17200 10800 17200 1 0 0
536
+{
537
+T 10900 17250 5 8 1 1 0 0 1
538
+pinnumber=10
539
+T 10900 17150 5 8 0 1 0 2 1
540
+pinseq=10
541
+T 10750 17200 9 8 1 1 0 6 1
542
+pinlabel=PB0 (nSS)
543
+T 10750 17200 5 8 0 1 0 8 1
544
+pintype=io
545
+}
546
+P 11100 17400 10800 17400 1 0 0
547
+{
548
+T 10900 17450 5 8 1 1 0 0 1
549
+pinnumber=11
550
+T 10900 17350 5 8 0 1 0 2 1
551
+pinseq=11
552
+T 10750 17400 9 8 1 1 0 6 1
553
+pinlabel=PB1 (SCK)
554
+T 10750 17400 5 8 0 1 0 8 1
555
+pintype=io
556
+}
557
+P 11100 17600 10800 17600 1 0 0
558
+{
559
+T 10900 17650 5 8 1 1 0 0 1
560
+pinnumber=12
561
+T 10900 17550 5 8 0 1 0 2 1
562
+pinseq=12
563
+T 10750 17600 9 8 1 1 0 6 1
564
+pinlabel=PB2 (MOSI)
565
+T 10750 17600 5 8 0 1 0 8 1
566
+pintype=io
567
+}
568
+P 11100 17800 10800 17800 1 0 0
569
+{
570
+T 10900 17850 5 8 1 1 0 0 1
571
+pinnumber=13
572
+T 10900 17750 5 8 0 1 0 2 1
573
+pinseq=13
574
+T 10750 17800 9 8 1 1 0 6 1
575
+pinlabel=PB3 (MISO)
576
+T 10750 17800 5 8 0 1 0 8 1
577
+pintype=io
578
+}
579
+P 11100 18000 10800 18000 1 0 0
580
+{
581
+T 10900 18050 5 8 1 1 0 0 1
582
+pinnumber=14
583
+T 10900 17950 5 8 0 1 0 2 1
584
+pinseq=14
585
+T 10750 18000 9 8 1 1 0 6 1
586
+pinlabel=PB4 (OC0)
587
+T 10750 18000 5 8 0 1 0 8 1
588
+pintype=io
589
+}
590
+P 11100 18200 10800 18200 1 0 0
591
+{
592
+T 10900 18250 5 8 1 1 0 0 1
593
+pinnumber=15
594
+T 10900 18150 5 8 0 1 0 2 1
595
+pinseq=15
596
+T 10750 18200 9 8 1 1 0 6 1
597
+pinlabel=PB5 (OC1A)
598
+T 10750 18200 5 8 0 1 0 8 1
599
+pintype=io
600
+}
601
+P 11100 18400 10800 18400 1 0 0
602
+{
603
+T 10900 18450 5 8 1 1 0 0 1
604
+pinnumber=16
605
+T 10900 18350 5 8 0 1 0 2 1
606
+pinseq=16
607
+T 10750 18400 9 8 1 1 0 6 1
608
+pinlabel=PB6 (OC1B)
609
+T 10750 18400 5 8 0 1 0 8 1
610
+pintype=io
611
+}
612
+P 11100 18600 10800 18600 1 0 0
613
+{
614
+T 10900 18650 5 8 1 1 0 0 1
615
+pinnumber=17
616
+T 10900 18550 5 8 0 1 0 2 1
617
+pinseq=17
618
+T 10750 18600 9 8 1 1 0 6 1
619
+pinlabel=PB7 (OC2/OC1C)
620
+T 10750 18600 5 8 0 1 0 8 1
621
+pintype=io
622
+}
623
+P 11100 19000 10800 19000 1 0 0
624
+{
625
+T 10900 19050 5 8 1 1 0 0 1
626
+pinnumber=51
627
+T 10900 18950 5 8 0 1 0 2 1
628
+pinseq=51
629
+T 10750 19000 9 8 1 1 0 6 1
630
+pinlabel=PA0 (AD0)
631
+T 10750 19000 5 8 0 1 0 8 1
632
+pintype=io
633
+}
634
+P 11100 19200 10800 19200 1 0 0
635
+{
636
+T 10900 19250 5 8 1 1 0 0 1
637
+pinnumber=50
638
+T 10900 19150 5 8 0 1 0 2 1
639
+pinseq=50
640
+T 10750 19200 9 8 1 1 0 6 1
641
+pinlabel=PA1 (AD1)
642
+T 10750 19200 5 8 0 1 0 8 1
643
+pintype=io
644
+}
645
+P 11100 19400 10800 19400 1 0 0
646
+{
647
+T 10900 19450 5 8 1 1 0 0 1
648
+pinnumber=49
649
+T 10900 19350 5 8 0 1 0 2 1
650
+pinseq=49
651
+T 10750 19400 9 8 1 1 0 6 1
652
+pinlabel=PA2 (AD2)
653
+T 10750 19400 5 8 0 1 0 8 1
654
+pintype=io
655
+}
656
+P 11100 19600 10800 19600 1 0 0
657
+{
658
+T 10900 19650 5 8 1 1 0 0 1
659
+pinnumber=48
660
+T 10900 19550 5 8 0 1 0 2 1
661
+pinseq=48
662
+T 10750 19600 9 8 1 1 0 6 1
663
+pinlabel=PA3 (AD3)
664
+T 10750 19600 5 8 0 1 0 8 1
665
+pintype=io
666
+}
667
+P 11100 19800 10800 19800 1 0 0
668
+{
669
+T 10900 19850 5 8 1 1 0 0 1
670
+pinnumber=47
671
+T 10900 19750 5 8 0 1 0 2 1
672
+pinseq=47
673
+T 10750 19800 9 8 1 1 0 6 1
674
+pinlabel=PA4 (AD4)
675
+T 10750 19800 5 8 0 1 0 8 1
676
+pintype=io
677
+}
678
+P 11100 20000 10800 20000 1 0 0
679
+{
680
+T 10900 20050 5 8 1 1 0 0 1
681
+pinnumber=46
682
+T 10900 19950 5 8 0 1 0 2 1
683
+pinseq=46
684
+T 10750 20000 9 8 1 1 0 6 1
685
+pinlabel=PA5 (AD5)
686
+T 10750 20000 5 8 0 1 0 8 1
687
+pintype=io
688
+}
689
+P 11100 20200 10800 20200 1 0 0
690
+{
691
+T 10900 20250 5 8 1 1 0 0 1
692
+pinnumber=45
693
+T 10900 20150 5 8 0 1 0 2 1
694
+pinseq=45
695
+T 10750 20200 9 8 1 1 0 6 1
696
+pinlabel=PA6 (AD6)
697
+T 10750 20200 5 8 0 1 0 8 1
698
+pintype=io
699
+}
700
+P 11100 20400 10800 20400 1 0 0
701
+{
702
+T 10900 20450 5 8 1 1 0 0 1
703
+pinnumber=44
704
+T 10900 20350 5 8 0 1 0 2 1
705
+pinseq=44
706
+T 10750 20400 9 8 1 1 0 6 1
707
+pinlabel=PA7 (AD7)
708
+T 10750 20400 5 8 0 1 0 8 1
709
+pintype=io
710
+}
711
+]
712
+{
713
+T 10800 20900 5 10 1 1 0 6 1
714
+refdes=IC2
715
+T 7600 20900 5 10 1 1 0 0 1
716
+value=ATMEGA128
717
+T 7700 17450 5 10 0 0 0 0 1
718
+device=ATMEGA128
719
+}
720
+C 22400 7800 1 0 0 EMBEDDEDRTL8019AS.sym
721
+[
722
+P 26300 8200 26000 8200 1 0 0
723
+{
724
+T 26100 8250 5 8 1 1 0 0 1
725
+pinnumber=86
726
+T 26100 8150 5 8 0 1 0 2 1
727
+pinseq=86
728
+T 25950 8200 9 8 1 1 0 6 1
729
+pinlabel=GND
730
+T 25950 8200 5 8 0 1 0 8 1
731
+pintype=pwr
732
+}
733
+B 22800 7800 3200 14200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
734
+T 22800 14850 5 10 0 0 0 0 1
735
+numslots=0
736
+P 22500 21600 22800 21600 1 0 0
737
+{
738
+T 22700 21650 5 8 1 1 0 6 1
739
+pinnumber=5
740
+T 22700 21550 5 8 0 1 0 8 1
741
+pinseq=5
742
+T 22850 21600 9 8 1 1 0 0 1
743
+pinlabel=SA0
744
+T 22850 21600 5 8 0 1 0 2 1
745
+pintype=in
746
+}
747
+P 22500 21400 22800 21400 1 0 0
748
+{
749
+T 22700 21450 5 8 1 1 0 6 1
750
+pinnumber=7
751
+T 22700 21350 5 8 0 1 0 8 1
752
+pinseq=7
753
+T 22850 21400 9 8 1 1 0 0 1
754
+pinlabel=SA1
755
+T 22850 21400 5 8 0 1 0 2 1
756
+pintype=in
757
+}
758
+P 22500 21200 22800 21200 1 0 0
759
+{
760
+T 22700 21250 5 8 1 1 0 6 1
761
+pinnumber=8
762
+T 22700 21150 5 8 0 1 0 8 1
763
+pinseq=8
764
+T 22850 21200 9 8 1 1 0 0 1
765
+pinlabel=SA2
766
+T 22850 21200 5 8 0 1 0 2 1
767
+pintype=in
768
+}
769
+P 22500 21000 22800 21000 1 0 0
770
+{
771
+T 22700 21050 5 8 1 1 0 6 1
772
+pinnumber=9
773
+T 22700 20950 5 8 0 1 0 8 1
774
+pinseq=9
775
+T 22850 21000 9 8 1 1 0 0 1
776
+pinlabel=SA3
777
+T 22850 21000 5 8 0 1 0 2 1
778
+pintype=in
779
+}
780
+P 22500 20800 22800 20800 1 0 0
781
+{
782
+T 22700 20850 5 8 1 1 0 6 1
783
+pinnumber=10
784
+T 22700 20750 5 8 0 1 0 8 1
785
+pinseq=10
786
+T 22850 20800 9 8 1 1 0 0 1
787
+pinlabel=SA4
788
+T 22850 20800 5 8 0 1 0 2 1
789
+pintype=in
790
+}
791
+P 22500 20600 22800 20600 1 0 0
792
+{
793
+T 22700 20650 5 8 1 1 0 6 1
794
+pinnumber=11
795
+T 22700 20550 5 8 0 1 0 8 1
796
+pinseq=11
797
+T 22850 20600 9 8 1 1 0 0 1
798
+pinlabel=SA5
799
+T 22850 20600 5 8 0 1 0 2 1
800
+pintype=in
801
+}
802
+P 22500 20400 22800 20400 1 0 0
803
+{
804
+T 22700 20450 5 8 1 1 0 6 1
805
+pinnumber=12
806
+T 22700 20350 5 8 0 1 0 8 1
807
+pinseq=12
808
+T 22850 20400 9 8 1 1 0 0 1
809
+pinlabel=SA6
810
+T 22850 20400 5 8 0 1 0 2 1
811
+pintype=in
812
+}
813
+P 22500 20200 22800 20200 1 0 0
814
+{
815
+T 22700 20250 5 8 1 1 0 6 1
816
+pinnumber=13
817
+T 22700 20150 5 8 0 1 0 8 1
818
+pinseq=13
819
+T 22850 20200 9 8 1 1 0 0 1
820
+pinlabel=SA7
821
+T 22850 20200 5 8 0 1 0 2 1
822
+pintype=in
823
+}
824
+P 22500 20000 22800 20000 1 0 0
825
+{
826
+T 22700 20050 5 8 1 1 0 6 1
827
+pinnumber=15
828
+T 22700 19950 5 8 0 1 0 8 1
829
+pinseq=15
830
+T 22850 20000 9 8 1 1 0 0 1
831
+pinlabel=SA8
832
+T 22850 20000 5 8 0 1 0 2 1
833
+pintype=in
834
+}
835
+P 22500 19800 22800 19800 1 0 0
836
+{
837
+T 22700 19850 5 8 1 1 0 6 1
838
+pinnumber=16
839
+T 22700 19750 5 8 0 1 0 8 1
840
+pinseq=16
841
+T 22850 19800 9 8 1 1 0 0 1
842
+pinlabel=SA9
843
+T 22850 19800 5 8 0 1 0 2 1
844
+pintype=in
845
+}
846
+P 22500 19600 22800 19600 1 0 0
847
+{
848
+T 22700 19650 5 8 1 1 0 6 1
849
+pinnumber=18
850
+T 22700 19550 5 8 0 1 0 8 1
851
+pinseq=18
852
+T 22850 19600 9 8 1 1 0 0 1
853
+pinlabel=SA10
854
+T 22850 19600 5 8 0 1 0 2 1
855
+pintype=in
856
+}
857
+P 22500 19400 22800 19400 1 0 0
858
+{
859
+T 22700 19450 5 8 1 1 0 6 1
860
+pinnumber=19
861
+T 22700 19350 5 8 0 1 0 8 1
862
+pinseq=19
863
+T 22850 19400 9 8 1 1 0 0 1
864
+pinlabel=SA11
865
+T 22850 19400 5 8 0 1 0 2 1
866
+pintype=in
867
+}
868
+P 22500 19200 22800 19200 1 0 0
869
+{
870
+T 22700 19250 5 8 1 1 0 6 1
871
+pinnumber=20
872
+T 22700 19150 5 8 0 1 0 8 1
873
+pinseq=20
874
+T 22850 19200 9 8 1 1 0 0 1
875
+pinlabel=SA12
876
+T 22850 19200 5 8 0 1 0 2 1
877
+pintype=in
878
+}
879
+P 22500 19000 22800 19000 1 0 0
880
+{
881
+T 22700 19050 5 8 1 1 0 6 1
882
+pinnumber=21
883
+T 22700 18950 5 8 0 1 0 8 1
884
+pinseq=21
885
+T 22850 19000 9 8 1 1 0 0 1
886
+pinlabel=SA13
887
+T 22850 19000 5 8 0 1 0 2 1
888
+pintype=in
889
+}
890
+P 22500 18800 22800 18800 1 0 0
891
+{
892
+T 22700 18850 5 8 1 1 0 6 1
893
+pinnumber=22
894
+T 22700 18750 5 8 0 1 0 8 1
895
+pinseq=22
896
+T 22850 18800 9 8 1 1 0 0 1
897
+pinlabel=SA14
898
+T 22850 18800 5 8 0 1 0 2 1
899
+pintype=in
900
+}
901
+P 22500 18600 22800 18600 1 0 0
902
+{
903
+T 22700 18650 5 8 1 1 0 6 1
904
+pinnumber=23
905
+T 22700 18550 5 8 0 1 0 8 1
906
+pinseq=23
907
+T 22850 18600 9 8 1 1 0 0 1
908
+pinlabel=SA15
909
+T 22850 18600 5 8 0 1 0 2 1
910
+pintype=in
911
+}
912
+P 22500 18400 22800 18400 1 0 0
913
+{
914
+T 22700 18450 5 8 1 1 0 6 1
915
+pinnumber=24
916
+T 22700 18350 5 8 0 1 0 8 1
917
+pinseq=24
918
+T 22850 18400 9 8 1 1 0 0 1
919
+pinlabel=SA16
920
+T 22850 18400 5 8 0 1 0 2 1
921
+pintype=in
922
+}
923
+P 22500 18200 22800 18200 1 0 0
924
+{
925
+T 22700 18250 5 8 1 1 0 6 1
926
+pinnumber=25
927
+T 22700 18150 5 8 0 1 0 8 1
928
+pinseq=25
929
+T 22850 18200 9 8 1 1 0 0 1
930
+pinlabel=SA17
931
+T 22850 18200 5 8 0 1 0 2 1
932
+pintype=in
933
+}
934
+P 22500 18000 22800 18000 1 0 0
935
+{
936
+T 22700 18050 5 8 1 1 0 6 1
937
+pinnumber=26
938
+T 22700 17950 5 8 0 1 0 8 1
939
+pinseq=26
940
+T 22850 18000 9 8 1 1 0 0 1
941
+pinlabel=SA18
942
+T 22850 18000 5 8 0 1 0 2 1
943
+pintype=in
944
+}
945
+P 22500 17800 22800 17800 1 0 0
946
+{
947
+T 22700 17850 5 8 1 1 0 6 1
948
+pinnumber=27
949
+T 22700 17750 5 8 0 1 0 8 1
950
+pinseq=27
951
+T 22850 17800 9 8 1 1 0 0 1
952
+pinlabel=SA19
953
+T 22850 17800 5 8 0 1 0 2 1
954
+pintype=in
955
+}
956
+P 22500 17200 22800 17200 1 0 0
957
+{
958
+T 22700 17250 5 8 1 1 0 6 1
959
+pinnumber=36
960
+T 22700 17150 5 8 0 1 0 8 1
961
+pinseq=36
962
+T 22850 17200 9 8 1 1 0 0 1
963
+pinlabel=SD0
964
+T 22850 17200 5 8 0 1 0 2 1
965
+pintype=io
966
+}
967
+P 22500 17000 22800 17000 1 0 0
968
+{
969
+T 22700 17050 5 8 1 1 0 6 1
970
+pinnumber=37
971
+T 22700 16950 5 8 0 1 0 8 1
972
+pinseq=37
973
+T 22850 17000 9 8 1 1 0 0 1
974
+pinlabel=SD1
975
+T 22850 17000 5 8 0 1 0 2 1
976
+pintype=io
977
+}
978
+P 22500 16800 22800 16800 1 0 0
979
+{
980
+T 22700 16850 5 8 1 1 0 6 1
981
+pinnumber=38
982
+T 22700 16750 5 8 0 1 0 8 1
983
+pinseq=38
984
+T 22850 16800 9 8 1 1 0 0 1
985
+pinlabel=SD2
986
+T 22850 16800 5 8 0 1 0 2 1
987
+pintype=io
988
+}
989
+P 22500 16600 22800 16600 1 0 0
990
+{
991
+T 22700 16650 5 8 1 1 0 6 1
992
+pinnumber=39
993
+T 22700 16550 5 8 0 1 0 8 1
994
+pinseq=39
995
+T 22850 16600 9 8 1 1 0 0 1
996
+pinlabel=SD3
997
+T 22850 16600 5 8 0 1 0 2 1
998
+pintype=io
999
+}
1000
+P 22500 16400 22800 16400 1 0 0
1001
+{
1002
+T 22700 16450 5 8 1 1 0 6 1
1003
+pinnumber=40
1004
+T 22700 16350 5 8 0 1 0 8 1
1005
+pinseq=40
1006
+T 22850 16400 9 8 1 1 0 0 1
1007
+pinlabel=SD4
1008
+T 22850 16400 5 8 0 1 0 2 1
1009
+pintype=io
1010
+}
1011
+P 22500 16200 22800 16200 1 0 0
1012
+{
1013
+T 22700 16250 5 8 1 1 0 6 1
1014
+pinnumber=41
1015
+T 22700 16150 5 8 0 1 0 8 1
1016
+pinseq=41
1017
+T 22850 16200 9 8 1 1 0 0 1
1018
+pinlabel=SD5
1019
+T 22850 16200 5 8 0 1 0 2 1
1020
+pintype=io
1021
+}
1022
+P 22500 16000 22800 16000 1 0 0
1023
+{
1024
+T 22700 16050 5 8 1 1 0 6 1
1025
+pinnumber=42
1026
+T 22700 15950 5 8 0 1 0 8 1
1027
+pinseq=42
1028
+T 22850 16000 9 8 1 1 0 0 1
1029
+pinlabel=SD6
1030
+T 22850 16000 5 8 0 1 0 2 1
1031
+pintype=io
1032
+}
1033
+P 22500 15800 22800 15800 1 0 0
1034
+{
1035
+T 22700 15850 5 8 1 1 0 6 1
1036
+pinnumber=43
1037
+T 22700 15750 5 8 0 1 0 8 1
1038
+pinseq=43
1039
+T 22850 15800 9 8 1 1 0 0 1
1040
+pinlabel=SD7
1041
+T 22850 15800 5 8 0 1 0 2 1
1042
+pintype=io
1043
+}
1044
+P 22500 15600 22800 15600 1 0 0
1045
+{
1046
+T 22700 15650 5 8 1 1 0 6 1
1047
+pinnumber=95
1048
+T 22700 15550 5 8 0 1 0 8 1
1049
+pinseq=95
1050
+T 22850 15600 9 8 1 1 0 0 1
1051
+pinlabel=SD8
1052
+T 22850 15600 5 8 0 1 0 2 1
1053
+pintype=io
1054
+}
1055
+P 22500 15400 22800 15400 1 0 0
1056
+{
1057
+T 22700 15450 5 8 1 1 0 6 1
1058
+pinnumber=94
1059
+T 22700 15350 5 8 0 1 0 8 1
1060
+pinseq=94
1061
+T 22850 15400 9 8 1 1 0 0 1
1062
+pinlabel=SD9
1063
+T 22850 15400 5 8 0 1 0 2 1
1064
+pintype=io
1065
+}
1066
+P 22500 15200 22800 15200 1 0 0
1067
+{
1068
+T 22700 15250 5 8 1 1 0 6 1
1069
+pinnumber=93
1070
+T 22700 15150 5 8 0 1 0 8 1
1071
+pinseq=93
1072
+T 22850 15200 9 8 1 1 0 0 1
1073
+pinlabel=SD10
1074
+T 22850 15200 5 8 0 1 0 2 1
1075
+pintype=io
1076
+}
1077
+P 22500 15000 22800 15000 1 0 0
1078
+{
1079
+T 22700 15050 5 8 1 1 0 6 1
1080
+pinnumber=92
1081
+T 22700 14950 5 8 0 1 0 8 1
1082
+pinseq=92
1083
+T 22850 15000 9 8 1 1 0 0 1
1084
+pinlabel=SD11
1085
+T 22850 15000 5 8 0 1 0 2 1
1086
+pintype=io
1087
+}
1088
+P 22500 14800 22800 14800 1 0 0
1089
+{
1090
+T 22700 14850 5 8 1 1 0 6 1
1091
+pinnumber=91
1092
+T 22700 14750 5 8 0 1 0 8 1
1093
+pinseq=91
1094
+T 22850 14800 9 8 1 1 0 0 1
1095
+pinlabel=SD12
1096
+T 22850 14800 5 8 0 1 0 2 1
1097
+pintype=io
1098
+}
1099
+P 22500 14600 22800 14600 1 0 0
1100
+{
1101
+T 22700 14650 5 8 1 1 0 6 1
1102
+pinnumber=90
1103
+T 22700 14550 5 8 0 1 0 8 1
1104
+pinseq=90
1105
+T 22850 14600 9 8 1 1 0 0 1
1106
+pinlabel=SD13
1107
+T 22850 14600 5 8 0 1 0 2 1
1108
+pintype=io
1109
+}
1110
+P 22500 14400 22800 14400 1 0 0
1111
+{
1112
+T 22700 14450 5 8 1 1 0 6 1
1113
+pinnumber=88
1114
+T 22700 14350 5 8 0 1 0 8 1
1115
+pinseq=88
1116
+T 22850 14400 9 8 1 1 0 0 1
1117
+pinlabel=SD14
1118
+T 22850 14400 5 8 0 1 0 2 1
1119
+pintype=io
1120
+}
1121
+P 22500 14200 22800 14200 1 0 0
1122
+{
1123
+T 22700 14250 5 8 1 1 0 6 1
1124
+pinnumber=87
1125
+T 22700 14150 5 8 0 1 0 8 1
1126
+pinseq=87
1127
+T 22850 14200 9 8 1 1 0 0 1
1128
+pinlabel=SD15
1129
+T 22850 14200 5 8 0 1 0 2 1
1130
+pintype=io
1131
+}
1132
+P 22500 13600 22800 13600 1 0 0
1133
+{
1134
+T 22700 13650 5 8 1 1 0 6 1
1135
+pinnumber=4
1136
+T 22700 13550 5 8 0 1 0 8 1
1137
+pinseq=4
1138
+T 22850 13600 9 8 1 1 0 0 1
1139
+pinlabel=INT0
1140
+T 22850 13600 5 8 0 1 0 2 1
1141
+pintype=out
1142
+}
1143
+P 22500 13400 22800 13400 1 0 0
1144
+{
1145
+T 22700 13450 5 8 1 1 0 6 1
1146
+pinnumber=3
1147
+T 22700 13350 5 8 0 1 0 8 1
1148
+pinseq=3
1149
+T 22850 13400 9 8 1 1 0 0 1
1150
+pinlabel=INT1
1151
+T 22850 13400 5 8 0 1 0 2 1
1152
+pintype=out
1153
+}
1154
+P 22500 13200 22800 13200 1 0 0
1155
+{
1156
+T 22700 13250 5 8 1 1 0 6 1
1157
+pinnumber=2
1158
+T 22700 13150 5 8 0 1 0 8 1
1159
+pinseq=2
1160
+T 22850 13200 9 8 1 1 0 0 1
1161
+pinlabel=INT2
1162
+T 22850 13200 5 8 0 1 0 2 1
1163
+pintype=out
1164
+}
1165
+P 22500 13000 22800 13000 1 0 0
1166
+{
1167
+T 22700 13050 5 8 1 1 0 6 1
1168
+pinnumber=1
1169
+T 22700 12950 5 8 0 1 0 8 1
1170
+pinseq=1
1171
+T 22850 13000 9 8 1 1 0 0 1
1172
+pinlabel=INT3
1173
+T 22850 13000 5 8 0 1 0 2 1
1174
+pintype=out
1175
+}
1176
+P 22500 12800 22800 12800 1 0 0
1177
+{
1178
+T 22700 12850 5 8 1 1 0 6 1
1179
+pinnumber=100
1180
+T 22700 12750 5 8 0 1 0 8 1
1181
+pinseq=100
1182
+T 22850 12800 9 8 1 1 0 0 1
1183
+pinlabel=INT4
1184
+T 22850 12800 5 8 0 1 0 2 1
1185
+pintype=out
1186
+}
1187
+P 22500 12600 22800 12600 1 0 0
1188
+{
1189
+T 22700 12650 5 8 1 1 0 6 1
1190
+pinnumber=99
1191
+T 22700 12550 5 8 0 1 0 8 1
1192
+pinseq=99
1193
+T 22850 12600 9 8 1 1 0 0 1
1194
+pinlabel=INT5
1195
+T 22850 12600 5 8 0 1 0 2 1
1196
+pintype=out
1197
+}
1198
+P 22500 12400 22800 12400 1 0 0
1199
+{
1200
+T 22700 12450 5 8 1 1 0 6 1
1201
+pinnumber=98
1202
+T 22700 12350 5 8 0 1 0 8 1
1203
+pinseq=98
1204
+T 22850 12400 9 8 1 1 0 0 1
1205
+pinlabel=INT6
1206
+T 22850 12400 5 8 0 1 0 2 1
1207
+pintype=out
1208
+}
1209
+P 22500 12200 22800 12200 1 0 0
1210
+{
1211
+T 22700 12250 5 8 1 1 0 6 1
1212
+pinnumber=97
1213
+T 22700 12150 5 8 0 1 0 8 1
1214
+pinseq=97
1215
+T 22850 12200 9 8 1 1 0 0 1
1216
+pinlabel=INT7
1217
+T 22850 12200 5 8 0 1 0 2 1
1218
+pintype=out
1219
+}
1220
+P 22500 11600 22800 11600 1 0 0
1221
+{
1222
+T 22700 11650 5 8 1 1 0 6 1
1223
+pinnumber=34
1224
+T 22700 11550 5 8 0 1 0 8 1
1225
+pinseq=34
1226
+T 22850 11600 9 8 1 1 0 0 1
1227
+pinlabel=AEN
1228
+T 22850 11600 5 8 0 1 0 2 1
1229
+pintype=in
1230
+}
1231
+P 22500 11400 22800 11400 1 0 0
1232
+{
1233
+T 22700 11450 5 8 1 1 0 6 1
1234
+pinnumber=35
1235
+T 22700 11350 5 8 0 1 0 8 1
1236
+pinseq=35
1237
+T 22850 11400 9 8 1 1 0 0 1
1238
+pinlabel=IOCHRDY
1239
+T 22850 11400 5 8 0 1 0 2 1
1240
+pintype=out
1241
+}
1242
+P 22500 11200 22800 11200 1 0 0
1243
+{
1244
+T 22700 11250 5 8 1 1 0 6 1
1245
+pinnumber=96
1246
+T 22700 11150 5 8 0 1 0 8 1
1247
+pinseq=96
1248
+T 22850 11200 9 8 1 1 0 0 1
1249
+pinlabel=IOCS16B
1250
+T 22850 11200 5 8 0 1 0 2 1
1251
+pintype=io
1252
+}
1253
+P 22500 11000 22800 11000 1 0 0
1254
+{
1255
+T 22700 11050 5 8 1 1 0 6 1
1256
+pinnumber=29
1257
+T 22700 10950 5 8 0 1 0 8 1
1258
+pinseq=29
1259
+T 22850 11000 9 8 1 1 0 0 1
1260
+pinlabel=IORB
1261
+T 22850 11000 5 8 0 1 0 2 1
1262
+pintype=in
1263
+}
1264
+P 22500 10800 22800 10800 1 0 0
1265
+{
1266
+T 22700 10850 5 8 1 1 0 6 1
1267
+pinnumber=30
1268
+T 22700 10750 5 8 0 1 0 8 1
1269
+pinseq=30
1270
+T 22850 10800 9 8 1 1 0 0 1
1271
+pinlabel=IOWB
1272
+T 22850 10800 5 8 0 1 0 2 1
1273
+pintype=in
1274
+}
1275
+P 22500 10600 22800 10600 1 0 0
1276
+{
1277
+T 22700 10650 5 8 1 1 0 6 1
1278
+pinnumber=31
1279
+T 22700 10550 5 8 0 1 0 8 1
1280
+pinseq=31
1281
+T 22850 10600 9 8 1 1 0 0 1
1282
+pinlabel=SMEMRB
1283
+T 22850 10600 5 8 0 1 0 2 1
1284
+pintype=in
1285
+}
1286
+P 22500 10400 22800 10400 1 0 0
1287
+{
1288
+T 22700 10450 5 8 1 1 0 6 1
1289
+pinnumber=32
1290
+T 22700 10350 5 8 0 1 0 8 1
1291
+pinseq=32
1292
+T 22850 10400 9 8 1 1 0 0 1
1293
+pinlabel=SMEMWB
1294
+T 22850 10400 5 8 0 1 0 2 1
1295
+pintype=in
1296
+}
1297
+P 22500 10200 22800 10200 1 0 0
1298
+{
1299
+T 22700 10250 5 8 1 1 0 6 1
1300
+pinnumber=33
1301
+T 22700 10150 5 8 0 1 0 8 1
1302
+pinseq=33
1303
+T 22850 10200 9 8 1 1 0 0 1
1304
+pinlabel=RSTDRV
1305
+T 22850 10200 5 8 0 1 0 2 1
1306
+pintype=in
1307
+}
1308
+P 26300 8400 26000 8400 1 0 0
1309
+{
1310
+T 26100 8450 5 8 1 1 0 0 1
1311
+pinnumber=83
1312
+T 26100 8350 5 8 0 1 0 2 1
1313
+pinseq=83
1314
+T 25950 8400 9 8 1 1 0 6 1
1315
+pinlabel=GND
1316
+T 25950 8400 5 8 0 1 0 8 1
1317
+pintype=pwr
1318
+}
1319
+P 26300 8600 26000 8600 1 0 0
1320
+{
1321
+T 26100 8650 5 8 1 1 0 0 1
1322
+pinnumber=52
1323
+T 26100 8550 5 8 0 1 0 2 1
1324
+pinseq=52
1325
+T 25950 8600 9 8 1 1 0 6 1
1326
+pinlabel=GND
1327
+T 25950 8600 5 8 0 1 0 8 1
1328
+pintype=pwr
1329
+}
1330
+P 26300 8800 26000 8800 1 0 0
1331
+{
1332
+T 26100 8850 5 8 1 1 0 0 1
1333
+pinnumber=44
1334
+T 26100 8750 5 8 0 1 0 2 1
1335
+pinseq=44
1336
+T 25950 8800 9 8 1 1 0 6 1
1337
+pinlabel=GND
1338
+T 25950 8800 5 8 0 1 0 8 1
1339
+pintype=pwr
1340
+}
1341
+P 26300 9000 26000 9000 1 0 0
1342
+{
1343
+T 26100 9050 5 8 1 1 0 0 1
1344
+pinnumber=28
1345
+T 26100 8950 5 8 0 1 0 2 1
1346
+pinseq=28
1347
+T 25950 9000 9 8 1 1 0 6 1
1348
+pinlabel=GND
1349
+T 25950 9000 5 8 0 1 0 8 1
1350
+pintype=pwr
1351
+}
1352
+P 26300 9200 26000 9200 1 0 0
1353
+{
1354
+T 26100 9250 5 8 1 1 0 0 1
1355
+pinnumber=14
1356
+T 26100 9150 5 8 0 1 0 2 1
1357
+pinseq=14
1358
+T 25950 9200 9 8 1 1 0 6 1
1359
+pinlabel=GND
1360
+T 25950 9200 5 8 0 1 0 8 1
1361
+pintype=pwr
1362
+}
1363
+P 26300 9800 26000 9800 1 0 0
1364
+{
1365
+T 26100 9850 5 8 1 1 0 0 1
1366
+pinnumber=89
1367
+T 26100 9750 5 8 0 1 0 2 1
1368
+pinseq=89
1369
+T 25950 9800 9 8 1 1 0 6 1
1370
+pinlabel=VCC
1371
+T 25950 9800 5 8 0 1 0 8 1
1372
+pintype=pwr
1373
+}
1374
+P 26300 10000 26000 10000 1 0 0
1375
+{
1376
+T 26100 10050 5 8 1 1 0 0 1
1377
+pinnumber=70
1378
+T 26100 9950 5 8 0 1 0 2 1
1379
+pinseq=70
1380
+T 25950 10000 9 8 1 1 0 6 1
1381
+pinlabel=VCC
1382
+T 25950 10000 5 8 0 1 0 8 1
1383
+pintype=pwr
1384
+}
1385
+P 26300 10200 26000 10200 1 0 0
1386
+{
1387
+T 26100 10250 5 8 1 1 0 0 1
1388
+pinnumber=57
1389
+T 26100 10150 5 8 0 1 0 2 1
1390
+pinseq=57
1391
+T 25950 10200 9 8 1 1 0 6 1
1392
+pinlabel=VCC
1393
+T 25950 10200 5 8 0 1 0 8 1
1394
+pintype=pwr
1395
+}
1396
+P 26300 10400 26000 10400 1 0 0
1397
+{
1398
+T 26100 10450 5 8 1 1 0 0 1
1399
+pinnumber=47
1400
+T 26100 10350 5 8 0 1 0 2 1
1401
+pinseq=47
1402
+T 25950 10400 9 8 1 1 0 6 1
1403
+pinlabel=VCC
1404
+T 25950 10400 5 8 0 1 0 8 1
1405
+pintype=pwr
1406
+}
1407
+P 26300 10600 26000 10600 1 0 0
1408
+{
1409
+T 26100 10650 5 8 1 1 0 0 1
1410
+pinnumber=17
1411
+T 26100 10550 5 8 0 1 0 2 1
1412
+pinseq=17
1413
+T 25950 10600 9 8 1 1 0 6 1
1414
+pinlabel=VCC
1415
+T 25950 10600 5 8 0 1 0 8 1
1416
+pintype=pwr
1417
+}
1418
+P 26300 10800 26000 10800 1 0 0
1419
+{
1420
+T 26100 10850 5 8 1 1 0 0 1
1421
+pinnumber=6
1422
+T 26100 10750 5 8 0 1 0 2 1
1423
+pinseq=6
1424
+T 25950 10800 9 8 1 1 0 6 1
1425
+pinlabel=VCC
1426
+T 25950 10800 5 8 0 1 0 8 1
1427
+pintype=pwr
1428
+}
1429
+P 26300 11400 26000 11400 1 0 0
1430
+{
1431
+T 26100 11450 5 8 1 1 0 0 1
1432
+pinnumber=65
1433
+T 26100 11350 5 8 0 1 0 2 1
1434
+pinseq=65
1435
+T 25950 11400 9 8 1 1 0 6 1
1436
+pinlabel=JP
1437
+T 25950 11400 5 8 0 1 0 8 1
1438
+pintype=in
1439
+}
1440
+P 26300 12000 26000 12000 1 0 0
1441
+{
1442
+T 26100 12050 5 8 1 1 0 0 1
1443
+pinnumber=51
1444
+T 26100 11950 5 8 0 1 0 2 1
1445
+pinseq=51
1446
+T 25950 12000 9 8 1 1 0 6 1
1447
+pinlabel=X2
1448
+T 25950 12000 5 8 0 1 0 8 1
1449
+pintype=out
1450
+}
1451
+P 26300 12200 26000 12200 1 0 0
1452
+{
1453
+T 26100 12250 5 8 1 1 0 0 1
1454
+pinnumber=50
1455
+T 26100 12150 5 8 0 1 0 2 1
1456
+pinseq=50
1457
+T 25950 12200 9 8 1 1 0 6 1
1458
+pinlabel=X1
1459
+T 25950 12200 5 8 0 1 0 8 1
1460
+pintype=in
1461
+}
1462
+P 26300 12800 26000 12800 1 0 0
1463
+{
1464
+T 26100 12850 5 8 1 1 0 0 1
1465
+pinnumber=63
1466
+T 26100 12750 5 8 0 1 0 2 1
1467
+pinseq=63
1468
+T 25950 12800 9 8 1 1 0 6 1
1469
+pinlabel=LED2
1470
+T 25950 12800 5 8 0 1 0 8 1
1471
+pintype=out
1472
+}
1473
+P 26300 13000 26000 13000 1 0 0
1474
+{
1475
+T 26100 13050 5 8 1 1 0 0 1
1476
+pinnumber=62
1477
+T 26100 12950 5 8 0 1 0 2 1
1478
+pinseq=62
1479
+T 25950 13000 9 8 1 1 0 6 1
1480
+pinlabel=LED1
1481
+T 25950 13000 5 8 0 1 0 8 1
1482
+pintype=out
1483
+}
1484
+P 26300 13200 26000 13200 1 0 0
1485
+{
1486
+T 26100 13250 5 8 1 1 0 0 1
1487
+pinnumber=61
1488
+T 26100 13150 5 8 0 1 0 2 1
1489
+pinseq=61
1490
+T 25950 13200 9 8 1 1 0 6 1
1491
+pinlabel=LED0
1492
+T 25950 13200 5 8 0 1 0 8 1
1493
+pintype=out
1494
+}
1495
+P 26300 13400 26000 13400 1 0 0
1496
+{
1497
+T 26100 13450 5 8 1 1 0 0 1
1498
+pinnumber=60
1499
+T 26100 13350 5 8 0 1 0 2 1
1500
+pinseq=60
1501
+T 25950 13400 9 8 1 1 0 6 1
1502
+pinlabel=LEDBNC
1503
+T 25950 13400 5 8 0 1 0 8 1
1504
+pintype=out
1505
+}
1506
+P 26300 14000 26000 14000 1 0 0
1507
+{
1508
+T 26100 14050 5 8 1 1 0 0 1
1509
+pinnumber=45
1510
+T 26100 13950 5 8 0 1 0 2 1
1511
+pinseq=45
1512
+T 25950 14000 9 8 1 1 0 6 1
1513
+pinlabel=TPOUT+
1514
+T 25950 14000 5 8 0 1 0 8 1
1515
+pintype=out
1516
+}
1517
+P 26300 14200 26000 14200 1 0 0
1518
+{
1519
+T 26100 14250 5 8 1 1 0 0 1
1520
+pinnumber=46
1521
+T 26100 14150 5 8 0 1 0 2 1
1522
+pinseq=46
1523
+T 25950 14200 9 8 1 1 0 6 1
1524
+pinlabel=TPOUT-
1525
+T 25950 14200 5 8 0 1 0 8 1
1526
+pintype=out
1527
+}
1528
+P 26300 14400 26000 14400 1 0 0
1529
+{
1530
+T 26100 14450 5 8 1 1 0 0 1
1531
+pinnumber=59
1532
+T 26100 14350 5 8 0 1 0 2 1
1533
+pinseq=59
1534
+T 25950 14400 9 8 1 1 0 6 1
1535
+pinlabel=TPIN+
1536
+T 25950 14400 5 8 0 1 0 8 1
1537
+pintype=in
1538
+}
1539
+P 26300 14600 26000 14600 1 0 0
1540
+{
1541
+T 26100 14650 5 8 1 1 0 0 1
1542
+pinnumber=58
1543
+T 26100 14550 5 8 0 1 0 2 1
1544
+pinseq=58
1545
+T 25950 14600 9 8 1 1 0 6 1
1546
+pinlabel=TPIN-
1547
+T 25950 14600 5 8 0 1 0 8 1
1548
+pintype=in
1549
+}
1550
+P 26300 15200 26000 15200 1 0 0
1551
+{
1552
+T 26100 15250 5 8 1 1 0 0 1
1553
+pinnumber=48
1554
+T 26100 15150 5 8 0 1 0 2 1
1555
+pinseq=48
1556
+T 25950 15200 9 8 1 1 0 6 1
1557
+pinlabel=TX-
1558
+T 25950 15200 5 8 0 1 0 8 1
1559
+pintype=out
1560
+}
1561
+P 26300 15400 26000 15400 1 0 0
1562
+{
1563
+T 26100 15450 5 8 1 1 0 0 1
1564
+pinnumber=49
1565
+T 26100 15350 5 8 0 1 0 2 1
1566
+pinseq=49
1567
+T 25950 15400 9 8 1 1 0 6 1
1568
+pinlabel=TX+
1569
+T 25950 15400 5 8 0 1 0 8 1
1570
+pintype=out
1571
+}
1572
+P 26300 15600 26000 15600 1 0 0
1573
+{
1574
+T 26100 15650 5 8 1 1 0 0 1
1575
+pinnumber=55
1576
+T 26100 15550 5 8 0 1 0 2 1
1577
+pinseq=55
1578
+T 25950 15600 9 8 1 1 0 6 1
1579
+pinlabel=RX-
1580
+T 25950 15600 5 8 0 1 0 8 1
1581
+pintype=in
1582
+}
1583
+P 26300 15800 26000 15800 1 0 0
1584
+{
1585
+T 26100 15850 5 8 1 1 0 0 1
1586
+pinnumber=56
1587
+T 26100 15750 5 8 0 1 0 2 1
1588
+pinseq=56
1589
+T 25950 15800 9 8 1 1 0 6 1
1590
+pinlabel=RX+
1591
+T 25950 15800 5 8 0 1 0 8 1
1592
+pintype=in
1593
+}
1594
+P 26300 16000 26000 16000 1 0 0
1595
+{
1596
+T 26100 16050 5 8 1 1 0 0 1
1597
+pinnumber=53
1598
+T 26100 15950 5 8 0 1 0 2 1
1599
+pinseq=53
1600
+T 25950 16000 9 8 1 1 0 6 1
1601
+pinlabel=CD-
1602
+T 25950 16000 5 8 0 1 0 8 1
1603
+pintype=in
1604
+}
1605
+P 26300 16200 26000 16200 1 0 0
1606
+{
1607
+T 26100 16250 5 8 1 1 0 0 1
1608
+pinnumber=54
1609
+T 26100 16150 5 8 0 1 0 2 1
1610
+pinseq=54
1611
+T 25950 16200 9 8 1 1 0 6 1
1612
+pinlabel=CD+
1613
+T 25950 16200 5 8 0 1 0 8 1
1614
+pintype=in
1615
+}
1616
+P 26300 16800 26000 16800 1 0 0
1617
+{
1618
+T 26100 16850 5 8 1 1 0 0 1
1619
+pinnumber=64
1620
+T 26100 16750 5 8 0 1 0 2 1
1621
+pinseq=64
1622
+T 25950 16800 9 8 1 1 0 6 1
1623
+pinlabel=AUI
1624
+T 25950 16800 5 8 0 1 0 8 1
1625
+pintype=in
1626
+}
1627
+P 26300 17400 26000 17400 1 0 0
1628
+{
1629
+T 26100 17450 5 8 1 1 0 0 1
1630
+pinnumber=76
1631
+T 26100 17350 5 8 0 1 0 2 1
1632
+pinseq=76
1633
+T 25950 17400 9 8 1 1 0 6 1
1634
+pinlabel=EECS
1635
+T 25950 17400 5 8 0 1 0 8 1
1636
+pintype=out
1637
+}
1638
+P 26300 17600 26000 17600 1 0 0
1639
+{
1640
+T 26100 17650 5 8 1 1 0 0 1
1641
+pinnumber=75
1642
+T 26100 17550 5 8 0 1 0 2 1
1643
+pinseq=75
1644
+T 25950 17600 9 8 1 1 0 6 1
1645
+pinlabel=BCSB
1646
+T 25950 17600 5 8 0 1 0 8 1
1647
+pintype=out
1648
+}
1649
+P 26300 18200 26000 18200 1 0 0
1650
+{
1651
+T 26100 18250 5 8 1 1 0 0 1
1652
+pinnumber=77
1653
+T 26100 18150 5 8 0 1 0 2 1
1654
+pinseq=77
1655
+T 25950 18200 9 8 1 1 0 6 1
1656
+pinlabel=BD7 EEDO
1657
+T 25950 18200 5 8 0 1 0 8 1
1658
+pintype=io
1659
+}
1660
+P 26300 18400 26000 18400 1 0 0
1661
+{
1662
+T 26100 18450 5 8 1 1 0 0 1
1663
+pinnumber=78
1664
+T 26100 18350 5 8 0 1 0 2 1
1665
+pinseq=78
1666
+T 25950 18400 9 8 1 1 0 6 1
1667
+pinlabel=BD6 EEDI
1668
+T 25950 18400 5 8 0 1 0 8 1
1669
+pintype=io
1670
+}
1671
+P 26300 18600 26000 18600 1 0 0
1672
+{
1673
+T 26100 18650 5 8 1 1 0 0 1
1674
+pinnumber=79
1675
+T 26100 18550 5 8 0 1 0 2 1
1676
+pinseq=79
1677
+T 25950 18600 9 8 1 1 0 6 1
1678
+pinlabel=BD5 EESK
1679
+T 25950 18600 5 8 0 1 0 8 1
1680
+pintype=io
1681
+}
1682
+P 26300 18800 26000 18800 1 0 0
1683
+{
1684
+T 26100 18850 5 8 1 1 0 0 1
1685
+pinnumber=80
1686
+T 26100 18750 5 8 0 1 0 2 1
1687
+pinseq=80
1688
+T 25950 18800 9 8 1 1 0 6 1
1689
+pinlabel=BD4
1690
+T 25950 18800 5 8 0 1 0 8 1
1691
+pintype=io
1692
+}
1693
+P 26300 19000 26000 19000 1 0 0
1694
+{
1695
+T 26100 19050 5 8 1 1 0 0 1
1696
+pinnumber=81
1697
+T 26100 18950 5 8 0 1 0 2 1
1698
+pinseq=81
1699
+T 25950 19000 9 8 1 1 0 6 1
1700
+pinlabel=BD3
1701
+T 25950 19000 5 8 0 1 0 8 1
1702
+pintype=io
1703
+}
1704
+P 26300 19200 26000 19200 1 0 0
1705
+{
1706
+T 26100 19250 5 8 1 1 0 0 1
1707
+pinnumber=82
1708
+T 26100 19150 5 8 0 1 0 2 1
1709
+pinseq=82
1710
+T 25950 19200 9 8 1 1 0 6 1
1711
+pinlabel=BD2
1712
+T 25950 19200 5 8 0 1 0 8 1
1713
+pintype=io
1714
+}
1715
+P 26300 19400 26000 19400 1 0 0
1716
+{
1717
+T 26100 19450 5 8 1 1 0 0 1
1718
+pinnumber=84
1719
+T 26100 19350 5 8 0 1 0 2 1
1720
+pinseq=84
1721
+T 25950 19400 9 8 1 1 0 6 1
1722
+pinlabel=BD1
1723
+T 25950 19400 5 8 0 1 0 8 1
1724
+pintype=io
1725
+}
1726
+P 26300 19600 26000 19600 1 0 0
1727
+{
1728
+T 26100 19650 5 8 1 1 0 0 1
1729
+pinnumber=85
1730
+T 26100 19550 5 8 0 1 0 2 1
1731
+pinseq=85
1732
+T 25950 19600 9 8 1 1 0 6 1
1733
+pinlabel=BD0
1734
+T 25950 19600 5 8 0 1 0 8 1
1735
+pintype=io
1736
+}
1737
+P 26300 20200 26000 20200 1 0 0
1738
+{
1739
+T 26100 20250 5 8 1 1 0 0 1
1740
+pinnumber=66
1741
+T 26100 20150 5 8 0 1 0 2 1
1742
+pinseq=66
1743
+T 25950 20200 9 8 1 1 0 6 1
1744
+pinlabel=BA21
1745
+T 25950 20200 5 8 0 1 0 8 1
1746
+pintype=out
1747
+}
1748
+P 26300 20400 26000 20400 1 0 0
1749
+{
1750
+T 26100 20450 5 8 1 1 0 0 1
1751
+pinnumber=67
1752
+T 26100 20350 5 8 0 1 0 2 1
1753
+pinseq=67
1754
+T 25950 20400 9 8 1 1 0 6 1
1755
+pinlabel=BA20
1756
+T 25950 20400 5 8 0 1 0 8 1
1757
+pintype=out
1758
+}
1759
+P 26300 20600 26000 20600 1 0 0
1760
+{
1761
+T 26100 20650 5 8 1 1 0 0 1
1762
+pinnumber=68
1763
+T 26100 20550 5 8 0 1 0 2 1
1764
+pinseq=68
1765
+T 25950 20600 9 8 1 1 0 6 1
1766
+pinlabel=BA19
1767
+T 25950 20600 5 8 0 1 0 8 1
1768
+pintype=out
1769
+}
1770
+P 26300 20800 26000 20800 1 0 0
1771
+{
1772
+T 26100 20850 5 8 1 1 0 0 1
1773
+pinnumber=69
1774
+T 26100 20750 5 8 0 1 0 2 1
1775
+pinseq=69
1776
+T 25950 20800 9 8 1 1 0 6 1
1777
+pinlabel=BA18
1778
+T 25950 20800 5 8 0 1 0 8 1
1779
+pintype=out
1780
+}
1781
+P 26300 21000 26000 21000 1 0 0
1782
+{
1783
+T 26100 21050 5 8 1 1 0 0 1
1784
+pinnumber=71
1785
+T 26100 20950 5 8 0 1 0 2 1
1786
+pinseq=71
1787
+T 25950 21000 9 8 1 1 0 6 1
1788
+pinlabel=BA17
1789
+T 25950 21000 5 8 0 1 0 8 1
1790
+pintype=out
1791
+}
1792
+P 26300 21200 26000 21200 1 0 0
1793
+{
1794
+T 26100 21250 5 8 1 1 0 0 1
1795
+pinnumber=72
1796
+T 26100 21150 5 8 0 1 0 2 1
1797
+pinseq=72
1798
+T 25950 21200 9 8 1 1 0 6 1
1799
+pinlabel=BA16
1800
+T 25950 21200 5 8 0 1 0 8 1
1801
+pintype=out
1802
+}
1803
+P 26300 21400 26000 21400 1 0 0
1804
+{
1805
+T 26100 21450 5 8 1 1 0 0 1
1806
+pinnumber=73
1807
+T 26100 21350 5 8 0 1 0 2 1
1808
+pinseq=73
1809
+T 25950 21400 9 8 1 1 0 6 1
1810
+pinlabel=BA15
1811
+T 25950 21400 5 8 0 1 0 8 1
1812
+pintype=out
1813
+}
1814
+P 26300 21600 26000 21600 1 0 0
1815
+{
1816
+T 26100 21650 5 8 1 1 0 0 1
1817
+pinnumber=74
1818
+T 26100 21550 5 8 0 1 0 2 1
1819
+pinseq=74
1820
+T 25950 21600 9 8 1 1 0 6 1
1821
+pinlabel=BA14
1822
+T 25950 21600 5 8 0 1 0 8 1
1823
+pintype=out
1824
+}
1825
+]
1826
+{
1827
+T 26000 22100 5 10 1 1 0 6 1
1828
+refdes=IC3
1829
+T 22800 22100 5 10 1 1 0 0 1
1830
+value=RTL8019AS
1831
+T 22800 13850 5 10 0 0 0 0 1
1832
+device=RTL8019AS
1833
+}
1834
+C 30700 16100 1 0 0 EMBEDDEDFB2022.sym
1835
+[
1836
+T 32700 18800 8 10 0 1 0 6 1
1837
+refdes=L?
1838
+T 31100 22150 5 10 0 0 0 0 1
1839
+device=ULN2803
1840
+P 30700 18400 31000 18400 1 0 0
1841
+{
1842
+T 30900 18450 5 8 1 1 0 6 1
1843
+pinnumber=1
1844
+T 30900 18350 5 8 0 1 0 8 1
1845
+pinseq=1
1846
+T 31050 18400 5 8 0 1 0 2 1
1847
+pintype=pas
1848
+}
1849
+P 33000 18400 32700 18400 1 0 0
1850
+{
1851
+T 32800 18450 5 8 1 1 0 0 1
1852
+pinnumber=12
1853
+T 32800 18350 5 8 0 1 0 2 1
1854
+pinseq=12
1855
+T 32650 18400 5 8 0 1 0 8 1
1856
+pintype=pas
1857
+}
1858
+B 31000 16100 1700 2600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
1859
+T 31100 23150 5 10 0 0 0 0 1
1860
+numslots=0
1861
+P 30700 18000 31000 18000 1 0 0
1862
+{
1863
+T 30900 18050 5 8 1 1 0 6 1
1864
+pinnumber=2
1865
+T 30900 17950 5 8 0 1 0 8 1
1866
+pinseq=2
1867
+T 31050 18000 5 8 0 1 0 2 1
1868
+pintype=pas
1869
+}
1870
+P 33000 18000 32700 18000 1 0 0
1871
+{
1872
+T 32800 18050 5 8 1 1 0 0 1
1873
+pinnumber=11
1874
+T 32800 17950 5 8 0 1 0 2 1
1875
+pinseq=11
1876
+T 32650 18000 5 8 0 1 0 8 1
1877
+pintype=pas
1878
+}
1879
+P 30700 17600 31000 17600 1 0 0
1880
+{
1881
+T 30900 17650 5 8 1 1 0 6 1
1882
+pinnumber=3
1883
+T 30900 17550 5 8 0 1 0 8 1
1884
+pinseq=3
1885
+T 31050 17600 5 8 0 1 0 2 1
1886
+pintype=pas
1887
+}
1888
+P 33000 17600 32700 17600 1 0 0
1889
+{
1890
+T 32800 17650 5 8 1 1 0 0 1
1891
+pinnumber=10
1892
+T 32800 17550 5 8 0 1 0 2 1
1893
+pinseq=10
1894
+T 32650 17600 5 8 0 1 0 8 1
1895
+pintype=pas
1896
+}
1897
+P 30700 17200 31000 17200 1 0 0
1898
+{
1899
+T 30900 17250 5 8 1 1 0 6 1
1900
+pinnumber=4
1901
+T 30900 17150 5 8 0 1 0 8 1
1902
+pinseq=4
1903
+T 31050 17200 5 8 0 1 0 2 1
1904
+pintype=pas
1905
+}
1906
+P 33000 17200 32700 17200 1 0 0
1907
+{
1908
+T 32800 17250 5 8 1 1 0 0 1
1909
+pinnumber=9
1910
+T 32800 17150 5 8 0 1 0 2 1
1911
+pinseq=9
1912
+T 32650 17200 5 8 0 1 0 8 1
1913
+pintype=pas
1914
+}
1915
+P 30700 16800 31000 16800 1 0 0
1916
+{
1917
+T 30900 16850 5 8 1 1 0 6 1
1918
+pinnumber=5
1919
+T 30900 16750 5 8 0 1 0 8 1
1920
+pinseq=5
1921
+T 31050 16800 5 8 0 1 0 2 1
1922
+pintype=pas
1923
+}
1924
+P 33000 16800 32700 16800 1 0 0
1925
+{
1926
+T 32800 16850 5 8 1 1 0 0 1
1927
+pinnumber=8
1928
+T 32800 16750 5 8 0 1 0 2 1
1929
+pinseq=8
1930
+T 32650 16800 5 8 0 1 0 8 1
1931
+pintype=pas
1932
+}
1933
+P 30700 16400 31000 16400 1 0 0
1934
+{
1935
+T 30900 16450 5 8 1 1 0 6 1
1936
+pinnumber=6
1937
+T 30900 16350 5 8 0 1 0 8 1
1938
+pinseq=6
1939
+T 31050 16400 5 8 0 1 0 2 1
1940
+pintype=pas
1941
+}
1942
+P 33000 16400 32700 16400 1 0 0
1943
+{
1944
+T 32800 16450 5 8 1 1 0 0 1
1945
+pinnumber=7
1946
+T 32800 16350 5 8 0 1 0 2 1
1947
+pinseq=7
1948
+T 32650 16400 5 8 0 1 0 8 1
1949
+pintype=pas
1950
+}
1951
+T 31000 18800 8 10 0 1 0 0 1
1952
+value=FB2022
1953
+B 31200 16300 600 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
1954
+T 31500 16800 9 10 1 0 90 4 1
1955
+LPF
1956
+L 31200 16400 31000 16400 3 0 0 0 -1 -1
1957
+L 31000 16800 31200 16800 3 0 0 0 -1 -1
1958
+L 31200 17200 31000 17200 3 0 0 0 -1 -1
1959
+L 31800 17200 32100 17200 3 0 0 0 -1 -1
1960
+L 31800 16800 32100 16800 3 0 0 0 -1 -1
1961
+L 31800 16400 32100 16400 3 0 0 0 -1 -1
1962
+A 32100 17100 100 270 180 3 0 0 0 -1 -1
1963
+A 32100 16900 100 270 180 3 0 0 0 -1 -1
1964
+A 32100 16700 100 270 180 3 0 0 0 -1 -1
1965
+A 32100 16500 100 270 180 3 0 0 0 -1 -1
1966
+L 32700 17200 32500 17200 3 0 0 0 -1 -1
1967
+L 32700 16800 32500 16800 3 0 0 0 -1 -1
1968
+L 32700 16400 32500 16400 3 0 0 0 -1 -1
1969
+A 32500 17100 100 90 180 3 0 0 0 -1 -1
1970
+A 32500 16900 100 90 180 3 0 0 0 -1 -1
1971
+A 32500 16700 100 90 180 3 0 0 0 -1 -1
1972
+A 32500 16500 100 90 180 3 0 0 0 -1 -1
1973
+B 31200 17500 600 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
1974
+L 31200 17600 31000 17600 3 0 0 0 -1 -1
1975
+L 31000 18000 31200 18000 3 0 0 0 -1 -1
1976
+L 31200 18400 31000 18400 3 0 0 0 -1 -1
1977
+L 31800 18400 32100 18400 3 0 0 0 -1 -1
1978
+L 31800 18000 32100 18000 3 0 0 0 -1 -1
1979
+L 31800 17600 32100 17600 3 0 0 0 -1 -1
1980
+A 32100 18300 100 270 180 3 0 0 0 -1 -1
1981
+A 32100 18100 100 270 180 3 0 0 0 -1 -1
1982
+A 32100 17900 100 270 180 3 0 0 0 -1 -1
1983
+A 32100 17700 100 270 180 3 0 0 0 -1 -1
1984
+L 32700 18400 32500 18400 3 0 0 0 -1 -1
1985
+L 32700 18000 32500 18000 3 0 0 0 -1 -1
1986
+L 32700 17600 32500 17600 3 0 0 0 -1 -1
1987
+A 32500 18300 100 90 180 3 0 0 0 -1 -1
1988
+A 32500 18100 100 90 180 3 0 0 0 -1 -1
1989
+A 32500 17900 100 90 180 3 0 0 0 -1 -1
1990
+A 32500 17700 100 90 180 3 0 0 0 -1 -1
1991
+T 31500 18000 9 10 1 0 90 4 1
1992
+LPF
1993
+B 32275 16300 50 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
1994
+B 32275 17500 50 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
1995
+]
1996
+{
1997
+T 32700 18800 5 10 1 1 0 6 1
1998
+refdes=L1
1999
+T 31000 18800 5 10 1 1 0 0 1
2000
+value=FB2022
2001
+}
2002
+N 26300 14000 28000 14000 4
2003
+N 29200 15900 29200 16400 4
2004
+N 29200 16400 30700 16400 4
2005
+N 30700 17200 28400 17200 4
2006
+N 28400 17200 28400 14400 4
2007
+N 28200 14200 26300 14200 4
2008
+N 26300 14400 28400 14400 4
2009
+N 28200 14200 28200 17600 4
2010
+N 28200 17600 30700 17600 4
2011
+N 28000 18400 28000 14000 4
2012
+N 29200 15900 28600 15900 4
2013
+C 30100 15000 1 90 0 EMBEDDEDcap.sym
2014
+[
2015
+P 29700 15000 29700 15200 1 0 0
2016
+{
2017
+T 29650 15100 5 8 0 1 90 0 1
2018
+pinnumber=1
2019
+T 29650 15100 5 8 0 0 90 0 1
2020
+pinseq=1
2021
+T 29700 15000 5 10 0 0 90 0 1
2022
+pintype=pas
2023
+}
2024
+P 29700 15900 29700 15700 1 0 0
2025
+{
2026
+T 29650 15700 5 8 0 1 90 0 1
2027
+pinnumber=2
2028
+T 29650 15700 5 8 0 0 90 0 1
2029
+pinseq=2
2030
+T 29700 15900 5 10 0 0 90 0 1
2031
+pintype=pas
2032
+}
2033
+L 29500 15400 29900 15400 3 0 0 0 -1 -1
2034
+L 29500 15500 29900 15500 3 0 0 0 -1 -1
2035
+L 29700 15700 29700 15500 3 0 0 0 -1 -1
2036
+L 29700 15400 29700 15200 3 0 0 0 -1 -1
2037
+T 29500 15300 5 10 0 0 90 0 1
2038
+device=capacitor
2039
+T 29400 15450 8 10 0 1 90 3 1
2040
+refdes=C?
2041
+T 30000 15450 8 10 0 1 90 5 1
2042
+value=?F
2043
+]
2044
+{
2045
+T 29650 15600 5 10 1 1 0 6 1
2046
+refdes=C14
2047
+T 29750 15300 5 10 1 1 0 2 1
2048
+value=10nF
2049
+}
2050
+C 30700 15000 1 90 0 EMBEDDEDcap.sym
2051
+[
2052
+P 30300 15000 30300 15200 1 0 0
2053
+{
2054
+T 30250 15100 5 8 0 1 90 0 1
2055
+pinnumber=1
2056
+T 30250 15100 5 8 0 0 90 0 1
2057
+pinseq=1
2058
+T 30300 15000 5 10 0 0 90 0 1
2059
+pintype=pas
2060
+}
2061
+P 30300 15900 30300 15700 1 0 0
2062
+{
2063
+T 30250 15700 5 8 0 1 90 0 1
2064
+pinnumber=2
2065
+T 30250 15700 5 8 0 0 90 0 1
2066
+pinseq=2
2067
+T 30300 15900 5 10 0 0 90 0 1
2068
+pintype=pas
2069
+}
2070
+L 30100 15400 30500 15400 3 0 0 0 -1 -1
2071
+L 30100 15500 30500 15500 3 0 0 0 -1 -1
2072
+L 30300 15700 30300 15500 3 0 0 0 -1 -1
2073
+L 30300 15400 30300 15200 3 0 0 0 -1 -1
2074
+T 30100 15300 5 10 0 0 90 0 1
2075
+device=capacitor
2076
+T 30000 15450 8 10 0 1 90 3 1
2077
+refdes=C?
2078
+T 30600 15450 8 10 0 1 90 5 1
2079
+value=?F
2080
+]
2081
+{
2082
+T 30250 15600 5 10 1 1 0 6 1
2083
+refdes=C15
2084
+T 30350 15300 5 10 1 1 0 2 1
2085
+value=10nF
2086
+}
2087
+N 30300 16800 30700 16800 4
2088
+N 30700 18000 29700 18000 4
2089
+C 29500 14300 1 0 0 EMBEDDEDgnd.sym
2090
+[
2091
+P 29700 14500 29700 14700 1 0 1
2092
+{
2093
+T 29758 14561 5 4 0 1 0 0 1
2094
+pinnumber=1
2095
+T 29758 14561 5 4 0 0 0 0 1
2096
+pinseq=1
2097
+T 29700 14500 5 10 0 0 0 0 1
2098
+pintype=pas
2099
+}
2100
+L 29600 14500 29800 14500 3 10 0 0 -1 -1
2101
+T 29800 14350 8 10 0 0 0 0 1
2102
+net=GND:1
2103
+T 29700 14400 8 10 0 1 0 5 1
2104
+value=GND
2105
+]
2106
+{
2107
+T 29700 14400 5 10 1 1 0 5 1
2108
+value=GND
2109
+}
2110
+C 30100 14300 1 0 0 EMBEDDEDgnd.sym
2111
+[
2112
+P 30300 14500 30300 14700 1 0 1
2113
+{
2114
+T 30358 14561 5 4 0 1 0 0 1
2115
+pinnumber=1
2116
+T 30358 14561 5 4 0 0 0 0 1
2117
+pinseq=1
2118
+T 30300 14500 5 10 0 0 0 0 1
2119
+pintype=pas
2120
+}
2121
+L 30200 14500 30400 14500 3 10 0 0 -1 -1
2122
+T 30400 14350 8 10 0 0 0 0 1
2123
+net=GND:1
2124
+T 30300 14400 8 10 0 1 0 5 1
2125
+value=GND
2126
+]
2127
+{
2128
+T 30300 14400 5 10 1 1 0 5 1
2129
+value=GND
2130
+}
2131
+N 30300 14700 30300 15000 4
2132
+N 29700 15000 29700 14700 4
2133
+C 34500 15000 1 90 0 EMBEDDEDcap.sym
2134
+[
2135
+P 34100 15000 34100 15200 1 0 0
2136
+{
2137
+T 34050 15100 5 8 0 1 90 0 1
2138
+pinnumber=1
2139
+T 34050 15100 5 8 0 0 90 0 1
2140
+pinseq=1
2141
+T 34100 15000 5 10 0 0 90 0 1
2142
+pintype=pas
2143
+}
2144
+P 34100 15900 34100 15700 1 0 0
2145
+{
2146
+T 34050 15700 5 8 0 1 90 0 1
2147
+pinnumber=2
2148
+T 34050 15700 5 8 0 0 90 0 1
2149
+pinseq=2
2150
+T 34100 15900 5 10 0 0 90 0 1
2151
+pintype=pas
2152
+}
2153
+L 33900 15400 34300 15400 3 0 0 0 -1 -1
2154
+L 33900 15500 34300 15500 3 0 0 0 -1 -1
2155
+L 34100 15700 34100 15500 3 0 0 0 -1 -1
2156
+L 34100 15400 34100 15200 3 0 0 0 -1 -1
2157
+T 33900 15300 5 10 0 0 90 0 1
2158
+device=capacitor
2159
+T 33800 15450 8 10 0 1 90 3 1
2160
+refdes=C?
2161
+T 34400 15450 8 10 0 1 90 5 1
2162
+value=?F
2163
+]
2164
+{
2165
+T 34050 15600 5 10 1 1 0 6 1
2166
+refdes=C17
2167
+T 34150 15300 5 10 1 1 0 2 1
2168
+value=10nF
2169
+}
2170
+N 34100 15900 34100 21800 4
2171
+N 33300 16800 33300 15900 4
2172
+N 34100 14700 34100 15000 4
2173
+N 33300 15000 33300 14700 4
2174
+C 33700 15000 1 90 0 EMBEDDEDcap.sym
2175
+[
2176
+P 33300 15000 33300 15200 1 0 0
2177
+{
2178
+T 33250 15100 5 8 0 1 90 0 1
2179
+pinnumber=1
2180
+T 33250 15100 5 8 0 0 90 0 1
2181
+pinseq=1
2182
+T 33300 15000 5 10 0 0 90 0 1
2183
+pintype=pas
2184
+}
2185
+P 33300 15900 33300 15700 1 0 0
2186
+{
2187
+T 33250 15700 5 8 0 1 90 0 1
2188
+pinnumber=2
2189
+T 33250 15700 5 8 0 0 90 0 1
2190
+pinseq=2
2191
+T 33300 15900 5 10 0 0 90 0 1
2192
+pintype=pas
2193
+}
2194
+L 33100 15400 33500 15400 3 0 0 0 -1 -1
2195
+L 33100 15500 33500 15500 3 0 0 0 -1 -1
2196
+L 33300 15700 33300 15500 3 0 0 0 -1 -1
2197
+L 33300 15400 33300 15200 3 0 0 0 -1 -1
2198
+T 33100 15300 5 10 0 0 90 0 1
2199
+device=capacitor
2200
+T 33000 15450 8 10 0 1 90 3 1
2201
+refdes=C?
2202
+T 33600 15450 8 10 0 1 90 5 1
2203
+value=?F
2204
+]
2205
+{
2206
+T 33350 15300 5 10 1 1 0 2 1
2207
+value=10nF
2208
+T 33250 15600 5 10 1 1 0 6 1
2209
+refdes=C16
2210
+}
2211
+C 26600 16100 1 0 0 EMBEDDEDgnd.sym
2212
+[
2213
+P 26800 16300 26800 16500 1 0 1
2214
+{
2215
+T 26858 16361 5 4 0 1 0 0 1
2216
+pinnumber=1
2217
+T 26858 16361 5 4 0 0 0 0 1
2218
+pinseq=1
2219
+T 26800 16300 5 10 0 0 0 0 1
2220
+pintype=pas
2221
+}
2222
+L 26700 16300 26900 16300 3 10 0 0 -1 -1
2223
+T 26900 16150 8 10 0 0 0 0 1
2224
+net=GND:1
2225
+T 26800 16200 8 10 0 1 0 5 1
2226
+value=GND
2227
+]
2228
+{
2229
+T 26800 16200 5 10 1 1 0 5 1
2230
+value=GND
2231
+}
2232
+N 26800 16800 26800 16500 4
2233
+N 26800 16800 26300 16800 4
2234
+C 29100 16100 1 90 0 EMBEDDEDres.sym
2235
+[
2236
+P 28800 17000 28800 16850 1 0 0
2237
+{
2238
+T 28750 16900 5 8 0 1 90 0 1
2239
+pinnumber=2
2240
+T 28750 16900 5 8 0 0 90 0 1
2241
+pinseq=2
2242
+T 28800 17000 5 10 0 0 90 0 1
2243
+pintype=pas
2244
+}
2245
+P 28800 16100 28800 16252 1 0 0
2246
+{
2247
+T 28750 16200 5 8 0 1 90 0 1
2248
+pinnumber=1
2249
+T 28750 16200 5 8 0 0 90 0 1
2250
+pinseq=1
2251
+T 28800 16100 5 10 0 0 90 0 1
2252
+pintype=pas
2253
+}
2254
+B 28700 16250 200 600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
2255
+T 28750 16500 5 10 0 0 90 0 1
2256
+device=resistor
2257
+T 28600 16550 8 10 0 1 90 3 1
2258
+refdes=R?
2259
+T 29000 16550 8 10 0 1 90 5 1
2260
+value=?E
2261
+]
2262
+{
2263
+T 28950 16700 5 10 1 1 0 0 1
2264
+refdes=R7
2265
+T 28950 16500 5 10 1 1 0 0 1
2266
+value=220E
2267
+}
2268
+N 28000 18400 30700 18400 4
2269
+C 36100 15200 1 0 0 EMBEDDEDcon8_gnd2.sym
2270
+[
2271
+P 35600 17200 35300 17200 1 0 1
2272
+{
2273
+T 35700 17200 5 8 1 1 0 1 1
2274
+pinnumber=2
2275
+T 36750 17150 5 8 0 0 0 6 1
2276
+pinseq=2
2277
+T 35600 17200 5 10 0 0 0 6 1
2278
+pintype=pas
2279
+}
2280
+P 35600 16800 35300 16800 1 0 1
2281
+{
2282
+T 35700 16800 5 8 1 1 0 1 1
2283
+pinnumber=4
2284
+T 36750 16750 5 8 0 0 0 6 1
2285
+pinseq=4
2286
+T 35600 16800 5 10 0 0 0 6 1
2287
+pintype=pas
2288
+}
2289
+P 35600 16400 35300 16400 1 0 1
2290
+{
2291
+T 35700 16400 5 8 1 1 0 1 1
2292
+pinnumber=6
2293
+T 36750 16350 5 8 0 0 0 6 1
2294
+pinseq=6
2295
+T 35600 16400 5 10 0 0 0 6 1
2296
+pintype=pas
2297
+}
2298
+P 35600 16000 35300 16000 1 0 1
2299
+{
2300
+T 35700 16000 5 8 1 1 0 1 1
2301
+pinnumber=8
2302
+T 36750 15950 5 8 0 0 0 6 1
2303
+pinseq=8
2304
+T 35600 16000 5 10 0 0 0 6 1
2305
+pintype=pas
2306
+}
2307
+P 35600 17400 35300 17400 1 0 1
2308
+{
2309
+T 35700 17400 5 8 1 1 0 1 1
2310
+pinnumber=1
2311
+T 36750 17350 5 8 0 0 0 6 1
2312
+pinseq=1
2313
+T 35600 17400 5 10 0 0 0 6 1
2314
+pintype=pas
2315
+}
2316
+P 35600 17000 35300 17000 1 0 1
2317
+{
2318
+T 35700 17000 5 8 1 1 0 1 1
2319
+pinnumber=3
2320
+T 36750 16950 5 8 0 0 0 6 1
2321
+pinseq=3
2322
+T 35600 17000 5 10 0 0 0 6 1
2323
+pintype=pas
2324
+}
2325
+P 35600 16600 35300 16600 1 0 1
2326
+{
2327
+T 35700 16600 5 8 1 1 0 1 1
2328
+pinnumber=5
2329
+T 36750 16550 5 8 0 0 0 6 1
2330
+pinseq=5
2331
+T 35600 16600 5 10 0 0 0 6 1
2332
+pintype=pas
2333
+}
2334
+P 35600 16200 35300 16200 1 0 1
2335
+{
2336
+T 35700 16200 5 8 1 1 0 1 1
2337
+pinnumber=7
2338
+T 36750 16150 5 8 0 0 0 6 1
2339
+pinseq=7
2340
+T 35600 16200 5 10 0 0 0 6 1
2341
+pintype=pas
2342
+}
2343
+B 35600 15400 500 2200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
2344
+T 34200 18200 5 10 0 0 0 6 1
2345
+device=8 pin connector
2346
+T 36100 17700 8 10 0 1 0 6 1
2347
+refdes=CON?
2348
+T 36100 15300 8 10 0 1 0 8 1
2349
+value=???
2350
+P 35600 15600 35300 15600 1 0 1
2351
+{
2352
+T 35700 15600 5 8 0 1 0 1 1
2353
+pinnumber=10
2354
+T 36750 15550 5 8 0 0 0 6 1
2355
+pinseq=10
2356
+T 35600 15600 5 10 0 0 0 6 1
2357
+pintype=pas
2358
+}
2359
+P 35600 15800 35300 15800 1 0 1
2360
+{
2361
+T 35700 15800 5 8 0 1 0 1 1
2362
+pinnumber=9
2363
+T 36750 15750 5 8 0 0 0 6 1
2364
+pinseq=9
2365
+T 35600 15800 5 10 0 0 0 6 1
2366
+pintype=pas
2367
+}
2368
+L 35600 15600 35775 15600 3 0 0 0 -1 -1
2369
+L 35800 15575 35800 15500 3 0 0 0 -1 -1
2370
+L 35900 15500 35700 15500 3 0 0 0 -1 -1
2371
+L 35800 15625 35800 15800 3 0 0 0 -1 -1
2372
+L 35800 15800 35600 15800 3 0 0 0 -1 -1
2373
+V 35800 15600 25 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
2374
+]
2375
+{
2376
+T 36100 17700 5 10 1 1 0 6 1
2377
+refdes=CON2
2378
+T 36100 15300 5 10 1 1 0 8 1
2379
+value=ETHERNET
2380
+}
2381
+N 28800 15900 28800 16100 4
2382
+N 28800 17000 28800 17200 4
2383
+N 33000 18400 35100 18400 4
2384
+N 35100 18400 35100 17400 4
2385
+N 35100 17400 35300 17400 4
2386
+N 35300 17200 34900 17200 4
2387
+N 34900 17200 34900 17600 4
2388
+N 34900 17600 33000 17600 4
2389
+N 33000 17200 34700 17200 4
2390
+N 34700 17200 34700 17000 4
2391
+N 34700 17000 35300 17000 4
2392
+N 33000 16400 35300 16400 4
2393
+N 35300 15800 34800 15800 4
2394
+N 34800 15600 35300 15600 4
2395
+N 28600 15900 28600 14600 4
2396
+N 28600 14600 26300 14600 4
2397
+C 28800 13300 1 0 0 EMBEDDEDres.sym
2398
+[
2399
+P 29700 13600 29550 13600 1 0 0
2400
+{
2401
+T 29600 13650 5 8 0 1 0 0 1
2402
+pinnumber=2
2403
+T 29600 13650 5 8 0 0 0 0 1
2404
+pinseq=2
2405
+T 29700 13600 5 10 0 0 0 0 1
2406
+pintype=pas
2407
+}
2408
+P 28800 13600 28952 13600 1 0 0
2409
+{
2410
+T 28900 13650 5 8 0 1 0 0 1
2411
+pinnumber=1
2412
+T 28900 13650 5 8 0 0 0 0 1
2413
+pinseq=1
2414
+T 28800 13600 5 10 0 0 0 0 1
2415
+pintype=pas
2416
+}
2417
+B 28950 13500 600 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
2418
+T 29200 13650 5 10 0 0 0 0 1
2419
+device=resistor
2420
+T 29250 13800 8 10 0 1 0 3 1
2421
+refdes=R?
2422
+T 29250 13400 8 10 0 1 0 5 1
2423
+value=?E
2424
+]
2425
+{
2426
+T 29650 13700 5 10 1 1 0 0 1
2427
+refdes=R8
2428
+T 29650 13500 5 10 1 1 0 2 1
2429
+value=1.5kE
2430
+}
2431
+C 31900 13300 1 0 0 EMBEDDEDled.sym
2432
+[
2433
+P 31900 13600 31700 13600 1 0 0
2434
+{
2435
+T 31800 13650 5 8 0 1 0 6 1
2436
+pinnumber=2
2437
+T 31800 13650 5 8 0 0 0 6 1
2438
+pinseq=2
2439
+T 31900 13600 5 10 0 0 0 6 1
2440
+pintype=pas
2441
+}
2442
+P 31200 13600 31400 13600 1 0 0
2443
+{
2444
+T 31400 13650 5 8 0 1 0 6 1
2445
+pinnumber=1
2446
+T 31400 13650 5 8 0 0 0 6 1
2447
+pinseq=1
2448
+T 31200 13600 5 10 0 0 0 6 1
2449
+pintype=pas
2450
+}
2451
+L 31600 13700 31500 13600 3 0 0 0 -1 -1
2452
+L 31500 13600 31600 13500 3 0 0 0 -1 -1
2453
+L 31600 13700 31600 13500 3 0 0 0 -1 -1
2454
+L 31500 13700 31500 13500 3 0 0 0 -1 -1
2455
+L 31500 13600 31400 13600 3 0 0 0 -1 -1
2456
+L 31600 13600 31700 13600 3 0 0 0 -1 -1
2457
+T 31300 14300 5 10 0 0 0 6 1
2458
+device=LED
2459
+T 31550 13800 8 10 0 1 0 3 1
2460
+refdes=LED?
2461
+L 31550 13775 31500 13775 3 0 0 0 -1 -1
2462
+L 31500 13725 31500 13775 3 0 0 0 -1 -1
2463
+L 31525 13775 31575 13725 3 0 0 0 -1 -1
2464
+L 31500 13750 31550 13700 3 0 0 0 -1 -1
2465
+T 31550 13400 8 10 0 1 0 5 1
2466
+value=???
2467
+]
2468
+{
2469
+T 31650 13800 5 10 1 1 0 1 1
2470
+refdes=LED2
2471
+T 31650 13500 5 10 1 1 0 2 1
2472
+value=green
2473
+}
2474
+C 30000 12900 1 0 0 EMBEDDEDres.sym
2475
+[
2476
+P 30900 13200 30750 13200 1 0 0
2477
+{
2478
+T 30800 13250 5 8 0 1 0 0 1
2479
+pinnumber=2
2480
+T 30800 13250 5 8 0 0 0 0 1
2481
+pinseq=2
2482
+T 30900 13200 5 10 0 0 0 0 1
2483
+pintype=pas
2484
+}
2485
+P 30000 13200 30152 13200 1 0 0
2486
+{
2487
+T 30100 13250 5 8 0 1 0 0 1
2488
+pinnumber=1
2489
+T 30100 13250 5 8 0 0 0 0 1
2490
+pinseq=1
2491
+T 30000 13200 5 10 0 0 0 0 1
2492
+pintype=pas
2493
+}
2494
+B 30150 13100 600 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
2495
+T 30400 13250 5 10 0 0 0 0 1
2496
+device=resistor
2497
+T 30450 13400 8 10 0 1 0 3 1
2498
+refdes=R?
2499
+T 30450 13000 8 10 0 1 0 5 1
2500
+value=?E
2501
+]
2502
+{
2503
+T 30850 13300 5 10 1 1 0 0 1
2504
+refdes=R9
2505
+T 30850 13100 5 10 1 1 0 2 1
2506
+value=1.5kE
2507
+}
2508
+C 32900 12900 1 0 0 EMBEDDEDled.sym
2509
+[
2510
+P 32900 13200 32700 13200 1 0 0
2511
+{
2512
+T 32800 13250 5 8 0 1 0 6 1
2513
+pinnumber=2
2514
+T 32800 13250 5 8 0 0 0 6 1
2515
+pinseq=2
2516
+T 32900 13200 5 10 0 0 0 6 1
2517
+pintype=pas
2518
+}
2519
+P 32200 13200 32400 13200 1 0 0
2520
+{
2521
+T 32400 13250 5 8 0 1 0 6 1
2522
+pinnumber=1
2523
+T 32400 13250 5 8 0 0 0 6 1
2524
+pinseq=1
2525
+T 32200 13200 5 10 0 0 0 6 1
2526
+pintype=pas
2527
+}
2528
+L 32600 13300 32500 13200 3 0 0 0 -1 -1
2529
+L 32500 13200 32600 13100 3 0 0 0 -1 -1
2530
+L 32600 13300 32600 13100 3 0 0 0 -1 -1
2531
+L 32500 13300 32500 13100 3 0 0 0 -1 -1
2532
+L 32500 13200 32400 13200 3 0 0 0 -1 -1
2533
+L 32600 13200 32700 13200 3 0 0 0 -1 -1
2534
+T 32300 13900 5 10 0 0 0 6 1
2535
+device=LED
2536
+T 32550 13400 8 10 0 1 0 3 1
2537
+refdes=LED?
2538
+L 32550 13375 32500 13375 3 0 0 0 -1 -1
2539
+L 32500 13325 32500 13375 3 0 0 0 -1 -1
2540
+L 32525 13375 32575 13325 3 0 0 0 -1 -1
2541
+L 32500 13350 32550 13300 3 0 0 0 -1 -1
2542
+T 32550 13000 8 10 0 1 0 5 1
2543
+value=???
2544
+]
2545
+{
2546
+T 32650 13400 5 10 1 1 0 1 1
2547
+refdes=LED3
2548
+T 32650 13100 5 10 1 1 0 2 1
2549
+value=yellow
2550
+}
2551
+C 28800 12500 1 0 0 EMBEDDEDres.sym
2552
+[
2553
+P 29700 12800 29550 12800 1 0 0
2554
+{
2555
+T 29600 12850 5 8 0 1 0 0 1
2556
+pinnumber=2
2557
+T 29600 12850 5 8 0 0 0 0 1
2558
+pinseq=2
2559
+T 29700 12800 5 10 0 0 0 0 1
2560
+pintype=pas
2561
+}
2562
+P 28800 12800 28952 12800 1 0 0
2563
+{
2564
+T 28900 12850 5 8 0 1 0 0 1
2565
+pinnumber=1
2566
+T 28900 12850 5 8 0 0 0 0 1
2567
+pinseq=1
2568
+T 28800 12800 5 10 0 0 0 0 1
2569
+pintype=pas
2570
+}
2571
+B 28950 12700 600 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
2572
+T 29200 12850 5 10 0 0 0 0 1
2573
+device=resistor
2574
+T 29250 13000 8 10 0 1 0 3 1
2575
+refdes=R?
2576
+T 29250 12600 8 10 0 1 0 5 1
2577
+value=?E
2578
+]
2579
+{
2580
+T 29650 12900 5 10 1 1 0 0 1
2581
+refdes=R10
2582
+T 29650 12700 5 10 1 1 0 2 1
2583
+value=1.5kE
2584
+}
2585
+C 31900 12500 1 0 0 EMBEDDEDled.sym
2586
+[
2587
+P 31900 12800 31700 12800 1 0 0
2588
+{
2589
+T 31800 12850 5 8 0 1 0 6 1
2590
+pinnumber=2
2591
+T 31800 12850 5 8 0 0 0 6 1
2592
+pinseq=2
2593
+T 31900 12800 5 10 0 0 0 6 1
2594
+pintype=pas
2595
+}
2596
+P 31200 12800 31400 12800 1 0 0
2597
+{
2598
+T 31400 12850 5 8 0 1 0 6 1
2599
+pinnumber=1
2600
+T 31400 12850 5 8 0 0 0 6 1
2601
+pinseq=1
2602
+T 31200 12800 5 10 0 0 0 6 1
2603
+pintype=pas
2604
+}
2605
+L 31600 12900 31500 12800 3 0 0 0 -1 -1
2606
+L 31500 12800 31600 12700 3 0 0 0 -1 -1
2607
+L 31600 12900 31600 12700 3 0 0 0 -1 -1
2608
+L 31500 12900 31500 12700 3 0 0 0 -1 -1
2609
+L 31500 12800 31400 12800 3 0 0 0 -1 -1
2610
+L 31600 12800 31700 12800 3 0 0 0 -1 -1
2611
+T 31300 13500 5 10 0 0 0 6 1
2612
+device=LED
2613
+T 31550 13000 8 10 0 1 0 3 1
2614
+refdes=LED?
2615
+L 31550 12975 31500 12975 3 0 0 0 -1 -1
2616
+L 31500 12925 31500 12975 3 0 0 0 -1 -1
2617
+L 31525 12975 31575 12925 3 0 0 0 -1 -1
2618
+L 31500 12950 31550 12900 3 0 0 0 -1 -1
2619
+T 31550 12600 8 10 0 1 0 5 1
2620
+value=???
2621
+]
2622
+{
2623
+T 31650 13000 5 10 1 1 0 1 1
2624
+refdes=LED4
2625
+T 31650 12700 5 10 1 1 0 2 1
2626
+value=yellow
2627
+}
2628
+N 29700 13600 31200 13600 4
2629
+N 30900 13200 32200 13200 4
2630
+N 31200 12800 29700 12800 4
2631
+N 30000 13200 28600 13200 4
2632
+N 28600 13200 28600 13000 4
2633
+N 28600 13000 26300 13000 4
2634
+N 26300 12800 28800 12800 4
2635
+N 26300 13200 28400 13200 4
2636
+N 31900 12800 33300 12800 4
2637
+N 33300 13200 32900 13200 4
2638
+N 31900 13600 33300 13600 4
2639
+C 33100 13800 1 0 0 EMBEDDEDvdd5.sym
2640
+[
2641
+P 33300 13900 33300 13800 1 0 1
2642
+{
2643
+T 33300 14000 3 6 0 1 0 0 1
2644
+pinnumber=1
2645
+T 33300 14000 3 6 0 0 0 0 1
2646
+pinseq=1
2647
+T 33300 13900 5 10 0 0 0 0 1
2648
+pintype=pas
2649
+}
2650
+V 33300 14000 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
2651
+L 33300 13950 33300 13900 3 0 0 0 -1 -1
2652
+T 33400 13850 8 10 0 0 0 0 1
2653
+net=VDD5:1
2654
+T 33300 14100 8 10 0 1 0 3 1
2655
+value=VDD5
2656
+]
2657
+{
2658
+T 33300 14100 5 10 1 1 0 3 1
2659
+value=VDD5
2660
+}
2661
+N 33300 12800 33300 13800 4
2662
+N 28400 13200 28400 13600 4
2663
+N 28400 13600 28800 13600 4
2664
+C 29700 10300 1 90 0 EMBEDDEDcap.sym
2665
+[
2666
+P 29300 10300 29300 10500 1 0 0
2667
+{
2668
+T 29250 10400 5 8 0 1 90 0 1
2669
+pinnumber=1
2670
+T 29250 10400 5 8 0 0 90 0 1
2671
+pinseq=1
2672
+T 29300 10300 5 10 0 0 90 0 1
2673
+pintype=pas
2674
+}
2675
+P 29300 11200 29300 11000 1 0 0
2676
+{
2677
+T 29250 11000 5 8 0 1 90 0 1
2678
+pinnumber=2
2679
+T 29250 11000 5 8 0 0 90 0 1
2680
+pinseq=2
2681
+T 29300 11200 5 10 0 0 90 0 1
2682
+pintype=pas
2683
+}
2684
+L 29100 10700 29500 10700 3 0 0 0 -1 -1
2685
+L 29100 10800 29500 10800 3 0 0 0 -1 -1
2686
+L 29300 11000 29300 10800 3 0 0 0 -1 -1
2687
+L 29300 10700 29300 10500 3 0 0 0 -1 -1
2688
+T 29100 10600 5 10 0 0 90 0 1
2689
+device=capacitor
2690
+T 29000 10750 8 10 0 1 90 3 1
2691
+refdes=C?
2692
+T 29600 10750 8 10 0 1 90 5 1
2693
+value=?F
2694
+]
2695
+{
2696
+T 29250 10900 5 10 1 1 0 6 1
2697
+refdes=C12
2698
+T 29350 10600 5 10 1 1 0 2 1
2699
+value=33pF
2700
+}
2701
+C 31200 10300 1 90 0 EMBEDDEDcap.sym
2702
+[
2703
+P 30800 10300 30800 10500 1 0 0
2704
+{
2705
+T 30750 10400 5 8 0 1 90 0 1
2706
+pinnumber=1
2707
+T 30750 10400 5 8 0 0 90 0 1
2708
+pinseq=1
2709
+T 30800 10300 5 10 0 0 90 0 1
2710
+pintype=pas
2711
+}
2712
+P 30800 11200 30800 11000 1 0 0
2713
+{
2714
+T 30750 11000 5 8 0 1 90 0 1
2715
+pinnumber=2
2716
+T 30750 11000 5 8 0 0 90 0 1
2717
+pinseq=2
2718
+T 30800 11200 5 10 0 0 90 0 1
2719
+pintype=pas
2720
+}
2721
+L 30600 10700 31000 10700 3 0 0 0 -1 -1
2722
+L 30600 10800 31000 10800 3 0 0 0 -1 -1
2723
+L 30800 11000 30800 10800 3 0 0 0 -1 -1
2724
+L 30800 10700 30800 10500 3 0 0 0 -1 -1
2725
+T 30600 10600 5 10 0 0 90 0 1
2726
+device=capacitor
2727
+T 30500 10750 8 10 0 1 90 3 1
2728
+refdes=C?
2729
+T 31100 10750 8 10 0 1 90 5 1
2730
+value=?F
2731
+]
2732
+{
2733
+T 30750 10900 5 10 1 1 0 6 1
2734
+refdes=C13
2735
+T 30850 10600 5 10 1 1 0 2 1
2736
+value=33pF
2737
+}
2738
+C 29100 9600 1 0 0 EMBEDDEDgnd.sym
2739
+[
2740
+P 29300 9800 29300 10000 1 0 1
2741
+{
2742
+T 29358 9861 5 4 0 1 0 0 1
2743
+pinnumber=1
2744
+T 29358 9861 5 4 0 0 0 0 1
2745
+pinseq=1
2746
+T 29300 9800 5 10 0 0 0 0 1
2747
+pintype=pas
2748
+}
2749
+L 29200 9800 29400 9800 3 10 0 0 -1 -1
2750
+T 29400 9650 8 10 0 0 0 0 1
2751
+net=GND:1
2752
+T 29300 9700 8 10 0 1 0 5 1
2753
+value=GND
2754
+]
2755
+{
2756
+T 29300 9700 5 10 1 1 0 5 1
2757
+value=GND
2758
+}
2759
+C 30600 9600 1 0 0 EMBEDDEDgnd.sym
2760
+[
2761
+P 30800 9800 30800 10000 1 0 1
2762
+{
2763
+T 30858 9861 5 4 0 1 0 0 1
2764
+pinnumber=1
2765
+T 30858 9861 5 4 0 0 0 0 1
2766
+pinseq=1
2767
+T 30800 9800 5 10 0 0 0 0 1
2768
+pintype=pas
2769
+}
2770
+L 30700 9800 30900 9800 3 10 0 0 -1 -1
2771
+T 30900 9650 8 10 0 0 0 0 1
2772
+net=GND:1
2773
+T 30800 9700 8 10 0 1 0 5 1
2774
+value=GND
2775
+]
2776
+{
2777
+T 30800 9700 5 10 1 1 0 5 1
2778
+value=GND
2779
+}
2780
+N 30800 10000 30800 10300 4
2781
+N 29300 10300 29300 10000 4
2782
+C 29700 11000 1 0 0 EMBEDDEDcrystal.sym
2783
+[
2784
+P 30300 11500 30150 11500 1 0 0
2785
+{
2786
+T 30200 11550 5 8 0 1 0 0 1
2787
+pinnumber=2
2788
+T 30200 11550 5 8 0 0 0 0 1
2789
+pinseq=2
2790
+T 30300 11500 5 10 0 0 0 0 1
2791
+pintype=pas
2792
+}
2793
+P 29800 11500 29952 11500 1 0 0
2794
+{
2795
+T 29900 11550 5 8 0 1 0 0 1
2796
+pinnumber=1
2797
+T 29900 11550 5 8 0 0 0 0 1
2798
+pinseq=1
2799
+T 29800 11500 5 10 0 0 0 0 1
2800
+pintype=pas
2801
+}
2802
+B 30000 11300 100 400 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
2803
+T 30100 11350 5 10 0 0 0 0 1
2804
+device=resistor
2805
+T 30050 11800 8 10 0 1 0 3 1
2806
+refdes=X?
2807
+T 30050 11200 8 10 0 1 0 5 1
2808
+value=?MHz
2809
+L 30150 11700 30150 11300 3 5 0 0 -1 -1
2810
+L 29950 11300 29950 11700 3 5 0 0 -1 -1
2811
+]
2812
+{
2813
+T 30050 11800 5 10 1 1 0 3 1
2814
+refdes=X2
2815
+T 30050 11200 5 10 1 1 0 5 1
2816
+value=20MHz
2817
+}
2818
+N 30300 11500 30800 11500 4
2819
+N 29300 11500 29800 11500 4
2820
+N 29300 11200 29300 12000 4
2821
+N 29300 12000 26300 12000 4
2822
+N 26300 12200 30800 12200 4
2823
+N 30800 11200 30800 12200 4
2824
+C 27700 8600 1 90 0 EMBEDDEDcap.sym
2825
+[
2826
+P 27300 8600 27300 8800 1 0 0
2827
+{
2828
+T 27250 8700 5 8 0 1 90 0 1
2829
+pinnumber=1
2830
+T 27250 8700 5 8 0 0 90 0 1
2831
+pinseq=1
2832
+T 27300 8600 5 10 0 0 90 0 1
2833
+pintype=pas
2834
+}
2835
+P 27300 9500 27300 9300 1 0 0
2836
+{
2837
+T 27250 9300 5 8 0 1 90 0 1
2838
+pinnumber=2
2839
+T 27250 9300 5 8 0 0 90 0 1
2840
+pinseq=2
2841
+T 27300 9500 5 10 0 0 90 0 1
2842
+pintype=pas
2843
+}
2844
+L 27100 9000 27500 9000 3 0 0 0 -1 -1
2845
+L 27100 9100 27500 9100 3 0 0 0 -1 -1
2846
+L 27300 9300 27300 9100 3 0 0 0 -1 -1
2847
+L 27300 9000 27300 8800 3 0 0 0 -1 -1
2848
+T 27100 8900 5 10 0 0 90 0 1
2849
+device=capacitor
2850
+T 27000 9050 8 10 0 1 90 3 1
2851
+refdes=C?
2852
+T 27600 9050 8 10 0 1 90 5 1
2853
+value=?F
2854
+]
2855
+{
2856
+T 27250 9200 5 10 1 1 0 6 1
2857
+refdes=C10
2858
+T 27350 8900 5 10 1 1 0 2 1
2859
+value=100nF
2860
+}
2861
+C 28700 8600 1 90 0 EMBEDDEDcap.sym
2862
+[
2863
+P 28300 8600 28300 8800 1 0 0
2864
+{
2865
+T 28250 8700 5 8 0 1 90 0 1
2866
+pinnumber=1
2867
+T 28250 8700 5 8 0 0 90 0 1
2868
+pinseq=1
2869
+T 28300 8600 5 10 0 0 90 0 1
2870
+pintype=pas
2871
+}
2872
+P 28300 9500 28300 9300 1 0 0
2873
+{
2874
+T 28250 9300 5 8 0 1 90 0 1
2875
+pinnumber=2
2876
+T 28250 9300 5 8 0 0 90 0 1
2877
+pinseq=2
2878
+T 28300 9500 5 10 0 0 90 0 1
2879
+pintype=pas
2880
+}
2881
+L 28100 9000 28500 9000 3 0 0 0 -1 -1
2882
+L 28100 9100 28500 9100 3 0 0 0 -1 -1
2883
+L 28300 9300 28300 9100 3 0 0 0 -1 -1
2884
+L 28300 9000 28300 8800 3 0 0 0 -1 -1
2885
+T 28100 8900 5 10 0 0 90 0 1
2886
+device=capacitor
2887
+T 28000 9050 8 10 0 1 90 3 1
2888
+refdes=C?
2889
+T 28600 9050 8 10 0 1 90 5 1
2890
+value=?F
2891
+]
2892
+{
2893
+T 28250 9200 5 10 1 1 0 6 1
2894
+refdes=C11
2895
+T 28350 8900 5 10 1 1 0 2 1
2896
+value=100nF
2897
+}
2898
+C 27100 7600 1 0 0 EMBEDDEDgnd.sym
2899
+[
2900
+P 27300 7800 27300 8000 1 0 1
2901
+{
2902
+T 27358 7861 5 4 0 1 0 0 1
2903
+pinnumber=1
2904
+T 27358 7861 5 4 0 0 0 0 1
2905
+pinseq=1
2906
+T 27300 7800 5 10 0 0 0 0 1
2907
+pintype=pas
2908
+}
2909
+L 27200 7800 27400 7800 3 10 0 0 -1 -1
2910
+T 27400 7650 8 10 0 0 0 0 1
2911
+net=GND:1
2912
+T 27300 7700 8 10 0 1 0 5 1
2913
+value=GND
2914
+]
2915
+{
2916
+T 27300 7700 5 10 1 1 0 5 1
2917
+value=GND
2918
+}
2919
+N 26500 8400 26300 8400 4
2920
+N 26300 8600 26500 8600 4
2921
+N 26500 8800 26300 8800 4
2922
+N 26300 9000 26500 9000 4
2923
+N 26300 9200 26500 9200 4
2924
+N 26500 8200 26500 9200 4
2925
+N 26500 10000 26300 10000 4
2926
+N 26300 10200 26500 10200 4
2927
+N 26500 10400 26300 10400 4
2928
+N 26300 10600 26500 10600 4
2929
+N 26300 10800 26500 10800 4
2930
+N 26300 11400 26500 11400 4
2931
+N 26500 9800 26500 11400 4
2932
+N 27300 9800 27300 9500 4
2933
+N 26300 9800 28300 9800 4
2934
+N 28300 9800 28300 9500 4
2935
+N 26300 8200 28300 8200 4
2936
+N 27300 8200 26500 8200 4
2937
+N 27300 8200 27300 8000 4
2938
+N 27300 9800 27300 10000 4
2939
+C 27100 10000 1 0 0 EMBEDDEDvdd5.sym
2940
+[
2941
+P 27300 10100 27300 10000 1 0 1
2942
+{
2943
+T 27300 10200 3 6 0 1 0 0 1
2944
+pinnumber=1
2945
+T 27300 10200 3 6 0 0 0 0 1
2946
+pinseq=1
2947
+T 27300 10100 5 10 0 0 0 0 1
2948
+pintype=pas
2949
+}
2950
+V 27300 10200 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
2951
+L 27300 10150 27300 10100 3 0 0 0 -1 -1
2952
+T 27400 10050 8 10 0 0 0 0 1
2953
+net=VDD5:1
2954
+T 27300 10300 8 10 0 1 0 3 1
2955
+value=VDD5
2956
+]
2957
+{
2958
+T 27300 10300 5 10 1 1 0 3 1
2959
+value=VDD5
2960
+}
2961
+C 19800 10900 1 0 0 EMBEDDEDres.sym
2962
+[
2963
+P 20700 11200 20550 11200 1 0 0
2964
+{
2965
+T 20600 11250 5 8 0 1 0 0 1
2966
+pinnumber=2
2967
+T 20600 11250 5 8 0 0 0 0 1
2968
+pinseq=2
2969
+T 20700 11200 5 10 0 0 0 0 1
2970
+pintype=pas
2971
+}
2972
+P 19800 11200 19952 11200 1 0 0
2973
+{
2974
+T 19900 11250 5 8 0 1 0 0 1
2975
+pinnumber=1
2976
+T 19900 11250 5 8 0 0 0 0 1
2977
+pinseq=1
2978
+T 19800 11200 5 10 0 0 0 0 1
2979
+pintype=pas
2980
+}
2981
+B 19950 11100 600 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
2982
+T 20200 11250 5 10 0 0 0 0 1
2983
+device=resistor
2984
+T 20250 11400 8 10 0 1 0 3 1
2985
+refdes=R?
2986
+T 20250 11000 8 10 0 1 0 5 1
2987
+value=?E
2988
+]
2989
+{
2990
+T 19850 11300 5 10 1 1 0 6 1
2991
+refdes=R6
2992
+T 20650 11300 5 10 1 1 0 0 1
2993
+value=27kE
2994
+}
2995
+N 22500 11200 20700 11200 4
2996
+N 22500 11600 21400 11600 4
2997
+N 19400 11200 19800 11200 4
2998
+N 19400 10000 19400 11200 4
2999
+N 22500 10400 21800 10400 4
3000
+N 21800 10600 22500 10600 4
3001
+N 21800 10400 21800 12000 4
3002
+C 21600 12000 1 0 0 EMBEDDEDvdd5.sym
3003
+[
3004
+P 21800 12100 21800 12000 1 0 1
3005
+{
3006
+T 21800 12200 3 6 0 1 0 0 1
3007
+pinnumber=1
3008
+T 21800 12200 3 6 0 0 0 0 1
3009
+pinseq=1
3010
+T 21800 12100 5 10 0 0 0 0 1
3011
+pintype=pas
3012
+}
3013
+V 21800 12200 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
3014
+L 21800 12150 21800 12100 3 0 0 0 -1 -1
3015
+T 21900 12050 8 10 0 0 0 0 1
3016
+net=VDD5:1
3017
+T 21800 12300 8 10 0 1 0 3 1
3018
+value=VDD5
3019
+]
3020
+{
3021
+T 21800 12300 5 10 1 1 0 3 1
3022
+value=VDD5
3023
+}
3024
+C 19200 9600 1 0 0 EMBEDDEDgnd.sym
3025
+[
3026
+P 19400 9800 19400 10000 1 0 1
3027
+{
3028
+T 19458 9861 5 4 0 1 0 0 1
3029
+pinnumber=1
3030
+T 19458 9861 5 4 0 0 0 0 1
3031
+pinseq=1
3032
+T 19400 9800 5 10 0 0 0 0 1
3033
+pintype=pas
3034
+}
3035
+L 19300 9800 19500 9800 3 10 0 0 -1 -1
3036
+T 19500 9650 8 10 0 0 0 0 1
3037
+net=GND:1
3038
+T 19400 9700 8 10 0 1 0 5 1
3039
+value=GND
3040
+]
3041
+{
3042
+T 19400 9700 5 10 1 1 0 5 1
3043
+value=GND
3044
+}
3045
+N 22500 11000 17800 11000 4
3046
+N 22500 10800 18000 10800 4
3047
+N 22500 10200 21200 10200 4
3048
+N 22500 13600 21400 13600 4
3049
+N 22500 20600 22300 20600 4
3050
+N 22300 20400 22500 20400 4
3051
+N 22500 20200 22300 20200 4
3052
+N 22500 20000 21800 20000 4
3053
+N 21800 19800 22500 19800 4
3054
+N 22500 19600 22300 19600 4
3055
+N 22300 19400 22500 19400 4
3056
+N 22500 19200 22300 19200 4
3057
+N 22300 17800 22300 20600 4
3058
+N 22300 19000 22500 19000 4
3059
+N 22500 18800 22300 18800 4
3060
+N 22300 18600 22500 18600 4
3061
+N 22500 18400 22300 18400 4
3062
+N 22300 18200 22500 18200 4
3063
+N 22500 18000 22300 18000 4
3064
+N 21800 19800 21800 20200 4
3065
+N 22300 17800 22500 17800 4
3066
+C 21600 17800 1 0 0 EMBEDDEDgnd.sym
3067
+[
3068
+P 21800 18000 21800 18200 1 0 1
3069
+{
3070
+T 21858 18061 5 4 0 1 0 0 1
3071
+pinnumber=1
3072
+T 21858 18061 5 4 0 0 0 0 1
3073
+pinseq=1
3074
+T 21800 18000 5 10 0 0 0 0 1
3075
+pintype=pas
3076
+}
3077
+L 21700 18000 21900 18000 3 10 0 0 -1 -1
3078
+T 21900 17850 8 10 0 0 0 0 1
3079
+net=GND:1
3080
+T 21800 17900 8 10 0 1 0 5 1
3081
+value=GND
3082
+]
3083
+{
3084
+T 21800 17900 5 10 1 1 0 5 1
3085
+value=GND
3086
+}
3087
+C 21600 20200 1 0 0 EMBEDDEDvdd5.sym
3088
+[
3089
+P 21800 20300 21800 20200 1 0 1
3090
+{
3091
+T 21800 20400 3 6 0 1 0 0 1
3092
+pinnumber=1
3093
+T 21800 20400 3 6 0 0 0 0 1
3094
+pinseq=1
3095
+T 21800 20300 5 10 0 0 0 0 1
3096
+pintype=pas
3097
+}
3098
+V 21800 20400 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
3099
+L 21800 20350 21800 20300 3 0 0 0 -1 -1
3100
+T 21900 20250 8 10 0 0 0 0 1
3101
+net=VDD5:1
3102
+T 21800 20500 8 10 0 1 0 3 1
3103
+value=VDD5
3104
+]
3105
+{
3106
+T 21800 20500 5 10 1 1 0 3 1
3107
+value=VDD5
3108
+}
3109
+N 22300 18400 21800 18400 4
3110
+N 21800 18200 21800 18400 4
3111
+N 22500 17200 19800 17200 4
3112
+N 19800 19000 11100 19000 4
3113
+N 11100 19200 19600 19200 4
3114
+N 19600 17000 22500 17000 4
3115
+N 22500 16800 19400 16800 4
3116
+N 19400 19400 11100 19400 4
3117
+N 11100 19600 19200 19600 4
3118
+N 19200 16600 22500 16600 4
3119
+N 19000 16400 22500 16400 4
3120
+N 19000 19800 11100 19800 4
3121
+N 11100 20000 18800 20000 4
3122
+N 18800 16200 22500 16200 4
3123
+N 22500 16000 18600 16000 4
3124
+N 18600 20200 11100 20200 4
3125
+N 18400 15800 22500 15800 4
3126
+N 18400 20400 11100 20400 4
3127
+N 22500 21600 17400 21600 4
3128
+N 22500 21400 17200 21400 4
3129
+N 22500 21200 17000 21200 4
3130
+N 16800 21900 16800 21000 4
3131
+N 16800 21000 22500 21000 4
3132
+N 22500 20800 16600 20800 4
3133
+N 16600 20800 16600 21700 4
3134
+N 11100 12400 21200 12400 4
3135
+N 11100 13200 18000 13200 4
3136
+N 11100 13000 17800 13000 4
3137
+N 21200 10200 21200 12400 4
3138
+N 11100 12800 21400 12800 4
3139
+N 21400 12800 21400 13600 4
3140
+C 15300 7500 1 0 0 EMBEDDEDcon10.sym
3141
+[
3142
+P 14800 9500 14500 9500 1 0 1
3143
+{
3144
+T 14900 9500 5 8 1 1 0 1 1
3145
+pinnumber=2
3146
+T 15950 9450 5 8 0 0 0 6 1
3147
+pinseq=2
3148
+T 14800 9500 5 10 0 0 0 6 1
3149
+pintype=pas
3150
+}
3151
+P 14800 9100 14500 9100 1 0 1
3152
+{
3153
+T 14900 9100 5 8 1 1 0 1 1
3154
+pinnumber=4
3155
+T 15950 9050 5 8 0 0 0 6 1
3156
+pinseq=4
3157
+T 14800 9100 5 10 0 0 0 6 1
3158
+pintype=pas
3159
+}
3160
+P 14800 8700 14500 8700 1 0 1
3161
+{
3162
+T 14900 8700 5 8 1 1 0 1 1
3163
+pinnumber=6
3164
+T 15950 8650 5 8 0 0 0 6 1
3165
+pinseq=6
3166
+T 14800 8700 5 10 0 0 0 6 1
3167
+pintype=pas
3168
+}
3169
+P 14800 8300 14500 8300 1 0 1
3170
+{
3171
+T 14900 8300 5 8 1 1 0 1 1
3172
+pinnumber=8
3173
+T 15950 8250 5 8 0 0 0 6 1
3174
+pinseq=8
3175
+T 14800 8300 5 10 0 0 0 6 1
3176
+pintype=pas
3177
+}
3178
+P 14800 9700 14500 9700 1 0 1
3179
+{
3180
+T 14900 9700 5 8 1 1 0 1 1
3181
+pinnumber=1
3182
+T 15950 9650 5 8 0 0 0 6 1
3183
+pinseq=1
3184
+T 14800 9700 5 10 0 0 0 6 1
3185
+pintype=pas
3186
+}
3187
+P 14800 9300 14500 9300 1 0 1
3188
+{
3189
+T 14900 9300 5 8 1 1 0 1 1
3190
+pinnumber=3
3191
+T 15950 9250 5 8 0 0 0 6 1
3192
+pinseq=3
3193
+T 14800 9300 5 10 0 0 0 6 1
3194
+pintype=pas
3195
+}
3196
+P 14800 8900 14500 8900 1 0 1
3197
+{
3198
+T 14900 8900 5 8 1 1 0 1 1
3199
+pinnumber=5
3200
+T 15950 8850 5 8 0 0 0 6 1
3201
+pinseq=5
3202
+T 14800 8900 5 10 0 0 0 6 1
3203
+pintype=pas
3204
+}
3205
+P 14800 8500 14500 8500 1 0 1
3206
+{
3207
+T 14900 8500 5 8 1 1 0 1 1
3208
+pinnumber=7
3209
+T 15950 8450 5 8 0 0 0 6 1
3210
+pinseq=7
3211
+T 14800 8500 5 10 0 0 0 6 1
3212
+pintype=pas
3213
+}
3214
+P 14800 7900 14500 7900 1 0 1
3215
+{
3216
+T 14900 7900 5 8 1 1 0 1 1
3217
+pinnumber=10
3218
+T 15950 7850 5 8 0 0 0 6 1
3219
+pinseq=10
3220
+T 14800 7900 5 10 0 0 0 6 1
3221
+pintype=pas
3222
+}
3223
+P 14800 8100 14500 8100 1 0 1
3224
+{
3225
+T 14900 8100 5 8 1 1 0 1 1
3226
+pinnumber=9
3227
+T 15950 8050 5 8 0 0 0 6 1
3228
+pinseq=9
3229
+T 14800 8100 5 10 0 0 0 6 1
3230
+pintype=pas
3231
+}
3232
+B 14800 7700 500 2200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
3233
+T 13400 10500 5 10 0 0 0 6 1
3234
+device=10 pin connector
3235
+T 15300 10000 8 10 0 1 0 6 1
3236
+refdes=CON?
3237
+T 15300 7600 8 10 0 1 0 8 1
3238
+value=???
3239
+]
3240
+{
3241
+T 15300 10000 5 10 1 1 0 6 1
3242
+refdes=CON9
3243
+T 15300 7600 5 10 1 1 0 8 1
3244
+value=DEBUG
3245
+}
3246
+N 14300 9300 14300 9500 4
3247
+N 14300 9300 14500 9300 4
3248
+N 14500 9100 14300 9100 4
3249
+N 14300 8700 14500 8700 4
3250
+N 14500 8300 14300 8300 4
3251
+N 14300 7700 14300 9100 4
3252
+N 14300 7900 14500 7900 4
3253
+C 14100 7300 1 0 0 EMBEDDEDgnd.sym
3254
+[
3255
+P 14300 7500 14300 7700 1 0 1
3256
+{
3257
+T 14358 7561 5 4 0 1 0 0 1
3258
+pinnumber=1
3259
+T 14358 7561 5 4 0 0 0 0 1
3260
+pinseq=1
3261
+T 14300 7500 5 10 0 0 0 0 1
3262
+pintype=pas
3263
+}
3264
+L 14200 7500 14400 7500 3 10 0 0 -1 -1
3265
+T 14400 7350 8 10 0 0 0 0 1
3266
+net=GND:1
3267
+T 14300 7400 8 10 0 1 0 5 1
3268
+value=GND
3269
+]
3270
+{
3271
+T 14300 7400 5 10 1 1 0 5 1
3272
+value=GND
3273
+}
3274
+N 12000 11800 11100 11800 4
3275
+N 12000 9700 14500 9700 4
3276
+N 14500 8100 12200 8100 4
3277
+N 12200 12000 11100 12000 4
3278
+N 14500 8500 13600 8500 4
3279
+N 13600 8500 13600 16100 4
3280
+N 14500 8900 13800 8900 4
3281
+N 13800 8900 13800 21200 4
3282
+N 13800 21200 7000 21200 4
3283
+N 7000 20400 7000 21200 4
3284
+C 5900 20100 1 0 0 EMBEDDEDres.sym
3285
+[
3286
+P 6800 20400 6650 20400 1 0 0
3287
+{
3288
+T 6700 20450 5 8 0 1 0 0 1
3289
+pinnumber=2
3290
+T 6700 20450 5 8 0 0 0 0 1
3291
+pinseq=2
3292
+T 6800 20400 5 10 0 0 0 0 1
3293
+pintype=pas
3294
+}
3295
+P 5900 20400 6052 20400 1 0 0
3296
+{
3297
+T 6000 20450 5 8 0 1 0 0 1
3298
+pinnumber=1
3299
+T 6000 20450 5 8 0 0 0 0 1
3300
+pinseq=1
3301
+T 5900 20400 5 10 0 0 0 0 1
3302
+pintype=pas
3303
+}
3304
+B 6050 20300 600 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
3305
+T 6300 20450 5 10 0 0 0 0 1
3306
+device=resistor
3307
+T 6350 20600 8 10 0 1 0 3 1
3308
+refdes=R?
3309
+T 6350 20200 8 10 0 1 0 5 1
3310
+value=?E
3311
+]
3312
+{
3313
+T 6350 20600 5 10 1 1 0 3 1
3314
+refdes=R1
3315
+T 6350 20200 5 10 1 1 0 5 1
3316
+value=10kE
3317
+}
3318
+C 3000 20800 1 0 0 EMBEDDEDvdd5.sym
3319
+[
3320
+P 3200 20900 3200 20800 1 0 1
3321
+{
3322
+T 3200 21000 3 6 0 1 0 0 1
3323
+pinnumber=1
3324
+T 3200 21000 3 6 0 0 0 0 1
3325
+pinseq=1
3326
+T 3200 20900 5 10 0 0 0 0 1
3327
+pintype=pas
3328
+}
3329
+V 3200 21000 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
3330
+L 3200 20950 3200 20900 3 0 0 0 -1 -1
3331
+T 3300 20850 8 10 0 0 0 0 1
3332
+net=VDD5:1
3333
+T 3200 21100 8 10 0 1 0 3 1
3334
+value=VDD5
3335
+]
3336
+{
3337
+T 3200 21100 5 10 1 1 0 3 1
3338
+value=VDD5
3339
+}
3340
+C 3900 17800 1 90 0 EMBEDDEDcap.sym
3341
+[
3342
+P 3500 17800 3500 18000 1 0 0
3343
+{
3344
+T 3450 17900 5 8 0 1 90 0 1
3345
+pinnumber=1
3346
+T 3450 17900 5 8 0 0 90 0 1
3347
+pinseq=1
3348
+T 3500 17800 5 10 0 0 90 0 1
3349
+pintype=pas
3350
+}
3351
+P 3500 18700 3500 18500 1 0 0
3352
+{
3353
+T 3450 18500 5 8 0 1 90 0 1
3354
+pinnumber=2
3355
+T 3450 18500 5 8 0 0 90 0 1
3356
+pinseq=2
3357
+T 3500 18700 5 10 0 0 90 0 1
3358
+pintype=pas
3359
+}
3360
+L 3300 18200 3700 18200 3 0 0 0 -1 -1
3361
+L 3300 18300 3700 18300 3 0 0 0 -1 -1
3362
+L 3500 18500 3500 18300 3 0 0 0 -1 -1
3363
+L 3500 18200 3500 18000 3 0 0 0 -1 -1
3364
+T 3300 18100 5 10 0 0 90 0 1
3365
+device=capacitor
3366
+T 3200 18250 8 10 0 1 90 3 1
3367
+refdes=C?
3368
+T 3800 18250 8 10 0 1 90 5 1
3369
+value=?F
3370
+]
3371
+{
3372
+T 3450 18400 5 10 1 1 0 6 1
3373
+refdes=C9
3374
+T 3550 18100 5 10 1 1 0 2 1
3375
+value=22pF
3376
+}
3377
+C 1800 16200 1 0 0 EMBEDDEDgnd.sym
3378
+[
3379
+P 2000 16400 2000 16600 1 0 1
3380
+{
3381
+T 2058 16461 5 4 0 1 0 0 1
3382
+pinnumber=1
3383
+T 2058 16461 5 4 0 0 0 0 1
3384
+pinseq=1
3385
+T 2000 16400 5 10 0 0 0 0 1
3386
+pintype=pas
3387
+}
3388
+L 1900 16400 2100 16400 3 10 0 0 -1 -1
3389
+T 2100 16250 8 10 0 0 0 0 1
3390
+net=GND:1
3391
+T 2000 16300 8 10 0 1 0 5 1
3392
+value=GND
3393
+]
3394
+{
3395
+T 2000 16300 5 10 1 1 0 5 1
3396
+value=GND
3397
+}
3398
+N 2000 17800 2000 16600 4
3399
+C 2400 18500 1 0 0 EMBEDDEDcrystal.sym
3400
+[
3401
+P 3000 19000 2850 19000 1 0 0
3402
+{
3403
+T 2900 19050 5 8 0 1 0 0 1
3404
+pinnumber=2
3405
+T 2900 19050 5 8 0 0 0 0 1
3406
+pinseq=2
3407
+T 3000 19000 5 10 0 0 0 0 1
3408
+pintype=pas
3409
+}
3410
+P 2500 19000 2652 19000 1 0 0
3411
+{
3412
+T 2600 19050 5 8 0 1 0 0 1
3413
+pinnumber=1
3414
+T 2600 19050 5 8 0 0 0 0 1
3415
+pinseq=1
3416
+T 2500 19000 5 10 0 0 0 0 1
3417
+pintype=pas
3418
+}
3419
+B 2700 18800 100 400 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
3420
+T 2800 18850 5 10 0 0 0 0 1
3421
+device=resistor
3422
+T 2750 19300 8 10 0 1 0 3 1
3423
+refdes=X?
3424
+T 2750 18700 8 10 0 1 0 5 1
3425
+value=?MHz
3426
+L 2850 19200 2850 18800 3 5 0 0 -1 -1
3427
+L 2650 18800 2650 19200 3 5 0 0 -1 -1
3428
+]
3429
+{
3430
+T 2750 19300 5 10 1 1 0 3 1
3431
+refdes=X1
3432
+T 2750 18700 5 10 1 1 0 5 1
3433
+value=16MHz
3434
+}
3435
+N 2000 19000 2500 19000 4
3436
+N 3500 18700 3500 19000 4
3437
+C 2400 17800 1 90 0 EMBEDDEDcap.sym
3438
+[
3439
+P 2000 17800 2000 18000 1 0 0
3440
+{
3441
+T 1950 17900 5 8 0 1 90 0 1
3442
+pinnumber=1
3443
+T 1950 17900 5 8 0 0 90 0 1
3444
+pinseq=1
3445
+T 2000 17800 5 10 0 0 90 0 1
3446
+pintype=pas
3447
+}
3448
+P 2000 18700 2000 18500 1 0 0
3449
+{
3450
+T 1950 18500 5 8 0 1 90 0 1
3451
+pinnumber=2
3452
+T 1950 18500 5 8 0 0 90 0 1
3453
+pinseq=2
3454
+T 2000 18700 5 10 0 0 90 0 1
3455
+pintype=pas
3456
+}
3457
+L 1800 18200 2200 18200 3 0 0 0 -1 -1
3458
+L 1800 18300 2200 18300 3 0 0 0 -1 -1
3459
+L 2000 18500 2000 18300 3 0 0 0 -1 -1
3460
+L 2000 18200 2000 18000 3 0 0 0 -1 -1
3461
+T 1800 18100 5 10 0 0 90 0 1
3462
+device=capacitor
3463
+T 1700 18250 8 10 0 1 90 3 1
3464
+refdes=C?
3465
+T 2300 18250 8 10 0 1 90 5 1
3466
+value=?F
3467
+]
3468
+{
3469
+T 2050 18100 5 10 1 1 0 2 1
3470
+value=22pF
3471
+T 1950 18400 5 10 1 1 0 6 1
3472
+refdes=C8
3473
+}
3474
+N 6800 20400 7300 20400 4
3475
+N 3000 19000 7300 19000 4
3476
+N 7300 19600 2000 19600 4
3477
+N 2000 18700 2000 19600 4
3478
+N 7100 17000 7300 17000 4
3479
+N 7100 16800 7100 18000 4
3480
+N 7100 18000 7300 18000 4
3481
+N 6900 9500 6900 18200 4
3482
+N 6900 17200 7300 17200 4
3483
+N 7300 17400 6900 17400 4
3484
+C 5600 17100 1 90 0 EMBEDDEDcap.sym
3485
+[
3486
+P 5200 17100 5200 17300 1 0 0
3487
+{
3488
+T 5150 17200 5 8 0 1 90 0 1
3489
+pinnumber=1
3490
+T 5150 17200 5 8 0 0 90 0 1
3491
+pinseq=1
3492
+T 5200 17100 5 10 0 0 90 0 1
3493
+pintype=pas
3494
+}
3495
+P 5200 18000 5200 17800 1 0 0
3496
+{
3497
+T 5150 17800 5 8 0 1 90 0 1
3498
+pinnumber=2
3499
+T 5150 17800 5 8 0 0 90 0 1
3500
+pinseq=2
3501
+T 5200 18000 5 10 0 0 90 0 1
3502
+pintype=pas
3503
+}
3504
+L 5000 17500 5400 17500 3 0 0 0 -1 -1
3505
+L 5000 17600 5400 17600 3 0 0 0 -1 -1
3506
+L 5200 17800 5200 17600 3 0 0 0 -1 -1
3507
+L 5200 17500 5200 17300 3 0 0 0 -1 -1
3508
+T 5000 17400 5 10 0 0 90 0 1
3509
+device=capacitor
3510
+T 4900 17550 8 10 0 1 90 3 1
3511
+refdes=C?
3512
+T 5500 17550 8 10 0 1 90 5 1
3513
+value=?F
3514
+]
3515
+{
3516
+T 5150 17700 5 10 1 1 0 6 1
3517
+refdes=C6
3518
+T 5250 17400 5 10 1 1 0 2 1
3519
+value=100nF
3520
+}
3521
+C 4700 17100 1 90 0 EMBEDDEDcap.sym
3522
+[
3523
+P 4300 17100 4300 17300 1 0 0
3524
+{
3525
+T 4250 17200 5 8 0 1 90 0 1
3526
+pinnumber=1
3527
+T 4250 17200 5 8 0 0 90 0 1
3528
+pinseq=1
3529
+T 4300 17100 5 10 0 0 90 0 1
3530
+pintype=pas
3531
+}
3532
+P 4300 18000 4300 17800 1 0 0
3533
+{
3534
+T 4250 17800 5 8 0 1 90 0 1
3535
+pinnumber=2
3536
+T 4250 17800 5 8 0 0 90 0 1
3537
+pinseq=2
3538
+T 4300 18000 5 10 0 0 90 0 1
3539
+pintype=pas
3540
+}
3541
+L 4100 17500 4500 17500 3 0 0 0 -1 -1
3542
+L 4100 17600 4500 17600 3 0 0 0 -1 -1
3543
+L 4300 17800 4300 17600 3 0 0 0 -1 -1
3544
+L 4300 17500 4300 17300 3 0 0 0 -1 -1
3545
+T 4100 17400 5 10 0 0 90 0 1
3546
+device=capacitor
3547
+T 4000 17550 8 10 0 1 90 3 1
3548
+refdes=C?
3549
+T 4600 17550 8 10 0 1 90 5 1
3550
+value=?F
3551
+]
3552
+{
3553
+T 4250 17700 5 10 1 1 0 6 1
3554
+refdes=C5
3555
+T 4350 17400 5 10 1 1 0 2 1
3556
+value=100nF
3557
+}
3558
+N 4300 18200 7300 18200 4
3559
+N 5200 18200 5200 18000 4
3560
+N 5200 16800 5200 17100 4
3561
+N 4300 16800 4300 17100 4
3562
+N 6900 14800 7300 14800 4
3563
+N 2000 16800 7300 16800 4
3564
+N 3500 16800 3500 17800 4
3565
+N 7600 10200 7600 10500 4
3566
+C 9700 10200 1 0 0 EMBEDDEDres.sym
3567
+[
3568
+P 10600 10500 10450 10500 1 0 0
3569
+{
3570
+T 10500 10550 5 8 0 1 0 0 1
3571
+pinnumber=2
3572
+T 10500 10550 5 8 0 0 0 0 1
3573
+pinseq=2
3574
+T 10600 10500 5 10 0 0 0 0 1
3575
+pintype=pas
3576
+}
3577
+P 9700 10500 9852 10500 1 0 0
3578
+{
3579
+T 9800 10550 5 8 0 1 0 0 1
3580
+pinnumber=1
3581
+T 9800 10550 5 8 0 0 0 0 1
3582
+pinseq=1
3583
+T 9700 10500 5 10 0 0 0 0 1
3584
+pintype=pas
3585
+}
3586
+B 9850 10400 600 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
3587
+T 10100 10550 5 10 0 0 0 0 1
3588
+device=resistor
3589
+T 10150 10700 8 10 0 1 0 3 1
3590
+refdes=R?
3591
+T 10150 10300 8 10 0 1 0 5 1
3592
+value=?E
3593
+]
3594
+{
3595
+T 10150 10700 5 10 1 1 0 3 1
3596
+refdes=R5
3597
+T 10150 10300 5 10 1 1 0 5 1
3598
+value=1.5kE
3599
+}
3600
+C 9100 10200 1 0 0 EMBEDDEDled.sym
3601
+[
3602
+P 9100 10500 8900 10500 1 0 0
3603
+{
3604
+T 9000 10550 5 8 0 1 0 6 1
3605
+pinnumber=2
3606
+T 9000 10550 5 8 0 0 0 6 1
3607
+pinseq=2
3608
+T 9100 10500 5 10 0 0 0 6 1
3609
+pintype=pas
3610
+}
3611
+P 8400 10500 8600 10500 1 0 0
3612
+{
3613
+T 8600 10550 5 8 0 1 0 6 1
3614
+pinnumber=1
3615
+T 8600 10550 5 8 0 0 0 6 1
3616
+pinseq=1
3617
+T 8400 10500 5 10 0 0 0 6 1
3618
+pintype=pas
3619
+}
3620
+L 8800 10600 8700 10500 3 0 0 0 -1 -1
3621
+L 8700 10500 8800 10400 3 0 0 0 -1 -1
3622
+L 8800 10600 8800 10400 3 0 0 0 -1 -1
3623
+L 8700 10600 8700 10400 3 0 0 0 -1 -1
3624
+L 8700 10500 8600 10500 3 0 0 0 -1 -1
3625
+L 8800 10500 8900 10500 3 0 0 0 -1 -1
3626
+T 8500 11200 5 10 0 0 0 6 1
3627
+device=LED
3628
+T 8750 10700 8 10 0 1 0 3 1
3629
+refdes=LED?
3630
+L 8750 10675 8700 10675 3 0 0 0 -1 -1
3631
+L 8700 10625 8700 10675 3 0 0 0 -1 -1
3632
+L 8725 10675 8775 10625 3 0 0 0 -1 -1
3633
+L 8700 10650 8750 10600 3 0 0 0 -1 -1
3634
+T 8750 10300 8 10 0 1 0 5 1
3635
+value=???
3636
+]
3637
+{
3638
+T 8750 10800 5 10 1 1 0 3 1
3639
+refdes=LED1
3640
+T 8750 10300 5 10 1 1 0 5 1
3641
+value=green
3642
+}
3643
+N 9700 10500 9100 10500 4
3644
+N 8400 10500 7600 10500 4
3645
+C 7400 9800 1 0 0 EMBEDDEDgnd.sym
3646
+[
3647
+P 7600 10000 7600 10200 1 0 1
3648
+{
3649
+T 7658 10061 5 4 0 1 0 0 1
3650
+pinnumber=1
3651
+T 7658 10061 5 4 0 0 0 0 1
3652
+pinseq=1
3653
+T 7600 10000 5 10 0 0 0 0 1
3654
+pintype=pas
3655
+}
3656
+L 7500 10000 7700 10000 3 10 0 0 -1 -1
3657
+T 7700 9850 8 10 0 0 0 0 1
3658
+net=GND:1
3659
+T 7600 9900 8 10 0 1 0 5 1
3660
+value=GND
3661
+]
3662
+{
3663
+T 7600 9900 5 10 1 1 0 5 1
3664
+value=GND
3665
+}
3666
+C 2800 29600 1 270 0 EMBEDDEDcap_pol.sym
3667
+[
3668
+P 3200 29600 3200 29400 1 0 0
3669
+{
3670
+T 3250 29500 5 8 0 1 270 0 1
3671
+pinnumber=1
3672
+T 3250 29500 5 8 0 0 270 0 1
3673
+pinseq=1
3674
+T 3200 29600 5 10 0 0 270 0 1
3675
+pintype=pas
3676
+}
3677
+P 3200 28700 3200 28900 1 0 0
3678
+{
3679
+T 3250 28900 5 8 0 1 270 0 1
3680
+pinnumber=2
3681
+T 3250 28900 5 8 0 0 270 0 1
3682
+pinseq=2
3683
+T 3200 28700 5 10 0 0 270 0 1
3684
+pintype=pas
3685
+}
3686
+L 3400 29200 3000 29200 3 0 0 0 -1 -1
3687
+L 3200 28900 3200 29100 3 0 0 0 -1 -1
3688
+L 3200 29200 3200 29400 3 0 0 0 -1 -1
3689
+L 3400 29311 3300 29311 3 0 0 0 -1 -1
3690
+L 3349 29260 3349 29360 3 0 0 0 -1 -1
3691
+L 3400 29100 3000 29100 3 0 0 0 -1 -1
3692
+T 3400 29200 5 10 0 0 270 0 1
3693
+device=polarized capacitor
3694
+T 3500 29150 8 10 0 1 270 3 1
3695
+refdes=C?
3696
+T 2900 29150 8 10 0 1 270 5 1
3697
+value=?F
3698
+]
3699
+{
3700
+T 3150 29300 5 10 1 1 0 6 1
3701
+refdes=C1
3702
+T 3350 29000 5 10 1 1 0 2 1
3703
+value=100uF
3704
+T 3350 28800 5 10 1 1 0 2 1
3705
+description=16V
3706
+}
3707
+C 3800 29600 1 270 0 EMBEDDEDcap.sym
3708
+[
3709
+P 4200 29600 4200 29400 1 0 0
3710
+{
3711
+T 4250 29500 5 8 0 1 270 0 1
3712
+pinnumber=1
3713
+T 4250 29500 5 8 0 0 270 0 1
3714
+pinseq=1
3715
+T 4200 29600 5 10 0 0 270 0 1
3716
+pintype=pas
3717
+}
3718
+P 4200 28700 4200 28900 1 0 0
3719
+{
3720
+T 4250 28900 5 8 0 1 270 0 1
3721
+pinnumber=2
3722
+T 4250 28900 5 8 0 0 270 0 1
3723
+pinseq=2
3724
+T 4200 28700 5 10 0 0 270 0 1
3725
+pintype=pas
3726
+}
3727
+L 4400 29200 4000 29200 3 0 0 0 -1 -1
3728
+L 4400 29100 4000 29100 3 0 0 0 -1 -1
3729
+L 4200 28900 4200 29100 3 0 0 0 -1 -1
3730
+L 4200 29200 4200 29400 3 0 0 0 -1 -1
3731
+T 4400 29300 5 10 0 0 270 0 1
3732
+device=capacitor
3733
+T 4500 29150 8 10 0 1 270 3 1
3734
+refdes=C?
3735
+T 3900 29150 8 10 0 1 270 5 1
3736
+value=?F
3737
+]
3738
+{
3739
+T 4150 29300 5 10 1 1 0 6 1
3740
+refdes=C2
3741
+T 4350 29000 5 10 1 1 0 2 1
3742
+value=100nF
3743
+}
3744
+N 4700 30100 2900 30100 4
3745
+N 4200 29600 4200 30100 4
3746
+N 4200 28400 4200 28700 4
3747
+N 3200 28700 3200 28400 4
3748
+N 3200 29600 3200 30100 4
3749
+C 7300 29600 1 270 0 EMBEDDEDcap_pol.sym
3750
+[
3751
+P 7700 29600 7700 29400 1 0 0
3752
+{
3753
+T 7750 29500 5 8 0 1 270 0 1
3754
+pinnumber=1
3755
+T 7750 29500 5 8 0 0 270 0 1
3756
+pinseq=1
3757
+T 7700 29600 5 10 0 0 270 0 1
3758
+pintype=pas
3759
+}
3760
+P 7700 28700 7700 28900 1 0 0
3761
+{
3762
+T 7750 28900 5 8 0 1 270 0 1
3763
+pinnumber=2
3764
+T 7750 28900 5 8 0 0 270 0 1
3765
+pinseq=2
3766
+T 7700 28700 5 10 0 0 270 0 1
3767
+pintype=pas
3768
+}
3769
+L 7900 29200 7500 29200 3 0 0 0 -1 -1
3770
+L 7700 28900 7700 29100 3 0 0 0 -1 -1
3771
+L 7700 29200 7700 29400 3 0 0 0 -1 -1
3772
+L 7900 29311 7800 29311 3 0 0 0 -1 -1
3773
+L 7849 29260 7849 29360 3 0 0 0 -1 -1
3774
+L 7900 29100 7500 29100 3 0 0 0 -1 -1
3775
+T 7900 29200 5 10 0 0 270 0 1
3776
+device=polarized capacitor
3777
+T 8000 29150 8 10 0 1 270 3 1
3778
+refdes=C?
3779
+T 7400 29150 8 10 0 1 270 5 1
3780
+value=?F
3781
+]
3782
+{
3783
+T 7650 29300 5 10 1 1 0 6 1
3784
+refdes=C4
3785
+T 7850 29000 5 10 1 1 0 2 1
3786
+value=10uF
3787
+T 7850 28800 5 10 1 1 0 2 1
3788
+description=16V
3789
+}
3790
+N 7700 29600 7700 30500 4
3791
+N 7700 28400 7700 28700 4
3792
+C 7500 30500 1 0 0 EMBEDDEDvdd5.sym
3793
+[
3794
+P 7700 30600 7700 30500 1 0 1
3795
+{
3796
+T 7700 30700 5 6 0 1 0 0 1
3797
+pinnumber=1
3798
+T 7700 30700 5 6 0 0 0 0 1
3799
+pinseq=1
3800
+T 7700 30600 5 10 0 0 0 0 1
3801
+pintype=pas
3802
+}
3803
+V 7700 30700 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
3804
+L 7700 30650 7700 30600 3 0 0 0 -1 -1
3805
+T 7800 30550 8 10 0 0 0 0 1
3806
+net=VDD5:1
3807
+T 7700 30800 8 10 0 1 0 3 1
3808
+value=VDD5
3809
+]
3810
+{
3811
+T 7700 30800 5 10 1 1 0 3 1
3812
+value=VDD5
3813
+}
3814
+T 1000 33000 9 20 1 0 0 0 5
3815
+flaneth - flash and ethernet
3816
+version 0.1.3 date 2008-06-08
3817
+Copyright (C) 2007-2008 Stefan Schuermans
3818
+Copyleft: GNU public license V2
3819
+a blinkenarea.org project
3820
+N 33300 14700 34800 14700 4
3821
+C 3400 20100 1 0 0 EMBEDDEDdiode_schottky.sym
3822
+[
3823
+P 3400 20400 3600 20400 1 0 0
3824
+{
3825
+T 3500 20450 5 8 0 1 0 0 1
3826
+pinnumber=2
3827
+T 3500 20450 5 8 0 0 0 0 1
3828
+pinseq=2
3829
+T 3400 20400 5 10 0 0 0 0 1
3830
+pintype=pas
3831
+}
3832
+P 4100 20400 3900 20400 1 0 0
3833
+{
3834
+T 3900 20450 5 8 0 1 0 0 1
3835
+pinnumber=1
3836
+T 3900 20450 5 8 0 0 0 0 1
3837
+pinseq=1
3838
+T 4100 20400 5 10 0 0 0 0 1
3839
+pintype=pas
3840
+}
3841
+L 3700 20500 3800 20400 3 0 0 0 -1 -1
3842
+L 3800 20400 3700 20300 3 0 0 0 -1 -1
3843
+L 3700 20500 3700 20300 3 0 0 0 -1 -1
3844
+L 3800 20500 3800 20300 3 0 0 0 -1 -1
3845
+L 3800 20400 3900 20400 3 0 0 0 -1 -1
3846
+L 3700 20400 3600 20400 3 0 0 0 -1 -1
3847
+T 4000 21100 5 10 0 0 0 0 1
3848
+device=diode
3849
+L 3800 20500 3825 20500 3 0 0 0 -1 -1
3850
+L 3825 20500 3825 20475 3 0 0 0 -1 -1
3851
+L 3800 20300 3775 20300 3 0 0 0 -1 -1
3852
+L 3775 20300 3775 20325 3 0 0 0 -1 -1
3853
+]
3854
+{
3855
+T 3750 20600 5 10 1 1 0 3 1
3856
+refdes=D2
3857
+T 3750 20200 5 10 1 1 0 5 1
3858
+value=BAT46
3859
+}
3860
+N 3200 20800 3200 20400 4
3861
+N 3200 20400 3400 20400 4
3862
+N 4100 20400 5900 20400 4
3863
+N 4300 18000 4300 20400 4
3864
+N 6900 9500 14500 9500 4
3865
+N 11100 12200 11400 12200 4
3866
+N 11400 12200 11400 10500 4
3867
+N 11400 10500 10600 10500 4
3868
+C 10800 29900 1 0 0 EMBEDDEDpin.sym
3869
+[
3870
+P 10800 30200 10952 30200 1 0 0
3871
+{
3872
+T 10900 30250 5 8 0 1 0 0 1
3873
+pinnumber=1
3874
+T 10900 30250 5 8 0 0 0 0 1
3875
+pinseq=1
3876
+T 10800 30200 5 10 0 0 0 0 1
3877
+pintype=pas
3878
+}
3879
+T 11200 30250 5 10 0 0 0 0 1
3880
+device=resistor
3881
+T 11150 30200 8 10 0 1 0 1 1
3882
+refdes=J?
3883
+A 11100 30200 150 90 180 3 0 0 0 -1 -1
3884
+]
3885
+{
3886
+T 11150 30200 5 10 1 1 0 1 1
3887
+refdes=J1
3888
+}
3889
+C 10800 29400 1 0 0 EMBEDDEDpin.sym
3890
+[
3891
+P 10800 29700 10952 29700 1 0 0
3892
+{
3893
+T 10900 29750 5 8 0 1 0 0 1
3894
+pinnumber=1
3895
+T 10900 29750 5 8 0 0 0 0 1
3896
+pinseq=1
3897
+T 10800 29700 5 10 0 0 0 0 1
3898
+pintype=pas
3899
+}
3900
+T 11200 29750 5 10 0 0 0 0 1
3901
+device=resistor
3902
+T 11150 29700 8 10 0 1 0 1 1
3903
+refdes=J?
3904
+A 11100 29700 150 90 180 3 0 0 0 -1 -1
3905
+]
3906
+{
3907
+T 11150 29700 5 10 1 1 0 1 1
3908
+refdes=J2
3909
+}
3910
+C 10800 28900 1 0 0 EMBEDDEDpin.sym
3911
+[
3912
+P 10800 29200 10952 29200 1 0 0
3913
+{
3914
+T 10900 29250 5 8 0 1 0 0 1
3915
+pinnumber=1
3916
+T 10900 29250 5 8 0 0 0 0 1
3917
+pinseq=1
3918
+T 10800 29200 5 10 0 0 0 0 1
3919
+pintype=pas
3920
+}
3921
+T 11200 29250 5 10 0 0 0 0 1
3922
+device=resistor
3923
+T 11150 29200 8 10 0 1 0 1 1
3924
+refdes=J?
3925
+A 11100 29200 150 90 180 3 0 0 0 -1 -1
3926
+]
3927
+{
3928
+T 11150 29200 5 10 1 1 0 1 1
3929
+refdes=J3
3930
+}
3931
+C 10200 27800 1 0 0 EMBEDDEDgnd.sym
3932
+[
3933
+P 10400 28000 10400 28200 1 0 1
3934
+{
3935
+T 10458 28061 5 4 0 1 0 0 1
3936
+pinnumber=1
3937
+T 10458 28061 5 4 0 0 0 0 1
3938
+pinseq=1
3939
+T 10400 28000 5 10 0 0 0 0 1
3940
+pintype=pas
3941
+}
3942
+L 10300 28000 10500 28000 3 10 0 0 -1 -1
3943
+T 10500 27850 8 10 0 0 0 0 1
3944
+net=GND:1
3945
+T 10400 27900 8 10 0 1 0 5 1
3946
+value=GND
3947
+]
3948
+{
3949
+T 10400 27900 5 10 1 1 0 5 1
3950
+value=GND
3951
+}
3952
+N 10400 28200 10400 30200 4
3953
+N 10400 30200 10800 30200 4
3954
+N 10800 29700 10400 29700 4
3955
+N 10400 29200 10800 29200 4
3956
+C 6200 29600 1 270 0 EMBEDDEDcap.sym
3957
+[
3958
+P 6600 29600 6600 29400 1 0 0
3959
+{
3960
+T 6650 29500 5 8 0 1 270 0 1
3961
+pinnumber=1
3962
+T 6650 29500 5 8 0 0 270 0 1
3963
+pinseq=1
3964
+T 6600 29600 5 10 0 0 270 0 1
3965
+pintype=pas
3966
+}
3967
+P 6600 28700 6600 28900 1 0 0
3968
+{
3969
+T 6650 28900 5 8 0 1 270 0 1
3970
+pinnumber=2
3971
+T 6650 28900 5 8 0 0 270 0 1
3972
+pinseq=2
3973
+T 6600 28700 5 10 0 0 270 0 1
3974
+pintype=pas
3975
+}
3976
+L 6800 29200 6400 29200 3 0 0 0 -1 -1
3977
+L 6800 29100 6400 29100 3 0 0 0 -1 -1
3978
+L 6600 28900 6600 29100 3 0 0 0 -1 -1
3979
+L 6600 29200 6600 29400 3 0 0 0 -1 -1
3980
+T 6800 29300 5 10 0 0 270 0 1
3981
+device=capacitor
3982
+T 6900 29150 8 10 0 1 270 3 1
3983
+refdes=C?
3984
+T 6300 29150 8 10 0 1 270 5 1
3985
+value=?F
3986
+]
3987
+{
3988
+T 6550 29300 5 10 1 1 0 6 1
3989
+refdes=C3
3990
+T 6750 29000 5 10 1 1 0 2 1
3991
+value=100nF
3992
+}
3993
+C 4700 29400 1 0 0 EMBEDDED7800.sym
3994
+[
3995
+P 4700 30100 5000 30100 1 0 0
3996
+{
3997
+T 4900 30150 5 8 1 1 0 6 1
3998
+pinnumber=1
3999
+T 4900 30050 5 8 0 1 0 8 1
4000
+pinseq=3
4001
+T 5050 30100 9 8 1 1 0 0 1
4002
+pinlabel=IN
4003
+T 5050 30100 5 8 0 1 0 2 1
4004
+pintype=pwr
4005
+}
4006
+P 6100 30100 5800 30100 1 0 0
4007
+{
4008
+T 5900 30150 5 8 1 1 0 0 1
4009
+pinnumber=3
4010
+T 5900 30050 5 8 0 1 0 2 1
4011
+pinseq=3
4012
+T 5750 30100 9 8 1 1 0 6 1
4013
+pinlabel=OUT
4014
+T 5750 30100 5 8 0 1 0 8 1
4015
+pintype=out
4016
+}
4017
+B 5000 29700 800 600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
4018
+T 5100 36450 5 10 0 0 0 0 1
4019
+numslots=0
4020
+P 5400 29400 5400 29700 1 0 0
4021
+{
4022
+T 5450 29550 5 8 1 1 180 7 1
4023
+pinnumber=2
4024
+T 5450 29600 5 8 0 1 90 8 1
4025
+pinseq=2
4026
+T 5400 29775 9 8 1 1 180 5 1
4027
+pinlabel=GND
4028
+T 5400 29750 5 8 0 1 90 2 1
4029
+pintype=pwr
4030
+}
4031
+]
4032
+{
4033
+T 5900 30400 5 10 1 1 0 6 1
4034
+refdes=IC1
4035
+T 6700 35450 5 10 0 0 0 0 1
4036
+device=7805
4037
+T 4900 30400 5 10 1 1 0 0 1
4038
+value=7805
4039
+}
4040
+C 10800 28400 1 0 0 EMBEDDEDpin.sym
4041
+[
4042
+P 10800 28700 10952 28700 1 0 0
4043
+{
4044
+T 10900 28750 5 8 0 1 0 0 1
4045
+pinnumber=1
4046
+T 10900 28750 5 8 0 0 0 0 1
4047
+pinseq=1
4048
+T 10800 28700 5 10 0 0 0 0 1
4049
+pintype=pas
4050
+}
4051
+A 11100 28700 150 90 180 3 0 0 0 -1 -1
4052
+T 11200 28750 5 10 0 0 0 0 1
4053
+device=resistor
4054
+T 11150 28700 8 10 0 1 0 1 1
4055
+refdes=J?
4056
+]
4057
+{
4058
+T 11150 28700 5 10 1 1 0 1 1
4059
+refdes=J4
4060
+}
4061
+N 10400 28700 10800 28700 4
4062
+C 2200 29800 1 0 0 EMBEDDEDdiode.sym
4063
+[
4064
+P 2200 30100 2400 30100 1 0 0
4065
+{
4066
+T 2300 30150 5 8 0 1 0 0 1
4067
+pinnumber=2
4068
+T 2300 30150 5 8 0 0 0 0 1
4069
+pinseq=2
4070
+T 2200 30100 5 10 0 0 0 0 1
4071
+pintype=pas
4072
+}
4073
+P 2900 30100 2700 30100 1 0 0
4074
+{
4075
+T 2700 30150 5 8 0 1 0 0 1
4076
+pinnumber=1
4077
+T 2700 30150 5 8 0 0 0 0 1
4078
+pinseq=1
4079
+T 2900 30100 5 10 0 0 0 0 1
4080
+pintype=pas
4081
+}
4082
+L 2500 30200 2600 30100 3 0 0 0 -1 -1
4083
+L 2600 30100 2500 30000 3 0 0 0 -1 -1
4084
+L 2500 30200 2500 30000 3 0 0 0 -1 -1
4085
+L 2600 30200 2600 30000 3 0 0 0 -1 -1
4086
+L 2600 30100 2700 30100 3 0 0 0 -1 -1
4087
+L 2500 30100 2400 30100 3 0 0 0 -1 -1
4088
+]
4089
+{
4090
+T 4400 30800 5 10 0 0 0 0 1
4091
+device=diode
4092
+T 2550 30300 5 10 1 1 0 3 1
4093
+refdes=D1
4094
+T 2550 29900 5 10 1 1 0 5 1
4095
+value=1N4001
4096
+}
4097
+N 6600 28400 6600 28700 4
4098
+C 1800 27800 1 0 0 EMBEDDEDgnd.sym
4099
+[
4100
+P 2000 28000 2000 28200 1 0 1
4101
+{
4102
+T 2058 28061 5 4 0 1 0 0 1
4103
+pinnumber=1
4104
+T 2058 28061 5 4 0 0 0 0 1
4105
+pinseq=1
4106
+T 2000 28000 5 10 0 0 0 0 1
4107
+pintype=pas
4108
+}
4109
+L 1900 28000 2100 28000 3 10 0 0 -1 -1
4110
+T 2100 27850 8 10 0 0 0 0 1
4111
+net=GND:1
4112
+T 2000 27900 8 10 0 1 0 5 1
4113
+value=GND
4114
+]
4115
+{
4116
+T 2000 27900 5 10 1 1 0 5 1
4117
+value=GND
4118
+}
4119
+N 6600 29600 6600 30100 4
4120
+N 6100 30100 7700 30100 4
4121
+N 5400 28400 5400 29400 4
4122
+C 22300 24200 1 0 0 EMBEDDEDCompactFlash.sym
4123
+[
4124
+B 22800 24700 3200 7400 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
4125
+T 22700 31250 5 10 0 0 0 0 1
4126
+numslots=0
4127
+P 26300 25600 26000 25600 1 0 0
4128
+{
4129
+T 26100 25650 5 8 1 1 0 0 1
4130
+pinnumber=1
4131
+T 26100 25550 5 8 0 1 0 2 1
4132
+pinseq=1
4133
+T 25950 25600 9 8 1 1 0 6 1
4134
+pinlabel=GND
4135
+T 25950 25600 5 8 0 1 0 8 1
4136
+pintype=pwr
4137
+}
4138
+P 22500 27400 22800 27400 1 0 0
4139
+{
4140
+T 22700 27450 5 8 1 1 0 6 1
4141
+pinnumber=2
4142
+T 22700 27350 5 8 0 1 0 8 1
4143
+pinseq=2
4144
+T 22850 27400 9 8 1 1 0 0 1
4145
+pinlabel=D03
4146
+T 22850 27400 5 8 0 1 0 2 1
4147
+pintype=io
4148
+}
4149
+P 22500 27200 22800 27200 1 0 0
4150
+{
4151
+T 22700 27250 5 8 1 1 0 6 1
4152
+pinnumber=3
4153
+T 22700 27150 5 8 0 1 0 8 1
4154
+pinseq=3
4155
+T 22850 27200 9 8 1 1 0 0 1
4156
+pinlabel=D04
4157
+T 22850 27200 5 8 0 1 0 2 1
4158
+pintype=io
4159
+}
4160
+P 22500 27000 22800 27000 1 0 0
4161
+{
4162
+T 22700 27050 5 8 1 1 0 6 1
4163
+pinnumber=4
4164
+T 22700 26950 5 8 0 1 0 8 1
4165
+pinseq=4
4166
+T 22850 27000 9 8 1 1 0 0 1
4167
+pinlabel=D05
4168
+T 22850 27000 5 8 0 1 0 2 1
4169
+pintype=io
4170
+}
4171
+P 22500 26800 22800 26800 1 0 0
4172
+{
4173
+T 22700 26850 5 8 1 1 0 6 1
4174
+pinnumber=5
4175
+T 22700 26750 5 8 0 1 0 8 1
4176
+pinseq=5
4177
+T 22850 26800 9 8 1 1 0 0 1
4178
+pinlabel=D06
4179
+T 22850 26800 5 8 0 1 0 2 1
4180
+pintype=io
4181
+}
4182
+P 22500 26600 22800 26600 1 0 0
4183
+{
4184
+T 22700 26650 5 8 1 1 0 6 1
4185
+pinnumber=6
4186
+T 22700 26550 5 8 0 1 0 8 1
4187
+pinseq=6
4188
+T 22850 26600 9 8 1 1 0 0 1
4189
+pinlabel=D07
4190
+T 22850 26600 5 8 0 1 0 2 1
4191
+pintype=io
4192
+}
4193
+P 26300 31800 26000 31800 1 0 0
4194
+{
4195
+T 26100 31850 5 8 1 1 0 0 1
4196
+pinnumber=7
4197
+T 26100 31750 5 8 0 1 0 2 1
4198
+pinseq=7
4199
+T 25950 31800 9 8 1 1 0 6 1
4200
+pinlabel=nCE1
4201
+T 25950 31800 5 8 0 1 0 8 1
4202
+pintype=in
4203
+}
4204
+P 22500 28600 22800 28600 1 0 0
4205
+{
4206
+T 22700 28650 5 8 1 1 0 6 1
4207
+pinnumber=8
4208
+T 22700 28550 5 8 0 1 0 8 1
4209
+pinseq=8
4210
+T 22850 28600 9 8 1 1 0 0 1
4211
+pinlabel=A10
4212
+T 22850 28600 5 8 0 1 0 2 1
4213
+pintype=in
4214
+}
4215
+P 26300 31000 26000 31000 1 0 0
4216
+{
4217
+T 26100 31050 5 8 1 1 0 0 1
4218
+pinnumber=9
4219
+T 26100 30950 5 8 0 1 0 2 1
4220
+pinseq=9
4221
+T 25950 31000 9 8 1 1 0 6 1
4222
+pinlabel=nOE
4223
+T 25950 31000 5 8 0 1 0 8 1
4224
+pintype=in
4225
+}
4226
+P 22500 28800 22800 28800 1 0 0
4227
+{
4228
+T 22700 28850 5 8 1 1 0 6 1
4229
+pinnumber=10
4230
+T 22700 28750 5 8 0 1 0 8 1
4231
+pinseq=10
4232
+T 22850 28800 9 8 1 1 0 0 1
4233
+pinlabel=A09
4234
+T 22850 28800 5 8 0 1 0 2 1
4235
+pintype=in
4236
+}
4237
+P 22500 29000 22800 29000 1 0 0
4238
+{
4239
+T 22700 29050 5 8 1 1 0 6 1
4240
+pinnumber=11
4241
+T 22700 28950 5 8 0 1 0 8 1
4242
+pinseq=11
4243
+T 22850 29000 9 8 1 1 0 0 1
4244
+pinlabel=A08
4245
+T 22850 29000 5 8 0 1 0 2 1
4246
+pintype=in
4247
+}
4248
+P 22500 29200 22800 29200 1 0 0
4249
+{
4250
+T 22700 29250 5 8 1 1 0 6 1
4251
+pinnumber=12
4252
+T 22700 29150 5 8 0 1 0 8 1
4253
+pinseq=12
4254
+T 22850 29200 9 8 1 1 0 0 1
4255
+pinlabel=A07
4256
+T 22850 29200 5 8 0 1 0 2 1
4257
+pintype=in
4258
+}
4259
+P 26300 26800 26000 26800 1 0 0
4260
+{
4261
+T 26100 26850 5 8 1 1 0 0 1
4262
+pinnumber=13
4263
+T 26100 26750 5 8 0 1 0 2 1
4264
+pinseq=13
4265
+T 25950 26800 9 8 1 1 0 6 1
4266
+pinlabel=VCC
4267
+T 25950 26800 5 8 0 1 0 8 1
4268
+pintype=pwr
4269
+}
4270
+P 22500 29400 22800 29400 1 0 0
4271
+{
4272
+T 22700 29450 5 8 1 1 0 6 1
4273
+pinnumber=14
4274
+T 22700 29350 5 8 0 1 0 8 1
4275
+pinseq=14
4276
+T 22850 29400 9 8 1 1 0 0 1
4277
+pinlabel=A06
4278
+T 22850 29400 5 8 0 1 0 2 1
4279
+pintype=in
4280
+}
4281
+P 22500 29600 22800 29600 1 0 0
4282
+{
4283
+T 22700 29650 5 8 1 1 0 6 1
4284
+pinnumber=15
4285
+T 22700 29550 5 8 0 1 0 8 1
4286
+pinseq=15
4287
+T 22850 29600 9 8 1 1 0 0 1
4288
+pinlabel=A05
4289
+T 22850 29600 5 8 0 1 0 2 1
4290
+pintype=in
4291
+}
4292
+P 22500 29800 22800 29800 1 0 0
4293
+{
4294
+T 22700 29850 5 8 1 1 0 6 1
4295
+pinnumber=16
4296
+T 22700 29750 5 8 0 1 0 8 1
4297
+pinseq=16
4298
+T 22850 29800 9 8 1 1 0 0 1
4299
+pinlabel=A04
4300
+T 22850 29800 5 8 0 1 0 2 1
4301
+pintype=in
4302
+}
4303
+P 22500 30000 22800 30000 1 0 0
4304
+{
4305
+T 22700 30050 5 8 1 1 0 6 1
4306
+pinnumber=17
4307
+T 22700 29950 5 8 0 1 0 8 1
4308
+pinseq=17
4309
+T 22850 30000 9 8 1 1 0 0 1
4310
+pinlabel=A03
4311
+T 22850 30000 5 8 0 1 0 2 1
4312
+pintype=in
4313
+}
4314
+P 22500 30200 22800 30200 1 0 0
4315
+{
4316
+T 22700 30250 5 8 1 1 0 6 1
4317
+pinnumber=18
4318
+T 22700 30150 5 8 0 1 0 8 1
4319
+pinseq=18
4320
+T 22850 30200 9 8 1 1 0 0 1
4321
+pinlabel=A02
4322
+T 22850 30200 5 8 0 1 0 2 1
4323
+pintype=in
4324
+}
4325
+P 22500 30400 22800 30400 1 0 0
4326
+{
4327
+T 22700 30450 5 8 1 1 0 6 1
4328
+pinnumber=19
4329
+T 22700 30350 5 8 0 1 0 8 1
4330
+pinseq=19
4331
+T 22850 30400 9 8 1 1 0 0 1
4332
+pinlabel=A01
4333
+T 22850 30400 5 8 0 1 0 2 1
4334
+pintype=in
4335
+}
4336
+P 22500 30600 22800 30600 1 0 0
4337
+{
4338
+T 22700 30650 5 8 1 1 0 6 1
4339
+pinnumber=20
4340
+T 22700 30550 5 8 0 1 0 8 1
4341
+pinseq=20
4342
+T 22850 30600 9 8 1 1 0 0 1
4343
+pinlabel=A00
4344
+T 22850 30600 5 8 0 1 0 2 1
4345
+pintype=in
4346
+}
4347
+P 22500 27600 22800 27600 1 0 0
4348
+{
4349
+T 22700 27650 5 8 1 1 0 6 1
4350
+pinnumber=23
4351
+T 22700 27550 5 8 0 1 0 8 1
4352
+pinseq=23
4353
+T 22850 27600 9 8 1 1 0 0 1
4354
+pinlabel=D02
4355
+T 22850 27600 5 8 0 1 0 2 1
4356
+pintype=io
4357
+}
4358
+P 26300 29800 26000 29800 1 0 0
4359
+{
4360
+T 26100 29850 5 8 1 1 0 0 1
4361
+pinnumber=24
4362
+T 26100 29750 5 8 0 1 0 2 1
4363
+pinseq=24
4364
+T 25950 29800 9 8 1 1 0 6 1
4365
+pinlabel=WP
4366
+T 25950 29800 5 8 0 1 0 8 1
4367
+pintype=out
4368
+}
4369
+P 22500 31200 22800 31200 1 0 0
4370
+{
4371
+T 22700 31250 5 8 1 1 0 6 1
4372
+pinnumber=25
4373
+T 22700 31150 5 8 0 1 0 8 1
4374
+pinseq=25
4375
+T 22850 31200 9 8 1 1 0 0 1
4376
+pinlabel=nCD2
4377
+T 22850 31200 5 8 0 1 0 2 1
4378
+pintype=out
4379
+}
4380
+P 26300 25400 26000 25400 1 0 0
4381
+{
4382
+T 26100 25450 5 8 1 1 0 0 1
4383
+pinnumber=50
4384
+T 26100 25350 5 8 0 1 0 2 1
4385
+pinseq=50
4386
+T 25950 25400 9 8 1 1 0 6 1
4387
+pinlabel=GND
4388
+T 25950 25400 5 8 0 1 0 8 1
4389
+pintype=pwr
4390
+}
4391
+P 22500 26000 22800 26000 1 0 0
4392
+{
4393
+T 22700 26050 5 8 1 1 0 6 1
4394
+pinnumber=49
4395
+T 22700 25950 5 8 0 1 0 8 1
4396
+pinseq=49
4397
+T 22850 26000 9 8 1 1 0 0 1
4398
+pinlabel=D10
4399
+T 22850 26000 5 8 0 1 0 2 1
4400
+pintype=io
4401
+}
4402
+P 22500 26200 22800 26200 1 0 0
4403
+{
4404
+T 22700 26250 5 8 1 1 0 6 1
4405
+pinnumber=48
4406
+T 22700 26150 5 8 0 1 0 8 1
4407
+pinseq=48
4408
+T 22850 26200 9 8 1 1 0 0 1
4409
+pinlabel=D09
4410
+T 22850 26200 5 8 0 1 0 2 1
4411
+pintype=io
4412
+}
4413
+P 22500 26400 22800 26400 1 0 0
4414
+{
4415
+T 22700 26450 5 8 1 1 0 6 1
4416
+pinnumber=47
4417
+T 22700 26350 5 8 0 1 0 8 1
4418
+pinseq=47
4419
+T 22850 26400 9 8 1 1 0 0 1
4420
+pinlabel=D08
4421
+T 22850 26400 5 8 0 1 0 2 1
4422
+pintype=io
4423
+}
4424
+P 26300 27600 26000 27600 1 0 0
4425
+{
4426
+T 26100 27650 5 8 1 1 0 0 1
4427
+pinnumber=46
4428
+T 26100 27550 5 8 0 1 0 2 1
4429
+pinseq=46
4430
+T 25950 27600 9 8 1 1 0 6 1
4431
+pinlabel=BVD1
4432
+T 25950 27600 5 8 0 1 0 8 1
4433
+pintype=out
4434
+}
4435
+P 26300 27800 26000 27800 1 0 0
4436
+{
4437
+T 26100 27850 5 8 1 1 0 0 1
4438
+pinnumber=45
4439
+T 26100 27750 5 8 0 1 0 2 1
4440
+pinseq=45
4441
+T 25950 27800 9 8 1 1 0 6 1
4442
+pinlabel=BVD2
4443
+T 25950 27800 5 8 0 1 0 8 1
4444
+pintype=out
4445
+}
4446
+P 26300 29000 26000 29000 1 0 0
4447
+{
4448
+T 26100 29050 5 8 1 1 0 0 1
4449
+pinnumber=44
4450
+T 26100 28950 5 8 0 1 0 2 1
4451
+pinseq=44
4452
+T 25950 29000 9 8 1 1 0 6 1
4453
+pinlabel=nREG
4454
+T 25950 29000 5 8 0 1 0 8 1
4455
+pintype=in
4456
+}
4457
+P 26300 29200 26000 29200 1 0 0
4458
+{
4459
+T 26100 29250 5 8 1 1 0 0 1
4460
+pinnumber=43
4461
+T 26100 29150 5 8 0 1 0 2 1
4462
+pinseq=43
4463
+T 25950 29200 9 8 1 1 0 6 1
4464
+pinlabel=nINP
4465
+T 25950 29200 5 8 0 1 0 8 1
4466
+pintype=out
4467
+}
4468
+P 26300 29400 26000 29400 1 0 0
4469
+{
4470
+T 26100 29450 5 8 1 1 0 0 1
4471
+pinnumber=42
4472
+T 26100 29350 5 8 0 1 0 2 1
4473
+pinseq=42
4474
+T 25950 29400 9 8 1 1 0 6 1
4475
+pinlabel=nWAIT
4476
+T 25950 29400 5 8 0 1 0 8 1
4477
+pintype=out
4478
+}
4479
+P 22500 31800 22800 31800 1 0 0
4480
+{
4481
+T 22700 31850 5 8 1 1 0 6 1
4482
+pinnumber=41
4483
+T 22700 31750 5 8 0 1 0 8 1
4484
+pinseq=41
4485
+T 22850 31800 9 8 1 1 0 0 1
4486
+pinlabel=nRST
4487
+T 22850 31800 5 8 0 1 0 2 1
4488
+pintype=in
4489
+}
4490
+P 26300 28200 26000 28200 1 0 0
4491
+{
4492
+T 26100 28250 5 8 1 1 0 0 1
4493
+pinnumber=40
4494
+T 26100 28150 5 8 0 1 0 2 1
4495
+pinseq=40
4496
+T 25950 28200 9 8 1 1 0 6 1
4497
+pinlabel=nVS2
4498
+T 25950 28200 5 8 0 1 0 8 1
4499
+pintype=out
4500
+}
4501
+P 26300 31400 26000 31400 1 0 0
4502
+{
4503
+T 26100 31450 5 8 1 1 0 0 1
4504
+pinnumber=39
4505
+T 26100 31350 5 8 0 1 0 2 1
4506
+pinseq=39
4507
+T 25950 31400 9 8 1 1 0 6 1
4508
+pinlabel=nCSEL
4509
+T 25950 31400 5 8 0 1 0 8 1
4510
+pintype=in
4511
+}
4512
+P 26300 26600 26000 26600 1 0 0
4513
+{
4514
+T 26100 26650 5 8 1 1 0 0 1
4515
+pinnumber=38
4516
+T 26100 26550 5 8 0 1 0 2 1
4517
+pinseq=38
4518
+T 25950 26600 9 8 1 1 0 6 1
4519
+pinlabel=VCC
4520
+T 25950 26600 5 8 0 1 0 8 1
4521
+pintype=pwr
4522
+}
4523
+P 26300 29600 26000 29600 1 0 0
4524
+{
4525
+T 26100 29650 5 8 1 1 0 0 1
4526
+pinnumber=37
4527
+T 26100 29550 5 8 0 1 0 2 1
4528
+pinseq=37
4529
+T 25950 29600 9 8 1 1 0 6 1
4530
+pinlabel=RDY
4531
+T 25950 29600 5 8 0 1 0 8 1
4532
+pintype=out
4533
+}
4534
+P 26300 30800 26000 30800 1 0 0
4535
+{
4536
+T 26100 30850 5 8 1 1 0 0 1
4537
+pinnumber=36
4538
+T 26100 30750 5 8 0 1 0 2 1
4539
+pinseq=36
4540
+T 25950 30800 9 8 1 1 0 6 1
4541
+pinlabel=nWE
4542
+T 25950 30800 5 8 0 1 0 8 1
4543
+pintype=in
4544
+}
4545
+P 26300 30200 26000 30200 1 0 0
4546
+{
4547
+T 26100 30250 5 8 1 1 0 0 1
4548
+pinnumber=35
4549
+T 26100 30150 5 8 0 1 0 2 1
4550
+pinseq=35
4551
+T 25950 30200 9 8 1 1 0 6 1
4552
+pinlabel=nIOW
4553
+T 25950 30200 5 8 0 1 0 8 1
4554
+pintype=in
4555
+}
4556
+P 26300 30400 26000 30400 1 0 0
4557
+{
4558
+T 26100 30450 5 8 1 1 0 0 1
4559
+pinnumber=34
4560
+T 26100 30350 5 8 0 1 0 2 1
4561
+pinseq=34
4562
+T 25950 30400 9 8 1 1 0 6 1
4563
+pinlabel=nIOR
4564
+T 25950 30400 5 8 0 1 0 8 1
4565
+pintype=in
4566
+}
4567
+P 26300 28400 26000 28400 1 0 0
4568
+{
4569
+T 26100 28450 5 8 1 1 0 0 1
4570
+pinnumber=33
4571
+T 26100 28350 5 8 0 1 0 2 1
4572
+pinseq=33
4573
+T 25950 28400 9 8 1 1 0 6 1
4574
+pinlabel=nVS1
4575
+T 25950 28400 5 8 0 1 0 8 1
4576
+pintype=out
4577
+}
4578
+P 26300 31600 26000 31600 1 0 0
4579
+{
4580
+T 26100 31650 5 8 1 1 0 0 1
4581
+pinnumber=32
4582
+T 26100 31550 5 8 0 1 0 2 1
4583
+pinseq=32
4584
+T 25950 31600 9 8 1 1 0 6 1
4585
+pinlabel=nCE2
4586
+T 25950 31600 5 8 0 1 0 8 1
4587
+pintype=in
4588
+}
4589
+P 22500 25000 22800 25000 1 0 0
4590
+{
4591
+T 22700 25050 5 8 1 1 0 6 1
4592
+pinnumber=31
4593
+T 22700 24950 5 8 0 1 0 8 1
4594
+pinseq=31
4595
+T 22850 25000 9 8 1 1 0 0 1
4596
+pinlabel=D15
4597
+T 22850 25000 5 8 0 1 0 2 1
4598
+pintype=io
4599
+}
4600
+P 22500 25200 22800 25200 1 0 0
4601
+{
4602
+T 22700 25250 5 8 1 1 0 6 1
4603
+pinnumber=30
4604
+T 22700 25150 5 8 0 1 0 8 1
4605
+pinseq=30
4606
+T 22850 25200 9 8 1 1 0 0 1
4607
+pinlabel=D14
4608
+T 22850 25200 5 8 0 1 0 2 1
4609
+pintype=io
4610
+}
4611
+P 22500 25400 22800 25400 1 0 0
4612
+{
4613
+T 22700 25450 5 8 1 1 0 6 1
4614
+pinnumber=29
4615
+T 22700 25350 5 8 0 1 0 8 1
4616
+pinseq=29
4617
+T 22850 25400 9 8 1 1 0 0 1
4618
+pinlabel=D13
4619
+T 22850 25400 5 8 0 1 0 2 1
4620
+pintype=io
4621
+}
4622
+P 22500 25600 22800 25600 1 0 0
4623
+{
4624
+T 22700 25650 5 8 1 1 0 6 1
4625
+pinnumber=28
4626
+T 22700 25550 5 8 0 1 0 8 1
4627
+pinseq=28
4628
+T 22850 25600 9 8 1 1 0 0 1
4629
+pinlabel=D12
4630
+T 22850 25600 5 8 0 1 0 2 1
4631
+pintype=io
4632
+}
4633
+P 22500 25800 22800 25800 1 0 0
4634
+{
4635
+T 22700 25850 5 8 1 1 0 6 1
4636
+pinnumber=27
4637
+T 22700 25750 5 8 0 1 0 8 1
4638
+pinseq=27
4639
+T 22850 25800 9 8 1 1 0 0 1
4640
+pinlabel=D11
4641
+T 22850 25800 5 8 0 1 0 2 1
4642
+pintype=io
4643
+}
4644
+P 22500 31400 22800 31400 1 0 0
4645
+{
4646
+T 22700 31450 5 8 1 1 0 6 1
4647
+pinnumber=26
4648
+T 22700 31350 5 8 0 1 0 8 1
4649
+pinseq=26
4650
+T 22850 31400 9 8 1 1 0 0 1
4651
+pinlabel=nCD1
4652
+T 22850 31400 5 8 0 1 0 2 1
4653
+pintype=out
4654
+}
4655
+P 22500 27800 22800 27800 1 0 0
4656
+{
4657
+T 22700 27850 5 8 1 1 0 6 1
4658
+pinnumber=22
4659
+T 22700 27750 5 8 0 1 0 8 1
4660
+pinseq=22
4661
+T 22850 27800 9 8 1 1 0 0 1
4662
+pinlabel=D01
4663
+T 22850 27800 5 8 0 1 0 2 1
4664
+pintype=io
4665
+}
4666
+P 22500 28000 22800 28000 1 0 0
4667
+{
4668
+T 22700 28050 5 8 1 1 0 6 1
4669
+pinnumber=21
4670
+T 22700 27950 5 8 0 1 0 8 1
4671
+pinseq=21
4672
+T 22850 28000 9 8 1 1 0 0 1
4673
+pinlabel=D00
4674
+T 22850 28000 5 8 0 1 0 2 1
4675
+pintype=io
4676
+}
4677
+P 26300 25200 26000 25200 1 0 0
4678
+{
4679
+T 26100 25250 5 8 1 1 0 0 1
4680
+pinnumber=100
4681
+T 26100 25150 5 8 0 1 0 2 1
4682
+pinseq=100
4683
+T 25950 25200 9 8 1 1 0 6 1
4684
+pinlabel=GND
4685
+T 25950 25200 5 8 0 1 0 8 1
4686
+pintype=pas
4687
+}
4688
+P 26300 25000 26000 25000 1 0 0
4689
+{
4690
+T 26100 25050 5 8 1 1 0 0 1
4691
+pinnumber=101
4692
+T 26100 24950 5 8 0 1 0 2 1
4693
+pinseq=101
4694
+T 25950 25000 9 8 1 1 0 6 1
4695
+pinlabel=GND
4696
+T 25950 25000 5 8 0 1 0 8 1
4697
+pintype=pas
4698
+}
4699
+]
4700
+{
4701
+T 26000 32200 5 10 1 1 0 6 1
4702
+refdes=CF1
4703
+T 22700 30250 5 10 0 0 0 0 1
4704
+device=CompactFlash
4705
+T 22800 32200 5 10 1 1 0 0 1
4706
+value=CompactFlash
4707
+}
4708
+C 27400 25500 1 90 0 EMBEDDEDcap.sym
4709
+[
4710
+P 27000 25500 27000 25700 1 0 0
4711
+{
4712
+T 26950 25600 5 8 0 1 90 0 1
4713
+pinnumber=1
4714
+T 26950 25600 5 8 0 0 90 0 1
4715
+pinseq=1
4716
+T 27000 25500 5 10 0 0 90 0 1
4717
+pintype=pas
4718
+}
4719
+P 27000 26400 27000 26200 1 0 0
4720
+{
4721
+T 26950 26200 5 8 0 1 90 0 1
4722
+pinnumber=2
4723
+T 26950 26200 5 8 0 0 90 0 1
4724
+pinseq=2
4725
+T 27000 26400 5 10 0 0 90 0 1
4726
+pintype=pas
4727
+}
4728
+L 26800 25900 27200 25900 3 0 0 0 -1 -1
4729
+L 26800 26000 27200 26000 3 0 0 0 -1 -1
4730
+L 27000 26200 27000 26000 3 0 0 0 -1 -1
4731
+L 27000 25900 27000 25700 3 0 0 0 -1 -1
4732
+T 26800 25800 5 10 0 0 90 0 1
4733
+device=capacitor
4734
+T 26700 25950 8 10 0 1 90 3 1
4735
+refdes=C?
4736
+T 27300 25950 8 10 0 1 90 5 1
4737
+value=?F
4738
+]
4739
+{
4740
+T 26950 26100 5 10 1 1 0 6 1
4741
+refdes=C19
4742
+T 27050 25800 5 10 1 1 0 2 1
4743
+value=100nF
4744
+}
4745
+C 28400 25500 1 90 0 EMBEDDEDcap.sym
4746
+[
4747
+P 28000 25500 28000 25700 1 0 0
4748
+{
4749
+T 27950 25600 5 8 0 1 90 0 1
4750
+pinnumber=1
4751
+T 27950 25600 5 8 0 0 90 0 1
4752
+pinseq=1
4753
+T 28000 25500 5 10 0 0 90 0 1
4754
+pintype=pas
4755
+}
4756
+P 28000 26400 28000 26200 1 0 0
4757
+{
4758
+T 27950 26200 5 8 0 1 90 0 1
4759
+pinnumber=2
4760
+T 27950 26200 5 8 0 0 90 0 1
4761
+pinseq=2
4762
+T 28000 26400 5 10 0 0 90 0 1
4763
+pintype=pas
4764
+}
4765
+L 27800 25900 28200 25900 3 0 0 0 -1 -1
4766
+L 27800 26000 28200 26000 3 0 0 0 -1 -1
4767
+L 28000 26200 28000 26000 3 0 0 0 -1 -1
4768
+L 28000 25900 28000 25700 3 0 0 0 -1 -1
4769
+T 27800 25800 5 10 0 0 90 0 1
4770
+device=capacitor
4771
+T 27700 25950 8 10 0 1 90 3 1
4772
+refdes=C?
4773
+T 28300 25950 8 10 0 1 90 5 1
4774
+value=?F
4775
+]
4776
+{
4777
+T 27950 26100 5 10 1 1 0 6 1
4778
+refdes=C20
4779
+T 28050 25800 5 10 1 1 0 2 1
4780
+value=100nF
4781
+}
4782
+N 27000 26400 27000 26600 4
4783
+N 28000 26600 28000 26400 4
4784
+N 28000 25500 28000 25200 4
4785
+N 27000 25200 27000 25500 4
4786
+C 28700 26800 1 0 0 EMBEDDEDvdd5.sym
4787
+[
4788
+P 28900 26900 28900 26800 1 0 1
4789
+{
4790
+T 28900 27000 5 6 0 1 0 0 1
4791
+pinnumber=1
4792
+T 28900 27000 5 6 0 0 0 0 1
4793
+pinseq=1
4794
+T 28900 26900 5 10 0 0 0 0 1
4795
+pintype=pas
4796
+}
4797
+V 28900 27000 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
4798
+L 28900 26950 28900 26900 3 0 0 0 -1 -1
4799
+T 29000 26850 8 10 0 0 0 0 1
4800
+net=VDD5:1
4801
+T 28900 27100 8 10 0 1 0 3 1
4802
+value=VDD5
4803
+]
4804
+{
4805
+T 28900 27100 5 10 1 1 0 3 1
4806
+value=VDD5
4807
+}
4808
+C 28700 24600 1 0 0 EMBEDDEDgnd.sym
4809
+[
4810
+P 28900 24800 28900 25000 1 0 1
4811
+{
4812
+T 28958 24861 5 4 0 1 0 0 1
4813
+pinnumber=1
4814
+T 28958 24861 5 4 0 0 0 0 1
4815
+pinseq=1
4816
+T 28900 24800 5 10 0 0 0 0 1
4817
+pintype=pas
4818
+}
4819
+L 28800 24800 29000 24800 3 10 0 0 -1 -1
4820
+T 29000 24650 8 10 0 0 0 0 1
4821
+net=GND:1
4822
+T 28900 24700 8 10 0 1 0 5 1
4823
+value=GND
4824
+]
4825
+{
4826
+T 28900 24700 5 10 1 1 0 5 1
4827
+value=GND
4828
+}
4829
+N 26500 25000 26500 25600 4
4830
+N 26500 25600 26300 25600 4
4831
+N 26300 25400 26500 25400 4
4832
+N 26300 25200 26500 25200 4
4833
+N 27300 8200 27300 8600 4
4834
+N 28300 8600 28300 8200 4
4835
+N 26300 26800 26500 26800 4
4836
+N 26500 26800 26500 26600 4
4837
+C 28500 26400 1 270 0 EMBEDDEDcap_pol.sym
4838
+[
4839
+P 28900 26400 28900 26200 1 0 0
4840
+{
4841
+T 28950 26300 5 8 0 1 270 0 1
4842
+pinnumber=1
4843
+T 28950 26300 5 8 0 0 270 0 1
4844
+pinseq=1
4845
+T 28900 26400 5 10 0 0 270 0 1
4846
+pintype=pas
4847
+}
4848
+P 28900 25500 28900 25700 1 0 0
4849
+{
4850
+T 28950 25700 5 8 0 1 270 0 1
4851
+pinnumber=2
4852
+T 28950 25700 5 8 0 0 270 0 1
4853
+pinseq=2
4854
+T 28900 25500 5 10 0 0 270 0 1
4855
+pintype=pas
4856
+}
4857
+L 29100 26000 28700 26000 3 0 0 0 -1 -1
4858
+L 28900 25700 28900 25900 3 0 0 0 -1 -1
4859
+L 28900 26000 28900 26200 3 0 0 0 -1 -1
4860
+L 29100 26111 29000 26111 3 0 0 0 -1 -1
4861
+L 29049 26060 29049 26160 3 0 0 0 -1 -1
4862
+L 29100 25900 28700 25900 3 0 0 0 -1 -1
4863
+T 29100 26000 5 10 0 0 270 0 1
4864
+device=polarized capacitor
4865
+T 29200 25950 8 10 0 1 270 3 1
4866
+refdes=C?
4867
+T 28600 25950 8 10 0 1 270 5 1
4868
+value=?F
4869
+]
4870
+{
4871
+T 28850 26100 5 10 1 1 0 6 1
4872
+refdes=C18
4873
+T 29050 25800 5 10 1 1 0 2 1
4874
+value=10uF
4875
+T 29050 25600 5 10 1 1 0 2 1
4876
+description=16V
4877
+}
4878
+N 26500 25000 26300 25000 4
4879
+N 26300 26600 28900 26600 4
4880
+N 28900 26400 28900 26800 4
4881
+N 28900 25000 28900 25500 4
4882
+N 21400 11600 21400 12600 4
4883
+N 21400 12600 11100 12600 4
4884
+C 27400 32000 1 90 0 EMBEDDEDres.sym
4885
+[
4886
+P 27100 32900 27100 32750 1 0 0
4887
+{
4888
+T 27050 32800 5 8 0 1 90 0 1
4889
+pinnumber=2
4890
+T 27050 32800 5 8 0 0 90 0 1
4891
+pinseq=2
4892
+T 27100 32900 5 10 0 0 90 0 1
4893
+pintype=pas
4894
+}
4895
+P 27100 32000 27100 32152 1 0 0
4896
+{
4897
+T 27050 32100 5 8 0 1 90 0 1
4898
+pinnumber=1
4899
+T 27050 32100 5 8 0 0 90 0 1
4900
+pinseq=1
4901
+T 27100 32000 5 10 0 0 90 0 1
4902
+pintype=pas
4903
+}
4904
+B 27000 32150 200 600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
4905
+T 27050 32400 5 10 0 0 90 0 1
4906
+device=resistor
4907
+T 26900 32450 8 10 0 1 90 3 1
4908
+refdes=R?
4909
+T 27300 32450 8 10 0 1 90 5 1
4910
+value=?E
4911
+]
4912
+{
4913
+T 27250 32500 5 10 1 1 0 0 1
4914
+refdes=R12
4915
+T 27250 32400 5 10 1 1 0 2 1
4916
+value=10kE
4917
+}
4918
+N 27100 32900 27100 33100 4
4919
+N 22500 30000 22300 30000 4
4920
+N 22500 28800 22300 28800 4
4921
+N 22500 29000 22300 29000 4
4922
+N 22500 29200 22300 29200 4
4923
+N 22500 29400 22300 29400 4
4924
+N 22500 29600 22300 29600 4
4925
+N 22500 29800 22300 29800 4
4926
+N 22300 28600 22300 30000 4
4927
+C 21600 28600 1 0 0 EMBEDDEDgnd.sym
4928
+[
4929
+P 21800 28800 21800 29000 1 0 1
4930
+{
4931
+T 21858 28861 5 4 0 1 0 0 1
4932
+pinnumber=1
4933
+T 21858 28861 5 4 0 0 0 0 1
4934
+pinseq=1
4935
+T 21800 28800 5 10 0 0 0 0 1
4936
+pintype=pas
4937
+}
4938
+L 21700 28800 21900 28800 3 10 0 0 -1 -1
4939
+T 21900 28650 8 10 0 0 0 0 1
4940
+net=GND:1
4941
+T 21800 28700 8 10 0 1 0 5 1
4942
+value=GND
4943
+]
4944
+{
4945
+T 21800 28700 5 10 1 1 0 5 1
4946
+value=GND
4947
+}
4948
+N 22300 28600 22500 28600 4
4949
+N 26300 30400 26500 30400 4
4950
+N 26500 30200 26300 30200 4
4951
+N 26300 31600 26500 31600 4
4952
+C 26300 33300 1 0 0 EMBEDDEDvdd5.sym
4953
+[
4954
+P 26500 33400 26500 33300 1 0 1
4955
+{
4956
+T 26500 33500 5 6 0 1 0 0 1
4957
+pinnumber=1
4958
+T 26500 33500 5 6 0 0 0 0 1
4959
+pinseq=1
4960
+T 26500 33400 5 10 0 0 0 0 1
4961
+pintype=pas
4962
+}
4963
+V 26500 33500 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
4964
+L 26500 33450 26500 33400 3 0 0 0 -1 -1
4965
+T 26600 33350 8 10 0 0 0 0 1
4966
+net=VDD5:1
4967
+T 26500 33600 8 10 0 1 0 3 1
4968
+value=VDD5
4969
+]
4970
+{
4971
+T 26500 33600 5 10 1 1 0 3 1
4972
+value=VDD5
4973
+}
4974
+N 26500 33100 27100 33100 4
4975
+N 27100 29600 27100 32000 4
4976
+C 22400 32000 1 90 0 EMBEDDEDres.sym
4977
+[
4978
+P 22100 32900 22100 32750 1 0 0
4979
+{
4980
+T 22050 32800 5 8 0 1 90 0 1
4981
+pinnumber=2
4982
+T 22050 32800 5 8 0 0 90 0 1
4983
+pinseq=2
4984
+T 22100 32900 5 10 0 0 90 0 1
4985
+pintype=pas
4986
+}
4987
+P 22100 32000 22100 32152 1 0 0
4988
+{
4989
+T 22050 32100 5 8 0 1 90 0 1
4990
+pinnumber=1
4991
+T 22050 32100 5 8 0 0 90 0 1
4992
+pinseq=1
4993
+T 22100 32000 5 10 0 0 90 0 1
4994
+pintype=pas
4995
+}
4996
+B 22000 32150 200 600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
4997
+T 22050 32400 5 10 0 0 90 0 1
4998
+device=resistor
4999
+T 21900 32450 8 10 0 1 90 3 1
5000
+refdes=R?
5001
+T 22300 32450 8 10 0 1 90 5 1
5002
+value=?E
5003
+]
5004
+{
5005
+T 21950 32500 5 10 1 1 0 6 1
5006
+refdes=R11
5007
+T 21950 32400 5 10 1 1 0 8 1
5008
+value=10kE
5009
+}
5010
+N 22100 31400 22100 32000 4
5011
+N 22100 32900 22100 33300 4
5012
+C 21900 33300 1 0 0 EMBEDDEDvdd5.sym
5013
+[
5014
+P 22100 33400 22100 33300 1 0 1
5015
+{
5016
+T 22100 33500 5 6 0 1 0 0 1
5017
+pinnumber=1
5018
+T 22100 33500 5 6 0 0 0 0 1
5019
+pinseq=1
5020
+T 22100 33400 5 10 0 0 0 0 1
5021
+pintype=pas
5022
+}
5023
+V 22100 33500 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
5024
+L 22100 33450 22100 33400 3 0 0 0 -1 -1
5025
+T 22200 33350 8 10 0 0 0 0 1
5026
+net=VDD5:1
5027
+T 22100 33600 8 10 0 1 0 3 1
5028
+value=VDD5
5029
+]
5030
+{
5031
+T 22100 33600 5 10 1 1 0 3 1
5032
+value=VDD5
5033
+}
5034
+N 26300 31400 26700 31400 4
5035
+N 26700 31400 26700 28800 4
5036
+C 26500 28400 1 0 0 EMBEDDEDgnd.sym
5037
+[
5038
+P 26700 28600 26700 28800 1 0 1
5039
+{
5040
+T 26758 28661 5 4 0 1 0 0 1
5041
+pinnumber=1
5042
+T 26758 28661 5 4 0 0 0 0 1
5043
+pinseq=1
5044
+T 26700 28600 5 10 0 0 0 0 1
5045
+pintype=pas
5046
+}
5047
+L 26600 28600 26800 28600 3 10 0 0 -1 -1
5048
+T 26800 28450 8 10 0 0 0 0 1
5049
+net=GND:1
5050
+T 26700 28500 8 10 0 1 0 5 1
5051
+value=GND
5052
+]
5053
+{
5054
+T 26700 28500 5 10 1 1 0 5 1
5055
+value=GND
5056
+}
5057
+N 26300 29000 26500 29000 4
5058
+N 26500 29000 26500 33300 4
5059
+N 22500 28000 19800 28000 4
5060
+N 19600 27800 22500 27800 4
5061
+N 17400 30600 22500 30600 4
5062
+N 17200 30400 22500 30400 4
5063
+N 17000 30200 22500 30200 4
5064
+N 18400 15800 18400 26600 4
5065
+N 18400 26600 22500 26600 4
5066
+N 18600 26800 22500 26800 4
5067
+N 18600 16000 18600 26800 4
5068
+N 18800 16200 18800 27000 4
5069
+N 18800 27000 22500 27000 4
5070
+N 19000 27200 22500 27200 4
5071
+N 19000 16400 19000 27200 4
5072
+N 19200 16600 19200 27400 4
5073
+N 19200 27400 22500 27400 4
5074
+N 19400 27600 22500 27600 4
5075
+N 19400 16800 19400 27600 4
5076
+N 19600 17000 19600 27800 4
5077
+N 19800 17200 19800 28000 4
5078
+N 18000 10800 18000 23900 4
5079
+N 18000 23900 30200 23900 4
5080
+N 30200 23900 30200 30800 4
5081
+N 26300 30800 30200 30800 4
5082
+N 26300 31000 30400 31000 4
5083
+N 30400 23700 30400 31000 4
5084
+N 17800 11000 17800 23700 4
5085
+N 17800 23700 30400 23700 4
5086
+N 17400 21600 17400 30600 4
5087
+N 17200 21400 17200 30400 4
5088
+N 17000 21200 17000 30200 4
5089
+N 7300 16200 3400 16200 4
5090
+N 3400 16200 3400 15500 4
5091
+N 3400 15500 1500 15500 4
5092
+N 1300 15300 3600 15300 4
5093
+N 3600 15300 3600 16000 4
5094
+N 3600 16000 7300 16000 4
5095
+N 7300 15800 3800 15800 4
5096
+N 3800 15100 3800 15800 4
5097
+N 7300 15600 4000 15600 4
5098
+N 4000 15600 4000 14900 4
5099
+N 7300 15400 4200 15400 4
5100
+N 4200 15400 4200 14700 4
5101
+N 4000 14900 900 14900 4
5102
+N 700 14700 4200 14700 4
5103
+N 3800 15100 1100 15100 4
5104
+N 700 14700 700 22500 4
5105
+N 700 22500 17400 22500 4
5106
+N 900 22300 17200 22300 4
5107
+N 900 14900 900 22300 4
5108
+N 1100 15100 1100 22100 4
5109
+N 1100 22100 17000 22100 4
5110
+N 1300 21900 16800 21900 4
5111
+N 1300 15300 1300 21900 4
5112
+N 1500 15500 1500 21700 4
5113
+N 1500 21700 16600 21700 4
5114
+N 14900 31400 22500 31400 4
5115
+N 14900 18000 14900 31400 4
5116
+N 14900 18000 11100 18000 4
5117
+N 14700 31800 22500 31800 4
5118
+N 14700 18200 14700 31800 4
5119
+N 14700 18200 11100 18200 4
5120
+N 11100 18400 14500 18400 4
5121
+N 14500 18400 14500 24100 4
5122
+N 14300 24300 14300 18600 4
5123
+N 14300 18600 11100 18600 4
5124
+N 14500 24100 30000 24100 4
5125
+N 30000 24100 30000 31800 4
5126
+N 26300 31800 30000 31800 4
5127
+N 26300 29600 29800 29600 4
5128
+N 29800 29600 29800 24300 4
5129
+N 14300 24300 29800 24300 4
5130
+N 2000 28400 7700 28400 4
5131
+C 1000 29300 1 0 0 EMBEDDEDcon2_big.sym
5132
+[
5133
+P 1500 29700 1800 29700 1 0 1
5134
+{
5135
+T 1400 29700 5 8 1 1 0 7 1
5136
+pinnumber=2
5137
+T 350 29650 5 8 0 0 0 0 1
5138
+pinseq=2
5139
+T 1500 29700 5 10 0 0 0 0 1
5140
+pintype=pas
5141
+}
5142
+P 1500 30100 1800 30100 1 0 1
5143
+{
5144
+T 1400 30100 5 8 1 1 0 7 1
5145
+pinnumber=1
5146
+T 350 30050 5 8 0 0 0 0 1
5147
+pinseq=1
5148
+T 1500 30100 5 10 0 0 0 0 1
5149
+pintype=pas
5150
+}
5151
+B 1000 29500 500 800 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5152
+]
5153
+{
5154
+T 2900 32300 5 10 0 0 0 0 1
5155
+device=2 pin connector
5156
+T 1000 30400 5 10 1 1 0 0 1
5157
+refdes=CON1
5158
+T 1000 29400 5 10 1 1 0 2 1
5159
+value=9-12V=
5160
+}
5161
+N 1800 30100 2200 30100 4
5162
+N 1800 29700 2000 29700 4
5163
+N 2000 28200 2000 29700 4
5164
+N 12000 9300 12000 11800 4
5165
+C 12300 8400 1 90 0 EMBEDDEDres.sym
5166
+[
5167
+P 12000 9300 12000 9150 1 0 0
5168
+{
5169
+T 11950 9200 5 8 0 1 90 0 1
5170
+pinnumber=2
5171
+T 11950 9200 5 8 0 0 90 0 1
5172
+pinseq=2
5173
+T 12000 9300 5 10 0 0 90 0 1
5174
+pintype=pas
5175
+}
5176
+P 12000 8400 12000 8552 1 0 0
5177
+{
5178
+T 11950 8500 5 8 0 1 90 0 1
5179
+pinnumber=1
5180
+T 11950 8500 5 8 0 0 90 0 1
5181
+pinseq=1
5182
+T 12000 8400 5 10 0 0 90 0 1
5183
+pintype=pas
5184
+}
5185
+B 11900 8550 200 600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5186
+T 11950 8800 5 10 0 0 90 0 1
5187
+device=resistor
5188
+T 11800 8850 8 10 0 1 90 3 1
5189
+refdes=R?
5190
+T 12200 8850 8 10 0 1 90 5 1
5191
+value=?E
5192
+]
5193
+{
5194
+T 11850 8900 5 10 1 1 0 6 1
5195
+refdes=R4
5196
+T 11850 8800 5 10 1 1 0 8 1
5197
+value=3.3kE
5198
+}
5199
+C 14000 15600 1 0 0 EMBEDDEDres.sym
5200
+[
5201
+P 14900 15900 14750 15900 1 0 0
5202
+{
5203
+T 14800 15950 5 8 0 1 0 0 1
5204
+pinnumber=2
5205
+T 14800 15950 5 8 0 0 0 0 1
5206
+pinseq=2
5207
+T 14900 15900 5 10 0 0 0 0 1
5208
+pintype=pas
5209
+}
5210
+P 14000 15900 14152 15900 1 0 0
5211
+{
5212
+T 14100 15950 5 8 0 1 0 0 1
5213
+pinnumber=1
5214
+T 14100 15950 5 8 0 0 0 0 1
5215
+pinseq=1
5216
+T 14000 15900 5 10 0 0 0 0 1
5217
+pintype=pas
5218
+}
5219
+B 14150 15800 600 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5220
+T 14400 15950 5 10 0 0 0 0 1
5221
+device=resistor
5222
+T 14450 16100 8 10 0 1 0 3 1
5223
+refdes=R?
5224
+T 14450 15700 8 10 0 1 0 5 1
5225
+value=?E
5226
+]
5227
+{
5228
+T 14450 16100 5 10 1 1 0 3 1
5229
+refdes=R3
5230
+T 14450 15700 5 10 1 1 0 5 1
5231
+value=3.3kE
5232
+}
5233
+C 13900 16100 1 90 0 EMBEDDEDres.sym
5234
+[
5235
+P 13600 17000 13600 16850 1 0 0
5236
+{
5237
+T 13550 16900 5 8 0 1 90 0 1
5238
+pinnumber=2
5239
+T 13550 16900 5 8 0 0 90 0 1
5240
+pinseq=2
5241
+T 13600 17000 5 10 0 0 90 0 1
5242
+pintype=pas
5243
+}
5244
+P 13600 16100 13600 16252 1 0 0
5245
+{
5246
+T 13550 16200 5 8 0 1 90 0 1
5247
+pinnumber=1
5248
+T 13550 16200 5 8 0 0 90 0 1
5249
+pinseq=1
5250
+T 13600 16100 5 10 0 0 90 0 1
5251
+pintype=pas
5252
+}
5253
+B 13500 16250 200 600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5254
+T 13550 16500 5 10 0 0 90 0 1
5255
+device=resistor
5256
+T 13400 16550 8 10 0 1 90 3 1
5257
+refdes=R?
5258
+T 13800 16550 8 10 0 1 90 5 1
5259
+value=?E
5260
+]
5261
+{
5262
+T 13450 16600 5 10 1 1 0 6 1
5263
+refdes=R2
5264
+T 13450 16500 5 10 1 1 0 8 1
5265
+value=3.3kE
5266
+}
5267
+N 13600 17000 13600 17400 4
5268
+N 11100 17400 13600 17400 4
5269
+N 13600 15900 14000 15900 4
5270
+C 10500 24600 1 270 0 EMBEDDEDcon10.sym
5271
+[
5272
+P 12500 24100 12500 23800 1 0 1
5273
+{
5274
+T 12500 24200 5 8 1 1 90 1 1
5275
+pinnumber=2
5276
+T 12450 25250 5 8 0 0 90 8 1
5277
+pinseq=2
5278
+T 12500 24100 5 10 0 0 90 8 1
5279
+pintype=pas
5280
+}
5281
+P 12100 24100 12100 23800 1 0 1
5282
+{
5283
+T 12100 24200 5 8 1 1 90 1 1
5284
+pinnumber=4
5285
+T 12050 25250 5 8 0 0 90 8 1
5286
+pinseq=4
5287
+T 12100 24100 5 10 0 0 90 8 1
5288
+pintype=pas
5289
+}
5290
+P 11700 24100 11700 23800 1 0 1
5291
+{
5292
+T 11700 24200 5 8 1 1 90 1 1
5293
+pinnumber=6
5294
+T 11650 25250 5 8 0 0 90 8 1
5295
+pinseq=6
5296
+T 11700 24100 5 10 0 0 90 8 1
5297
+pintype=pas
5298
+}
5299
+P 11300 24100 11300 23800 1 0 1
5300
+{
5301
+T 11300 24200 5 8 1 1 90 1 1
5302
+pinnumber=8
5303
+T 11250 25250 5 8 0 0 90 8 1
5304
+pinseq=8
5305
+T 11300 24100 5 10 0 0 90 8 1
5306
+pintype=pas
5307
+}
5308
+P 12700 24100 12700 23800 1 0 1
5309
+{
5310
+T 12700 24200 5 8 1 1 90 1 1
5311
+pinnumber=1
5312
+T 12650 25250 5 8 0 0 90 8 1
5313
+pinseq=1
5314
+T 12700 24100 5 10 0 0 90 8 1
5315
+pintype=pas
5316
+}
5317
+P 12300 24100 12300 23800 1 0 1
5318
+{
5319
+T 12300 24200 5 8 1 1 90 1 1
5320
+pinnumber=3
5321
+T 12250 25250 5 8 0 0 90 8 1
5322
+pinseq=3
5323
+T 12300 24100 5 10 0 0 90 8 1
5324
+pintype=pas
5325
+}
5326
+P 11900 24100 11900 23800 1 0 1
5327
+{
5328
+T 11900 24200 5 8 1 1 90 1 1
5329
+pinnumber=5
5330
+T 11850 25250 5 8 0 0 90 8 1
5331
+pinseq=5
5332
+T 11900 24100 5 10 0 0 90 8 1
5333
+pintype=pas
5334
+}
5335
+P 11500 24100 11500 23800 1 0 1
5336
+{
5337
+T 11500 24200 5 8 1 1 90 1 1
5338
+pinnumber=7
5339
+T 11450 25250 5 8 0 0 90 8 1
5340
+pinseq=7
5341
+T 11500 24100 5 10 0 0 90 8 1
5342
+pintype=pas
5343
+}
5344
+P 10900 24100 10900 23800 1 0 1
5345
+{
5346
+T 10900 24200 5 8 1 1 90 1 1
5347
+pinnumber=10
5348
+T 10850 25250 5 8 0 0 90 8 1
5349
+pinseq=10
5350
+T 10900 24100 5 10 0 0 90 8 1
5351
+pintype=pas
5352
+}
5353
+P 11100 24100 11100 23800 1 0 1
5354
+{
5355
+T 11100 24200 5 8 1 1 90 1 1
5356
+pinnumber=9
5357
+T 11050 25250 5 8 0 0 90 8 1
5358
+pinseq=9
5359
+T 11100 24100 5 10 0 0 90 8 1
5360
+pintype=pas
5361
+}
5362
+B 10700 24100 2200 500 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5363
+T 13500 22700 5 10 0 0 90 8 1
5364
+device=10 pin connector
5365
+T 13000 24600 8 10 0 1 90 8 1
5366
+refdes=CON?
5367
+T 10600 24600 8 10 0 1 90 6 1
5368
+value=???
5369
+]
5370
+{
5371
+T 10700 24700 5 10 1 1 0 0 1
5372
+refdes=CON6
5373
+T 12900 24700 5 10 1 1 0 6 1
5374
+value=GPIO A
5375
+}
5376
+N 26500 25200 28900 25200 4
5377
+N 11100 16800 11300 16800 4
5378
+N 11300 16800 11300 23800 4
5379
+N 11100 16600 11500 16600 4
5380
+N 11500 16600 11500 23800 4
5381
+N 11100 16400 11700 16400 4
5382
+N 11700 16400 11700 23800 4
5383
+N 11100 16200 11900 16200 4
5384
+N 11900 16200 11900 23800 4
5385
+N 11100 16000 12100 16000 4
5386
+N 12100 16000 12100 23800 4
5387
+N 11100 15800 12300 15800 4
5388
+N 12300 15800 12300 23800 4
5389
+N 11100 15600 12500 15600 4
5390
+N 12500 15600 12500 23800 4
5391
+N 11100 15400 12700 15400 4
5392
+N 12700 15400 12700 23800 4
5393
+C 10700 23000 1 0 0 EMBEDDEDgnd.sym
5394
+[
5395
+P 10900 23200 10900 23400 1 0 1
5396
+{
5397
+T 10958 23261 5 4 0 1 0 0 1
5398
+pinnumber=1
5399
+T 10958 23261 5 4 0 0 0 0 1
5400
+pinseq=1
5401
+T 10900 23200 5 10 0 0 0 0 1
5402
+pintype=pas
5403
+}
5404
+L 10800 23200 11000 23200 3 10 0 0 -1 -1
5405
+T 11000 23050 8 10 0 0 0 0 1
5406
+net=GND:1
5407
+T 10900 23100 8 10 0 1 0 5 1
5408
+value=GND
5409
+]
5410
+{
5411
+T 10900 23100 5 10 1 1 0 5 1
5412
+value=GND
5413
+}
5414
+C 10000 24000 1 0 0 EMBEDDEDvdd5.sym
5415
+[
5416
+P 10200 24100 10200 24000 1 0 1
5417
+{
5418
+T 10200 24200 5 6 0 1 0 0 1
5419
+pinnumber=1
5420
+T 10200 24200 5 6 0 0 0 0 1
5421
+pinseq=1
5422
+T 10200 24100 5 10 0 0 0 0 1
5423
+pintype=pas
5424
+}
5425
+V 10200 24200 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
5426
+L 10200 24150 10200 24100 3 0 0 0 -1 -1
5427
+T 10300 24050 8 10 0 0 0 0 1
5428
+net=VDD5:1
5429
+T 10200 24300 8 10 0 1 0 3 1
5430
+value=VDD5
5431
+]
5432
+{
5433
+T 10200 24300 5 10 1 1 0 3 1
5434
+value=VDD5
5435
+}
5436
+N 10900 23800 10900 23400 4
5437
+N 10200 24000 10200 23600 4
5438
+N 10200 23600 11100 23600 4
5439
+N 11100 23600 11100 23800 4
5440
+C 5200 14000 1 180 0 EMBEDDEDcon10.sym
5441
+[
5442
+P 5700 12000 6000 12000 1 0 1
5443
+{
5444
+T 5600 12000 5 8 1 1 180 1 1
5445
+pinnumber=2
5446
+T 4550 12050 5 8 0 0 180 6 1
5447
+pinseq=2
5448
+T 5700 12000 5 10 0 0 180 6 1
5449
+pintype=pas
5450
+}
5451
+P 5700 12400 6000 12400 1 0 1
5452
+{
5453
+T 5600 12400 5 8 1 1 180 1 1
5454
+pinnumber=4
5455
+T 4550 12450 5 8 0 0 180 6 1
5456
+pinseq=4
5457
+T 5700 12400 5 10 0 0 180 6 1
5458
+pintype=pas
5459
+}
5460
+P 5700 12800 6000 12800 1 0 1
5461
+{
5462
+T 5600 12800 5 8 1 1 180 1 1
5463
+pinnumber=6
5464
+T 4550 12850 5 8 0 0 180 6 1
5465
+pinseq=6
5466
+T 5700 12800 5 10 0 0 180 6 1
5467
+pintype=pas
5468
+}
5469
+P 5700 13200 6000 13200 1 0 1
5470
+{
5471
+T 5600 13200 5 8 1 1 180 1 1
5472
+pinnumber=8
5473
+T 4550 13250 5 8 0 0 180 6 1
5474
+pinseq=8
5475
+T 5700 13200 5 10 0 0 180 6 1
5476
+pintype=pas
5477
+}
5478
+P 5700 11800 6000 11800 1 0 1
5479
+{
5480
+T 5600 11800 5 8 1 1 180 1 1
5481
+pinnumber=1
5482
+T 4550 11850 5 8 0 0 180 6 1
5483
+pinseq=1
5484
+T 5700 11800 5 10 0 0 180 6 1
5485
+pintype=pas
5486
+}
5487
+P 5700 12200 6000 12200 1 0 1
5488
+{
5489
+T 5600 12200 5 8 1 1 180 1 1
5490
+pinnumber=3
5491
+T 4550 12250 5 8 0 0 180 6 1
5492
+pinseq=3
5493
+T 5700 12200 5 10 0 0 180 6 1
5494
+pintype=pas
5495
+}
5496
+P 5700 12600 6000 12600 1 0 1
5497
+{
5498
+T 5600 12600 5 8 1 1 180 1 1
5499
+pinnumber=5
5500
+T 4550 12650 5 8 0 0 180 6 1
5501
+pinseq=5
5502
+T 5700 12600 5 10 0 0 180 6 1
5503
+pintype=pas
5504
+}
5505
+P 5700 13000 6000 13000 1 0 1
5506
+{
5507
+T 5600 13000 5 8 1 1 180 1 1
5508
+pinnumber=7
5509
+T 4550 13050 5 8 0 0 180 6 1
5510
+pinseq=7
5511
+T 5700 13000 5 10 0 0 180 6 1
5512
+pintype=pas
5513
+}
5514
+P 5700 13600 6000 13600 1 0 1
5515
+{
5516
+T 5600 13600 5 8 1 1 180 1 1
5517
+pinnumber=10
5518
+T 4550 13650 5 8 0 0 180 6 1
5519
+pinseq=10
5520
+T 5700 13600 5 10 0 0 180 6 1
5521
+pintype=pas
5522
+}
5523
+P 5700 13400 6000 13400 1 0 1
5524
+{
5525
+T 5600 13400 5 8 1 1 180 1 1
5526
+pinnumber=9
5527
+T 4550 13450 5 8 0 0 180 6 1
5528
+pinseq=9
5529
+T 5700 13400 5 10 0 0 180 6 1
5530
+pintype=pas
5531
+}
5532
+B 5200 11600 500 2200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5533
+T 7100 11000 5 10 0 0 180 6 1
5534
+device=10 pin connector
5535
+T 5200 11500 8 10 0 1 180 6 1
5536
+refdes=CON?
5537
+T 5200 13900 8 10 0 1 180 8 1
5538
+value=???
5539
+]
5540
+{
5541
+T 5200 13900 5 10 1 1 0 0 1
5542
+refdes=CON7
5543
+T 5200 11500 5 10 1 1 0 2 1
5544
+value=GPIO B
5545
+}
5546
+N 6000 11800 7300 11800 4
5547
+N 7300 12000 6000 12000 4
5548
+N 6000 12200 7300 12200 4
5549
+N 7300 12400 6000 12400 4
5550
+N 6000 12600 7300 12600 4
5551
+N 7300 12800 6000 12800 4
5552
+N 6000 13000 7300 13000 4
5553
+N 7300 13200 6000 13200 4
5554
+C 6200 11100 1 0 0 EMBEDDEDgnd.sym
5555
+[
5556
+P 6400 11300 6400 11500 1 0 1
5557
+{
5558
+T 6458 11361 5 4 0 1 0 0 1
5559
+pinnumber=1
5560
+T 6458 11361 5 4 0 0 0 0 1
5561
+pinseq=1
5562
+T 6400 11300 5 10 0 0 0 0 1
5563
+pintype=pas
5564
+}
5565
+L 6300 11300 6500 11300 3 10 0 0 -1 -1
5566
+T 6500 11150 8 10 0 0 0 0 1
5567
+net=GND:1
5568
+T 6400 11200 8 10 0 1 0 5 1
5569
+value=GND
5570
+]
5571
+{
5572
+T 6400 11200 5 10 1 1 0 5 1
5573
+value=GND
5574
+}
5575
+N 6400 11500 6400 13600 4
5576
+N 6400 13600 6000 13600 4
5577
+N 6000 13400 6200 13400 4
5578
+N 6200 13400 6200 13800 4
5579
+C 6000 13800 1 0 0 EMBEDDEDvdd5.sym
5580
+[
5581
+P 6200 13900 6200 13800 1 0 1
5582
+{
5583
+T 6200 14000 5 6 0 1 0 0 1
5584
+pinnumber=1
5585
+T 6200 14000 5 6 0 0 0 0 1
5586
+pinseq=1
5587
+T 6200 13900 5 10 0 0 0 0 1
5588
+pintype=pas
5589
+}
5590
+V 6200 14000 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
5591
+L 6200 13950 6200 13900 3 0 0 0 -1 -1
5592
+T 6300 13850 8 10 0 0 0 0 1
5593
+net=VDD5:1
5594
+T 6200 14100 8 10 0 1 0 3 1
5595
+value=VDD5
5596
+]
5597
+{
5598
+T 6200 14100 5 10 1 1 0 3 1
5599
+value=VDD5
5600
+}
5601
+N 11100 14000 12600 14000 4
5602
+N 12800 14200 11100 14200 4
5603
+N 26300 18600 26500 18600 4
5604
+N 26500 18600 26500 22700 4
5605
+N 26700 22900 26700 18400 4
5606
+N 26700 18400 26300 18400 4
5607
+N 26300 18200 26900 18200 4
5608
+N 26900 18200 26900 23100 4
5609
+N 27100 23300 27100 17400 4
5610
+N 27100 17400 26300 17400 4
5611
+N 11100 15000 20600 15000 4
5612
+N 20600 15000 20600 23300 4
5613
+N 20600 23300 27100 23300 4
5614
+N 20800 23100 26900 23100 4
5615
+N 20800 23100 20800 14800 4
5616
+N 20800 14800 11100 14800 4
5617
+N 11100 14600 21000 14600 4
5618
+N 21000 14600 21000 22900 4
5619
+N 21000 22900 26700 22900 4
5620
+N 21200 22700 26500 22700 4
5621
+N 21200 14400 21200 22700 4
5622
+N 11100 14400 21200 14400 4
5623
+N 16600 17800 11100 17800 4
5624
+N 11100 17600 16600 17600 4
5625
+N 11100 17200 15100 17200 4
5626
+N 15100 17200 15100 17400 4
5627
+N 15100 17400 16600 17400 4
5628
+N 14900 15900 15300 15900 4
5629
+N 15300 15900 15300 18000 4
5630
+N 15300 18000 16600 18000 4
5631
+C 16000 18200 1 0 0 EMBEDDEDvdd5.sym
5632
+[
5633
+P 16200 18300 16200 18200 1 0 1
5634
+{
5635
+T 16200 18400 5 6 0 1 0 0 1
5636
+pinnumber=1
5637
+T 16200 18400 5 6 0 0 0 0 1
5638
+pinseq=1
5639
+T 16200 18300 5 10 0 0 0 0 1
5640
+pintype=pas
5641
+}
5642
+V 16200 18400 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
5643
+L 16200 18350 16200 18300 3 0 0 0 -1 -1
5644
+T 16300 18250 8 10 0 0 0 0 1
5645
+net=VDD5:1
5646
+T 16200 18500 8 10 0 1 0 3 1
5647
+value=VDD5
5648
+]
5649
+{
5650
+T 16200 18500 5 10 1 1 0 3 1
5651
+value=VDD5
5652
+}
5653
+C 17400 15800 1 0 0 EMBEDDEDcon10.sym
5654
+[
5655
+P 16900 17800 16600 17800 1 0 1
5656
+{
5657
+T 17000 17800 5 8 1 1 0 1 1
5658
+pinnumber=2
5659
+T 18050 17750 5 8 0 0 0 6 1
5660
+pinseq=2
5661
+T 16900 17800 5 10 0 0 0 6 1
5662
+pintype=pas
5663
+}
5664
+P 16900 17400 16600 17400 1 0 1
5665
+{
5666
+T 17000 17400 5 8 1 1 0 1 1
5667
+pinnumber=4
5668
+T 18050 17350 5 8 0 0 0 6 1
5669
+pinseq=4
5670
+T 16900 17400 5 10 0 0 0 6 1
5671
+pintype=pas
5672
+}
5673
+P 16900 17000 16600 17000 1 0 1
5674
+{
5675
+T 17000 17000 5 8 1 1 0 1 1
5676
+pinnumber=6
5677
+T 18050 16950 5 8 0 0 0 6 1
5678
+pinseq=6
5679
+T 16900 17000 5 10 0 0 0 6 1
5680
+pintype=pas
5681
+}
5682
+P 16900 16600 16600 16600 1 0 1
5683
+{
5684
+T 17000 16600 5 8 1 1 0 1 1
5685
+pinnumber=8
5686
+T 18050 16550 5 8 0 0 0 6 1
5687
+pinseq=8
5688
+T 16900 16600 5 10 0 0 0 6 1
5689
+pintype=pas
5690
+}
5691
+P 16900 18000 16600 18000 1 0 1
5692
+{
5693
+T 17000 18000 5 8 1 1 0 1 1
5694
+pinnumber=1
5695
+T 18050 17950 5 8 0 0 0 6 1
5696
+pinseq=1
5697
+T 16900 18000 5 10 0 0 0 6 1
5698
+pintype=pas
5699
+}
5700
+P 16900 17600 16600 17600 1 0 1
5701
+{
5702
+T 17000 17600 5 8 1 1 0 1 1
5703
+pinnumber=3
5704
+T 18050 17550 5 8 0 0 0 6 1
5705
+pinseq=3
5706
+T 16900 17600 5 10 0 0 0 6 1
5707
+pintype=pas
5708
+}
5709
+P 16900 17200 16600 17200 1 0 1
5710
+{
5711
+T 17000 17200 5 8 1 1 0 1 1
5712
+pinnumber=5
5713
+T 18050 17150 5 8 0 0 0 6 1
5714
+pinseq=5
5715
+T 16900 17200 5 10 0 0 0 6 1
5716
+pintype=pas
5717
+}
5718
+P 16900 16800 16600 16800 1 0 1
5719
+{
5720
+T 17000 16800 5 8 1 1 0 1 1
5721
+pinnumber=7
5722
+T 18050 16750 5 8 0 0 0 6 1
5723
+pinseq=7
5724
+T 16900 16800 5 10 0 0 0 6 1
5725
+pintype=pas
5726
+}
5727
+P 16900 16200 16600 16200 1 0 1
5728
+{
5729
+T 17000 16200 5 8 1 1 0 1 1
5730
+pinnumber=10
5731
+T 18050 16150 5 8 0 0 0 6 1
5732
+pinseq=10
5733
+T 16900 16200 5 10 0 0 0 6 1
5734
+pintype=pas
5735
+}
5736
+P 16900 16400 16600 16400 1 0 1
5737
+{
5738
+T 17000 16400 5 8 1 1 0 1 1
5739
+pinnumber=9
5740
+T 18050 16350 5 8 0 0 0 6 1
5741
+pinseq=9
5742
+T 16900 16400 5 10 0 0 0 6 1
5743
+pintype=pas
5744
+}
5745
+B 16900 16000 500 2200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5746
+T 15500 18800 5 10 0 0 0 6 1
5747
+device=10 pin connector
5748
+T 17400 18300 8 10 0 1 0 6 1
5749
+refdes=CON?
5750
+T 17400 15900 8 10 0 1 0 8 1
5751
+value=???
5752
+]
5753
+{
5754
+T 17400 18300 5 10 1 1 0 6 1
5755
+refdes=CON8
5756
+T 17400 15900 5 10 1 1 0 8 1
5757
+value=SPI I2C
5758
+}
5759
+N 16200 18200 16200 16400 4
5760
+N 16200 16400 16600 16400 4
5761
+N 16200 17200 16600 17200 4
5762
+N 16600 17000 16400 17000 4
5763
+N 16400 16200 16600 16200 4
5764
+N 16400 16000 16400 17000 4
5765
+C 16200 15600 1 0 0 EMBEDDEDgnd.sym
5766
+[
5767
+P 16400 15800 16400 16000 1 0 1
5768
+{
5769
+T 16458 15861 5 4 0 1 0 0 1
5770
+pinnumber=1
5771
+T 16458 15861 5 4 0 0 0 0 1
5772
+pinseq=1
5773
+T 16400 15800 5 10 0 0 0 0 1
5774
+pintype=pas
5775
+}
5776
+L 16300 15800 16500 15800 3 10 0 0 -1 -1
5777
+T 16500 15650 8 10 0 0 0 0 1
5778
+net=GND:1
5779
+T 16400 15700 8 10 0 1 0 5 1
5780
+value=GND
5781
+]
5782
+{
5783
+T 16400 15700 5 10 1 1 0 5 1
5784
+value=GND
5785
+}
5786
+N 11100 13600 15700 13600 4
5787
+N 15700 13600 15700 16800 4
5788
+N 15700 16800 16600 16800 4
5789
+N 16600 16600 15900 16600 4
5790
+N 15900 13800 15900 16600 4
5791
+N 11100 13800 15900 13800 4
5792
+C 6100 3200 1 0 0 EMBEDDEDMAX232.sym
5793
+[
5794
+T 8300 6963 8 10 0 1 0 6 1
5795
+refdes=IC?
5796
+T 6500 9250 5 10 0 0 0 0 1
5797
+device=MAX232
5798
+P 6100 6500 6400 6500 1 0 0
5799
+{
5800
+T 6300 6550 5 8 1 1 0 6 1
5801
+pinnumber=1
5802
+T 6300 6450 5 8 0 1 0 8 1
5803
+pinseq=1
5804
+T 6450 6500 9 8 1 1 0 0 1
5805
+pinlabel=C1+
5806
+T 6450 6500 5 8 0 1 0 2 1
5807
+pintype=pas
5808
+}
5809
+B 6400 3400 1900 3400 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5810
+T 6500 10250 5 10 0 0 0 0 1
5811
+numslots=0
5812
+P 6100 3700 6400 3700 1 0 0
5813
+{
5814
+T 6300 3750 5 8 1 1 0 6 1
5815
+pinnumber=8
5816
+T 6300 3650 5 8 0 1 0 8 1
5817
+pinseq=8
5818
+T 6450 3700 9 8 1 1 0 0 1
5819
+pinlabel=R2in
5820
+T 6450 3700 5 8 0 1 0 2 1
5821
+pintype=in
5822
+}
5823
+P 8600 3700 8300 3700 1 0 0
5824
+{
5825
+T 8400 3750 5 8 1 1 0 0 1
5826
+pinnumber=9
5827
+T 8400 3650 5 8 0 1 0 2 1
5828
+pinseq=9
5829
+T 8250 3700 9 8 1 1 0 6 1
5830
+pinlabel=R2out
5831
+T 8250 3700 5 8 0 1 0 8 1
5832
+pintype=out
5833
+}
5834
+P 6100 6100 6400 6100 1 0 0
5835
+{
5836
+T 6300 6150 5 8 1 1 0 6 1
5837
+pinnumber=2
5838
+T 6300 6050 5 8 0 1 0 8 1
5839
+pinseq=2
5840
+T 6450 6100 9 8 1 1 0 0 1
5841
+pinlabel=Vs+
5842
+T 6450 6100 5 8 0 1 0 2 1
5843
+pintype=pas
5844
+}
5845
+P 6100 5700 6400 5700 1 0 0
5846
+{
5847
+T 6300 5750 5 8 1 1 0 6 1
5848
+pinnumber=3
5849
+T 6300 5650 5 8 0 1 0 8 1
5850
+pinseq=3
5851
+T 6450 5700 9 8 1 1 0 0 1
5852
+pinlabel=C1-
5853
+T 6450 5700 5 8 0 1 0 2 1
5854
+pintype=pas
5855
+}
5856
+P 8600 6500 8300 6500 1 0 0
5857
+{
5858
+T 8400 6550 5 8 1 1 0 0 1
5859
+pinnumber=16
5860
+T 8400 6450 5 8 0 1 0 2 1
5861
+pinseq=16
5862
+T 8250 6500 9 8 1 1 0 6 1
5863
+pinlabel=VCC
5864
+T 8250 6500 5 8 0 1 0 8 1
5865
+pintype=pwr
5866
+}
5867
+P 6100 5300 6400 5300 1 0 0
5868
+{
5869
+T 6300 5350 5 8 1 1 0 6 1
5870
+pinnumber=4
5871
+T 6300 5250 5 8 0 1 0 8 1
5872
+pinseq=4
5873
+T 6450 5300 9 8 1 1 0 0 1
5874
+pinlabel=C2+
5875
+T 6450 5300 5 8 0 1 0 2 1
5876
+pintype=pas
5877
+}
5878
+P 8600 6100 8300 6100 1 0 0
5879
+{
5880
+T 8400 6150 5 8 1 1 0 0 1
5881
+pinnumber=15
5882
+T 8400 6050 5 8 0 1 0 2 1
5883
+pinseq=15
5884
+T 8250 6100 9 8 1 1 0 6 1
5885
+pinlabel=GND
5886
+T 8250 6100 5 8 0 1 0 8 1
5887
+pintype=pwr
5888
+}
5889
+P 6100 4900 6400 4900 1 0 0
5890
+{
5891
+T 6300 4950 5 8 1 1 0 6 1
5892
+pinnumber=5
5893
+T 6300 4850 5 8 0 1 0 8 1
5894
+pinseq=5
5895
+T 6450 4900 9 8 1 1 0 0 1
5896
+pinlabel=C2-
5897
+T 6450 4900 5 8 0 1 0 2 1
5898
+pintype=pas
5899
+}
5900
+P 8600 5700 8300 5700 1 0 0
5901
+{
5902
+T 8400 5750 5 8 1 1 0 0 1
5903
+pinnumber=14
5904
+T 8400 5650 5 8 0 1 0 2 1
5905
+pinseq=14
5906
+T 8250 5700 9 8 1 1 0 6 1
5907
+pinlabel=T1out
5908
+T 8250 5700 5 8 0 1 0 8 1
5909
+pintype=out
5910
+}
5911
+P 6100 4500 6400 4500 1 0 0
5912
+{
5913
+T 6300 4550 5 8 1 1 0 6 1
5914
+pinnumber=6
5915
+T 6300 4450 5 8 0 1 0 8 1
5916
+pinseq=6
5917
+T 6450 4500 9 8 1 1 0 0 1
5918
+pinlabel=Vs-
5919
+T 6450 4500 5 8 0 1 0 2 1
5920
+pintype=pas
5921
+}
5922
+P 8600 5300 8300 5300 1 0 0
5923
+{
5924
+T 8400 5350 5 8 1 1 0 0 1
5925
+pinnumber=13
5926
+T 8400 5250 5 8 0 1 0 2 1
5927
+pinseq=13
5928
+T 8250 5300 9 8 1 1 0 6 1
5929
+pinlabel=R1in
5930
+T 8250 5300 5 8 0 1 0 8 1
5931
+pintype=in
5932
+}
5933
+P 6100 4100 6400 4100 1 0 0
5934
+{
5935
+T 6300 4150 5 8 1 1 0 6 1
5936
+pinnumber=7
5937
+T 6300 4050 5 8 0 1 0 8 1
5938
+pinseq=7
5939
+T 6450 4100 9 8 1 1 0 0 1
5940
+pinlabel=T2out
5941
+T 6450 4100 5 8 0 1 0 2 1
5942
+pintype=out
5943
+}
5944
+P 8600 4900 8300 4900 1 0 0
5945
+{
5946
+T 8400 4950 5 8 1 1 0 0 1
5947
+pinnumber=12
5948
+T 8400 4850 5 8 0 1 0 2 1
5949
+pinseq=12
5950
+T 8250 4900 9 8 1 1 0 6 1
5951
+pinlabel=R1out
5952
+T 8250 4900 5 8 0 1 0 8 1
5953
+pintype=out
5954
+}
5955
+P 8600 4500 8300 4500 1 0 0
5956
+{
5957
+T 8400 4550 5 8 1 1 0 0 1
5958
+pinnumber=11
5959
+T 8400 4450 5 8 0 1 0 2 1
5960
+pinseq=11
5961
+T 8250 4500 9 8 1 1 0 6 1
5962
+pinlabel=T1in
5963
+T 8250 4500 5 8 0 1 0 8 1
5964
+pintype=in
5965
+}
5966
+P 8600 4100 8300 4100 1 0 0
5967
+{
5968
+T 8400 4150 5 8 1 1 0 0 1
5969
+pinnumber=10
5970
+T 8400 4050 5 8 0 1 0 2 1
5971
+pinseq=10
5972
+T 8250 4100 9 8 1 1 0 6 1
5973
+pinlabel=T2in
5974
+T 8250 4100 5 8 0 1 0 8 1
5975
+pintype=in
5976
+}
5977
+L 7200 4100 6900 4100 3 0 0 0 -1 -1
5978
+L 7250 4100 7550 4250 3 0 0 0 -1 -1
5979
+L 7550 4250 7550 3950 3 0 0 0 -1 -1
5980
+L 7250 4100 7550 3950 3 0 0 0 -1 -1
5981
+L 7550 4100 7900 4100 3 0 0 0 -1 -1
5982
+V 7225 4100 25 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5983
+L 7500 3700 7800 3700 3 0 0 0 -1 -1
5984
+L 7450 3700 7150 3850 3 0 0 0 -1 -1
5985
+L 7150 3850 7150 3550 3 0 0 0 -1 -1
5986
+L 7450 3700 7150 3550 3 0 0 0 -1 -1
5987
+L 7150 3700 6800 3700 3 0 0 0 -1 -1
5988
+V 7475 3700 25 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5989
+L 7600 5000 7750 5300 3 0 0 0 -1 -1
5990
+L 7750 5300 7450 5300 3 0 0 0 -1 -1
5991
+L 7600 5000 7450 5300 3 0 0 0 -1 -1
5992
+V 7600 4975 25 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5993
+L 7200 5250 7050 4950 3 0 0 0 -1 -1
5994
+L 7050 4950 7350 4950 3 0 0 0 -1 -1
5995
+L 7200 5250 7350 4950 3 0 0 0 -1 -1
5996
+V 7200 5275 25 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
5997
+L 7600 4950 7600 4850 3 0 0 0 -1 -1
5998
+L 7600 4850 7850 4850 3 0 0 0 -1 -1
5999
+L 7600 5300 7600 5400 3 0 0 0 -1 -1
6000
+L 7600 5400 7900 5400 3 0 0 0 -1 -1
6001
+L 7200 4950 7200 4500 3 0 0 0 -1 -1
6002
+L 7200 4500 7950 4500 3 0 0 0 -1 -1
6003
+L 7200 5300 7200 5700 3 0 0 0 -1 -1
6004
+L 7200 5700 7850 5700 3 0 0 0 -1 -1
6005
+T 6400 6963 8 10 0 1 0 0 1
6006
+value=MAX232
6007
+]
6008
+{
6009
+T 8300 6913 5 10 1 1 0 6 1
6010
+refdes=IC4
6011
+T 6400 6900 5 10 1 1 0 0 1
6012
+value=MAX232A
6013
+}
6014
+N 8800 6900 8800 6500 4
6015
+N 8600 6500 9000 6500 4
6016
+N 4800 6500 4800 5700 4
6017
+N 4800 5700 6100 5700 4
6018
+N 4800 5300 4800 4900 4
6019
+N 4800 4900 6100 4900 4
6020
+N 4300 6100 6100 6100 4
6021
+N 4300 4500 6100 4500 4
6022
+C 3500 5100 1 0 0 EMBEDDEDgnd.sym
6023
+[
6024
+P 3700 5300 3700 5500 1 0 1
6025
+{
6026
+T 3758 5361 5 4 0 1 0 0 1
6027
+pinnumber=1
6028
+T 3758 5361 5 4 0 0 0 0 1
6029
+pinseq=1
6030
+T 3700 5300 5 10 0 0 0 0 1
6031
+pintype=pas
6032
+}
6033
+L 3600 5300 3800 5300 3 10 0 0 -1 -1
6034
+T 3800 5150 8 10 0 0 0 0 1
6035
+net=GND:1
6036
+T 3700 5200 8 10 0 1 0 5 1
6037
+value=GND
6038
+]
6039
+{
6040
+T 3700 5200 5 10 1 1 0 5 1
6041
+value=GND
6042
+}
6043
+C 800 600 1 0 0 EMBEDDEDDB9s.sym
6044
+[
6045
+L 800 1900 800 4300 3 0 0 0 -1 -1
6046
+T 1800 3500 5 10 0 0 0 0 1
6047
+device=DB9s
6048
+V 1400 1900 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6049
+P 1450 1900 2000 1900 1 0 1
6050
+{
6051
+T 1800 1950 5 8 1 1 0 0 1
6052
+pinnumber=5
6053
+T 1800 1950 5 8 0 0 0 0 1
6054
+pinseq=5
6055
+T 1450 1900 5 10 0 0 0 0 1
6056
+pintype=pas
6057
+}
6058
+A 1550 1750 150 250 110 3 0 0 0 -1 -1
6059
+A 875 1900 75 180 60 3 0 0 0 -1 -1
6060
+A 1550 4490 150 0 110 3 0 0 0 -1 -1
6061
+A 875 4300 75 120 60 3 0 0 0 -1 -1
6062
+L 1700 1737 1700 4505 3 0 0 0 -1 -1
6063
+V 1100 2200 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6064
+P 1150 2200 2000 2200 1 0 1
6065
+{
6066
+T 1800 2250 5 8 1 1 0 0 1
6067
+pinnumber=9
6068
+T 1800 2250 5 8 0 0 0 0 1
6069
+pinseq=9
6070
+T 1150 2200 5 10 0 0 0 0 1
6071
+pinseq=pas
6072
+}
6073
+V 1400 2500 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6074
+P 1450 2500 2000 2500 1 0 1
6075
+{
6076
+T 1800 2550 5 8 1 1 0 0 1
6077
+pinnumber=4
6078
+T 1800 2550 5 8 0 0 0 0 1
6079
+pinseq=4
6080
+T 1450 2500 5 10 0 0 0 0 1
6081
+pinseq=pas
6082
+}
6083
+V 1100 2800 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6084
+P 1150 2800 2000 2800 1 0 1
6085
+{
6086
+T 1800 2850 5 8 1 1 0 0 1
6087
+pinnumber=8
6088
+T 1800 2850 5 8 0 0 0 0 1
6089
+pinseq=8
6090
+T 1150 2800 5 10 0 0 0 0 1
6091
+pinseq=pas
6092
+}
6093
+V 1400 3100 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6094
+P 1450 3100 2000 3100 1 0 1
6095
+{
6096
+T 1800 3150 5 8 1 1 0 0 1
6097
+pinnumber=3
6098
+T 1800 3150 5 8 0 0 0 0 1
6099
+pinseq=3
6100
+T 1450 3100 5 10 0 0 0 0 1
6101
+pintype=pas
6102
+}
6103
+V 1100 3400 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6104
+P 1150 3400 2000 3400 1 0 1
6105
+{
6106
+T 1800 3450 5 8 1 1 0 0 1
6107
+pinnumber=7
6108
+T 1800 3450 5 8 0 0 0 0 1
6109
+pinseq=7
6110
+T 1150 3400 5 10 0 0 0 0 1
6111
+pintype=pas
6112
+}
6113
+V 1400 3700 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6114
+P 1450 3700 2000 3700 1 0 1
6115
+{
6116
+T 1800 3750 5 8 1 1 0 0 1
6117
+pinnumber=2
6118
+T 1800 3750 5 8 0 0 0 0 1
6119
+pinseq=2
6120
+T 1450 3700 5 10 0 0 0 0 1
6121
+pintype=pas
6122
+}
6123
+V 1100 4000 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6124
+P 1150 4000 2000 4000 1 0 1
6125
+{
6126
+T 1800 4050 5 8 1 1 0 0 1
6127
+pinnumber=6
6128
+T 1800 4050 5 8 0 0 0 0 1
6129
+pinseq=6
6130
+T 1150 4000 5 10 0 0 0 0 1
6131
+pintype=pas
6132
+}
6133
+V 1400 4300 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6134
+P 1450 4300 2000 4300 1 0 1
6135
+{
6136
+T 1800 4350 5 8 1 1 0 0 1
6137
+pinnumber=1
6138
+T 1800 4350 5 8 0 0 0 0 1
6139
+pinseq=1
6140
+T 1450 4300 5 10 0 0 0 0 1
6141
+pintype=pas
6142
+}
6143
+L 838 1834 1502 1608 3 0 0 0 -1 -1
6144
+L 1500 4631 837 4365 3 0 0 0 -1 -1
6145
+T 1000 4800 8 10 0 1 0 0 1
6146
+refdes=CON?
6147
+T 1000 1000 8 10 0 1 0 2 1
6148
+value=DB9
6149
+P 1450 1400 2000 1400 1 0 1
6150
+{
6151
+T 1800 1450 5 8 1 1 0 0 1
6152
+pinnumber=100
6153
+T 1800 1450 5 8 0 0 0 0 1
6154
+pinseq=100
6155
+T 1450 1400 5 10 0 0 0 0 1
6156
+pintype=pas
6157
+}
6158
+P 1450 1100 2000 1100 1 0 1
6159
+{
6160
+T 1800 1150 5 8 1 1 0 0 1
6161
+pinnumber=101
6162
+T 1800 1150 5 8 0 0 0 0 1
6163
+pinseq=101
6164
+T 1450 1100 5 10 0 0 0 0 1
6165
+pintype=pas
6166
+}
6167
+L 1450 1100 1400 1100 3 0 0 0 -1 -1
6168
+L 1400 1100 1400 1400 3 0 0 0 -1 -1
6169
+L 1450 1400 1400 1400 3 0 0 0 -1 -1
6170
+L 1400 1400 1400 1650 3 0 0 0 -1 -1
6171
+]
6172
+{
6173
+T 1000 4850 5 10 1 1 0 0 1
6174
+refdes=CON5
6175
+T 1000 900 5 10 1 1 0 2 1
6176
+value=SERIAL B
6177
+T 1000 600 5 10 1 1 0 2 1
6178
+description=DSUB9 male
6179
+}
6180
+N 2000 4300 2600 4300 4
6181
+N 2600 900 2600 4300 4
6182
+N 2600 1900 2000 1900 4
6183
+C 2400 500 1 0 0 EMBEDDEDgnd.sym
6184
+[
6185
+P 2600 700 2600 900 1 0 1
6186
+{
6187
+T 2658 761 5 4 0 1 0 0 1
6188
+pinnumber=1
6189
+T 2658 761 5 4 0 0 0 0 1
6190
+pinseq=1
6191
+T 2600 700 5 10 0 0 0 0 1
6192
+pintype=pas
6193
+}
6194
+L 2500 700 2700 700 3 10 0 0 -1 -1
6195
+T 2700 550 8 10 0 0 0 0 1
6196
+net=GND:1
6197
+T 2600 600 8 10 0 1 0 5 1
6198
+value=GND
6199
+]
6200
+{
6201
+T 2600 600 5 10 1 1 0 5 1
6202
+value=GND
6203
+}
6204
+N 2000 3400 2200 3400 4
6205
+N 2200 3400 2200 2800 4
6206
+N 2200 2800 2000 2800 4
6207
+N 2000 2500 2400 2500 4
6208
+N 2400 2500 2400 4000 4
6209
+N 2400 4000 2000 4000 4
6210
+N 3200 6100 3200 4500 4
6211
+N 3200 4500 3400 4500 4
6212
+N 4800 5300 5000 5300 4
6213
+N 5900 5300 6100 5300 4
6214
+N 3700 5500 3700 5700 4
6215
+N 3200 6100 3400 6100 4
6216
+N 4800 6500 5000 6500 4
6217
+N 5900 6500 6100 6500 4
6218
+N 8600 6100 10100 6100 4
6219
+C 10400 5900 1 0 0 EMBEDDEDgnd.sym
6220
+[
6221
+P 10600 6100 10600 6300 1 0 1
6222
+{
6223
+T 10658 6161 5 4 0 1 0 0 1
6224
+pinnumber=1
6225
+T 10658 6161 5 4 0 0 0 0 1
6226
+pinseq=1
6227
+T 10600 6100 5 10 0 0 0 0 1
6228
+pintype=pas
6229
+}
6230
+L 10500 6100 10700 6100 3 10 0 0 -1 -1
6231
+T 10700 5950 8 10 0 0 0 0 1
6232
+net=GND:1
6233
+T 10600 6000 8 10 0 1 0 5 1
6234
+value=GND
6235
+]
6236
+{
6237
+T 10600 6050 5 10 1 1 0 5 1
6238
+value=GND
6239
+}
6240
+N 10100 6100 10100 6500 4
6241
+C 8600 6900 1 0 0 EMBEDDEDvdd5.sym
6242
+[
6243
+P 8800 7000 8800 6900 1 0 1
6244
+{
6245
+T 8800 7100 5 6 0 1 0 0 1
6246
+pinnumber=1
6247
+T 8800 7100 5 6 0 0 0 0 1
6248
+pinseq=1
6249
+T 8800 7000 5 10 0 0 0 0 1
6250
+pintype=pas
6251
+}
6252
+V 8800 7100 50 3 5 0 0 -1 -1 0 -1 -1 -1 -1 -1
6253
+L 8800 7050 8800 7000 3 0 0 0 -1 -1
6254
+T 8900 6950 8 10 0 0 0 0 1
6255
+net=VDD5:1
6256
+T 8800 7200 8 10 0 1 0 3 1
6257
+value=VDD5
6258
+]
6259
+{
6260
+T 8800 7200 5 10 1 1 0 3 1
6261
+value=VDD5
6262
+}
6263
+N 10600 6300 10600 6500 4
6264
+N 9900 6500 10600 6500 4
6265
+C 5000 6100 1 0 0 EMBEDDEDcap.sym
6266
+[
6267
+P 5000 6500 5200 6500 1 0 0
6268
+{
6269
+T 5100 6550 5 8 0 1 0 0 1
6270
+pinnumber=1
6271
+T 5100 6550 5 8 0 0 0 0 1
6272
+pinseq=1
6273
+T 5000 6500 5 10 0 0 0 0 1
6274
+pintype=pas
6275
+}
6276
+P 5900 6500 5700 6500 1 0 0
6277
+{
6278
+T 5700 6550 5 8 0 1 0 0 1
6279
+pinnumber=2
6280
+T 5700 6550 5 8 0 0 0 0 1
6281
+pinseq=2
6282
+T 5900 6500 5 10 0 0 0 0 1
6283
+pintype=pas
6284
+}
6285
+L 5400 6700 5400 6300 3 0 0 0 -1 -1
6286
+L 5500 6700 5500 6300 3 0 0 0 -1 -1
6287
+L 5700 6500 5500 6500 3 0 0 0 -1 -1
6288
+L 5400 6500 5200 6500 3 0 0 0 -1 -1
6289
+T 5300 6700 5 10 0 0 0 0 1
6290
+device=capacitor
6291
+T 5450 6800 8 10 0 1 0 3 1
6292
+refdes=C?
6293
+T 5450 6200 8 10 0 1 0 5 1
6294
+value=?F
6295
+]
6296
+{
6297
+T 5350 6550 5 10 1 1 0 6 1
6298
+refdes=C22
6299
+T 5600 6550 5 10 1 1 0 0 1
6300
+value=100nF
6301
+}
6302
+C 3400 5700 1 0 0 EMBEDDEDcap.sym
6303
+[
6304
+P 3400 6100 3600 6100 1 0 0
6305
+{
6306
+T 3500 6150 5 8 0 1 0 0 1
6307
+pinnumber=1
6308
+T 3500 6150 5 8 0 0 0 0 1
6309
+pinseq=1
6310
+T 3400 6100 5 10 0 0 0 0 1
6311
+pintype=pas
6312
+}
6313
+P 4300 6100 4100 6100 1 0 0
6314
+{
6315
+T 4100 6150 5 8 0 1 0 0 1
6316
+pinnumber=2
6317
+T 4100 6150 5 8 0 0 0 0 1
6318
+pinseq=2
6319
+T 4300 6100 5 10 0 0 0 0 1
6320
+pintype=pas
6321
+}
6322
+L 3800 6300 3800 5900 3 0 0 0 -1 -1
6323
+L 3900 6300 3900 5900 3 0 0 0 -1 -1
6324
+L 4100 6100 3900 6100 3 0 0 0 -1 -1
6325
+L 3800 6100 3600 6100 3 0 0 0 -1 -1
6326
+T 3700 6300 5 10 0 0 0 0 1
6327
+device=capacitor
6328
+T 3850 6400 8 10 0 1 0 3 1
6329
+refdes=C?
6330
+T 3850 5800 8 10 0 1 0 5 1
6331
+value=?F
6332
+]
6333
+{
6334
+T 3750 6150 5 10 1 1 0 6 1
6335
+refdes=C23
6336
+T 4000 6150 5 10 1 1 0 0 1
6337
+value=100nF
6338
+}
6339
+C 5000 4900 1 0 0 EMBEDDEDcap.sym
6340
+[
6341
+P 5000 5300 5200 5300 1 0 0
6342
+{
6343
+T 5100 5350 5 8 0 1 0 0 1
6344
+pinnumber=1
6345
+T 5100 5350 5 8 0 0 0 0 1
6346
+pinseq=1
6347
+T 5000 5300 5 10 0 0 0 0 1
6348
+pintype=pas
6349
+}
6350
+P 5900 5300 5700 5300 1 0 0
6351
+{
6352
+T 5700 5350 5 8 0 1 0 0 1
6353
+pinnumber=2
6354
+T 5700 5350 5 8 0 0 0 0 1
6355
+pinseq=2
6356
+T 5900 5300 5 10 0 0 0 0 1
6357
+pintype=pas
6358
+}
6359
+L 5400 5500 5400 5100 3 0 0 0 -1 -1
6360
+L 5500 5500 5500 5100 3 0 0 0 -1 -1
6361
+L 5700 5300 5500 5300 3 0 0 0 -1 -1
6362
+L 5400 5300 5200 5300 3 0 0 0 -1 -1
6363
+T 5300 5500 5 10 0 0 0 0 1
6364
+device=capacitor
6365
+T 5450 5600 8 10 0 1 0 3 1
6366
+refdes=C?
6367
+T 5450 5000 8 10 0 1 0 5 1
6368
+value=?F
6369
+]
6370
+{
6371
+T 5350 5350 5 10 1 1 0 6 1
6372
+refdes=C24
6373
+T 5600 5350 5 10 1 1 0 0 1
6374
+value=100nF
6375
+}
6376
+C 3400 4100 1 0 0 EMBEDDEDcap.sym
6377
+[
6378
+P 3400 4500 3600 4500 1 0 0
6379
+{
6380
+T 3500 4550 5 8 0 1 0 0 1
6381
+pinnumber=1
6382
+T 3500 4550 5 8 0 0 0 0 1
6383
+pinseq=1
6384
+T 3400 4500 5 10 0 0 0 0 1
6385
+pintype=pas
6386
+}
6387
+P 4300 4500 4100 4500 1 0 0
6388
+{
6389
+T 4100 4550 5 8 0 1 0 0 1
6390
+pinnumber=2
6391
+T 4100 4550 5 8 0 0 0 0 1
6392
+pinseq=2
6393
+T 4300 4500 5 10 0 0 0 0 1
6394
+pintype=pas
6395
+}
6396
+L 3800 4700 3800 4300 3 0 0 0 -1 -1
6397
+L 3900 4700 3900 4300 3 0 0 0 -1 -1
6398
+L 4100 4500 3900 4500 3 0 0 0 -1 -1
6399
+L 3800 4500 3600 4500 3 0 0 0 -1 -1
6400
+T 3700 4700 5 10 0 0 0 0 1
6401
+device=capacitor
6402
+T 3850 4800 8 10 0 1 0 3 1
6403
+refdes=C?
6404
+T 3850 4200 8 10 0 1 0 5 1
6405
+value=?F
6406
+]
6407
+{
6408
+T 3750 4550 5 10 1 1 0 6 1
6409
+refdes=C25
6410
+T 4000 4550 5 10 1 1 0 0 1
6411
+value=100nF
6412
+}
6413
+N 12200 4500 12200 12000 4
6414
+N 12200 4500 8600 4500 4
6415
+N 8600 4900 12000 4900 4
6416
+N 12000 4900 12000 8400 4
6417
+N 12800 4100 12800 14200 4
6418
+N 12800 4100 8600 4100 4
6419
+N 12600 3700 12600 14000 4
6420
+N 12600 3700 8600 3700 4
6421
+N 3700 5700 3200 5700 4
6422
+N 8600 5700 10900 5700 4
6423
+N 10900 5700 10900 8100 4
6424
+N 10900 8100 2000 8100 4
6425
+N 8600 5300 11100 5300 4
6426
+N 11100 5300 11100 8700 4
6427
+N 11100 8700 2000 8700 4
6428
+N 6100 4100 5900 4100 4
6429
+N 2000 3700 6100 3700 4
6430
+N 5900 4100 5900 3100 4
6431
+N 5900 3100 2000 3100 4
6432
+C 800 5600 1 0 0 EMBEDDEDDB9s.sym
6433
+[
6434
+L 800 6900 800 9300 3 0 0 0 -1 -1
6435
+T 1800 8500 5 10 0 0 0 0 1
6436
+device=DB9s
6437
+V 1400 6900 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6438
+P 1450 6900 2000 6900 1 0 1
6439
+{
6440
+T 1800 6950 5 8 1 1 0 0 1
6441
+pinnumber=5
6442
+T 1800 6950 5 8 0 0 0 0 1
6443
+pinseq=5
6444
+T 1450 6900 5 10 0 0 0 0 1
6445
+pintype=pas
6446
+}
6447
+A 1550 6750 150 250 110 3 0 0 0 -1 -1
6448
+A 875 6900 75 180 60 3 0 0 0 -1 -1
6449
+A 1550 9490 150 0 110 3 0 0 0 -1 -1
6450
+A 875 9300 75 120 60 3 0 0 0 -1 -1
6451
+L 1700 6737 1700 9505 3 0 0 0 -1 -1
6452
+V 1100 7200 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6453
+P 1150 7200 2000 7200 1 0 1
6454
+{
6455
+T 1800 7250 5 8 1 1 0 0 1
6456
+pinnumber=9
6457
+T 1800 7250 5 8 0 0 0 0 1
6458
+pinseq=9
6459
+T 1150 7200 5 10 0 0 0 0 1
6460
+pinseq=pas
6461
+}
6462
+V 1400 7500 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6463
+P 1450 7500 2000 7500 1 0 1
6464
+{
6465
+T 1800 7550 5 8 1 1 0 0 1
6466
+pinnumber=4
6467
+T 1800 7550 5 8 0 0 0 0 1
6468
+pinseq=4
6469
+T 1450 7500 5 10 0 0 0 0 1
6470
+pinseq=pas
6471
+}
6472
+V 1100 7800 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6473
+P 1150 7800 2000 7800 1 0 1
6474
+{
6475
+T 1800 7850 5 8 1 1 0 0 1
6476
+pinnumber=8
6477
+T 1800 7850 5 8 0 0 0 0 1
6478
+pinseq=8
6479
+T 1150 7800 5 10 0 0 0 0 1
6480
+pinseq=pas
6481
+}
6482
+V 1400 8100 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6483
+P 1450 8100 2000 8100 1 0 1
6484
+{
6485
+T 1800 8150 5 8 1 1 0 0 1
6486
+pinnumber=3
6487
+T 1800 8150 5 8 0 0 0 0 1
6488
+pinseq=3
6489
+T 1450 8100 5 10 0 0 0 0 1
6490
+pintype=pas
6491
+}
6492
+V 1100 8400 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6493
+P 1150 8400 2000 8400 1 0 1
6494
+{
6495
+T 1800 8450 5 8 1 1 0 0 1
6496
+pinnumber=7
6497
+T 1800 8450 5 8 0 0 0 0 1
6498
+pinseq=7
6499
+T 1150 8400 5 10 0 0 0 0 1
6500
+pintype=pas
6501
+}
6502
+V 1400 8700 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6503
+P 1450 8700 2000 8700 1 0 1
6504
+{
6505
+T 1800 8750 5 8 1 1 0 0 1
6506
+pinnumber=2
6507
+T 1800 8750 5 8 0 0 0 0 1
6508
+pinseq=2
6509
+T 1450 8700 5 10 0 0 0 0 1
6510
+pintype=pas
6511
+}
6512
+V 1100 9000 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6513
+P 1150 9000 2000 9000 1 0 1
6514
+{
6515
+T 1800 9050 5 8 1 1 0 0 1
6516
+pinnumber=6
6517
+T 1800 9050 5 8 0 0 0 0 1
6518
+pinseq=6
6519
+T 1150 9000 5 10 0 0 0 0 1
6520
+pintype=pas
6521
+}
6522
+V 1400 9300 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6523
+P 1450 9300 2000 9300 1 0 1
6524
+{
6525
+T 1800 9350 5 8 1 1 0 0 1
6526
+pinnumber=1
6527
+T 1800 9350 5 8 0 0 0 0 1
6528
+pinseq=1
6529
+T 1450 9300 5 10 0 0 0 0 1
6530
+pintype=pas
6531
+}
6532
+L 838 6834 1502 6608 3 0 0 0 -1 -1
6533
+L 1500 9631 837 9365 3 0 0 0 -1 -1
6534
+T 1000 9800 8 10 0 1 0 0 1
6535
+refdes=CON?
6536
+T 1000 6000 8 10 0 1 0 2 1
6537
+value=DB9
6538
+P 1450 6400 2000 6400 1 0 1
6539
+{
6540
+T 1800 6450 5 8 1 1 0 0 1
6541
+pinnumber=100
6542
+T 1800 6450 5 8 0 0 0 0 1
6543
+pinseq=100
6544
+T 1450 6400 5 10 0 0 0 0 1
6545
+pintype=pas
6546
+}
6547
+P 1450 6100 2000 6100 1 0 1
6548
+{
6549
+T 1800 6150 5 8 1 1 0 0 1
6550
+pinnumber=101
6551
+T 1800 6150 5 8 0 0 0 0 1
6552
+pinseq=101
6553
+T 1450 6100 5 10 0 0 0 0 1
6554
+pintype=pas
6555
+}
6556
+L 1450 6100 1400 6100 3 0 0 0 -1 -1
6557
+L 1400 6100 1400 6400 3 0 0 0 -1 -1
6558
+L 1450 6400 1400 6400 3 0 0 0 -1 -1
6559
+L 1400 6400 1400 6650 3 0 0 0 -1 -1
6560
+]
6561
+{
6562
+T 1000 9850 5 10 1 1 0 0 1
6563
+refdes=CON4
6564
+T 1000 5900 5 10 1 1 0 2 1
6565
+value=SERIAL A
6566
+T 1000 5600 5 10 1 1 0 2 1
6567
+description=DSUB9 male
6568
+}
6569
+N 2000 9300 2600 9300 4
6570
+N 2600 5900 2600 9300 4
6571
+N 2600 6900 2000 6900 4
6572
+C 2400 5500 1 0 0 EMBEDDEDgnd.sym
6573
+[
6574
+P 2600 5700 2600 5900 1 0 1
6575
+{
6576
+T 2658 5761 5 4 0 1 0 0 1
6577
+pinnumber=1
6578
+T 2658 5761 5 4 0 0 0 0 1
6579
+pinseq=1
6580
+T 2600 5700 5 10 0 0 0 0 1
6581
+pintype=pas
6582
+}
6583
+L 2500 5700 2700 5700 3 10 0 0 -1 -1
6584
+T 2700 5550 8 10 0 0 0 0 1
6585
+net=GND:1
6586
+T 2600 5600 8 10 0 1 0 5 1
6587
+value=GND
6588
+]
6589
+{
6590
+T 2600 5600 5 10 1 1 0 5 1
6591
+value=GND
6592
+}
6593
+N 2000 8400 2200 8400 4
6594
+N 2200 8400 2200 7800 4
6595
+N 2200 7800 2000 7800 4
6596
+N 2000 7500 2400 7500 4
6597
+N 2400 7500 2400 9000 4
6598
+N 2400 9000 2000 9000 4
6599
+N 22300 29200 21800 29200 4
6600
+N 21800 29000 21800 29200 4
6601
+N 2000 1400 2600 1400 4
6602
+N 2600 1100 2000 1100 4
6603
+N 2000 6100 2600 6100 4
6604
+N 2600 6400 2000 6400 4
6605
+C 6400 17100 1 90 0 EMBEDDEDcap.sym
6606
+[
6607
+P 6000 17100 6000 17300 1 0 0
6608
+{
6609
+T 5950 17200 5 8 0 1 90 0 1
6610
+pinnumber=1
6611
+T 5950 17200 5 8 0 0 90 0 1
6612
+pinseq=1
6613
+T 6000 17100 5 10 0 0 90 0 1
6614
+pintype=pas
6615
+}
6616
+P 6000 18000 6000 17800 1 0 0
6617
+{
6618
+T 5950 17800 5 8 0 1 90 0 1
6619
+pinnumber=2
6620
+T 5950 17800 5 8 0 0 90 0 1
6621
+pinseq=2
6622
+T 6000 18000 5 10 0 0 90 0 1
6623
+pintype=pas
6624
+}
6625
+L 5800 17500 6200 17500 3 0 0 0 -1 -1
6626
+L 5800 17600 6200 17600 3 0 0 0 -1 -1
6627
+L 6000 17800 6000 17600 3 0 0 0 -1 -1
6628
+L 6000 17500 6000 17300 3 0 0 0 -1 -1
6629
+T 5800 17400 5 10 0 0 90 0 1
6630
+device=capacitor
6631
+T 5700 17550 8 10 0 1 90 3 1
6632
+refdes=C?
6633
+T 6300 17550 8 10 0 1 90 5 1
6634
+value=?F
6635
+]
6636
+{
6637
+T 5950 17700 5 10 1 1 0 6 1
6638
+refdes=C7
6639
+T 6050 17400 5 10 1 1 0 2 1
6640
+value=100nF
6641
+}
6642
+N 6000 17100 6000 16800 4
6643
+N 6000 18000 6000 18400 4
6644
+N 6000 18400 7300 18400 4
6645
+C 9000 6100 1 0 0 EMBEDDEDcap.sym
6646
+[
6647
+P 9000 6500 9200 6500 1 0 0
6648
+{
6649
+T 9100 6550 5 8 0 1 0 0 1
6650
+pinnumber=1
6651
+T 9100 6550 5 8 0 0 0 0 1
6652
+pinseq=1
6653
+T 9000 6500 5 10 0 0 0 0 1
6654
+pintype=pas
6655
+}
6656
+P 9900 6500 9700 6500 1 0 0
6657
+{
6658
+T 9700 6550 5 8 0 1 0 0 1
6659
+pinnumber=2
6660
+T 9700 6550 5 8 0 0 0 0 1
6661
+pinseq=2
6662
+T 9900 6500 5 10 0 0 0 0 1
6663
+pintype=pas
6664
+}
6665
+L 9400 6700 9400 6300 3 0 0 0 -1 -1
6666
+L 9500 6700 9500 6300 3 0 0 0 -1 -1
6667
+L 9700 6500 9500 6500 3 0 0 0 -1 -1
6668
+L 9400 6500 9200 6500 3 0 0 0 -1 -1
6669
+T 9300 6700 5 10 0 0 0 0 1
6670
+device=capacitor
6671
+T 9450 6800 8 10 0 1 0 3 1
6672
+refdes=C?
6673
+T 9450 6200 8 10 0 1 0 5 1
6674
+value=?F
6675
+]
6676
+{
6677
+T 9350 6550 5 10 1 1 0 6 1
6678
+refdes=C21
6679
+T 9600 6550 5 10 1 1 0 0 1
6680
+value=100nF
6681
+}
6682
+C 30600 19200 1 0 0 EMBEDDEDLF1S022.sym
6683
+[
6684
+T 33400 22600 8 10 0 1 0 6 1
6685
+refdes=CON?
6686
+T 31000 25250 5 10 0 0 0 0 1
6687
+device=LF1S022
6688
+P 30700 22200 31000 22200 1 0 0
6689
+{
6690
+T 30900 22250 5 8 1 1 0 6 1
6691
+pinnumber=4
6692
+T 30900 22150 5 8 0 1 0 8 1
6693
+pinseq=4
6694
+T 31050 22200 5 8 0 1 0 2 1
6695
+pintype=pas
6696
+}
6697
+B 31000 19400 2400 3100 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6698
+T 31000 26250 5 10 0 0 0 0 1
6699
+numslots=0
6700
+P 30700 21800 31000 21800 1 0 0
6701
+{
6702
+T 30900 21850 5 8 1 1 0 6 1
6703
+pinnumber=3
6704
+T 30900 21750 5 8 0 1 0 8 1
6705
+pinseq=3
6706
+T 31050 21800 5 8 0 1 0 2 1
6707
+pintype=pas
6708
+}
6709
+P 33700 21800 33400 21800 1 0 0
6710
+{
6711
+T 33500 21850 5 8 1 1 0 0 1
6712
+pinnumber=1
6713
+T 33500 21750 5 8 0 1 0 2 1
6714
+pinseq=1
6715
+T 33350 21800 5 8 0 1 0 8 1
6716
+pintype=pas
6717
+}
6718
+P 30700 21400 31000 21400 1 0 0
6719
+{
6720
+T 30900 21450 5 8 1 1 0 6 1
6721
+pinnumber=5
6722
+T 30900 21350 5 8 0 1 0 8 1
6723
+pinseq=5
6724
+T 31050 21400 5 8 0 1 0 2 1
6725
+pintype=pas
6726
+}
6727
+P 30700 21000 31000 21000 1 0 0
6728
+{
6729
+T 30900 21050 5 8 1 1 0 6 1
6730
+pinnumber=6
6731
+T 30900 20950 5 8 0 1 0 8 1
6732
+pinseq=6
6733
+T 31050 21000 5 8 0 1 0 2 1
6734
+pintype=pas
6735
+}
6736
+P 33700 19600 33400 19600 1 0 0
6737
+{
6738
+T 33500 19650 5 8 1 1 0 0 1
6739
+pinnumber=10
6740
+T 33500 19550 5 8 0 1 0 2 1
6741
+pinseq=10
6742
+T 33350 19600 5 8 0 1 0 8 1
6743
+pintype=pas
6744
+}
6745
+P 30700 20600 31000 20600 1 0 0
6746
+{
6747
+T 30900 20650 5 8 1 1 0 6 1
6748
+pinnumber=8
6749
+T 30900 20550 5 8 0 1 0 8 1
6750
+pinseq=8
6751
+T 31050 20600 5 8 0 1 0 2 1
6752
+pintype=pas
6753
+}
6754
+P 33700 20600 33400 20600 1 0 0
6755
+{
6756
+T 33500 20650 5 8 1 1 0 0 1
6757
+pinnumber=2
6758
+T 33500 20550 5 8 0 1 0 2 1
6759
+pinseq=2
6760
+T 33350 20600 5 8 0 1 0 8 1
6761
+pintype=pas
6762
+}
6763
+P 30700 20200 31000 20200 1 0 0
6764
+{
6765
+T 30900 20250 5 8 1 1 0 6 1
6766
+pinnumber=7
6767
+T 30900 20150 5 8 0 1 0 8 1
6768
+pinseq=7
6769
+T 31050 20200 5 8 0 1 0 2 1
6770
+pintype=pas
6771
+}
6772
+P 33700 19800 33400 19800 1 0 0
6773
+{
6774
+T 33500 19850 5 8 1 1 0 0 1
6775
+pinnumber=9
6776
+T 33500 19750 5 8 0 1 0 2 1
6777
+pinseq=9
6778
+T 33350 19800 5 8 0 1 0 8 1
6779
+pintype=pas
6780
+}
6781
+T 31000 22600 8 10 0 1 0 0 1
6782
+value=LF1S022
6783
+B 31200 20100 600 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6784
+T 31500 20600 9 10 1 0 90 4 1
6785
+LPF
6786
+L 31200 20200 31000 20200 3 0 0 0 -1 -1
6787
+L 31000 20600 31200 20600 3 0 0 0 -1 -1
6788
+L 31200 21000 31000 21000 3 0 0 0 -1 -1
6789
+L 31800 21000 32100 21000 3 0 0 0 -1 -1
6790
+L 31800 20600 32100 20600 3 0 0 0 -1 -1
6791
+L 31800 20200 32100 20200 3 0 0 0 -1 -1
6792
+A 32100 20900 100 270 180 3 0 0 0 -1 -1
6793
+A 32100 20700 100 270 180 3 0 0 0 -1 -1
6794
+A 32100 20500 100 270 180 3 0 0 0 -1 -1
6795
+A 32100 20300 100 270 180 3 0 0 0 -1 -1
6796
+L 32600 21000 32500 21000 3 0 0 0 -1 -1
6797
+L 33400 20600 32500 20600 3 0 0 0 -1 -1
6798
+L 32700 20200 32500 20200 3 0 0 0 -1 -1
6799
+A 32500 20900 100 90 180 3 0 0 0 -1 -1
6800
+A 32500 20700 100 90 180 3 0 0 0 -1 -1
6801
+A 32500 20500 100 90 180 3 0 0 0 -1 -1
6802
+A 32500 20300 100 90 180 3 0 0 0 -1 -1
6803
+B 31200 21300 600 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6804
+L 31200 21400 31000 21400 3 0 0 0 -1 -1
6805
+L 31000 21800 31200 21800 3 0 0 0 -1 -1
6806
+L 31200 22200 31000 22200 3 0 0 0 -1 -1
6807
+L 31800 22200 32100 22200 3 0 0 0 -1 -1
6808
+L 31800 21800 32100 21800 3 0 0 0 -1 -1
6809
+L 31800 21400 32100 21400 3 0 0 0 -1 -1
6810
+A 32100 22100 100 270 180 3 0 0 0 -1 -1
6811
+A 32100 21900 100 270 180 3 0 0 0 -1 -1
6812
+A 32100 21700 100 270 180 3 0 0 0 -1 -1
6813
+A 32100 21500 100 270 180 3 0 0 0 -1 -1
6814
+L 32700 22200 32500 22200 3 0 0 0 -1 -1
6815
+L 33400 21800 32500 21800 3 0 0 0 -1 -1
6816
+L 32800 21400 32500 21400 3 0 0 0 -1 -1
6817
+A 32500 22100 100 90 180 3 0 0 0 -1 -1
6818
+A 32500 21900 100 90 180 3 0 0 0 -1 -1
6819
+A 32500 21700 100 90 180 3 0 0 0 -1 -1
6820
+A 32500 21500 100 90 180 3 0 0 0 -1 -1
6821
+T 31500 21800 9 10 1 0 90 4 1
6822
+LPF
6823
+B 32275 20100 50 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6824
+B 32275 21300 50 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
6825
+L 33400 19800 33200 19800 3 0 0 0 -1 -1
6826
+L 33200 19800 33200 19500 3 0 0 0 -1 -1
6827
+L 33300 19500 33100 19500 3 0 0 0 -1 -1
6828
+L 33200 19600 33400 19600 3 0 0 0 -1 -1
6829
+L 32800 21600 32800 20800 3 0 0 0 -1 -1
6830
+L 32800 20800 33100 20800 3 0 0 0 -1 -1
6831
+L 33100 20800 33100 21000 3 0 0 0 -1 -1
6832
+L 33100 21000 33200 21000 3 0 0 0 -1 -1
6833
+L 33200 21000 33200 21100 3 0 0 0 -1 -1
6834
+L 33300 21100 33200 21100 3 0 0 0 -1 -1
6835
+L 33200 19500 33200 19800 3 0 0 0 -1 -1
6836
+L 32800 21600 33100 21600 3 0 0 0 -1 -1
6837
+L 33100 21600 33100 21400 3 0 0 0 -1 -1
6838
+L 33100 21400 33200 21400 3 0 0 0 -1 -1
6839
+L 33200 21400 33200 21300 3 0 0 0 -1 -1
6840
+L 33200 21300 33300 21300 3 0 0 0 -1 -1
6841
+L 33300 21100 33300 21300 3 0 0 0 -1 -1
6842
+T 32900 21500 9 10 1 0 90 4 1
6843
+1
6844
+T 32900 20900 9 10 1 0 90 4 1
6845
+8
6846
+L 32700 22200 32700 21500 3 0 0 0 -1 -1
6847
+L 32700 21500 32800 21500 3 0 0 0 -1 -1
6848
+L 32600 21000 32600 21300 3 0 0 0 -1 -1
6849
+L 32600 21300 32800 21300 3 0 0 0 -1 -1
6850
+L 32700 20200 32700 21000 3 0 0 0 -1 -1
6851
+L 32700 21000 32800 21000 3 0 0 0 -1 -1
6852
+]
6853
+{
6854
+T 33400 22600 5 10 1 1 0 6 1
6855
+refdes=CON3
6856
+T 31000 25250 5 10 0 0 0 0 1
6857
+device=LF1S022
6858
+T 31000 22600 5 10 1 1 0 0 1
6859
+value=LF1S022
6860
+}
6861
+N 30300 15900 30300 20600 4
6862
+N 30300 20600 30700 20600 4
6863
+N 29700 15900 29700 21800 4
6864
+N 29700 21800 30700 21800 4
6865
+N 30700 22200 29500 22200 4
6866
+N 29500 22200 29500 18400 4
6867
+N 29900 17600 29900 21400 4
6868
+N 29900 21400 30700 21400 4
6869
+N 30700 21000 30100 21000 4
6870
+N 30100 21000 30100 17200 4
6871
+N 30500 16400 30500 20200 4
6872
+N 30500 20200 30700 20200 4
6873
+N 33000 16800 33900 16800 4
6874
+N 33900 16800 33900 20600 4
6875
+N 33900 20600 33700 20600 4
6876
+N 33000 18000 34100 18000 4
6877
+N 34100 21800 33700 21800 4
6878
+N 34800 14700 34800 16100 4
6879
+N 34800 16100 34300 16100 4
6880
+N 34300 16100 34300 19800 4
6881
+N 34300 19800 33700 19800 4
6882
+N 33700 19600 34300 19600 4
... ...
@@ -0,0 +1,2 @@
1
+#! /bin/bash
2
+gnetlist -q -g PCB -o flaneth.net flaneth.sch
... ...
@@ -0,0 +1,10 @@
1
+*.d
2
+*.lst
3
+*.o
4
+http_content.inc
5
+main.eep
6
+main.elf
7
+main.hex
8
+main.lss
9
+main.map
10
+main.sym
... ...
@@ -0,0 +1,10 @@
1
+flaneth - flash and ethernet - dartboard mod
2
+Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
3
+Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
4
+a BlinkenArea project - http://www.blinkenarea.org/
5
+
6
+0.1 2008-11-09
7
+--------------
8
+first version
9
+based on flaneth 0.2
10
+
... ...
@@ -0,0 +1,447 @@
1
+# flaneth - flash and ethernet - dartboard mod
2
+# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
3
+# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
4
+# a BlinkenArea project - http://www.blinkenarea.org/
5
+
6
+include Makefile.conf
7
+
8
+# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al.
9
+# Released to the Public Domain
10
+# Please read the make user manual!
11
+#
12
+# Additional material for this makefile was submitted by:
13
+#  Tim Henigan
14
+#  Peter Fleury
15
+#  Reiner Patommel
16
+#  Sander Pool
17
+#  Frederik Rouleau
18
+#  Markus Pfaff
19
+#  Stefan Schuermans
20
+#
21
+# On command line:
22
+#
23
+# make all = Make software.
24
+#
25
+# make clean = Clean out built project files.
26
+#
27
+# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
28
+#
29
+# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
30
+#                4.07 or greater).
31
+#
32
+# make program_fuses = Set the fuse bits of the device, using avrdude.  Please
33
+#                      customize the avrdude settings below first!
34
+#
35
+# make program = Download the hex file to the device, using avrdude.  Please
36
+#                customize the avrdude settings below first!
37
+#
38
+# make filename.s = Just compile filename.c into the assembler code only
39
+#
40
+# To rebuild project do "make clean" then "make all".
41
+#
42
+
43
+
44
+# MCU name
45
+MCU = atmega128
46
+
47
+# Output format. (can be srec, ihex, binary)
48
+FORMAT = ihex
49
+
50
+# Target file name (without extension).
51
+TARGET = main
52
+
53
+# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
54
+# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
55
+OPT = s
56
+
57
+
58
+# List C source files here. (C dependencies are automatically generated.)
59
+SRC = $(TARGET).c
60
+
61
+# If there is more than one source file, append them above, or modify and
62
+# uncomment the following:
63
+SRC += arp.c bus.c cf.c checksum.c config.c dhcp.c dart.c \
64
+       eeprom.c ethernet.c http.c icmp.c ip.c random.c \
65
+       rtl8019.c status.c tcp.c timing.c uart.c udp.c \
66
+       xtea.c
67
+
68
+# You can also wrap lines by appending a backslash to the end of the line:
69
+#SRC += baz.c \
70
+#xyzzy.c
71
+
72
+
73
+
74
+# List Assembler source files here.
75
+# Make them always end in a capital .S.  Files ending in a lowercase .s
76
+# will not be considered source files but generated files (assembler
77
+# output from the compiler), and will be deleted upon "make clean"!
78
+# Even though the DOS/Win* filesystem matches both .s and .S the same,
79
+# it will preserve the spelling of the filenames, and gcc itself does
80
+# care about how the name is spelled on its command-line.
81
+ASRC =
82
+
83
+
84
+# List any extra directories to look for include files here.
85
+#     Each directory must be seperated by a space.
86
+EXTRAINCDIRS = 
87
+
88
+
89
+# Optional compiler flags.
90
+#  -g:        generate debugging information (for GDB, or for COFF conversion)
91
+#  -O*:       optimization level
92
+#  -f...:     tuning, see gcc manual and avr-libc documentation
93
+#  -Wall...:  warning level
94
+#  -Wa,...:   tell GCC to pass this to the assembler.
95
+#    -ahlms:  create assembler listing
96
+CFLAGS = -g -O$(OPT) \
97
+-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
98
+-Wall -Wstrict-prototypes \
99
+-Wa,-adhlns=$(<:.c=.lst) \
100
+$(patsubst %,-I%,$(EXTRAINCDIRS)) \
101
+$(DBG_FLAGS)
102
+
103
+
104
+# Set a "language standard" compiler flag.
105
+#   Unremark just one line below to set the language standard to use.
106
+#   gnu99 = C99 + GNU extensions. See GCC manual for more information.
107
+#CFLAGS += -std=c89
108
+#CFLAGS += -std=gnu89
109
+#CFLAGS += -std=c99
110
+CFLAGS += -std=gnu99
111
+
112
+# do not use C99 strict aliasing rules
113
+#   this kills some warnings occuring when casting pointer types
114
+CFLAGS += -fno-strict-aliasing
115
+
116
+
117
+
118
+# Optional assembler flags.
119
+#  -Wa,...:   tell GCC to pass this to the assembler.
120
+#  -ahlms:    create listing
121
+#  -gstabs:   have the assembler create line number information; note that
122
+#             for use in COFF files, additional information about filenames
123
+#             and function names needs to be present in the assembler source
124
+#             files -- see avr-libc docs [FIXME: not yet described there]
125
+ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
126
+
127
+
128
+
129
+# Optional linker flags.
130
+#  -Wl,...:   tell GCC to pass this to linker.
131
+#  -Map:      create map file
132
+#  --cref:    add cross reference to  map file
133
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
134
+
135
+
136
+
137
+# Additional libraries
138
+
139
+# Minimalistic printf version
140
+#LDFLAGS += -Wl,-u,vfprintf -lprintf_min
141
+
142
+# Floating point printf version (requires -lm below)
143
+#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
144
+
145
+# -lm = math library
146
+LDFLAGS += -lm
147
+
148
+
149
+
150
+# rebuilding is required if one of the following files is changed
151
+REBUILD_DEPS = Makefile.conf
152
+
153
+
154
+
155
+# Programming support using avrdude. Settings and variables.
156
+
157
+# Programming hardware: alf avr910 avrisp bascom bsd 
158
+# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
159
+#
160
+# Type: avrdude -c ?
161
+# to get a full listing.
162
+#
163
+AVRDUDE_PROGRAMMER = stk200
164
+
165
+
166
+#AVRDUDE_PORT = com1	# programmer connected to serial device
167
+#AVRDUDE_PORT = lpt1	# programmer connected to parallel port
168
+AVRDUDE_PORT = /dev/parport0
169
+
170
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
171
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
172
+
173
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
174
+
175
+# Uncomment the following if you want avrdude's erase cycle counter.
176
+# Note that this counter needs to be initialized first using -Yn,
177
+# see avrdude manual.
178
+#AVRDUDE_ERASE += -y
179
+
180
+# Uncomment the following if you do /not/ wish a verification to be
181
+# performed after programming the device.
182
+#AVRDUDE_FLAGS += -V
183
+
184
+# Increase verbosity level.  Please use this when submitting bug
185
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
186
+# to submit bug reports.
187
+#AVRDUDE_FLAGS += -v -v
188
+
189
+AVRDUDE_WRITE_FUSES = -u -U lfuse:w:0xAF:m -U hfuse:w:0xC9:m -U efuse:w:0xFF:m
190
+
191
+
192
+
193
+# ---------------------------------------------------------------------------
194
+
195
+# Define directories, if needed.
196
+DIRAVR = 
197
+DIRAVRBIN = 
198
+DIRAVRUTILS = 
199
+DIRINC = 
200
+DIRLIB = 
201
+
202
+
203
+# Define programs and commands.
204
+SHELL = sh
205
+
206
+CC = avr-gcc
207
+
208
+OBJCOPY = avr-objcopy
209
+OBJDUMP = avr-objdump
210
+SIZE = avr-size
211
+
212
+
213
+# Programming support using avrdude.
214
+AVRDUDE = avrdude
215
+
216
+
217
+REMOVE = rm -f
218
+COPY = cp
219
+
220
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
221
+ELFSIZE = $(SIZE) -A $(TARGET).elf
222
+
223
+
224
+
225
+# Define Messages
226
+# English
227
+MSG_ERRORS_NONE = Errors: none
228
+MSG_BEGIN = -------- begin --------
229
+MSG_END = --------  end  --------
230
+MSG_SIZE_BEFORE = Size before: 
231
+MSG_SIZE_AFTER = Size after:
232
+MSG_COFF = Converting to AVR COFF:
233
+MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
234
+MSG_FLASH = Creating load file for Flash:
235
+MSG_EEPROM = Creating load file for EEPROM:
236
+MSG_EXTENDED_LISTING = Creating Extended Listing:
237
+MSG_SYMBOL_TABLE = Creating Symbol Table:
238
+MSG_LINKING = Linking:
239
+MSG_COMPILING = Compiling:
240
+MSG_ASSEMBLING = Assembling:
241
+MSG_CLEANING = Cleaning project:
242
+
243
+
244
+
245
+
246
+# Define all object files.
247
+OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) 
248
+
249
+# Define all listing files.
250
+LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
251
+
252
+# Combine all necessary flags and optional flags.
253
+# Add target processor to flags.
254
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
255
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
256
+
257
+
258
+
259
+# Default target.
260
+all: my_all begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
261
+	$(TARGET).lss $(TARGET).sym sizeafter finished end
262
+
263
+# Debug target.
264
+debug: DBG_FLAGS=-DDEBUG
265
+debug: all
266
+
267
+
268
+# Eye candy.
269
+# AVR Studio 3.x does not check make's exit code but relies on
270
+# the following magic strings to be generated by the compile job.
271
+begin:
272
+	@echo
273
+	@echo $(MSG_BEGIN)
274
+
275
+finished:
276
+	@echo $(MSG_ERRORS_NONE)
277
+
278
+end:
279
+	@echo $(MSG_END)
280
+	@echo
281
+
282
+
283
+# Display size of file.
284
+sizebefore:
285
+	@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
286
+
287
+sizeafter:
288
+	@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
289
+
290
+
291
+
292
+# Display compiler version information.
293
+gccversion : 
294
+	@$(CC) --version
295
+
296
+
297
+
298
+
299
+# Convert ELF to COFF for use in debugging / simulating in
300
+# AVR Studio or VMLAB.
301
+COFFCONVERT=$(OBJCOPY) --debugging \
302
+	--change-section-address .data-0x800000 \
303
+	--change-section-address .bss-0x800000 \
304
+	--change-section-address .noinit-0x800000 \
305
+	--change-section-address .eeprom-0x810000 
306
+
307
+
308
+coff: $(TARGET).elf
309
+	@echo
310
+	@echo $(MSG_COFF) $(TARGET).cof
311
+	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
312
+
313
+
314
+extcoff: $(TARGET).elf
315
+	@echo
316
+	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
317
+	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
318
+
319
+
320
+
321
+# Program the device fuses.  
322
+program_fuses:
323
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES)
324
+
325
+# Program the device.  
326
+program: $(TARGET).hex $(TARGET).eep
327
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
328
+
329
+
330
+
331
+
332
+# Create final output files (.hex, .eep) from ELF output file.
333
+%.hex: %.elf
334
+	@echo
335
+	@echo $(MSG_FLASH) $@
336
+	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
337
+
338
+%.eep: %.elf
339
+	@echo
340
+	@echo $(MSG_EEPROM) $@
341
+	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
342
+	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
343
+
344
+# Create extended listing file from ELF output file.
345
+%.lss: %.elf
346
+	@echo
347
+	@echo $(MSG_EXTENDED_LISTING) $@
348
+	$(OBJDUMP) -h -S $< > $@
349
+
350
+# Create a symbol table from ELF output file.
351
+%.sym: %.elf
352
+	@echo
353
+	@echo $(MSG_SYMBOL_TABLE) $@
354
+	avr-nm -n $< > $@
355
+
356
+
357
+
358
+# Link: create ELF output file from object files.
359
+.SECONDARY : $(TARGET).elf
360
+.PRECIOUS : $(OBJ)
361
+%.elf: $(OBJ)
362
+	@echo
363
+	@echo $(MSG_LINKING) $@
364
+	$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
365
+
366
+
367
+# Compile: create object files from C source files.
368
+%.o : %.c $(REBUILD_DEPS)
369
+	@echo
370
+	@echo $(MSG_COMPILING) $<
371
+	$(CC) -c $(ALL_CFLAGS) $< -o $@
372
+
373
+
374
+# Compile: create assembler files from C source files.
375
+%.s : %.c $(REBUILD_DEPS)
376
+	$(CC) -S $(ALL_CFLAGS) $< -o $@
377
+
378
+
379
+# Assemble: create object files from assembler source files.
380
+%.o : %.S $(REBUILD_DEPS)
381
+	@echo
382
+	@echo $(MSG_ASSEMBLING) $<
383
+	$(CC) -c $(ALL_ASFLAGS) $< -o $@
384
+
385
+
386
+
387
+
388
+
389
+
390
+# Target: clean project.
391
+clean: my_clean begin clean_list finished end
392
+
393
+clean_list :
394
+	@echo
395
+	@echo $(MSG_CLEANING)
396
+	$(REMOVE) $(TARGET).hex
397
+	$(REMOVE) $(TARGET).eep
398
+	$(REMOVE) $(TARGET).obj
399
+	$(REMOVE) $(TARGET).cof
400
+	$(REMOVE) $(TARGET).elf
401
+	$(REMOVE) $(TARGET).map
402
+	$(REMOVE) $(TARGET).obj
403
+	$(REMOVE) $(TARGET).a90
404
+	$(REMOVE) $(TARGET).sym
405
+	$(REMOVE) $(TARGET).lnk
406
+	$(REMOVE) $(TARGET).lss
407
+	$(REMOVE) $(OBJ)
408
+	$(REMOVE) $(LST)
409
+	$(REMOVE) $(SRC:.c=.s)
410
+	$(REMOVE) $(SRC:.c=.d)
411
+
412
+
413
+# Automatically generate C source code dependencies. 
414
+# (Code originally taken from the GNU make user manual and modified 
415
+# (See README.txt Credits).)
416
+#
417
+# Note that this will work with sh (bash) and sed that is shipped with WinAVR
418
+# (see the SHELL variable defined above).
419
+# This may not work with other shells or other seds.
420
+#
421
+%.d: %.c $(REBUILD_DEPS)
422
+	set -e; $(CC) -MM $(ALL_CFLAGS) $< \
423
+	| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
424
+	[ -s $@ ] || rm -f $@
425
+
426
+http.d: http.c http_content.inc
427
+
428
+
429
+# Remove the '-' if you want to see the dependency files generated.
430
+include $(SRC:.c=.d)
431
+
432
+
433
+
434
+my_all: http_content.inc
435
+
436
+http_content.inc: http_content.pl http_$(HTTP_SKIN)/* $(REBUILD_DEPS)
437
+	./http_content.pl http_$(HTTP_SKIN) http_content.inc || rm -f http_content.inc http_content.inc
438
+
439
+my_clean:
440
+	rm -f http_content.inc
441
+
442
+
443
+
444
+# Listing of phony targets.
445
+.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
446
+	clean clean_list program_fuses program my_all my_clean
447
+
... ...
@@ -0,0 +1,8 @@
1
+# flaneth - flash and ethernet
2
+# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
3
+# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
4
+# a BlinkenArea project - http://www.blinkenarea.org/
5
+
6
+# skin to use on http interface
7
+# HTTP_SKIN=[simple]
8
+HTTP_SKIN = simple
... ...
@@ -0,0 +1,240 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include "arp.h"
9
+#include "config.h"
10
+#include "debug.h"
11
+#include "ethernet.h"
12
+#include "ip.h"
13
+#include "macros.h"
14
+#include "nethelp.h"
15
+
16
+// timing parameters
17
+#define ArpTicksMax 150 // maximum age of ARP table entries (in 200ms steps)
18
+#define ArpNoMacTicksMax 50 // maximum age of ARP table entries without MAC (in 200ms steps)
19
+#define ArpRetryTicks 8 // time after which to retry ARP query (must be power of 2, in 200ms steps)
20
+
21
+// ARP table
22
+#define ArpTabFlagInUse 0x01
23
+#define ArpTabFlagMacOk 0x02
24
+struct ArpTable
25
+{
26
+  unsigned char Flags; // flags - see constants
27
+  unsigned char Ticks; // age of entry in 200ms steps
28
+  unsigned char Mac[6];
29
+  unsigned char Ip[4];
30
+} ArpTab[12];
31
+
32
+// initialize
33
+void ArpInit( void ) // (extern)
34
+{
35
+  unsigned char i;
36
+
37
+  // empty ARP tabale
38
+  for( i = 0; i < count( ArpTab ); i++ )
39
+    ArpTab[i].Flags = 0;
40
+}
41
+
42
+// send an ARP request
43
+static void ArpSendRequest( unsigned char * pIp )
44
+{
45
+  struct ArpPacket ArpRequest;
46
+
47
+  debug_arp_printf( "send req ip=%u.%u.%u.%u",
48
+                    pIp[0], pIp[1], pIp[2], pIp[3] );
49
+
50
+  // build ARP request
51
+  ArpRequest.ArpHdr.HwType = htons( 0x0001 ); // ethernet
52
+  ArpRequest.ArpHdr.ProtoType = htons( 0x0800 ); // IP
53
+  ArpRequest.ArpHdr.HwLen = 0x06; // length of a MAC address
54
+  ArpRequest.ArpHdr.ProtoLen = 0x04; // length of an IP address
55
+  ArpRequest.ArpHdr.Op = htons( 0x0001 ); // ARP request
56
+  mac_cpy( ArpRequest.ArpHdr.SrcMac, ConfigMac ); // own MAC
57
+  ip_cpy( ArpRequest.ArpHdr.SrcIp, ConfigIp ); // own IP
58
+  mac_cpy( ArpRequest.ArpHdr.DestMac, "\xFF\xFF\xFF\xFF\xFF\xFF" ); // broadcast MAC
59
+  ip_cpy( ArpRequest.ArpHdr.DestIp, pIp ); // requested IP
60
+
61
+  // sent ARP request
62
+  mac_cpy( ArpRequest.EthHdr.Dest, ArpRequest.ArpHdr.DestMac ); // ethernet destination address
63
+  ArpRequest.EthHdr.Type = htons( 0x0806 ); // ethernet packet type: ARP
64
+  EthernetSend( (unsigned char *)&ArpRequest, sizeof( ArpRequest ) );
65
+}
66
+
67
+// tick procedure - call every 200ms
68
+void ArpTick200( void ) // (extern)
69
+{
70
+  unsigned char i;
71
+
72
+  // increase age of ARP table entires and remove timed out ones
73
+  for( i = 0; i < count( ArpTab ); i++ )
74
+  {
75
+    if( ArpTab[i].Flags & ArpTabFlagInUse ) // entry in use
76
+    {
77
+      ArpTab[i].Ticks++; // increase age
78
+      if( ArpTab[i].Flags & ArpTabFlagMacOk ) // entry has got a MAC
79
+      {
80
+        if( ArpTab[i].Ticks > ArpTicksMax ) // too old
81
+          ArpTab[i].Flags = 0; // remove entry
82
+      }
83
+      else // entry has not got a MAC
84
+      {
85
+        if( ArpTab[i].Ticks > ArpNoMacTicksMax ) // too old
86
+          ArpTab[i].Flags = 0; // remove entry
87
+        else if( (ArpTab[i].Ticks & (ArpRetryTicks - 1)) == 0 ) // retry ARP request
88
+          ArpSendRequest( ArpTab[i].Ip );
89
+      }
90
+    }
91
+  }
92
+}
93
+
94
+// process a received ARP packet
95
+void ArpRecv( unsigned char * pData, unsigned short Length ) // (extern)
96
+{
97
+  struct ArpPacket * pArpPack;
98
+
99
+  // packet too short
100
+  if( Length < sizeof( struct ArpPacket ) )
101
+    return;
102
+
103
+  // convert pointer to ARP packet
104
+  // (this saves us from always casting pData)
105
+  pArpPack = (struct ArpPacket *)pData;
106
+
107
+  // not IP over ethernet
108
+  if( pArpPack->ArpHdr.HwType != htons( 0x0001 ) || // ethernet
109
+      pArpPack->ArpHdr.ProtoType != htons( 0x0800 ) || // IP
110
+      pArpPack->ArpHdr.HwLen != 0x06 || // length of a MAC address
111
+      pArpPack->ArpHdr.ProtoLen != 0x04 ) // length of an IP address
112
+    // we do not support other protocols than IP over ethernet
113
+    return;
114
+
115
+  // source MAC is broadcast MAC
116
+  if( mac_eq( pArpPack->ArpHdr.SrcMac, "\xFF\xFF\xFF\xFF\xFF\xFF" ) )
117
+    // broadcast MAC cannot be source, this is some kind of attack, get lost!
118
+    return;
119
+
120
+  // ARP request for own IP address
121
+  if( pArpPack->ArpHdr.Op == htons( 0x0001 ) && // ARP request
122
+      ip_eq( pArpPack->ArpHdr.DestIp, ConfigIp ) ) // own IP address
123
+  {
124
+    struct ArpPacket ArpReply;
125
+    // build ARP reply
126
+    ArpReply.ArpHdr.HwType = htons( 0x0001 ); // ethernet
127
+    ArpReply.ArpHdr.ProtoType = htons( 0x0800 ); // IP
128
+    ArpReply.ArpHdr.HwLen = 0x06; // length of a MAC address
129
+    ArpReply.ArpHdr.ProtoLen = 0x04; // length of an IP address
130
+    ArpReply.ArpHdr.Op = htons( 0x0002 ); // ARP reply
131
+    mac_cpy( ArpReply.ArpHdr.SrcMac, ConfigMac ); // own MAC
132
+    ip_cpy( ArpReply.ArpHdr.SrcIp, ConfigIp ); // own IP
133
+    mac_cpy( ArpReply.ArpHdr.DestMac, pArpPack->ArpHdr.SrcMac ); // requestor's MAC
134
+    ip_cpy( ArpReply.ArpHdr.DestIp, pArpPack->ArpHdr.SrcIp ); // requestor's IP
135
+
136
+    debug_arp_printf( "recv req src=%02X:%02X:%02X:%02X:%02X:%02X ip=%u.%u.%u.%u",
137
+                      pArpPack->ArpHdr.SrcMac[0], pArpPack->ArpHdr.SrcMac[1], pArpPack->ArpHdr.SrcMac[2],
138
+                      pArpPack->ArpHdr.SrcMac[3], pArpPack->ArpHdr.SrcMac[4], pArpPack->ArpHdr.SrcMac[5],
139
+                      pArpPack->ArpHdr.SrcIp[0], pArpPack->ArpHdr.SrcIp[1], 
140
+                      pArpPack->ArpHdr.SrcIp[2], pArpPack->ArpHdr.SrcIp[3] );
141
+
142
+    // sent ARP reply
143
+    mac_cpy( ArpReply.EthHdr.Dest, ArpReply.ArpHdr.DestMac ); // ethernet destination address
144
+    ArpReply.EthHdr.Type = htons( 0x0806 ); // ethernet packet type: ARP
145
+    EthernetSend( (unsigned char *)&ArpReply, sizeof( ArpReply ) );
146
+    return;
147
+  }
148
+
149
+  // ARP reply to own MAC address and own IP address
150
+  if( pArpPack->ArpHdr.Op == htons( 0x0002 ) && // ARP reply
151
+      mac_eq( pArpPack->ArpHdr.DestMac, ConfigMac ) && // own MAC address
152
+      ip_eq( pArpPack->ArpHdr.DestIp, ConfigIp ) ) // own IP address
153
+  {
154
+    unsigned char i;
155
+
156
+    debug_arp_printf( "recv reply src=%02X:%02X:%02X:%02X:%02X:%02X ip=%u.%u.%u.%u",
157
+                      pArpPack->ArpHdr.SrcMac[0], pArpPack->ArpHdr.SrcMac[1], pArpPack->ArpHdr.SrcMac[2],
158
+                      pArpPack->ArpHdr.SrcMac[3], pArpPack->ArpHdr.SrcMac[4], pArpPack->ArpHdr.SrcMac[5],
159
+                      pArpPack->ArpHdr.SrcIp[0], pArpPack->ArpHdr.SrcIp[1], 
160
+                      pArpPack->ArpHdr.SrcIp[2], pArpPack->ArpHdr.SrcIp[3] );
161
+
162
+    // search IP in ARP tabale
163
+    for( i = 0; i < count( ArpTab ); i++ )
164
+      if( (ArpTab[i].Flags & ArpTabFlagInUse) &&
165
+          ip_eq( pArpPack->ArpHdr.SrcIp, ArpTab[i].Ip ) )
166
+        break;
167
+    // if found in ARP table
168
+    // (we do not want to put an entry in the ARP table
169
+    // if we have not asked for the MAC of this IP)
170
+    if( i < count( ArpTab ) )
171
+    {
172
+      // update ARP table entry
173
+      ArpTab[i].Flags = ArpTabFlagInUse | ArpTabFlagMacOk;
174
+      ArpTab[i].Ticks = 0;
175
+      mac_cpy( ArpTab[i].Mac, pArpPack->ArpHdr.SrcMac );
176
+      // notify IP
177
+      // - IP might be waiting for the MAC to transmit a packet
178
+      IpGotMac( ArpTab[i].Ip, ArpTab[i].Mac );
179
+    }
180
+    return;
181
+  }
182
+
183
+}
184
+
185
+// lookup the MAC for an IP address
186
+// returns 0x00 in case of success, 0x01 if the MAC address is unknown
187
+unsigned char ArpLookup( unsigned char * pIp, unsigned char * pMac ) // (extern)
188
+{
189
+  unsigned char i, j;
190
+
191
+  // own IP
192
+  if( ip_eq( pIp, ConfigIp ) )
193
+    // own IP may not be looked up via ARP
194
+    return 0x01;
195
+
196
+  // search IP in ARP tabale
197
+  for( i = 0; i < count( ArpTab ); i++ )
198
+    if( (ArpTab[i].Flags & ArpTabFlagInUse) &&
199
+        ip_eq( pIp, ArpTab[i].Ip ) )
200
+      break;
201
+
202
+  // not found
203
+  if( i >= count( ArpTab ) )
204
+  {
205
+    // find a free entry
206
+    for( i = 0; i < count( ArpTab ); i++ )
207
+      if( ! (ArpTab[i].Flags & ArpTabFlagInUse) )
208
+        break;
209
+
210
+    // no free entry
211
+    if( i >= count( ArpTab ) )
212
+    {
213
+      // find oldest entry
214
+      i = 0;
215
+      for( j = 1; j < count( ArpTab ); j++ )
216
+        if( ArpTab[j].Ticks > ArpTab[i].Ticks )
217
+          i = j;
218
+    }
219
+
220
+    // set up this entry
221
+    ArpTab[i].Flags = ArpTabFlagInUse;
222
+    ArpTab[i].Ticks = 0;
223
+    ip_cpy( ArpTab[i].Ip, pIp );
224
+  }
225
+
226
+  // MAC available
227
+  if( ArpTab[i].Flags & ArpTabFlagMacOk )
228
+  {
229
+    // return MAC and success
230
+    mac_cpy( pMac, ArpTab[i].Mac );
231
+    return 0x00;
232
+  }
233
+
234
+  // send ARP request
235
+  ArpSendRequest( pIp );
236
+
237
+  // return no success for now
238
+  return 0x01;
239
+}
240
+
... ...
@@ -0,0 +1,48 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_arp
9
+#define INC_arp
10
+
11
+#include "ethernet.h"
12
+
13
+// header of an ARP packet
14
+struct ArpHeader
15
+{
16
+  unsigned short HwType;
17
+  unsigned short ProtoType;
18
+  unsigned char HwLen;
19
+  unsigned char ProtoLen;
20
+  unsigned short Op;
21
+  unsigned char SrcMac[6];
22
+  unsigned char SrcIp[4];
23
+  unsigned char DestMac[6];
24
+  unsigned char DestIp[4];
25
+};
26
+
27
+// an ARP packet
28
+struct ArpPacket
29
+{
30
+  struct EthernetHeader EthHdr;
31
+  struct ArpHeader ArpHdr;
32
+};
33
+
34
+// initialize
35
+extern void ArpInit( void );
36
+
37
+// tick procedure - call every 200ms
38
+extern void ArpTick200( void );
39
+
40
+// process a received ARP packet
41
+extern void ArpRecv( unsigned char * pData, unsigned short Length );
42
+
43
+// lookup the MAC for an IP address
44
+// returns 0x00 in case of success, 0x01 if the MAC address is unknown
45
+extern unsigned char ArpLookup( unsigned char * pIp, unsigned char * pMac );
46
+
47
+#endif // #ifdef INC_arp
48
+
... ...
@@ -0,0 +1,31 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/io.h>
9
+
10
+#include "bus.h"
11
+
12
+// initialize
13
+void BusInit( void ) // (extern)
14
+{
15
+  // address port to output
16
+  BUS_ADDR = 0x00; // default address
17
+  BUS_ADDR_DDR = 0xFF; // output
18
+
19
+  // data port to input
20
+  BUS_DATA = 0x00; // pull-ups off
21
+  BUS_DATA_DDR = 0x00; // input
22
+
23
+  // read pin to output
24
+  bit_set( BUS_PORT_nRD, BUS_BIT_nRD ); // nRD to high
25
+  bit_set( BUS_DDR_nRD, BUS_BIT_nRD ); // output
26
+
27
+  // write pin to output
28
+  bit_set( BUS_PORT_nWR, BUS_BIT_nWR ); // nWR to high
29
+  bit_set( BUS_DDR_nWR, BUS_BIT_nWR ); // output
30
+}
31
+
... ...
@@ -0,0 +1,36 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_bus
9
+#define INC_bus
10
+
11
+#include "macros.h"
12
+
13
+// IO pins of bus
14
+#define BUS_ADDR_DDR (DDRG)
15
+#define BUS_ADDR (PORTG)
16
+#define BUS_DATA_DDR (DDRA)
17
+#define BUS_DATA (PORTA)
18
+#define BUS_DATA_IN (PINA)
19
+#define BUS_DDR_nRD (DDRE)
20
+#define BUS_PORT_nRD (PORTE)
21
+#define BUS_BIT_nRD (6)
22
+#define BUS_DDR_nWR (DDRE)
23
+#define BUS_PORT_nWR (PORTE)
24
+#define BUS_BIT_nWR (7)
25
+
26
+// special pin commands
27
+#define BUS_READ_ACT( ) (bit_clear( BUS_PORT_nRD, BUS_BIT_nRD ))
28
+#define BUS_READ_IDLE( ) (bit_set( BUS_PORT_nRD, BUS_BIT_nRD ))
29
+#define BUS_WRITE_ACT( ) (bit_clear( BUS_PORT_nWR, BUS_BIT_nWR ))
30
+#define BUS_WRITE_IDLE( ) (bit_set( BUS_PORT_nWR, BUS_BIT_nWR ))
31
+
32
+// initialize
33
+extern void BusInit( void );
34
+
35
+#endif // #ifndef INC_bus
36
+
... ...
@@ -0,0 +1,605 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/io.h>
9
+
10
+#include "bus.h"
11
+#include "cf.h"
12
+#include "config.h"
13
+#include "debug.h"
14
+#include "macros.h"
15
+#include "status.h"
16
+#include "timing.h"
17
+
18
+// IO pins of compact flash
19
+#define CF_DDR_nCD (DDRB)
20
+#define CF_PORT_nCD (PORTB)
21
+#define CF_PIN_nCD (PINB)
22
+#define CF_BIT_nCD (4)
23
+#define CF_DDR_nRST (DDRB)
24
+#define CF_PORT_nRST (PORTB)
25
+#define CF_BIT_nRST (5)
26
+#define CF_DDR_RDY (DDRB)
27
+#define CF_PORT_RDY (PORTB)
28
+#define CF_PIN_RDY (PINB)
29
+#define CF_BIT_RDY (7)
30
+#define CF_DDR_nCE (DDRB)
31
+#define CF_PORT_nCE (PORTB)
32
+#define CF_BIT_nCE (6)
33
+// special pin commands
34
+#define CF_IS_DETECT( ) (is_bit_clear( CF_PIN_nCD, CF_BIT_nCD ))
35
+#define CF_RESET_ACT( ) (bit_clear( CF_PORT_nRST, CF_BIT_nRST ))
36
+#define CF_RESET_IDLE( ) (bit_set( CF_PORT_nRST, CF_BIT_nRST ))
37
+#define CF_IS_READY( ) (is_bit_set( CF_PIN_RDY, CF_BIT_RDY ))
38
+#define CF_CE_ACT( ) (bit_clear( CF_PORT_nCE, CF_BIT_nCE ))
39
+#define CF_CE_IDLE( ) (bit_set( CF_PORT_nCE, CF_BIT_nCE ))
40
+
41
+// compact flash registers
42
+#define CF_REG_DATA (0x00)
43
+#define CF_REG_ERR (0x01)
44
+#define CF_REG_SEC_CNT (0x02)
45
+#define CF_REG_SEC_NO (0x03)
46
+#define CF_REG_CYL_L (0x04)
47
+#define CF_REG_CYL_H (0x05)
48
+#define CF_REG_HEAD (0x06)
49
+#define CF_REG_STATUS (0x07)
50
+#define CF_REG_CMD (0x07)
51
+
52
+// compact flash status bits
53
+#define CF_SB_BUSY (7)
54
+#define CF_SB_RDY (6)
55
+#define CF_SB_DWF (5)
56
+#define CF_SB_DSC (4)
57
+#define CF_SB_DRQ (3)
58
+#define CF_SB_CORR (2)
59
+#define CF_SB_IDX (1)
60
+#define CF_SB_ERR (0)
61
+
62
+// compact flash commands
63
+#define CF_CMD_IDENTIFY (0xEC)
64
+#define CF_CMD_READ_SEC (0x20)
65
+#define CF_CMD_WRITE_SEC (0x30)
66
+
67
+// some number of bytes
68
+#define CF_BYTES_AT_ONCE (32) // number of bytes to read/write at once
69
+#define CF_BYTES_IDENTIFY (124) // number of bytes to read for identify
70
+
71
+// interesting locations in identify data
72
+#define CF_ID_OFS_ID_16 (0) // CF identifier, 16 bit
73
+#define CF_ID_OFS_CAPA_16 (98) // CF capabilities, 16 bit
74
+#define CF_ID_OFS_SEC_CNT_32 (120) // number of sectors on CF (in LBA mode), 32 bit
75
+
76
+// various CF constants
77
+#define CF_ID (0x848A) // identifier of compact flash cards
78
+#define CF_CAPA_BIT_LBA (9) // bit number of the LBA bit in the CF capabilities
79
+
80
+// timeout value for wait for ready counter (in 20ms steps)
81
+#define CF_WAIT_READY_20_TIMEOUT (4) // 80ms
82
+
83
+// compact flash insertion state
84
+enum CfInsertionState
85
+{
86
+  CfInsNone, // no compact flash inserted
87
+  CfInsNew, // new compact flash has been inserted, wait for powerup
88
+  CfInsReset, // resetting new compact flash
89
+  CfInsWait, // waiting for new compact flash to get ready after reset
90
+  CfInsReady, // compact flash inserted and ready to work with
91
+  CfInsError, // compact flash error occured, compact flash deactivated
92
+} CfInsState = CfInsNone;
93
+
94
+// compact flash working state
95
+enum CfWorkingState
96
+{
97
+  CfWorkNone, // no compact flash work to do
98
+  CfWorkIdentify, // identification of compact flash active
99
+} CfWorkState = CfWorkNone;
100
+
101
+// compact flash working step
102
+enum CfWorkingStep
103
+{
104
+  CfStepNone, // no step in progress
105
+  CfStepCmdStatus, // checking command status
106
+  CfStepDataTransfer, // transferring (reading/writing) data
107
+  CfStepDataStatus, // checking data status
108
+} CfWorkStep = CfStepNone;
109
+
110
+// number of sectors on compact flash card
111
+//  - zero if no CF card is present, CF card has not yet been identified or CF card error occured
112
+unsigned long CfSectorCnt = 0;
113
+
114
+// state of active command
115
+unsigned long CfSectorNo = 0; // current sector number of compact flash
116
+unsigned short CfNextOffset = 0; // next offset in sector that is processed (read, written, ...)
117
+
118
+// wait for ready counter of compact flash
119
+//  - counts down in 20ms steps
120
+//  - zero if inactive
121
+unsigned char CfWaitReady20 = 0;
122
+
123
+// sector buffer
124
+unsigned char CfSectorBuffer[CF_SECTOR_SIZE]; // (extern)
125
+
126
+// write a compact flash register (returns 1 if successful or 0 on error)
127
+//  - returns 0 on success and -1 on error
128
+extern inline char CfWriteReg( unsigned char reg, unsigned char val ) // force inlining by using "extern"
129
+{
130
+  if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
131
+    return -1; // error
132
+  BUS_DATA = val; // output value
133
+  BUS_DATA_DDR = 0xFF; // data port to output
134
+  BUS_ADDR = reg; // output address
135
+  CF_CE_ACT( ); // set card enable
136
+  BUS_WRITE_ACT( ); // activate write signal
137
+  nop( );
138
+  nop( );
139
+  nop( );
140
+  nop( );
141
+  nop( );
142
+  nop( );
143
+  BUS_WRITE_IDLE( ); // take back write signal
144
+  CF_CE_IDLE( ); // take back card enable
145
+  BUS_DATA_DDR = 0x00; // data back port to input
146
+  BUS_DATA = 0x00; // turn off pullups
147
+  return 0; // success
148
+}
149
+
150
+// write buffer to compact flash register (returns 1 if successful or 0 on error)
151
+//  - returns 0 on success and -1 on error
152
+extern inline char CfWriteRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern"
153
+{
154
+  if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
155
+    return -1; // error
156
+  BUS_DATA = *p_buf; // output first value to initialize port status before switching to output
157
+  BUS_DATA_DDR = 0xFF; // data port to output
158
+  BUS_ADDR = reg; // output address
159
+  CF_CE_ACT( ); // set card enable
160
+  for( ; len > 0; p_buf++, len-- ) {
161
+    if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
162
+      break;
163
+    BUS_DATA = *p_buf; // output value
164
+    BUS_WRITE_ACT( ); // activate write signal
165
+    nop( );
166
+    nop( );
167
+    nop( );
168
+    nop( );
169
+    nop( );
170
+    nop( );
171
+    BUS_WRITE_IDLE( ); // take back write signal
172
+  }
173
+  CF_CE_IDLE( ); // take back card enable
174
+  BUS_DATA_DDR = 0x00; // data back port to input
175
+  BUS_DATA = 0x00; // turn off pullups
176
+  return len <= 0 ? 0 : -1; // success if everything has been written
177
+}
178
+
179
+// write constant value to compact flash register multiple times (returns 1 if successful or 0 on error)
180
+//  - returns 0 on success and -1 on error
181
+extern inline char CfWriteRegConst( unsigned char reg, unsigned char val, unsigned short cnt ) // force inlining by using "extern"
182
+{
183
+  if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
184
+    return -1; // error
185
+  BUS_DATA = val; // output value
186
+  BUS_DATA_DDR = 0xFF; // data port to output
187
+  BUS_ADDR = reg; // output address
188
+  CF_CE_ACT( ); // set card enable
189
+  for( ; cnt > 0; cnt-- ) {
190
+    if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
191
+      break;
192
+    BUS_WRITE_ACT( ); // activate write signal
193
+    nop( );
194
+    nop( );
195
+    nop( );
196
+    nop( );
197
+    nop( );
198
+    nop( );
199
+    BUS_WRITE_IDLE( ); // take back write signal
200
+  }
201
+  CF_CE_IDLE( ); // take back card enable
202
+  BUS_DATA_DDR = 0x00; // data back port to input
203
+  BUS_DATA = 0x00; // turn off pullups
204
+  return cnt <= 0 ? 0 : -1; // success if everything has been written
205
+}
206
+
207
+// read a compact flash register (returns 1 if successful or 0 on error)
208
+//  - returns 0 on success and -1 on error
209
+extern inline char CfReadReg( unsigned char reg, unsigned char * p_var ) // force inlining by using "extern"
210
+{
211
+  if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
212
+    return -1; // error
213
+  BUS_ADDR = reg; // output address
214
+  CF_CE_ACT( ); // set card enable
215
+  BUS_READ_ACT( ); // activate read signal
216
+  nop( );
217
+  nop( );
218
+  nop( );
219
+  nop( );
220
+  nop( );
221
+  nop( );
222
+  *p_var = BUS_DATA_IN; // read data
223
+  BUS_READ_IDLE( ); // take back read signal
224
+  CF_CE_IDLE( ); // take back card enable
225
+  return 0; // success
226
+}
227
+
228
+// read buffer from a compact flash register (returns 1 if successful or 0 on error)
229
+//  - returns 0 on success and -1 on error
230
+extern inline char CfReadRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern"
231
+{
232
+  if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
233
+    return -1; // error
234
+  BUS_ADDR = reg; // output address
235
+  CF_CE_ACT( ); // set card enable
236
+  for( ; len > 0; p_buf++, len-- ) {
237
+    if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
238
+      break;
239
+    BUS_READ_ACT( ); // activate read signal
240
+    nop( );
241
+    nop( );
242
+    nop( );
243
+    nop( );
244
+    nop( );
245
+    nop( );
246
+    *p_buf = BUS_DATA_IN; // read data
247
+    BUS_READ_IDLE( ); // take back read signal
248
+  }
249
+  CF_CE_IDLE( ); // take back card enable
250
+  return len <= 0 ? 0 : -1; // success if everything has been read
251
+}
252
+
253
+// read a compact flash register multiple times and throw away data (returns 1 if successful or 0 on error)
254
+//  - returns 0 on success and -1 on error
255
+extern inline char CfReadRegMulti( unsigned char reg, unsigned short cnt ) // force inlining by using "extern"
256
+{
257
+  if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
258
+    return -1; // error
259
+  BUS_ADDR = reg; // output address
260
+  CF_CE_ACT( ); // set card enable
261
+  for( ; cnt > 0; cnt-- ) {
262
+    if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready
263
+      break;
264
+    BUS_READ_ACT( ); // activate read signal
265
+    nop( );
266
+    nop( );
267
+    nop( );
268
+    nop( );
269
+    nop( );
270
+    nop( );
271
+    BUS_READ_IDLE( ); // take back read signal
272
+  }
273
+  CF_CE_IDLE( ); // take back card enable
274
+  return cnt <= 0 ? 0 : -1; // success if everything has been read
275
+}
276
+
277
+// compact flash work done
278
+static void CfDone( void )
279
+{
280
+  debug_cf_printf( "CF done" );
281
+
282
+  // set working state and step to none
283
+  CfWorkState = CfWorkNone;
284
+  CfWorkStep = CfStepNone;
285
+
286
+  // reset state of active command
287
+  CfSectorNo = 0;
288
+  CfNextOffset = 0;
289
+
290
+  // disable wait for ready counter
291
+  CfWaitReady20 = 0;
292
+}
293
+
294
+// compact flash error occured
295
+static void CfError( void )
296
+{
297
+  debug_cf_printf( "CF error" );
298
+
299
+  // set insertion state to error
300
+  CfInsState = CfInsError;
301
+
302
+  // set working state and step to none
303
+  CfWorkState = CfWorkNone;
304
+  CfWorkStep = CfStepNone;
305
+
306
+  // reset all information about CF card
307
+  CfSectorCnt = 0;
308
+
309
+  // reset state of active command
310
+  CfSectorNo = 0;
311
+  CfNextOffset = 0;
312
+
313
+  // disable wait for ready counter
314
+  CfWaitReady20 = 0;
315
+}
316
+
317
+// process compact flash insertion
318
+static void CfProcIns( void )
319
+{
320
+  switch( CfInsState )
321
+  {
322
+
323
+    // no compact flash inserted
324
+    case CfInsNone:
325
+      // if compact flash is detected, set state to new CF
326
+      if( CF_IS_DETECT( ) ) {
327
+        CfInsState = CfInsNew;
328
+        debug_cf_printf( "new CF" );
329
+        break;
330
+      }
331
+      break;
332
+
333
+    // new compact flash has been inserted, wait for powerup
334
+    case CfInsNew:
335
+      // if compact flash has been removed, set state to none
336
+      if( ! CF_IS_DETECT( ) ) {
337
+        CfInsState = CfInsNone;
338
+        break;
339
+      }
340
+      // set reset
341
+      CF_RESET_ACT( );
342
+      CfInsState = CfInsReset;
343
+      break;
344
+
345
+    // resetting new compact flash
346
+    case CfInsReset:
347
+      // take back reset
348
+      CF_RESET_IDLE( );
349
+      // if compact flash has been removed, set state to none
350
+      if( ! CF_IS_DETECT( ) ) {
351
+        CfInsState = CfInsNone;
352
+        break;
353
+      }
354
+      break;
355
+
356
+    // waiting for new compact flash to get ready after reset
357
+    case CfInsWait:
358
+      // if compact flash has been removed, set state to none
359
+      if( ! CF_IS_DETECT( ) ) {
360
+        CfInsState = CfInsNone;
361
+        break;
362
+      }
363
+      // if compact flash card is ready, set state to ready
364
+      if( CF_IS_READY( ) ) {
365
+        CfInsState = CfInsReady;
366
+        debug_cf_printf( "CF ready" );
367
+      }
368
+      break;
369
+
370
+    // compact flash inserted and ready to work with
371
+    case CfInsReady:
372
+      // do nothing here, card work is done by task procedure
373
+      // (task will detect CF removal or timeout and set state to error)
374
+      break;
375
+
376
+    // compact flash error occured, compact flash deactivated
377
+    case CfInsError:
378
+      // if compact flash has been removed, set state to none
379
+      if( ! CF_IS_DETECT( ) ) {
380
+        CfInsState = CfInsNone;
381
+        debug_cf_printf( "CF removed" );
382
+      }
383
+      break;
384
+
385
+  } // switch( CfInsState )
386
+}
387
+
388
+// detect compact flash timeout
389
+//  - called every 20ms
390
+static void CfDetectTimeout20( void )
391
+{
392
+  // only detect CF timeout if insertion state is ready
393
+  // (otherwise, the insertion processing is still doing some work)
394
+  if( CfInsState != CfInsReady )
395
+    return;
396
+
397
+  // wait for ready counter not active
398
+  if( CfWaitReady20 <= 0 )
399
+    return;
400
+
401
+  // decrement wait for ready counter
402
+  CfWaitReady20--;
403
+
404
+  // timeout occured
405
+  if( CfWaitReady20 <= 0 ) {
406
+    debug_cf_printf( "timeout while waiting for CF ready" );
407
+    CfError( );
408
+  }
409
+}
410
+
411
+// continue with identifying compact flash
412
+static void CfProcWorkIdentify( void )
413
+{
414
+  unsigned char status = 0;
415
+  unsigned short len, val16;
416
+
417
+  switch( CfWorkStep ) {
418
+
419
+    // no step
420
+    case CfStepNone:
421
+      debug_cf_printf( "internal error (identify, CfStepNone)" );
422
+      CfError( );
423
+      break;
424
+
425
+    // checking command status
426
+    case CfStepCmdStatus:
427
+      // read status register
428
+      CfReadReg( CF_REG_STATUS, &status );
429
+      // check that BUSY=0, RDY=1, DWF=0, DSC=1, IDX=0, ERR=0
430
+      if( (status & (1 << CF_SB_BUSY | 1 << CF_SB_RDY | 1 << CF_SB_DWF | 1 << CF_SB_DSC | 1 << CF_SB_IDX | 1 << CF_SB_ERR)) != (1 << CF_SB_RDY | 1 << CF_SB_DSC) ) {
431
+        debug_cf_printf( "unexpected status 0x%02X (identify)", status );
432
+        CfError( );
433
+      }
434
+      // continue with data transfer
435
+      CfWorkStep = CfStepDataTransfer;
436
+      CfNextOffset = 0;
437
+      break;
438
+
439
+    // transferring data
440
+    case CfStepDataTransfer:
441
+      // still bytes to read
442
+      if( CfNextOffset < CF_BYTES_IDENTIFY ) {
443
+        // get number of bytes to read
444
+        len = CF_BYTES_IDENTIFY - CfNextOffset;
445
+        if( len > CF_BYTES_AT_ONCE )
446
+          len = CF_BYTES_AT_ONCE;
447
+        // read bytes
448
+        if( CfReadRegBuf( CF_REG_DATA, &CfSectorBuffer[CfNextOffset], len ) != 0 ) {
449
+          debug_cf_printf( "reading from CF failed (identify, offset 0x%03X, length 0x%02X)", CfNextOffset, len );
450
+          CfError( );
451
+          break;
452
+        }
453
+        CfNextOffset += len;
454
+      }
455
+      // all bytes read
456
+      if( CfNextOffset >= CF_BYTES_IDENTIFY ) {
457
+        // check identifier
458
+        val16 = (unsigned short)CfSectorBuffer[CF_ID_OFS_ID_16 + 0]
459
+              | (unsigned short)CfSectorBuffer[CF_ID_OFS_ID_16 + 1] << 8;
460
+        if( val16 != CF_ID ) {
461
+          debug_cf_printf( "invalid CF identifier: 0x%04X", val16 );
462
+          CfError( );
463
+          break;
464
+        }
465
+        // check if LBA mode is supported
466
+        val16 = (unsigned short)CfSectorBuffer[CF_ID_OFS_CAPA_16 + 0]
467
+              | (unsigned short)CfSectorBuffer[CF_ID_OFS_CAPA_16 + 1] << 8;
468
+        if( (val16 & 1 << CF_CAPA_BIT_LBA) == 0 ) {
469
+          debug_cf_printf( "CF does not support LBA mode" );
470
+          CfError( );
471
+          break;
472
+        }
473
+        // get number of sectors on CF
474
+        CfSectorCnt = (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 0]
475
+                    | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 1] << 8
476
+                    | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 1] << 16
477
+                    | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 1] << 24;
478
+        if( CfSectorCnt <= 0 ) {
479
+          debug_cf_printf( "CF does not contain any sectors" );
480
+          CfError( );
481
+          break;
482
+        }
483
+        // done
484
+        CfDone( );
485
+      }
486
+      break;
487
+
488
+    // checking data status
489
+    case CfStepDataStatus:
490
+      debug_cf_printf( "internal error (identify, CfStepDataStatus)" );
491
+      CfError( );
492
+      break;
493
+
494
+  } // switch( CfWorkStep )
495
+}
496
+
497
+// do normal compact flash work
498
+static void CfProcWork( void )
499
+{
500
+  // only do CF processing if insertion state is ready
501
+  // (otherwise, the insertion processing is still doing some work)
502
+  if( CfInsState != CfInsReady )
503
+    return;
504
+
505
+  // compact flash has been removed -> error
506
+  if( ! CF_IS_DETECT( ) ) {
507
+    debug_cf_printf( "CF no more present" );
508
+    CfError( );
509
+    return;
510
+  }
511
+
512
+  // compact flash is not ready
513
+  if( ! CF_IS_READY( ) ) {
514
+    // wait for ready not active --> error
515
+    if( CfWaitReady20 <= 0 ) {
516
+      debug_cf_printf( "CF no more ready" );
517
+      CfError( );
518
+    }
519
+    // do nothing if CF is not ready
520
+    return;
521
+  }
522
+
523
+  switch( CfWorkState ) {
524
+
525
+    // no compact flash work to do
526
+    case CfWorkNone:
527
+      // nothing to do here
528
+      break;
529
+
530
+    // identification of compact flash active
531
+    case CfWorkIdentify:
532
+      CfProcWorkIdentify( );
533
+      break;
534
+
535
+  } // switch( CfWorkState )
536
+}
537
+
538
+// identify compact flash
539
+//  - returns 0 on success, 1 if not idle and -1 on error
540
+static char CfIdentify( void )
541
+{
542
+  // check that no command is being worked on
543
+  if( CfWorkState != CfWorkNone )
544
+    return 1;
545
+
546
+  debug_cf_printf( "CF identify" );
547
+
548
+  // issue identify drive command
549
+  if( CfWriteReg( CF_REG_CMD, CF_CMD_IDENTIFY ) != 0 ) {
550
+    CfError( );
551
+    return -1;
552
+  }
553
+
554
+  // now identifying compact flash
555
+  CfWorkState = CfWorkIdentify;
556
+  CfWorkStep = CfStepCmdStatus;
557
+  CfNextOffset = 0;
558
+  CfWaitReady20 = CF_WAIT_READY_20_TIMEOUT;
559
+  return 0;
560
+}
561
+
562
+// initialize
563
+void CfInit( void ) // (extern)
564
+{
565
+  // setup ports
566
+  bit_clear( CF_PORT_nCD, CF_BIT_nCD ); // pull-up of card detect pin off (external pull-up is present)
567
+  bit_clear( CF_DDR_nCD, CF_BIT_nCD ); // card detect pin to input
568
+  bit_clear( CF_PORT_nRST, CF_BIT_nRST ); // reset pin to LOW
569
+  bit_set( CF_DDR_nRST, CF_BIT_nRST ); // reset pin to output
570
+  bit_clear( CF_PORT_RDY, CF_BIT_RDY ); // pull-up of ready pin pin off (external pull-up is present)
571
+  bit_clear( CF_DDR_RDY, CF_BIT_RDY ); // ready pin to input
572
+  bit_set( CF_PORT_nCE, CF_BIT_nCE ); // card enable to LOW
573
+  bit_set( CF_DDR_nCE, CF_BIT_nCE ); // card enable pin to output
574
+}
575
+
576
+// tick procedure - call every 20ms
577
+void CfTick20( void ) // (extern)
578
+{
579
+  // process compact flash insertion
580
+  CfProcIns( );
581
+
582
+  // detect compact flash timeout
583
+  CfDetectTimeout20( );
584
+}
585
+
586
+// task function to do the work - call from main loop
587
+void CfTask( void ) // (extern)
588
+{
589
+  // do nothing if no CF is inserted
590
+  if( CfInsState != CfInsReady )
591
+    return;
592
+
593
+  // compact flash is ready but not yet identified
594
+  if( CfSectorCnt == 0 ) {
595
+    // identify compact flash
596
+    CfIdentify( );
597
+  }
598
+
599
+  // do normal compact flash work
600
+  CfProcWork( );
601
+
602
+  // update status
603
+  StatusInfoCfPresent = CfInsState == CfInsReady; // report working CF if insertion state is ready
604
+}
605
+
... ...
@@ -0,0 +1,27 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_cf
9
+#define INC_cf
10
+
11
+// size of a sector in bytes
12
+#define CF_SECTOR_SIZE (512)
13
+
14
+// sector buffer
15
+extern unsigned char CfSectorBuffer[CF_SECTOR_SIZE];
16
+
17
+// initialize
18
+extern void CfInit( void );
19
+
20
+// tick procedure - call every 20ms
21
+extern void CfTick20( void );
22
+
23
+// task function to do the work - call from main loop
24
+extern void CfTask( void );
25
+
26
+#endif // #ifndef INC_cf
27
+
... ...
@@ -0,0 +1,38 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include "checksum.h"
9
+#include "macros.h"
10
+#include "nethelp.h"
11
+
12
+// generate a checksum
13
+// also includes Pseudo1 and Pseudo2 in the checksum - set to 0x0000 for normal operation
14
+// can also be used to check a checksum (returns 0 if correct)
15
+unsigned short Checksum( unsigned char * pData, unsigned short Length, unsigned short Pseudo1, unsigned short Pseudo2 ) // (extern)
16
+{
17
+  unsigned long sum;
18
+
19
+  // sum up data of pseudo header
20
+  sum = Pseudo1; // convert to 32 bit first
21
+  sum += Pseudo2;
22
+
23
+  // add full 16 bit words in header
24
+  for( ; Length >= 2; pData += 2, Length -= 2 )
25
+    sum += ntohs( *(unsigned short *)pData );
26
+
27
+  // add last byte
28
+  if( Length >= 1 )
29
+    sum += (unsigned short)(*pData << 8);
30
+
31
+  // convert sum to one's complement sum 
32
+  sum = (sum & 0x0000FFFF) + (sum >> 16); // add carries (bits 31..16) to sum (bits 15..0)
33
+  sum = (sum & 0x0000FFFF) + (sum >> 16); // still a carry possible (from last addition)
34
+
35
+  // return complement of one's complement sum
36
+  return ~(unsigned short)sum;
37
+}
38
+
... ...
@@ -0,0 +1,17 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_checksum
9
+#define INC_checksum
10
+
11
+// generate a checksum
12
+// also includes Pseudo1 and Pseudo2 in the checksum - set to 0x0000 for normal operation
13
+// can also be used to check a checksum (returns 0 if correct)
14
+extern unsigned short Checksum( unsigned char * pData, unsigned short Length, unsigned short Pseudo1, unsigned short Pseudo2 );
15
+
16
+#endif // #ifdef INC_checksum
17
+
... ...
@@ -0,0 +1,30 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include "config.h"
9
+
10
+// MAC address
11
+unsigned char ConfigMac[6] = { 0x02, 0xF7, 0xA4, 0xE7, 0x8D, 0xB3 }; // (extern)
12
+
13
+// IP configuration
14
+// - all zero for DHCP
15
+unsigned char ConfigIp[4] = { 0, 0, 0, 0 }; // own IP address (extern)
16
+unsigned char ConfigMask[4] = { 0, 0, 0, 0 }; // subnet mask (extern)
17
+unsigned char ConfigGw[4] = { 0, 0, 0, 0 }; // gateway IP address (extern)
18
+
19
+// port for S8P
20
+unsigned short ConfigS8pPort = 8; // disabled if 0 (extern)
21
+
22
+// symmetric key for S8P
23
+unsigned char ConfigS8pKey[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // (extern)
24
+
25
+// port for webserver
26
+unsigned short ConfigHttpPort = 80; // disabled if 0 (extern)
27
+
28
+// default output state
29
+unsigned char ConfigDefOut = 0x00; // (extern)
30
+
... ...
@@ -0,0 +1,31 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_config
9
+#define INC_config
10
+
11
+// MAC address
12
+extern unsigned char ConfigMac[6];
13
+
14
+// IP configuration
15
+extern unsigned char ConfigIp[4]; // own IP address
16
+extern unsigned char ConfigMask[4]; // subnet mask
17
+extern unsigned char ConfigGw[4]; // gateway IP address
18
+
19
+// port for S8P
20
+extern unsigned short ConfigS8pPort; // disabled if 0
21
+
22
+// symmetric key for S8P
23
+extern unsigned char ConfigS8pKey[16];
24
+
25
+// port for webserver
26
+extern unsigned short ConfigHttpPort; // disabled if 0
27
+
28
+// default output state
29
+extern unsigned char ConfigDefOut;
30
+
31
+#endif // #ifndef INC_config
... ...
@@ -0,0 +1,344 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/io.h>
9
+#include <avr/interrupt.h>
10
+
11
+#include "dart.h"
12
+#include "debug.h"
13
+#include "macros.h"
14
+#include "nethelp.h"
15
+#include "udp.h"
16
+
17
+// dartboard connection
18
+//  - 7 row pins connected via shottky diode (low passes to dartboard)
19
+//  - 12 column pins connected directly
20
+
21
+// IO-Pins
22
+// PB0: col10
23
+// PB2: col9
24
+// PB3: col8
25
+// PC[0-7]: col[0-7]
26
+// PF[0-6]: row[0-6]
27
+// PF7: col11
28
+
29
+// constants
30
+#define DartRows (7)
31
+#define DartCols (12)
32
+#define DartFields (DartRows * DartCols)
33
+#define DartDisableTicks (5)
34
+#define DartQueueSize (16)
35
+
36
+// if waiting for a field to be hit
37
+volatile unsigned char DartActive = 1;
38
+
39
+// current row being read
40
+volatile unsigned char DartRow = DartRows;
41
+volatile unsigned char DartRowBits = 1 << DartRows; // always 1 << DartRow
42
+
43
+// field that has been hit
44
+volatile unsigned char DartField = DartFields;
45
+
46
+// ticks dartboard is disabled
47
+//  - used after field has been hit to disable board for some time
48
+unsigned char DartDisable = 0;
49
+
50
+// destination to send dart UDP packets to
51
+unsigned char DartIp[4];
52
+unsigned short DartPort = 0;
53
+
54
+// dart queue
55
+unsigned char DartQueueStart = 0;
56
+unsigned char DartQueueEnd = 0;
57
+unsigned char DartQueue[DartQueueSize];
58
+
59
+// 128us interrupt (timer 2 overflow)
60
+SIGNAL( SIG_OVERFLOW2 )
61
+{
62
+  unsigned char b, c, f, col;
63
+
64
+  // do nothing if not waiting for a field to be hit
65
+  if( ! DartActive )
66
+    return;
67
+
68
+  // read inputs
69
+  b = ~PINB & 0x0D;
70
+  c = ~PINC;
71
+  f = ~PINF & 0x80;
72
+
73
+  // check if any input is active
74
+  //  - make common case (no input active) fast
75
+  if( b | c | f ) {
76
+
77
+    // no column
78
+    col = DartCols;
79
+
80
+    // find active column (any active column if multiple active)
81
+    if( b ) {
82
+      if( b & 0x08 ) col = 8;
83
+      else if( b & 0x04 ) col = 9;
84
+      else if( b & 0x01 ) col = 10;
85
+    } else if( c ) {
86
+      if( c & 0x0F ) {
87
+        if( c & 0x01 ) col = 0;
88
+        else if( c & 0x02 ) col = 1;
89
+        else if( c & 0x04 ) col = 2;
90
+        else if( c & 0x08 ) col = 3;
91
+      } else if( c & 0xF0 ) {
92
+        if( c & 0x10 ) col = 4;
93
+        else if( c & 0x20 ) col = 5;
94
+        else if( c & 0x40 ) col = 6;
95
+        else if( c & 0x80 ) col = 7;
96
+      }
97
+    } else if( f ) {
98
+      if( f & 0x80 ) col = 11;
99
+    }
100
+
101
+    // active column found
102
+    if( col < DartCols ) {
103
+      // save field number
104
+      DartField = DartRow * DartCols + col;
105
+      // do not wait for a field to be hit any more
106
+      DartActive = 0;
107
+    }
108
+
109
+  } // if( b | c | f )
110
+
111
+  // next row
112
+  DartRow++;
113
+  DartRowBits <<= 1;
114
+  if( DartRow >= DartRows ) {
115
+    DartRow = 0;
116
+    DartRowBits = 0x01;
117
+  }
118
+
119
+  // select new row
120
+  PORTF = 0xFF & ~DartRowBits;
121
+}
122
+
123
+// initialize
124
+void DartInit( void ) // (extern)
125
+{
126
+  // col to input with pull-up
127
+  // row to output, high
128
+  PORTB |= 0x0D;
129
+  DDRB &= ~0x0D;
130
+  PORTC = 0xFF;
131
+  DDRC = 0x00;
132
+  PORTF = 0xFF;
133
+  DDRF = 0x7F;
134
+
135
+  // configure timer 2 to 128us interval
136
+  TCCR2 = 0<<FOC2 | 0<<WGM21 | 0<<WGM20 | // normal mode
137
+          0<<COM21 | 0<<COM20 | // no waveform generation
138
+          0<<CS22 | 1<<CS21 | 0<<CS20; // 1/8 of sysclock (16MHz) -> overflow every 128us
139
+
140
+  // enable timer 2 overflow interrupt
141
+  TIMSK |= 1<<TOIE2;
142
+}
143
+
144
+// convert field number to meaning
145
+void DartField2Meaning( unsigned char field, unsigned char * factor,
146
+                                             unsigned char * value )
147
+{
148
+  switch( field ) {
149
+    case 0: *factor = 3; *value = 13; break;
150
+    case 1: *factor = 1; *value = 18; break;
151
+    case 2: *factor = 1; *value = 10; break;
152
+    case 3: *factor = 1; *value = 15; break;
153
+    case 4: *factor = 2; *value = 15; break;
154
+    case 5: *factor = 3; *value = 5; break;
155
+    case 6: *factor = 2; *value = 2; break;
156
+    case 7: *factor = 1; *value = 2; break;
157
+    case 8: *factor = 1; *value = 17; break;
158
+    case 9: *factor = 1; *value = 3; break;
159
+    case 10: *factor = 1; *value = 8; break;
160
+    case 11: *factor = 3; *value = 7; break;
161
+    case 12: *factor = 1; *value = 4; break;
162
+    case 13: *factor = 3; *value = 6; break;
163
+    case 14: *factor = 3; *value = 10; break;
164
+    case 15: *factor = 3; *value = 15; break;
165
+    case 16: *factor = 0; *value = 0; break;
166
+    case 17: *factor = 1; *value = 5; break;
167
+    case 18: *factor = 0; *value = 0; break;
168
+    case 19: *factor = 1; *value = 2; break;
169
+    case 20: *factor = 1; *value = 17; break;
170
+    case 21: *factor = 1; *value = 3; break;
171
+    case 22: *factor = 1; *value = 19; break;
172
+    case 23: *factor = 1; *value = 7; break;
173
+    case 24: *factor = 1; *value = 13; break;
174
+    case 25: *factor = 1; *value = 6; break;
175
+    case 26: *factor = 1; *value = 10; break;
176
+    case 27: *factor = 1; *value = 15; break;
177
+    case 28: *factor = 2; *value = 25; break;
178
+    case 29: *factor = 1; *value = 12; break;
179
+    case 30: *factor = 1; *value = 25; break;
180
+    case 31: *factor = 3; *value = 2; break;
181
+    case 32: *factor = 3; *value = 17; break;
182
+    case 33: *factor = 3; *value = 3; break;
183
+    case 34: *factor = 3; *value = 19; break;
184
+    case 35: *factor = 1; *value = 16; break;
185
+    case 36: *factor = 3; *value = 4; break;
186
+    case 37: *factor = 1; *value = 6; break;
187
+    case 38: *factor = 1; *value = 1; break;
188
+    case 39: *factor = 1; *value = 20; break;
189
+    case 40: *factor = 2; *value = 10; break;
190
+    case 41: *factor = 3; *value = 12; break;
191
+    case 42: *factor = 2; *value = 17; break;
192
+    case 43: *factor = 1; *value = 9; break;
193
+    case 44: *factor = 1; *value = 14; break;
194
+    case 45: *factor = 1; *value = 11; break;
195
+    case 46: *factor = 1; *value = 19; break;
196
+    case 47: *factor = 3; *value = 16; break;
197
+    case 48: *factor = 1; *value = 13; break;
198
+    case 49: *factor = 3; *value = 18; break;
199
+    case 50: *factor = 3; *value = 1; break;
200
+    case 51: *factor = 3; *value = 20; break;
201
+    case 52: *factor = 2; *value = 6; break;
202
+    case 53: *factor = 1; *value = 5; break;
203
+    case 54: *factor = 2; *value = 3; break;
204
+    case 55: *factor = 3; *value = 9; break;
205
+    case 56: *factor = 3; *value = 14; break;
206
+    case 57: *factor = 3; *value = 11; break;
207
+    case 58: *factor = 3; *value = 8; break;
208
+    case 59: *factor = 1; *value = 7; break;
209
+    case 60: *factor = 1; *value = 4; break;
210
+    case 61: *factor = 1; *value = 18; break;
211
+    case 62: *factor = 1; *value = 1; break;
212
+    case 63: *factor = 1; *value = 20; break;
213
+    case 64: *factor = 2; *value = 13; break;
214
+    case 65: *factor = 1; *value = 12; break;
215
+    case 66: *factor = 2; *value = 19; break;
216
+    case 67: *factor = 1; *value = 9; break;
217
+    case 68: *factor = 1; *value = 14; break;
218
+    case 69: *factor = 1; *value = 11; break;
219
+    case 70: *factor = 1; *value = 8; break;
220
+    case 71: *factor = 1; *value = 16; break;
221
+    case 72: *factor = 2; *value = 4; break;
222
+    case 73: *factor = 2; *value = 18; break;
223
+    case 74: *factor = 2; *value = 1; break;
224
+    case 75: *factor = 2; *value = 20; break;
225
+    case 76: *factor = 2; *value = 5; break;
226
+    case 77: *factor = 2; *value = 12; break;
227
+    case 78: *factor = 2; *value = 7; break;
228
+    case 79: *factor = 2; *value = 9; break;
229
+    case 80: *factor = 2; *value = 14; break;
230
+    case 81: *factor = 2; *value = 11; break;
231
+    case 82: *factor = 2; *value = 8; break;
232
+    case 83: *factor = 2; *value = 16; break;
233
+    default: *factor = 0; *value = 0; break;
234
+  }
235
+}
236
+
237
+// task procedure
238
+void DartTask( void ) // (extern)
239
+{
240
+  unsigned char factor, value, len, idx;
241
+  struct {
242
+    struct UdpPacket udp;
243
+    char text[6];
244
+  } data;
245
+
246
+  // a field has been hit
247
+  if( DartField < DartFields ) {
248
+
249
+    // convert field number to meaning
250
+    DartField2Meaning( DartField, &factor, &value );
251
+    if( factor <= 0 || value <= 0 ) {
252
+      debug_dart_printf( "field %u hit", DartField );
253
+    } else {
254
+      debug_dart_printf( "%ux%u (field %u) hit", factor, value, DartField );
255
+
256
+      // put into queue
257
+      idx = DartQueueEnd + 1;
258
+      if( idx >= DartQueueSize )
259
+        idx = 0;
260
+      if( idx != DartQueueStart ) {
261
+        DartQueue[DartQueueEnd] = DartField;
262
+        DartQueueEnd = idx;
263
+      }
264
+
265
+      // UDP packets have been requested
266
+      if( DartPort != 0 ) {
267
+        len = 0;
268
+        data.text[len++] = factor + '0';
269
+        data.text[len++] = 'x';
270
+        if( value >= 10 )
271
+          data.text[len++] = value / 10 + '0';
272
+        data.text[len++] = value % 10 + '0';
273
+        data.text[len++] = '\r';
274
+        data.text[len++] = '\n';
275
+        // send UDP packet
276
+        data.udp.UdpHdr.SrcPort = htons( 501 );
277
+        data.udp.UdpHdr.DestPort = htons( DartPort );
278
+        ip_cpy( data.udp.IpHdr.Dest, DartIp );
279
+        UdpSend( (unsigned char *)&data,
280
+                 sizeof( data ) - sizeof( data.text) + len );
281
+      }
282
+
283
+    }
284
+
285
+    // reset field
286
+    DartField = DartFields;
287
+    // disable dart board for a short time
288
+    DartDisable = DartDisableTicks;
289
+  }
290
+}
291
+
292
+// tick procedure - call every 200ms
293
+void DartTick200( void ) // (extern)
294
+{
295
+  // dart board is disabled
296
+  if( DartDisable > 0 ) {
297
+    // count down ticks
298
+    DartDisable--;
299
+    // disable period elapsed
300
+    if( DartDisable <= 0 ) {
301
+      // switch dart board to active
302
+      DartActive = 1;
303
+    }
304
+  }
305
+}
306
+
307
+// a dart request packet has been received
308
+void DartRequest( unsigned char ip[4], unsigned short port ) // (extern)
309
+{
310
+  // save new destination
311
+  ip_cpy( DartIp, ip );
312
+  DartPort = port;
313
+}
314
+
315
+// poll for dart event
316
+void DartPoll( unsigned char * factor, unsigned char * value ) // (extern)
317
+{
318
+  unsigned char field, fac, val;
319
+
320
+  // dart queue empty
321
+  if( DartQueueStart == DartQueueEnd ) {
322
+    *factor = 0;
323
+    *value = 0;
324
+    return;
325
+  }
326
+
327
+  // get entry from queue
328
+  field = DartQueue[DartQueueStart];
329
+  DartQueueStart++;
330
+  if( DartQueueStart >= DartQueueSize )
331
+    DartQueueStart = 0;
332
+
333
+  // convert field number to meaning
334
+  DartField2Meaning( field, &fac, &val );
335
+  if( factor <= 0 || value <= 0 ) {
336
+    debug_dart_printf( "from queue: field %u", field );
337
+  } else {
338
+    debug_dart_printf( "from queue: %ux%u (field %u)", fac, val, field );
339
+  }
340
+
341
+  *factor = fac;
342
+  *value = val;
343
+}
344
+
... ...
@@ -0,0 +1,27 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_dart
9
+#define INC_dart
10
+
11
+// initialize
12
+extern void DartInit( void );
13
+
14
+// task procedure
15
+extern void DartTask( void );
16
+
17
+// tick procedure - call every 200ms
18
+extern void DartTick200( void );
19
+
20
+// a dart request packet has been received
21
+extern void DartRequest( unsigned char ip[4], unsigned short port );
22
+
23
+// poll for dart event
24
+extern void DartPoll( unsigned char * factor, unsigned char * value );
25
+
26
+#endif // #ifdef INC_dart
27
+
... ...
@@ -0,0 +1,59 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_debug
9
+#define INC_debug
10
+
11
+#include <stdio.h>
12
+#include <avr/pgmspace.h>
13
+
14
+// debug configuration (what to debug)
15
+#define DEBUG_INIT 0
16
+#define DEBUG_EEPROM 0
17
+#define DEBUG_CF 0
18
+#define DEBUG_DART 1
19
+#define DEBUG_RTL8019 0
20
+#define DEBUG_ETHER 0
21
+#define DEBUG_ARP 0
22
+#define DEBUG_IP 0
23
+#define DEBUG_ICMP 0
24
+#define DEBUG_UDP 0
25
+#define DEBUG_DHCP 0
26
+#define DEBUG_TCP 0
27
+#define DEBUG_HTTP 1
28
+
29
+// debug version of printf
30
+#ifdef DEBUG
31
+#define debug_printf( fmt, arg... ) \
32
+  { \
33
+    static const PROGMEM char fmt_pgm[] = fmt"\r\n"; \
34
+    char fmt_buf[sizeof( fmt_pgm )]; \
35
+    for( int i = 0; i < sizeof( fmt_pgm ); i++ ) \
36
+      fmt_buf[i] = (char)pgm_read_byte_near( (uint16_t)fmt_pgm + i ); \
37
+    printf( fmt_buf, ##arg ); \
38
+  }
39
+#else
40
+#define debug_printf( fmt, arg... ) { }
41
+#endif
42
+
43
+// specialized debug versions of printf
44
+#define debug_specialized_printf( enabled, fmt, arg... ) { if( enabled ) debug_printf( fmt, ##arg ); }
45
+#define debug_init_printf( fmt, arg... ) debug_specialized_printf( DEBUG_INIT, "init: "fmt, ##arg )
46
+#define debug_eeprom_printf( fmt, arg... ) debug_specialized_printf( DEBUG_EEPROM, "eeprom: "fmt, ##arg )
47
+#define debug_cf_printf( fmt, arg... ) debug_specialized_printf( DEBUG_CF, "cf: "fmt, ##arg )
48
+#define debug_dart_printf( fmt, arg... ) debug_specialized_printf( DEBUG_DART, "dart: "fmt, ##arg )
49
+#define debug_rtl8019_printf( fmt, arg... ) debug_specialized_printf( DEBUG_RTL8019, "rtl8019: "fmt, ##arg )
50
+#define debug_ether_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ETHER, "ether: "fmt, ##arg )
51
+#define debug_arp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ARP, "arp: "fmt, ##arg )
52
+#define debug_ip_printf( fmt, arg... ) debug_specialized_printf( DEBUG_IP, "ip: "fmt, ##arg )
53
+#define debug_icmp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ICMP, "icmp: "fmt, ##arg )
54
+#define debug_udp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_UDP, "udp: "fmt, ##arg )
55
+#define debug_dhcp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_DHCP, "dhcp: "fmt, ##arg )
56
+#define debug_tcp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_TCP, "tcp: "fmt, ##arg )
57
+#define debug_http_printf( fmt, arg... ) debug_specialized_printf( DEBUG_HTTP, "http: "fmt, ##arg )
58
+
59
+#endif // #ifndef INC_debug
... ...
@@ -0,0 +1,496 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <string.h>
9
+
10
+#include "config.h"
11
+#include "checksum.h"
12
+#include "debug.h"
13
+#include "dhcp.h"
14
+#include "ethernet.h"
15
+#include "ip.h"
16
+#include "macros.h"
17
+#include "nethelp.h"
18
+#include "random.h"
19
+#include "udp.h"
20
+
21
+// configuration
22
+static const unsigned char DhcpRetrySecsMax = 10; // avarage timeout after which to retry DHCP action
23
+static const unsigned char DhcpRetriesMax = 5; // maximum number of retries before aborting DHCP action
24
+static const unsigned long DhcpLeaseRestMin = 300; // when to ask to extend lease
25
+static const unsigned char DhcpLeaseRenewFraction = 8; // to renw lease when only this fraction of lease is left
26
+
27
+// DHCP tick counter to get full seconds
28
+static unsigned char DhcpTicks = 0;
29
+
30
+// time of current DHCP action
31
+static unsigned char DhcpInProgress = 0; // if DHCP action is in progress
32
+static unsigned char DhcpRetries = 0; // number of retries left
33
+static unsigned char DhcpRetrySecs = 0; // rest of time for current retry
34
+
35
+// current XId
36
+static unsigned char DhcpHaveXId = 0; // if an XId exists at the moment
37
+static unsigned long DhcpXId = 0; // the current XId data
38
+static unsigned int DhcpXIdSecs = 0; // time of XId
39
+
40
+// DHCP server and lease time
41
+static unsigned char DhcpActive = 0; // if own IP is leased from DHCP
42
+static unsigned char DhcpServer[4]; // IP address of DHCP server own IP is leased from
43
+static unsigned long DhcpLeaseTime = 0; // total lease time
44
+static unsigned long DhcpLeaseRest = 0; // rest of lease time
45
+
46
+// send a DHCP packet
47
+// pData must point to a struct DhcpPacket with IpHdr.Dest, DhcpHdr.XId
48
+// DhcpHdr.Secs, DhcpHdr.Flags and DhcpHdr.YIAddr already initialized
49
+static void DhcpSend( unsigned char * pData, unsigned short Length ) // (extern)
50
+{
51
+  struct DhcpPacket * pDhcpPack;
52
+
53
+  // packet too short
54
+  if( Length < sizeof( struct DhcpPacket ) )
55
+    return;
56
+
57
+  // convert pointer to DHCP packet
58
+  // (this saves us from always casting pData)
59
+  pDhcpPack = (struct DhcpPacket *)pData;
60
+
61
+  debug_dhcp_printf( "send xid=%08lX len=%d",
62
+                     ntohl( pDhcpPack->DhcpHdr.XId ), Length );
63
+
64
+  // we are DHCP client
65
+  // - source port must be 68
66
+  // - destination port must be 67
67
+  pDhcpPack->UdpHdr.SrcPort = htons( 68 );
68
+  pDhcpPack->UdpHdr.DestPort = htons( 67 );
69
+  // set up DHCP header fields as client
70
+  pDhcpPack->DhcpHdr.Op = 1;
71
+  pDhcpPack->DhcpHdr.HType = 1;
72
+  pDhcpPack->DhcpHdr.HLen = 6;
73
+  pDhcpPack->DhcpHdr.HOps = 0;
74
+  memset( pDhcpPack->DhcpHdr.CIAddr, 0, 4 );
75
+  memset( pDhcpPack->DhcpHdr.SIAddr, 0, 4 );
76
+  memset( pDhcpPack->DhcpHdr.GIAddr, 0, 4 );
77
+  mac_cpy( pDhcpPack->DhcpHdr.CHAddr, ConfigMac );
78
+  memset( pDhcpPack->DhcpHdr.CHAddr + 6, 0, 10 );
79
+  memset( pDhcpPack->DhcpHdr.SName, 0, 64 );
80
+  memset( pDhcpPack->DhcpHdr.File, 0, 128 );
81
+  pDhcpPack->DhcpHdr.MCookie = htonl( 0x63825363 );
82
+
83
+  // send DHCP packet
84
+  UdpSend( pData, Length );
85
+}
86
+
87
+// send a DHCP discover
88
+static void DhcpDiscover( void )
89
+{
90
+  struct {
91
+    struct DhcpPacket DhcpPack;
92
+    unsigned char OptType[3];
93
+    unsigned char OptEnd[2];
94
+  } DhcpDiscover;
95
+
96
+  debug_dhcp_printf( "discover" );
97
+
98
+  ip_cpy( DhcpDiscover.DhcpPack.IpHdr.Dest, "\xFF\xFF\xFF\xFF" ); // broadcast
99
+  DhcpDiscover.DhcpPack.DhcpHdr.XId = htonl( DhcpXId );
100
+  DhcpDiscover.DhcpPack.DhcpHdr.Secs = htons( DhcpXIdSecs ); // use time of XId
101
+  DhcpDiscover.DhcpPack.DhcpHdr.Flags = htons( 0x8000 ); // broadcast
102
+  memset( DhcpDiscover.DhcpPack.DhcpHdr.YIAddr, 0, 4 );
103
+  DhcpDiscover.OptType[0] = 0x35; // DHCP discover
104
+  DhcpDiscover.OptType[1] = 0x01;
105
+  DhcpDiscover.OptType[2] = 0x01;
106
+  DhcpDiscover.OptEnd[0] = 0xFF; // end of options
107
+  DhcpDiscover.OptEnd[1] = 0x00;
108
+
109
+  DhcpSend( (unsigned char *)&DhcpDiscover, sizeof( DhcpDiscover ) );
110
+}
111
+
112
+// send a DHCP request
113
+static void DhcpRequest( void )
114
+{
115
+  struct {
116
+    struct DhcpPacket DhcpPack;
117
+    unsigned char OptType[3];
118
+    unsigned char OptReq[6];
119
+    unsigned char OptServer[6];
120
+    unsigned char OptEnd[2];
121
+  } DhcpRequest;
122
+
123
+  debug_dhcp_printf( "request ip=%d.%d.%d.%d",
124
+                     ConfigIp[0], ConfigIp[1], ConfigIp[2], ConfigIp[3] );
125
+
126
+  ip_cpy( DhcpRequest.DhcpPack.IpHdr.Dest, DhcpServer ); // send to DHCP server
127
+  DhcpRequest.DhcpPack.DhcpHdr.XId = htonl( DhcpXId );
128
+  DhcpRequest.DhcpPack.DhcpHdr.Secs = htons( DhcpXIdSecs ); // use time of XId
129
+  DhcpRequest.DhcpPack.DhcpHdr.Flags = htons( 0x0000 );
130
+  ip_cpy( DhcpRequest.DhcpPack.DhcpHdr.YIAddr, ConfigIp );
131
+  DhcpRequest.OptType[0] = 0x35; // DHCP request
132
+  DhcpRequest.OptType[1] = 0x01;
133
+  DhcpRequest.OptType[2] = 0x03;
134
+  DhcpRequest.OptReq[0] = 0x32; // requested IP
135
+  DhcpRequest.OptReq[1] = 0x04;
136
+  ip_cpy( &DhcpRequest.OptReq[2], ConfigIp );
137
+  DhcpRequest.OptServer[0] = 0x36; // DHCP server
138
+  DhcpRequest.OptServer[1] = 0x04;
139
+  ip_cpy( &DhcpRequest.OptServer[2], DhcpServer );
140
+  DhcpRequest.OptEnd[0] = 0xFF; // end of options
141
+  DhcpRequest.OptEnd[1] = 0x00;
142
+
143
+  DhcpSend( (unsigned char *)&DhcpRequest, sizeof( DhcpRequest ) );
144
+}
145
+
146
+// abort DHCP action
147
+static void DhcpAbort( void )
148
+{
149
+  // abort DHCP action
150
+  DhcpInProgress = 0;
151
+  DhcpRetries = 0;
152
+  DhcpRetrySecs = 0;
153
+
154
+  // forget XId
155
+  DhcpHaveXId = 0;
156
+  DhcpXId = 0;
157
+  DhcpXIdSecs = 0;
158
+
159
+  // give up IP address if it was leased
160
+  if( DhcpActive ) {
161
+    ip_cpy( ConfigIp, "\0\0\0\0" );
162
+    ip_cpy( ConfigMask, "\0\0\0\0" );
163
+    ip_cpy( ConfigGw, "\0\0\0\0" );
164
+    DhcpActive = 0;
165
+    DhcpLeaseTime = 0;
166
+    DhcpLeaseRest = 0;
167
+  }
168
+}
169
+
170
+// retry DHCP action
171
+static void DhcpRetry( void )
172
+{
173
+  // DHCP lease not active ---> re-send DHCP discover
174
+  if( ! DhcpActive ) {
175
+
176
+    // get time for next try
177
+    RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) );
178
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
179
+    // re-send DHCP discover
180
+    DhcpDiscover( );
181
+
182
+  }
183
+
184
+  // DHCP lease active and lease time almost over ---> re-send DHCP request
185
+  if( DhcpActive && (DhcpLeaseRest < DhcpLeaseRestMin ||
186
+                     DhcpLeaseRest < DhcpLeaseTime / DhcpLeaseRenewFraction) ) {
187
+
188
+    // get time for next try
189
+    RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) );
190
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
191
+    // re-send DHCP request
192
+    DhcpRequest( );
193
+
194
+  }
195
+}
196
+
197
+// start new DHCP action
198
+static void DhcpStart( void )
199
+{
200
+  // DHCP lease not active ---> DHCP discover
201
+  if( ! DhcpActive ) {
202
+
203
+    // DHCP operation starts
204
+    DhcpInProgress = 1;
205
+    DhcpRetries = DhcpRetriesMax;
206
+    RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) );
207
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
208
+    // get new XId
209
+    RandomGetData( (unsigned char *)&DhcpXId, sizeof( DhcpXId ) );
210
+    DhcpXIdSecs++;
211
+    DhcpHaveXId = 1;
212
+    // send DHCP discover
213
+    DhcpDiscover( );
214
+
215
+  }
216
+
217
+  // DHCP lease active and lease time almost over ---> DHCP request
218
+  if( DhcpActive && (DhcpLeaseRest < DhcpLeaseRestMin ||
219
+                     DhcpLeaseRest < DhcpLeaseTime / DhcpLeaseRenewFraction) ) {
220
+
221
+    // DHCP operation starts
222
+    DhcpInProgress = 1;
223
+    DhcpRetries = DhcpRetriesMax;
224
+    RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) );
225
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
226
+    // get new XId if none available
227
+    if( ! DhcpHaveXId ) {
228
+      RandomGetData( (unsigned char *)&DhcpXId, sizeof( DhcpXId ) );
229
+      DhcpXIdSecs++;
230
+      DhcpHaveXId = 1;
231
+    }
232
+    // send DHCP request
233
+    DhcpRequest( );
234
+
235
+  }
236
+}
237
+
238
+// tick procedure - every 1000ms
239
+static void DhcpTick1000( void )
240
+{
241
+  // DHCP operation in progress
242
+  if( DhcpInProgress ) {
243
+
244
+    // count down time of current try of current action
245
+    DhcpRetrySecs--;
246
+    if( DhcpRetrySecs <= 0 ) {
247
+
248
+      // count down retries
249
+      DhcpRetries--;
250
+
251
+      // no more retries left ---> abort, retry otherwise
252
+      if( DhcpRetries <= 0 )
253
+        DhcpAbort( );
254
+      else
255
+        DhcpRetry( );
256
+
257
+    }
258
+
259
+  }
260
+
261
+  // increase time of XId
262
+  DhcpXIdSecs++;
263
+
264
+  // dcrease remaining lease time
265
+  DhcpLeaseRest--;
266
+  // lease timed out ---> abort DHCP (will also invalidate IP)
267
+  if( DhcpLeaseRest <= 0 ) {
268
+    debug_dhcp_printf( "lease expired" );
269
+    DhcpAbort( );
270
+  }
271
+}
272
+
273
+// tick procedure - call every 200ms
274
+void DhcpTick200( void ) // (extern)
275
+{
276
+  // get 1 second interval
277
+  DhcpTicks++;
278
+  if( DhcpTicks >= 5 ) {
279
+    DhcpTicks = 0;
280
+    DhcpTick1000( );
281
+  }
282
+
283
+  // no DHCP operation in progress
284
+  if( ! DhcpInProgress ) {  
285
+    // DHCP lease active or no IP address ---> DHCP allowed (i.e. no static IP)
286
+    if( DhcpActive || ip_eq( ConfigIp, "\0\0\0\0" ) ) {
287
+      // start new DHCP action
288
+      DhcpStart( );
289
+    }
290
+  }
291
+}
292
+
293
+// process a received DHCP offer
294
+static void DhcpOffer( unsigned char addr[4], unsigned char mask[4],
295
+                       unsigned char gateway[4], unsigned long time,
296
+                       unsigned char server[4] )
297
+{
298
+  debug_dhcp_printf( "offer addr=%d.%d.%d.%d mask=%d.%d.%d.%d gw=%d.%d.%d.%d",
299
+                     addr[0], addr[1], addr[2], addr[3],
300
+                     mask[0], mask[1], mask[2], mask[3],
301
+                     gateway[0], gateway[1], gateway[2], gateway[3] );
302
+  debug_dhcp_printf( "offer time=%ld server=%d.%d.%d.%d",
303
+                     time, server[0], server[1], server[2], server[3] );
304
+
305
+  // use this IP address, mask and gateway
306
+  ip_cpy( ConfigIp, addr );
307
+  ip_cpy( ConfigMask, mask );
308
+  ip_cpy( ConfigGw, gateway );
309
+
310
+  // store DHCP server and lease time
311
+  DhcpActive = 1;
312
+  ip_cpy( DhcpServer, server );
313
+  DhcpLeaseTime = time;
314
+  DhcpLeaseRest = DhcpLeaseRestMin; // schedule DHCP request
315
+
316
+  // DHCP action finished
317
+  DhcpInProgress = 0;
318
+  DhcpRetries = 0;
319
+  DhcpRetrySecs = 0;
320
+}
321
+
322
+// process a received DHCP ack
323
+static void DhcpAck( unsigned char addr[4], unsigned char mask[4],
324
+                     unsigned char gateway[4], unsigned long time,
325
+                     unsigned char server[4] )
326
+{
327
+  debug_dhcp_printf( "ack addr=%d.%d.%d.%d mask=%d.%d.%d.%d gw=%d.%d.%d.%d",
328
+                     addr[0], addr[1], addr[2], addr[3],
329
+                     mask[0], mask[1], mask[2], mask[3],
330
+                     gateway[0], gateway[1], gateway[2], gateway[3] );
331
+  debug_dhcp_printf( "ack time=%ld server=%d.%d.%d.%d",
332
+                     time, server[0], server[1], server[2], server[3] );
333
+
334
+  // check if IP address, mask and gateway match
335
+  if( ! ip_eq( ConfigIp, addr ) ||
336
+      ! ip_eq( ConfigMask, mask ) ||
337
+      ! ip_eq( ConfigGw, gateway ) )
338
+  {
339
+    // mismatch ---> something is wrong, abort
340
+    DhcpAbort( );
341
+    return;
342
+  }
343
+
344
+  // store DHCP server and lease time
345
+  DhcpActive = 1;
346
+  ip_cpy( DhcpServer, server );
347
+  DhcpLeaseTime = time;
348
+  DhcpLeaseRest = time;
349
+
350
+  // DHCP action finished
351
+  DhcpInProgress = 0;
352
+  DhcpRetries = 0;
353
+  DhcpRetrySecs = 0;
354
+
355
+  // forget XId
356
+  DhcpHaveXId = 0;
357
+  DhcpXId = 0;
358
+  DhcpXIdSecs = 0;
359
+}
360
+
361
+// process a received DHCP packet
362
+void DhcpRecv( unsigned char * pData, unsigned short Length ) // (extern)
363
+{
364
+  struct DhcpPacket * pDhcpPack;
365
+  unsigned char *opt_ptr, tag, len;
366
+  unsigned short opt_len;
367
+  unsigned char type;
368
+  unsigned char have_mask, mask[4], have_gateway, gateway[4];
369
+  unsigned char have_time, have_server, server[4];
370
+  unsigned long time;
371
+
372
+  // packet too short
373
+  if( Length < sizeof( struct DhcpPacket ) )
374
+    return;
375
+
376
+  // convert pointer to UDP packet
377
+  // (this saves us from always casting pData)
378
+  pDhcpPack = (struct DhcpPacket *)pData;
379
+
380
+  // we are DHCP client
381
+  // - source port must be 67
382
+  // - destination port must be 68
383
+  if( pDhcpPack->UdpHdr.SrcPort != htons( 67 ) ||
384
+      pDhcpPack->UdpHdr.DestPort != htons( 68 ) )
385
+    return;
386
+  // check DHCP fields
387
+  if( pDhcpPack->DhcpHdr.Op != 2 ||
388
+      pDhcpPack->DhcpHdr.HType != 1 ||
389
+      pDhcpPack->DhcpHdr.HLen != 6 ||
390
+      pDhcpPack->DhcpHdr.HOps != 0 ||
391
+      pDhcpPack->DhcpHdr.MCookie != htonl( 0x63825363 ) )
392
+    return;
393
+
394
+  debug_dhcp_printf( "recv xid=%08lX len=%d",
395
+                     ntohl( pDhcpPack->DhcpHdr.XId ), Length );
396
+
397
+  // check XId
398
+  if( ! DhcpHaveXId || ntohl( pDhcpPack->DhcpHdr.XId ) != DhcpXId )
399
+    return;
400
+
401
+  // get options
402
+  opt_ptr = pData + sizeof( struct DhcpPacket );
403
+  opt_len = Length - sizeof( struct DhcpPacket );
404
+
405
+  // parse options
406
+  type = 0;
407
+  have_mask = 0;
408
+  have_gateway = 0;
409
+  time = 0;
410
+  have_time = 0;
411
+  have_server = 0;
412
+  while( opt_len > 2 ) {
413
+
414
+    // get tag and length
415
+    tag = *opt_ptr++;
416
+    len = *opt_ptr++;
417
+    if( opt_len < 2 + len )
418
+      break;
419
+
420
+    // get option
421
+    switch( tag ) {
422
+
423
+      // type
424
+      case 0x35:
425
+        if( len >= 1 )
426
+          type = opt_ptr[0];
427
+        break;
428
+
429
+      // subnet mask
430
+      case 0x01:
431
+        if( len >= 4 )
432
+          memcpy( mask, opt_ptr, 4 );
433
+          have_mask = 1;
434
+        break;
435
+
436
+      // gateway
437
+      case 0x03:
438
+        if( len >= 4 ) {
439
+          memcpy( gateway, opt_ptr, 4 );
440
+          have_gateway = 1;
441
+        }
442
+        break;
443
+
444
+      // lease time
445
+      case 0x33:
446
+        if( len >= 4 ) {
447
+          time = ntohl( *(unsigned long *)opt_ptr );
448
+          have_time = 1;
449
+        }
450
+        break;
451
+
452
+      // DHCP server
453
+      case 0x36:
454
+        if( len >= 4 ) {
455
+          memcpy( server, opt_ptr, 4 );
456
+          have_server = 1;
457
+        }
458
+        break;
459
+
460
+    }
461
+
462
+    // skip option
463
+    opt_ptr += len;
464
+    opt_len -= len;
465
+  }
466
+
467
+  debug_dhcp_printf( "type=%d%s%s%s%s", type,
468
+                     have_mask ? " mask" : "",
469
+                     have_gateway ? " gateway" : "",
470
+                     have_time ? " time" : "",
471
+                     have_server ? " server" : "" );
472
+
473
+  // fill in server from source address if not present
474
+  if( ! have_server ) {
475
+    ip_cpy( server, pDhcpPack->IpHdr.Src );
476
+    have_server = 1;
477
+  }
478
+
479
+  // process DHCP response
480
+  switch( type ) {
481
+
482
+    // DHCP offer
483
+    case 2:
484
+      if( have_mask && have_gateway && have_time && have_server )
485
+        DhcpOffer( pDhcpPack->DhcpHdr.YIAddr, mask, gateway, time, server );
486
+      break;
487
+
488
+    // DHCP ack
489
+    case 5:
490
+      if( have_mask && have_gateway && have_time && have_server )
491
+        DhcpAck( pDhcpPack->DhcpHdr.YIAddr, mask, gateway, time, server );
492
+      break;
493
+
494
+  }
495
+}
496
+
... ...
@@ -0,0 +1,51 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_dhcp
9
+#define INC_dhcp
10
+
11
+#include "ethernet.h"
12
+#include "ip.h"
13
+#include "udp.h"
14
+
15
+// header of an DHCP packet
16
+struct DhcpHeader
17
+{
18
+  unsigned char Op;
19
+  unsigned char HType;
20
+  unsigned char HLen;
21
+  unsigned char HOps;
22
+  unsigned long XId;
23
+  unsigned int Secs;
24
+  unsigned int Flags;
25
+  unsigned char CIAddr[4];
26
+  unsigned char YIAddr[4];
27
+  unsigned char SIAddr[4];
28
+  unsigned char GIAddr[4];
29
+  unsigned char CHAddr[16];
30
+  unsigned char SName[64];
31
+  unsigned char File[128];
32
+  unsigned long MCookie;
33
+};
34
+
35
+// a DHCP packet
36
+struct DhcpPacket
37
+{
38
+  struct EthernetHeader EthHdr;
39
+  struct IpHeader IpHdr;
40
+  struct UdpHeader UdpHdr;
41
+  struct DhcpHeader DhcpHdr;
42
+};
43
+
44
+// tick procedure - call every 200ms
45
+extern void DhcpTick200( void );
46
+
47
+// process a received UDP packet
48
+extern void DhcpRecv( unsigned char * pData, unsigned short Length );
49
+
50
+#endif // #ifdef INC_dhcp
51
+
... ...
@@ -0,0 +1,217 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/interrupt.h>
9
+#include <avr/eeprom.h>
10
+
11
+#include "config.h"
12
+#include "debug.h"
13
+#include "eeprom.h"
14
+#include "macros.h"
15
+#include "rtl8019.h"
16
+
17
+// flags for what needs to be written to the EEPROM
18
+unsigned char EepromNeedWrite = 0x00; // (extern)
19
+
20
+// writing what where
21
+unsigned char EepromWriteFlags = 0; // some flags
22
+#define EepromWriteFlagActive 0x01 // if writing something to EEPROM
23
+#define EepromWriteFlagCheck 0x02 // if writing check byte to EEPROM
24
+unsigned char * pEepromWriteSrc; // pointer to source data
25
+unsigned short EepromWriteDestAddr; // destination address in EEPROM
26
+unsigned char EepromWriteCnt; // number of bytes still to write
27
+
28
+// memory layout of EEPROM
29
+// - every byte B is stored as B, ~B for data safety
30
+// - so everythings needs double space
31
+#define EEPROM_ADDR_MAC 0
32
+#define EEPROM_ADDR_IP (EEPROM_ADDR_MAC + 2 * sizeof( ConfigMac ))
33
+#define EEPROM_ADDR_MASK (EEPROM_ADDR_IP + 2 * sizeof( ConfigIp ))
34
+#define EEPROM_ADDR_GW (EEPROM_ADDR_MASK + 2 * sizeof( ConfigMask ))
35
+#define EEPROM_ADDR_S8P_PORT (EEPROM_ADDR_GW + 2 * sizeof( ConfigGw ))
36
+#define EEPROM_ADDR_S8P_KEY (EEPROM_ADDR_S8P_PORT + 2 * sizeof( ConfigS8pPort ))
37
+#define EEPROM_ADDR_HTTP_PORT (EEPROM_ADDR_S8P_KEY + 2 * sizeof( ConfigS8pKey ))
38
+#define EEPROM_ADDR_DEF_OUT (EEPROM_ADDR_HTTP_PORT + 2 * sizeof( ConfigHttpPort ))
39
+#define EEPROM_ADDR_FreeFromHere (EEPROM_ADDR_DEF_OUT + 2 * sizeof( ConfigDefOut ))
40
+
41
+// get configuration from EEPROM - helper function
42
+// checks data in EEPROM
43
+// gets data from EEPROM
44
+// returns 0x00 if successful
45
+static inline unsigned char EepromGetConfigHelp( unsigned short SrcAddr, unsigned char * pDest, unsigned char Len )
46
+{
47
+  unsigned char i, b;
48
+
49
+  // check data in EEPROM
50
+  EEAR = SrcAddr;
51
+  for( i = 0; i < Len; i++ )
52
+  {
53
+    // read byte
54
+    bit_set( EECR, EERE );
55
+    b = EEDR;
56
+    EEAR++;
57
+    // XOR in check byte
58
+    bit_set( EECR, EERE );
59
+    b ^= EEDR;
60
+    EEAR++;
61
+    // XOR result must be 0xFF
62
+    if( b != 0xFF )
63
+      return 0x01; // error
64
+  }
65
+
66
+  // read data from EEPROM
67
+  EEAR = SrcAddr;
68
+  for( ; Len > 0; Len-- )
69
+  {
70
+    // read byte
71
+    bit_set( EECR, EERE );
72
+    *(pDest++) = EEDR;
73
+    EEAR += 2; // skip check byte
74
+  }
75
+  return 0x00; // success
76
+}
77
+
78
+// get configuration from EEPROM
79
+void EepromGetConfig( void ) // (extern)
80
+{
81
+  // get MAC
82
+  if( EepromGetConfigHelp( EEPROM_ADDR_MAC, ConfigMac, sizeof( ConfigMac ) ) == 0x00 )
83
+    // re-initialize RTL8019
84
+    RtlReinit( );
85
+
86
+  // get IP, subnet mask, gateway IP
87
+  EepromGetConfigHelp( EEPROM_ADDR_IP, ConfigIp, sizeof( ConfigIp ) );
88
+  EepromGetConfigHelp( EEPROM_ADDR_MASK, ConfigMask, sizeof( ConfigMask ) );
89
+  EepromGetConfigHelp( EEPROM_ADDR_GW, ConfigGw, sizeof( ConfigGw ) );
90
+
91
+  // get port for S8P
92
+  EepromGetConfigHelp( EEPROM_ADDR_S8P_PORT, (unsigned char *)&ConfigS8pPort, sizeof( ConfigS8pPort ) );
93
+
94
+  // get symmetric key for S8P
95
+  EepromGetConfigHelp( EEPROM_ADDR_S8P_KEY, ConfigS8pKey, sizeof( ConfigS8pKey ) );
96
+
97
+  // get port for webserver
98
+  EepromGetConfigHelp( EEPROM_ADDR_HTTP_PORT, (unsigned char *)&ConfigHttpPort, sizeof( ConfigHttpPort ) );
99
+
100
+  // get default output state
101
+  EepromGetConfigHelp( EEPROM_ADDR_DEF_OUT, &ConfigDefOut, sizeof( ConfigDefOut ) );
102
+}
103
+
104
+// task function to do the work - call from main loop
105
+void EepromTask( void ) // (extern)
106
+{
107
+  // not writing something to EEPROM
108
+  if( ! (EepromWriteFlags & EepromWriteFlagActive) )
109
+  {
110
+    // MAC needs to be written
111
+    if( EepromNeedWrite & EepromNeedWriteMac )
112
+    {
113
+      EepromNeedWrite &= ~EepromNeedWriteMac;
114
+      pEepromWriteSrc = ConfigMac;
115
+      EepromWriteDestAddr = EEPROM_ADDR_MAC;
116
+      EepromWriteCnt = sizeof( ConfigMac );
117
+      EepromWriteFlags = EepromWriteFlagActive;
118
+    }
119
+    // IP needs to be written
120
+    else if( EepromNeedWrite & EepromNeedWriteIp )
121
+    {
122
+      EepromNeedWrite &= ~EepromNeedWriteIp;
123
+      pEepromWriteSrc = ConfigIp;
124
+      EepromWriteDestAddr = EEPROM_ADDR_IP;
125
+      EepromWriteCnt = sizeof( ConfigIp );
126
+      EepromWriteFlags = EepromWriteFlagActive;
127
+    }
128
+    // subnet mask needs to be written
129
+    else if( EepromNeedWrite & EepromNeedWriteMask )
130
+    {
131
+      EepromNeedWrite &= ~EepromNeedWriteMask;
132
+      pEepromWriteSrc = ConfigMask;
133
+      EepromWriteDestAddr = EEPROM_ADDR_MASK;
134
+      EepromWriteCnt = sizeof( ConfigMask );
135
+      EepromWriteFlags = EepromWriteFlagActive;
136
+    }
137
+    // gateway IP needs to be written
138
+    else if( EepromNeedWrite & EepromNeedWriteGw )
139
+    {
140
+      EepromNeedWrite &= ~EepromNeedWriteGw;
141
+      pEepromWriteSrc = ConfigGw;
142
+      EepromWriteDestAddr = EEPROM_ADDR_GW;
143
+      EepromWriteCnt = sizeof( ConfigGw );
144
+      EepromWriteFlags = EepromWriteFlagActive;
145
+    }
146
+    // port for S8P needs to be written
147
+    else if( EepromNeedWrite & EepromNeedWriteS8pPort )
148
+    {
149
+      EepromNeedWrite &= ~EepromNeedWriteS8pPort;
150
+      pEepromWriteSrc = (unsigned char *)&ConfigS8pPort;
151
+      EepromWriteDestAddr = EEPROM_ADDR_S8P_PORT;
152
+      EepromWriteCnt = sizeof( ConfigS8pPort );
153
+      EepromWriteFlags = EepromWriteFlagActive;
154
+    }
155
+    // symmetric key for S8P needs to be written
156
+    else if( EepromNeedWrite & EepromNeedWriteS8pKey )
157
+    {
158
+      EepromNeedWrite &= ~EepromNeedWriteS8pKey;
159
+      pEepromWriteSrc = ConfigS8pKey;
160
+      EepromWriteDestAddr = EEPROM_ADDR_S8P_KEY;
161
+      EepromWriteCnt = sizeof( ConfigS8pKey );
162
+      EepromWriteFlags = EepromWriteFlagActive;
163
+    }
164
+    // port for webserver needs to be written
165
+    else if( EepromNeedWrite & EepromNeedWriteHttpPort )
166
+    {
167
+      EepromNeedWrite &= ~EepromNeedWriteHttpPort;
168
+      pEepromWriteSrc = (unsigned char *)&ConfigHttpPort;
169
+      EepromWriteDestAddr = EEPROM_ADDR_HTTP_PORT;
170
+      EepromWriteCnt = sizeof( ConfigHttpPort );
171
+      EepromWriteFlags = EepromWriteFlagActive;
172
+    }
173
+    // if default output state needs to be written
174
+    else if( EepromNeedWrite & EepromNeedWriteDefOut )
175
+    {
176
+      EepromNeedWrite &= ~EepromNeedWriteDefOut;
177
+      pEepromWriteSrc = &ConfigDefOut;
178
+      EepromWriteDestAddr = EEPROM_ADDR_DEF_OUT;
179
+      EepromWriteCnt = sizeof( ConfigDefOut );
180
+      EepromWriteFlags = EepromWriteFlagActive;
181
+    }
182
+    // nothing needs to be written
183
+    else
184
+      return;
185
+
186
+    debug_eeprom_printf( "write adr=0x%04X len=%u", EepromWriteDestAddr, EepromWriteCnt );
187
+  }
188
+
189
+  // EEPROM still busy
190
+  if( bit_is_set( EECR, EEWE ) )
191
+    // try again later
192
+    return;
193
+
194
+  // disable interrupts
195
+  cli( );
196
+
197
+  // get address in EEPROM and data to write
198
+  EEAR = EepromWriteDestAddr++;
199
+  if( EepromWriteFlags & EepromWriteFlagCheck ) // check byte
200
+  {
201
+    EEDR = ~*(pEepromWriteSrc++); // invert and advance source pointer
202
+    EepromWriteCnt--; // count down number of bytes to write
203
+    if( EepromWriteCnt <= 0 ) // finished
204
+      EepromWriteFlags &= ~EepromWriteFlagActive;
205
+  }
206
+  else // not check byte
207
+    EEDR = *pEepromWriteSrc; // use data byte as it is
208
+  EepromWriteFlags ^= EepromWriteFlagCheck; // toggle check byte bit
209
+
210
+  // initiate write to EEPROM
211
+  bit_set( EECR, EEMWE );
212
+  bit_set( EECR, EEWE );
213
+
214
+  // enable interrupts
215
+  sei( );
216
+}
217
+
... ...
@@ -0,0 +1,28 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_eeprom
9
+#define INC_eeprom
10
+
11
+// flags for what needs to be written to the EEPROM
12
+#define EepromNeedWriteMac 0x01
13
+#define EepromNeedWriteIp 0x02
14
+#define EepromNeedWriteMask 0x04
15
+#define EepromNeedWriteGw 0x08
16
+#define EepromNeedWriteS8pPort 0x10
17
+#define EepromNeedWriteS8pKey 0x20
18
+#define EepromNeedWriteHttpPort 0x40
19
+#define EepromNeedWriteDefOut 0x80
20
+extern unsigned char EepromNeedWrite;
21
+
22
+// get configuration from EEPROM
23
+extern void EepromGetConfig( void );
24
+
25
+// task function to do the work - call from main loop
26
+extern void EepromTask( void );
27
+
28
+#endif // #ifndef INC_eeprom
... ...
@@ -0,0 +1,74 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include "arp.h"
9
+#include "config.h"
10
+#include "debug.h"
11
+#include "ethernet.h"
12
+#include "ip.h"
13
+#include "macros.h"
14
+#include "nethelp.h"
15
+#include "rtl8019.h"
16
+
17
+// process a received ethernet packet
18
+void EthernetRecv( unsigned char * pData, unsigned short Length ) // (extern)
19
+{
20
+  struct EthernetPacket * pEthPack;
21
+
22
+  // packet too short
23
+  if( Length < sizeof( struct EthernetPacket ) )
24
+    return;
25
+
26
+  // convert pointer to ethernet packet
27
+  // (this saves us from always casting pData)
28
+  pEthPack = (struct EthernetPacket *)pData;
29
+
30
+  debug_ether_printf( "recv len=%u type=0x%04X src=%02X:%02X:%02X:%02X:%02X:%02X",
31
+                      Length, ntohs( pEthPack->EthHdr.Type ),
32
+                      pEthPack->EthHdr.Src[0], pEthPack->EthHdr.Src[1], pEthPack->EthHdr.Src[2],
33
+                      pEthPack->EthHdr.Src[3], pEthPack->EthHdr.Src[4], pEthPack->EthHdr.Src[5] ); 
34
+
35
+  // branch according to packet type
36
+  switch( pEthPack->EthHdr.Type )
37
+  {
38
+    // ARP
39
+    case htons( 0x0806 ):
40
+      ArpRecv( pData, Length );
41
+      break;
42
+    // IP
43
+    case htons( 0x0800 ):
44
+      IpRecv( pData, Length );
45
+      break;
46
+  }
47
+}
48
+
49
+// send an ethernet packet
50
+// pData must point to a struct EthernetPacket with EthHdr.Dest and EthHdr.Type already initialized
51
+void EthernetSend( unsigned char * pData, unsigned short Length ) // (extern)
52
+{
53
+  struct EthernetPacket * pEthPack;
54
+
55
+  // packet too short
56
+  if( Length < sizeof( struct EthernetPacket ) )
57
+    return;
58
+
59
+  // convert pointer to ethernet packet
60
+  // (this saves us from always casting pData)
61
+  pEthPack = (struct EthernetPacket *)pData;
62
+
63
+  debug_ether_printf( "send len=%u type=0x%04X dest=%02X:%02X:%02X:%02X:%02X:%02X",
64
+                      Length, ntohs( pEthPack->EthHdr.Type ),
65
+                      pEthPack->EthHdr.Dest[0], pEthPack->EthHdr.Dest[1], pEthPack->EthHdr.Dest[2],
66
+                      pEthPack->EthHdr.Dest[3], pEthPack->EthHdr.Dest[4], pEthPack->EthHdr.Dest[5] ); 
67
+
68
+  // fill in source address
69
+  mac_cpy( pEthPack->EthHdr.Src, ConfigMac );
70
+
71
+  // send packet
72
+  RtlWriteFrame( (unsigned char *)pData, Length );
73
+}
74
+
... ...
@@ -0,0 +1,33 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_ethernet
9
+#define INC_ethernet
10
+
11
+// header of an ethernet packet
12
+struct EthernetHeader
13
+{
14
+  unsigned char Dest[6];
15
+  unsigned char Src[6];
16
+  unsigned short Type;
17
+};
18
+
19
+// an ethernet packet
20
+struct EthernetPacket
21
+{
22
+  struct EthernetHeader EthHdr;
23
+};
24
+
25
+// process a received ethernet packet
26
+extern void EthernetRecv( unsigned char * pData, unsigned short Length );
27
+
28
+// send an ethernet packet
29
+// pData must point to a struct EthernetPacket with EthHdr.Dest and EthHdr.Type already initialized
30
+extern void EthernetSend( unsigned char * pData, unsigned short Length );
31
+
32
+#endif // #ifdef INC_ethernet
33
+
... ...
@@ -0,0 +1,579 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <string.h>
9
+#include <avr/pgmspace.h>
10
+
11
+#include "dart.h"
12
+#include "debug.h"
13
+#include "http.h"
14
+#include "macros.h"
15
+#include "tcp.h"
16
+
17
+// receive states while parsing HTTP request
18
+#define HTTP_RCV_CMD 0 // receiving HTTP command (e.g. GET)
19
+#define HTTP_RCV_FILE 1 // receiving filename
20
+#define HTTP_RCV_LEN 2 // receiving content length
21
+#define HTTP_RCV_HDR_END 3 // receiving header until end
22
+#define HTTP_RCV_DATA 4 // receiving post data
23
+#define HTTP_RCV_DONE 5 // receiving completed
24
+
25
+// knwon HTTP commands
26
+#define HTTP_CMD_UNKNOWN 0 // unknown HTTP command
27
+#define HTTP_CMD_GET 1 // GET command
28
+#define HTTP_CMD_POST 2 // POST command
29
+
30
+// files available using HTTP
31
+#define HTTP_FILE_NOT_FOUND 0 // file not found file
32
+#define HTTP_FILE_INDEX 1 // index file
33
+#define HTTP_FILE_DART 10 // dartboard response, still waiting
34
+#define HTTP_FILE_DART_NO 11 // dartboard response, no hit
35
+#define HTTP_FILE_DART_1D 12 // dartboard response, 1 digit hit
36
+#define HTTP_FILE_DART_2D 13 // dartboard response, 2 digit hit
37
+
38
+// maximum HTTP/SOAP timeout (must be less than TCP timeout)
39
+#define HttpMaxTimeout 45
40
+
41
+// content of webpages and strings to fill in for variables
42
+#include "http_content.inc"
43
+
44
+// table with HTTP connections
45
+struct HttpConnection
46
+{
47
+  unsigned char ConnNo; // number of the TCP connection, 0xFF is unused
48
+  unsigned long RcvCnt; // number of received bytes on connection
49
+  unsigned char RcvState; // what is being received at the moment
50
+  unsigned char RcvBuf[32]; // receive buffer
51
+  unsigned char RcvBufLen; // length of data in receive buffer
52
+  unsigned char Command; // the command the client issued
53
+  char PreHttp1; // flag if a HTTP version before 1.0 is used
54
+  unsigned char File; // the file the client requested
55
+  unsigned long DataLen; // length of the data the client posts
56
+  unsigned char DataTag; // flag if currently in a tag in HTTP request body
57
+  unsigned long DataValue; // numeric value posted in HTTP request body
58
+  uint16_t pSndData; // the data to send (progmem pointer)
59
+  unsigned short SndDataLen; // the length of the data to send
60
+  char Vars; // flag if to interpret variables
61
+  unsigned char DartFactor; // factor hit on dart board to transmit
62
+  unsigned char DartValue; // value hit on dart board to transmit
63
+} HttpConns[4];
64
+
65
+// parse HTTP command
66
+static void HttpParseCommand( struct HttpConnection * pConn )
67
+{
68
+  // GET command
69
+  if( pConn->RcvBufLen == 3 && strncasecmp( (const char *)pConn->RcvBuf, "GET", 3 ) == 0 )
70
+    pConn->Command = HTTP_CMD_GET;
71
+  // POST command
72
+  else if( pConn->RcvBufLen == 4 && strncasecmp( (const char *)pConn->RcvBuf, "POST", 4 ) == 0 )
73
+  {
74
+    pConn->Command = HTTP_CMD_POST;
75
+    pConn->DataLen = 0;
76
+  }
77
+  // unknown command is the default
78
+  else
79
+    pConn->Command = HTTP_CMD_UNKNOWN;
80
+}
81
+
82
+// parse HTTP file
83
+static void HttpParseFile( struct HttpConnection * pConn )
84
+{
85
+  // index file
86
+  if( (pConn->RcvBufLen == 1 && strncasecmp( (const char *)pConn->RcvBuf, "/", 1 ) == 0) ||
87
+      (pConn->RcvBufLen == 2 && strncasecmp( (const char *)pConn->RcvBuf, "/i", 2 ) == 0) )
88
+    pConn->File = HTTP_FILE_INDEX;
89
+  // dartboard response
90
+  else if( pConn->RcvBufLen == 5 && strncasecmp( (const char *)pConn->RcvBuf, "/dart", 5 ) == 0 )
91
+    pConn->File = HTTP_FILE_DART;
92
+  // error file is the default
93
+  else
94
+    pConn->File = HTTP_FILE_NOT_FOUND;
95
+}
96
+
97
+// process HTTP request
98
+static void HttpProcessRequest( struct HttpConnection * pConn )
99
+{
100
+  // different commands
101
+  switch( pConn->Command )
102
+  {
103
+
104
+    case HTTP_CMD_GET:
105
+    case HTTP_CMD_POST:
106
+
107
+      // different files
108
+      switch( pConn->File )
109
+      {
110
+
111
+        case HTTP_FILE_INDEX:
112
+          if( pConn->PreHttp1 )
113
+          {
114
+            pConn->pSndData = (uint16_t)HttpIndex + HttpIndexHeaderSize;
115
+            pConn->SndDataLen = sizeof( HttpIndex ) - 1 - HttpIndexHeaderSize;
116
+          }
117
+          else
118
+          {
119
+            pConn->pSndData = (uint16_t)HttpIndex;
120
+            pConn->SndDataLen = sizeof( HttpIndex ) - 1;
121
+          }
122
+          pConn->Vars = 0;
123
+          break;
124
+
125
+        case HTTP_FILE_DART_NO:
126
+          if( pConn->PreHttp1 )
127
+          {
128
+            pConn->pSndData = (uint16_t)HttpDartNo + HttpDartNoHeaderSize;
129
+            pConn->SndDataLen = sizeof( HttpDartNo ) - 1 - HttpDartNoHeaderSize;
130
+          }
131
+          else
132
+          {
133
+            pConn->pSndData = (uint16_t)HttpDartNo;
134
+            pConn->SndDataLen = sizeof( HttpDartNo ) - 1;
135
+          }
136
+          pConn->Vars = 1;
137
+          break;
138
+
139
+        case HTTP_FILE_DART_1D:
140
+          if( pConn->PreHttp1 )
141
+          {
142
+            pConn->pSndData = (uint16_t)HttpDart1d + HttpDart1dHeaderSize;
143
+            pConn->SndDataLen = sizeof( HttpDart1d ) - 1 - HttpDart1dHeaderSize;
144
+          }
145
+          else
146
+          {
147
+            pConn->pSndData = (uint16_t)HttpDart1d;
148
+            pConn->SndDataLen = sizeof( HttpDart1d ) - 1;
149
+          }
150
+          pConn->Vars = 1;
151
+          break;
152
+
153
+        case HTTP_FILE_DART_2D:
154
+          if( pConn->PreHttp1 )
155
+          {
156
+            pConn->pSndData = (uint16_t)HttpDart2d + HttpDart2dHeaderSize;
157
+            pConn->SndDataLen = sizeof( HttpDart2d ) - 1 - HttpDart2dHeaderSize;
158
+          }
159
+          else
160
+          {
161
+            pConn->pSndData = (uint16_t)HttpDart2d;
162
+            pConn->SndDataLen = sizeof( HttpDart2d ) - 1;
163
+          }
164
+          pConn->Vars = 1;
165
+          break;
166
+
167
+        case HTTP_FILE_NOT_FOUND:
168
+        default:
169
+          if( pConn->PreHttp1 )
170
+          {
171
+            pConn->pSndData = (uint16_t)HttpNotFound + HttpNotFoundHeaderSize;
172
+            pConn->SndDataLen = sizeof( HttpNotFound ) - 1 - HttpNotFoundHeaderSize;
173
+          }
174
+          else
175
+          {
176
+            pConn->pSndData = (uint16_t)HttpNotFound;
177
+            pConn->SndDataLen = sizeof( HttpNotFound ) - 1;
178
+          }
179
+          pConn->Vars = 0;
180
+
181
+      } // switch( pConn->File )
182
+      break;
183
+
184
+    case HTTP_CMD_UNKNOWN:
185
+    default:
186
+      if( pConn->PreHttp1 )
187
+      {
188
+        pConn->pSndData = (uint16_t)HttpBadRequest + HttpBadRequestHeaderSize;
189
+        pConn->SndDataLen = sizeof( HttpBadRequest ) - 1 - HttpBadRequestHeaderSize;
190
+      }
191
+      else
192
+      {
193
+        pConn->pSndData = (uint16_t)HttpBadRequest;
194
+        pConn->SndDataLen = sizeof( HttpBadRequest ) - 1;
195
+      }
196
+      pConn->Vars = 0;
197
+
198
+  } // switch( pConn->Command )
199
+}
200
+
201
+// called when connection is established
202
+void HttpConnect( unsigned char ConnNo )
203
+{
204
+  unsigned char i;
205
+  struct HttpConnection * pConn;
206
+
207
+  // find connection in table (in case TCP calls us twice, this should never happen)
208
+  for( i = 0; i < count( HttpConns ); i++ )
209
+    if( HttpConns[i].ConnNo == ConnNo )
210
+      break;
211
+  // connection not found
212
+  if( i >= count( HttpConns ) )
213
+  {
214
+    // find a free entry
215
+    for( i = 0; i < count( HttpConns ); i++ )
216
+      if( HttpConns[i].ConnNo == 0xFF )
217
+        break;
218
+    if( i >= count( HttpConns ) ) // no free entry found
219
+      return; // ignore this connection (will be closed in first call of HttpSend)
220
+  }
221
+  // get pointer to connection
222
+  pConn = &HttpConns[i];
223
+
224
+  debug_http_printf( "accept no=%u", ConnNo );
225
+
226
+  // put new connection into table
227
+  pConn->ConnNo = ConnNo;
228
+  pConn->RcvCnt = 0;
229
+  pConn->RcvState = HTTP_RCV_CMD;
230
+  pConn->RcvBufLen = 0;
231
+}
232
+
233
+// called when connection is closed / reset
234
+// (after this, the connection number may not be used any more)
235
+void HttpClose( unsigned char ConnNo )
236
+{
237
+  unsigned char i;
238
+  struct HttpConnection * pConn;
239
+
240
+  // find connection in table
241
+  for( i = 0; i < count( HttpConns ); i++ )
242
+    if( HttpConns[i].ConnNo == ConnNo )
243
+      break;
244
+  if( i >= count( HttpConns ) ) // connection not found
245
+    return; // ignore this (now already closed) connection
246
+  // get pointer to connection
247
+  pConn = &HttpConns[i];
248
+
249
+  debug_http_printf( "close no=%u", ConnNo );
250
+
251
+  // drop connection from table
252
+  pConn->ConnNo = 0xFF;
253
+}
254
+
255
+// called when sending data is possible
256
+// (return length of available data, 0xFFFF to close connection)
257
+unsigned short HttpSend( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short MaxLen )
258
+{
259
+  unsigned char i;
260
+  struct HttpConnection * pConn;
261
+  unsigned short len, j;
262
+  uint16_t src; // progmem pointer
263
+  char chr, * dest;
264
+  
265
+  // find connection in table
266
+  for( i = 0; i < count( HttpConns ); i++ )
267
+    if( HttpConns[i].ConnNo == ConnNo )
268
+      break;
269
+  if( i >= count( HttpConns ) ) // connection not found
270
+    return 0xFFFF; // close connection
271
+  // get pointer to connection
272
+  pConn = &HttpConns[i];
273
+  
274
+  // not done with receiving
275
+  if( pConn->RcvState != HTTP_RCV_DONE )
276
+    return 0; // do not send anything yet
277
+
278
+  // still waiting for dartboard
279
+  if( pConn->File == HTTP_FILE_DART )
280
+    return 0; // do not send anything yet
281
+
282
+  // at or behind end of data
283
+  if( Pos >= (unsigned long)pConn->SndDataLen )
284
+    return 0xFFFF; // request to close connection
285
+
286
+  // get number of bytes to send
287
+  len = min( pConn->SndDataLen - (unsigned short)Pos, MaxLen );
288
+  if( len == 0 ) // nothing to send
289
+    return 0;
290
+
291
+  // copy data to buffer
292
+  src = pConn->pSndData + (uint16_t)Pos;
293
+  dest = (char *)pBuffer;
294
+  for( j = 0; j < len; j++ )
295
+  {
296
+    // read current character
297
+    chr = (char)pgm_read_byte_near( src );
298
+    // variable
299
+    if( pConn->Vars && (unsigned char)chr >= 0x80 )
300
+    {
301
+      switch( chr ) {
302
+        case 0x80: chr = pConn->DartFactor + '0'; break;
303
+        case 0x90: chr = pConn->DartValue % 10 + '0'; break;
304
+        case 0x91: chr = pConn->DartValue / 10 + '0'; break;
305
+        default: chr = ' '; break;
306
+      }
307
+    }
308
+    *dest = chr; // copy character
309
+    // next character
310
+    src++;
311
+    dest++;
312
+  } // for( j ...
313
+
314
+  // return length of data in buffer
315
+  debug_http_printf( "send no=%u pos=%lu len=%u", ConnNo, Pos, len );
316
+  return len;
317
+}
318
+
319
+// called when data was sent and ACKed
320
+void HttpSent( unsigned char ConnNo, unsigned long Pos )
321
+{
322
+  // nothing needs to be done here
323
+}
324
+
325
+// called when data was received
326
+// must return new window size (not smaller than curWnd)
327
+unsigned short HttpReceived( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short Len, unsigned short curWnd )
328
+{
329
+  unsigned char i;
330
+  struct HttpConnection * pConn;
331
+
332
+  // find connection in table
333
+  for( i = 0; i < count( HttpConns ); i++ )
334
+    if( HttpConns[i].ConnNo == ConnNo )
335
+      break;
336
+  if( i >= count( HttpConns ) ) // connection not found
337
+    return max( curWnd, 256 ); // ignore this connection (will be closed in first call of HttpSend)
338
+  // get pointer to connection
339
+  pConn = &HttpConns[i];
340
+
341
+  // received duplicate data or missed some data
342
+  // (just to be on the safe side, this should never happen)
343
+  if( pConn->RcvCnt != Pos )
344
+  {
345
+    // close connection
346
+    TcpClose( pConn->ConnNo );
347
+    pConn->ConnNo = 0xFF;
348
+    return max( curWnd, 256 );
349
+  }
350
+
351
+  // process received data
352
+  for( ; Len > 0; pBuffer++, Len--, pConn->RcvCnt++ )
353
+  {
354
+    // store character in receive buffer (if it fits into it)
355
+    if( pConn->RcvBufLen < sizeof( pConn->RcvBuf ) )
356
+    {
357
+      pConn->RcvBuf[pConn->RcvBufLen] = *pBuffer;
358
+      pConn->RcvBufLen++;
359
+    }
360
+ 
361
+    // actions according to state
362
+    switch( pConn->RcvState )
363
+    {
364
+
365
+      // receiving HTTP command (e.g GET)
366
+      case HTTP_RCV_CMD:
367
+        if( *pBuffer == '\r' || *pBuffer == '\n' ) // newline
368
+        {
369
+          pConn->RcvBufLen--; // remove newline from buffer
370
+          HttpParseCommand( pConn ); // parse command
371
+          pConn->PreHttp1 = 1; // older than HTTP 1.0
372
+          pConn->File = HTTP_FILE_INDEX; // send index file
373
+          pConn->RcvState = HTTP_RCV_DONE; // receiving completed
374
+          debug_http_printf( "pre1+end no=%u", pConn->ConnNo );
375
+          pConn->RcvBufLen = 0; // empty receive buffer
376
+          HttpProcessRequest( pConn ); // now process request
377
+        }
378
+        else if( *pBuffer == ' ' || *pBuffer == '\t' ) // whitespace
379
+        {
380
+          pConn->RcvBufLen--; // remove whitespace from buffer
381
+          HttpParseCommand( pConn ); // parse command
382
+          pConn->RcvState = HTTP_RCV_FILE; // now receive filename
383
+          debug_http_printf( "cmd no=%u cmd=%u", pConn->ConnNo, pConn->Command );
384
+          pConn->RcvBufLen = 0; // empty receive buffer
385
+        }
386
+        break;
387
+      
388
+      // receiving filename
389
+      case HTTP_RCV_FILE:
390
+        if( *pBuffer == '\r' || *pBuffer == '\n' ) // newline
391
+        {
392
+          pConn->RcvBufLen--; // remove newline from buffer
393
+          HttpParseFile( pConn ); // parse file
394
+          pConn->PreHttp1 = 1; // older than HTTP 1.0
395
+          pConn->RcvState = HTTP_RCV_DONE; // receiving completed
396
+          debug_http_printf( "file+end no=%u file=%u", pConn->ConnNo, pConn->File );
397
+          pConn->RcvBufLen = 0; // empty receive buffer
398
+          HttpProcessRequest( pConn ); // now process request
399
+        }
400
+        else if( *pBuffer == ' ' || *pBuffer == '\t' ) // whitespace
401
+        {
402
+          pConn->RcvBufLen--; // remove whitespace from buffer
403
+          HttpParseFile( pConn ); // parse file
404
+          pConn->PreHttp1 = 0; // HTTP 1.0 or newer
405
+          if( pConn->Command == HTTP_CMD_POST )
406
+            pConn->RcvState = HTTP_RCV_LEN; // now receive content length
407
+          else
408
+            pConn->RcvState = HTTP_RCV_HDR_END; // now receive header until end
409
+          debug_http_printf( "file no=%u file=%u", pConn->ConnNo, pConn->File );
410
+          pConn->RcvBufLen = 0; // empty receive buffer
411
+        }
412
+        break;
413
+
414
+      // receiving content length
415
+      case HTTP_RCV_LEN:
416
+        if( *pBuffer == '\n' || *pBuffer == '\r' ) // newline
417
+        {
418
+          pConn->RcvBuf[pConn->RcvBufLen-1] = 0;
419
+          // content length line
420
+          if( pConn->RcvBufLen >= 15 && memcmp( pConn->RcvBuf, "content-length:", 15 ) == 0 )
421
+          {
422
+            for( i = 15; i < pConn->RcvBufLen; i++ )
423
+              if( pConn->RcvBuf[i] >= '0' && pConn->RcvBuf[i] <= '9' )
424
+                pConn->DataLen = pConn->DataLen * 10 + pConn->RcvBuf[i] - '0';
425
+            debug_http_printf( "data len %lu", pConn->DataLen );
426
+            pConn->RcvState = HTTP_RCV_HDR_END; // now receive header until end
427
+          }
428
+          // empty receive buffer
429
+          pConn->RcvBufLen = 0;
430
+          // re-insert newline if now receiving header until end
431
+          if( pConn->RcvState == HTTP_RCV_HDR_END )
432
+            pConn->RcvBuf[pConn->RcvBufLen++] = *pBuffer;
433
+        }
434
+        else if( *pBuffer >= 'A' && *pBuffer <= 'Z' ) // capital letter
435
+        {
436
+          pConn->RcvBuf[pConn->RcvBufLen - 1] |= 0x20; // convert to lower case
437
+        }
438
+        break;
439
+
440
+      // receiving header until end
441
+      case HTTP_RCV_HDR_END:
442
+        if( *pBuffer != '\r' && *pBuffer != '\n' ) // not a newline
443
+        {
444
+          pConn->RcvBufLen = 0; // empty receive buffer
445
+          break;
446
+        }
447
+        if( (pConn->RcvBufLen == 2 && memcmp( pConn->RcvBuf, "\r\r", 2 ) == 0) || // CR CR
448
+            (pConn->RcvBufLen == 2 && memcmp( pConn->RcvBuf, "\n\n", 2 ) == 0) || // LF LF
449
+            (pConn->RcvBufLen == 3 && memcmp( pConn->RcvBuf, "\r\n\n", 3 ) == 0) || // CR LF LF
450
+            (pConn->RcvBufLen == 3 && memcmp( pConn->RcvBuf, "\n\r\n", 3 ) == 0) || // LF CR LF
451
+            pConn->RcvBufLen == 4 ) // CR LF CR LF (or some other combination of 4 times CR or LF)
452
+        {
453
+          if( pConn->Command == HTTP_CMD_POST && pConn->DataLen > 0 )
454
+          {
455
+            pConn->RcvState = HTTP_RCV_DATA; // now receive post data
456
+            pConn->DataTag = 0; // not in a tag
457
+            pConn->DataValue = 0; // no value yet
458
+          }
459
+          else
460
+            pConn->RcvState = HTTP_RCV_DONE; // receiving completed
461
+          debug_http_printf( "end no=%u", pConn->ConnNo );
462
+          pConn->RcvBufLen = 0; // empty receive buffer
463
+          HttpProcessRequest( pConn ); // now process request
464
+        }
465
+        break;
466
+
467
+      // receiving post data
468
+      case HTTP_RCV_DATA:
469
+        pConn->RcvBufLen = 0; // ignore any data in receive buffer
470
+        // process data byte for byte
471
+        if( pConn->DataTag ) { // in a tag
472
+          if( *pBuffer == '>' ) // end of tag
473
+            pConn->DataTag = 0;
474
+        } else { // not in a tag
475
+          if( *pBuffer == '<' ) // start of tag
476
+            pConn->DataTag = 1;
477
+          if( *pBuffer >= '0' && *pBuffer <= '9' ) // a digit
478
+            pConn->DataValue = pConn->DataValue * 10 + *pBuffer - '0'; // collect digits
479
+        }
480
+        // count down number of bytes to receive
481
+        if( pConn->DataLen > 0 )
482
+          pConn->DataLen--;
483
+        if( pConn->DataLen <= 0 ) {
484
+          debug_http_printf( "data value %lu", pConn->DataValue );
485
+          if( pConn->DataValue > HttpMaxTimeout ) // limit timeout (must be less than TCP timeout)
486
+            pConn->DataValue = HttpMaxTimeout;
487
+          pConn->DataValue *= 5; // convert from seconds to ticks
488
+          pConn->RcvState = HTTP_RCV_DONE; // receiving completed
489
+        }
490
+        break;
491
+
492
+      // receiving completed
493
+      case HTTP_RCV_DONE:
494
+        pConn->RcvBufLen = 0; // ignore any additional data
495
+        break;
496
+
497
+    } // switch( pConn->RcvState )
498
+  } // for( ; Len > 0; pBuffer++, Len--, pConn->RcvCnt++ )
499
+
500
+  // return at least 256 bytes window size
501
+  // - we are always able to receive data
502
+  return max( curWnd, 256 );
503
+}
504
+
505
+// http notification functions
506
+struct TcpNotify HttpNotify = // (extern)
507
+{
508
+  .Connect = HttpConnect,
509
+  .Close = HttpClose,
510
+  .Send = HttpSend,
511
+  .Sent = HttpSent,
512
+  .Received = HttpReceived,
513
+};
514
+
515
+// initialize
516
+void HttpInit( void ) // (extern)
517
+{
518
+  unsigned char i;
519
+
520
+  // no HTTP connections yet
521
+  for( i = 0; i < count( HttpConns ); i++ )
522
+    HttpConns[i].ConnNo = 0xFF;
523
+}
524
+
525
+// http tick procedure - call every 200ms
526
+void HttpTick200( void ) // (extern)
527
+{
528
+  unsigned char i, factor, value;
529
+
530
+  // process all HTTP connections
531
+  for( i = 0; i < count( HttpConns ); i++ ) {
532
+    struct HttpConnection * pConn = &HttpConns[i];
533
+
534
+    // connection in use and waiting for dart
535
+    if( pConn->ConnNo != 0xFF &&
536
+        pConn->RcvState == HTTP_RCV_DONE &&
537
+        pConn->File == HTTP_FILE_DART ) {
538
+
539
+        // poll dart
540
+        DartPoll( &factor, &value );
541
+
542
+        // 2 digit field hit
543
+        if( factor > 0 && value >= 10 ) {
544
+          pConn->DartFactor = factor;
545
+          pConn->DartValue = value;
546
+          pConn->File = HTTP_FILE_DART_2D;
547
+          HttpProcessRequest( pConn ); // re-process request
548
+          TcpSend( pConn->ConnNo ); // data to send is available now
549
+        }
550
+
551
+        // 1 digit field hit
552
+        else if( factor > 0 && value > 0 ) {
553
+          pConn->DartFactor = factor;
554
+          pConn->DartValue = value;
555
+          pConn->File = HTTP_FILE_DART_1D;
556
+          HttpProcessRequest( pConn ); // re-process request
557
+          TcpSend( pConn->ConnNo ); // data to send is available now
558
+        }
559
+
560
+        // no field hit
561
+        else {
562
+          // no timeout yet ---> count down time
563
+          if( pConn->DataValue > 0 ) {
564
+            pConn->DataValue--;
565
+          }
566
+          // timeout
567
+          else {
568
+            pConn->DartFactor = 0;
569
+            pConn->DartValue = 0;
570
+            pConn->File = HTTP_FILE_DART_NO;
571
+            HttpProcessRequest( pConn ); // re-process request
572
+            TcpSend( pConn->ConnNo ); // data to send is available now
573
+          }
574
+        }
575
+
576
+    } // in use
577
+  } // for( i ...
578
+}
579
+
... ...
@@ -0,0 +1,23 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_http
9
+#define INC_http
10
+
11
+#include "tcp.h"
12
+
13
+// initialize
14
+extern void HttpInit( void );
15
+
16
+// http notification functions
17
+extern struct TcpNotify HttpNotify;
18
+
19
+// http tick procedure - call every 200ms
20
+extern void HttpTick200( void );
21
+
22
+#endif // #ifdef INC_http
23
+
... ...
@@ -0,0 +1,221 @@
1
+#! /usr/bin/perl
2
+
3
+# flaneth - flash and ethernet - dartboard mod
4
+# version 0.1 date 2008-11-09
5
+# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
6
+# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
7
+# a BlinkenArea project - http://www.blinkenarea.org/
8
+
9
+use strict;
10
+
11
+my $VERSION="version 0.1 date 2008-11-09";
12
+
13
+
14
+
15
+die( "usage: $0 <http_dir> <http_content.inc>\n" ) if( @ARGV < 2 );
16
+
17
+my $dir = @ARGV[0];
18
+my $output = @ARGV[1];
19
+
20
+
21
+
22
+# maximum
23
+# usage: $m = max( $a, $b )
24
+sub max
25
+{
26
+  my $a = shift;
27
+  my $b = shift;
28
+  return $a > $b ? $a : $b;
29
+}
30
+
31
+
32
+
33
+# convert a character to a string
34
+# usage: $txt = chr2str( $ascii_code, $cnt )
35
+sub chr2str
36
+{
37
+  my $ascii_code = shift;
38
+  my $cnt = shift;
39
+
40
+  my $txt = "";
41
+
42
+  for( ; $cnt > 0; $cnt-- ) {
43
+    $txt .= pack( "C", $ascii_code );
44
+  }
45
+
46
+  return $txt;
47
+}
48
+
49
+
50
+
51
+# c string escaping
52
+# usage: $escaped = str_esc( $txt )
53
+sub str_esc
54
+{
55
+  my $txt = shift;
56
+
57
+  my $escaped = "";
58
+  for( my $i = 0; $i < length( $txt ); $i++ ) {
59
+    my $chr = substr( $txt, $i, 1 );
60
+    if( $chr eq '\\' ) {
61
+      $escaped .= "\\\\";
62
+    } elsif( $chr eq '"' ) {
63
+      $escaped .= "\\\"";
64
+    } elsif( $chr eq "\t" ) {
65
+      $escaped .= "\\t";
66
+    } elsif( $chr eq "\r" ) {
67
+      $escaped .= "\\r";
68
+    } elsif( $chr eq "\n" ) {
69
+      $escaped .= "\\n";
70
+    } elsif( $chr ge ' ' && $chr le '~' ) {
71
+      $escaped .= $chr;
72
+    } else {
73
+      $escaped .= sprintf( "\\x%02X", unpack( "C", $chr ) );
74
+    }
75
+  }
76
+
77
+  return $escaped;
78
+}
79
+
80
+
81
+
82
+# replace variables
83
+# usage: $line_replaced = var_replace( $line )
84
+sub var_replace
85
+{
86
+  my $line = shift;
87
+
88
+  my $var;
89
+  $line =~ s/__VERSION__/$VERSION/g;
90
+  $var = chr2str( 0x80, 1 );
91
+  $line =~ s/__FACTOR__/$var/g;
92
+  $var = chr2str( 0x90, 1 );
93
+  $line =~ s/__VALUE_L__/$var/g;
94
+  $var = chr2str( 0x91, 1 );
95
+  $line =~ s/__VALUE_H__/$var/g;
96
+
97
+  return $line;
98
+}
99
+
100
+
101
+
102
+# get file size
103
+# usage: $size = file_size( $filename )
104
+sub file_size
105
+{
106
+  my $filename = shift;
107
+
108
+  my @info = stat( $filename );
109
+
110
+  return @info[7] if( @info > 7 ); # @info[7] is the size (see documentation of stat)
111
+
112
+  return 0;
113
+}
114
+
115
+
116
+
117
+# convert a text file to c code
118
+# usage: ($code, $len) = textfile2code( $filename )
119
+sub textfile2code
120
+{
121
+  my $filename = shift;
122
+
123
+  my $txt = "";
124
+  my $len = 0;
125
+
126
+  open( TEXTFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" );
127
+
128
+  my $line;
129
+  while( $line = <TEXTFILE> ) {
130
+    $line = var_replace( $line );
131
+    $txt .= "\"" . str_esc( $line ) . "\"\n";
132
+    $len += length( $line );
133
+  }
134
+
135
+
136
+  close( TEXTFILE );
137
+
138
+  return ($txt, $len);
139
+}
140
+
141
+
142
+
143
+# convert a binary file to c code
144
+# usage: ($code, $len) = binfile2code( $filename )
145
+sub binfile2code
146
+{
147
+  my $filename = shift;
148
+
149
+  my $txt = "";
150
+  my $len = 0;
151
+
152
+  open( BINFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" );
153
+  binmode( BINFILE );
154
+
155
+  my $val;
156
+  while( 1 ) {
157
+    $txt.= "\"";
158
+    my $i;
159
+    for( $i = 0; $i < 0x10; $i++ ) {
160
+      read( BINFILE, $val, 1 ) or last;
161
+      $txt .= sprintf( "\\x%02X", unpack( "C", $val ) );
162
+      $len++;
163
+    }
164
+    $txt .= "\"\n";
165
+    last if( $i < 0x10 );
166
+  }
167
+
168
+  close( BINFILE );
169
+
170
+  return ($txt, $len);
171
+}
172
+
173
+
174
+
175
+# generate page
176
+# usage: $page = gen_page( $ret, $file, $name, $ctype, $bin )
177
+sub gen_page
178
+{
179
+  my $ret = shift;
180
+  my $file = shift;
181
+  my $name = shift;
182
+  my $ctype = shift;
183
+  my $bin = shift;
184
+
185
+  my ($code, $len);
186
+  if( $bin ) {
187
+    ($code, $len) = binfile2code( $file );
188
+  } else {
189
+    ($code, $len) = textfile2code( $file );
190
+  }
191
+
192
+  my $header =
193
+    "const char PROGMEM Http${name}[] =\n" .
194
+    "\"HTTP/1.0 $ret\\r\\n\"\n" .
195
+    "\"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n\"\n" .
196
+    "\"Connection: close\\r\\n\"\n" .
197
+    "\"Content-Type: $ctype\\r\\n\"\n" .
198
+    "\"Content-Length: $len\\r\\n\"\n" .
199
+    "\"\\r\\n\"\n";
200
+  my $hlen = length( $header );
201
+
202
+  return "#define Http${name}HeaderSize $hlen\n$header$code;\n\n"
203
+}
204
+
205
+open( OUTPUT, ">", "$output" ) or die( "cannot open \"$output\" for writing: $!\n" );
206
+
207
+print OUTPUT <<EOF;
208
+//content for webpages
209
+// - characters from 0x80..0xFF indicate a 1 character variable
210
+
211
+EOF
212
+
213
+print( OUTPUT gen_page( "400 Bad Request", "$dir/bad_request.html", "BadRequest", "text/html", 0 ) );
214
+print( OUTPUT gen_page( "404 Not Found", "$dir/not_found.html", "NotFound", "text/html", 0 ) );
215
+print( OUTPUT gen_page( "200 Ok", "$dir/index.html", "Index", "text/html", 0 ) );
216
+print( OUTPUT gen_page( "200 Ok", "$dir/dart_no.xml", "DartNo", "text/xml", 0 ) );
217
+print( OUTPUT gen_page( "200 Ok", "$dir/dart_1d.xml", "Dart1d", "text/xml", 0 ) );
218
+print( OUTPUT gen_page( "200 Ok", "$dir/dart_2d.xml", "Dart2d", "text/xml", 0 ) );
219
+
220
+close( OUTPUT );
221
+
... ...
@@ -0,0 +1,9 @@
1
+<html>
2
+  <head><title>flaneth - 400 Bad Request</title></head>
3
+  <body>
4
+    <h1>flaneth - 400 Bad Request</h1>
5
+    Your browser sent a request that this server could not understand.<br>
6
+    <br><br>
7
+    flaneth - __VERSION__
8
+  </body>
9
+</html>
... ...
@@ -0,0 +1,10 @@
1
+<soap:Envelope
2
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
3
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
4
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
5
+    <GetHitResponse>
6
+      <factor>__FACTOR__</factor>
7
+      <value>__VALUE_L__</value>
8
+    </GetHitResponse>
9
+  </soap:Body>
10
+</soap:Envelope>
... ...
@@ -0,0 +1,10 @@
1
+<soap:Envelope
2
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
3
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
4
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
5
+    <GetHitResponse>
6
+      <factor>__FACTOR__</factor>
7
+      <value>__VALUE_H____VALUE_L__</value>
8
+    </GetHitResponse>
9
+  </soap:Body>
10
+</soap:Envelope>
... ...
@@ -0,0 +1,8 @@
1
+<soap:Envelope
2
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
3
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
4
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
5
+    <GetHitResponse>
6
+    </GetHitResponse>
7
+  </soap:Body>
8
+</soap:Envelope>
... ...
@@ -0,0 +1,85 @@
1
+<html>
2
+  <head>
3
+    <title>flaneth - dartboard mod</title>
4
+    <meta http-equiv="pragma" content="no-cache">
5
+  </head>
6
+  <body>
7
+    <h1>UDP interface</h1>
8
+      <ul>
9
+        <li>send empty UDP datagram to UDP port 501</li>
10
+        <li>receive UDP datagrams containing hit field (e.g. 2x25 for double bull)</li>
11
+      </ul>
12
+    <br><br>
13
+    <h1>SOAP interface</h1>
14
+      <ul>
15
+        <li>URL: http://flaneth-dartboard-mod:80/dart</li>
16
+      </ul>
17
+      <ul>
18
+        <li>
19
+          example request:
20
+<pre>
21
+&lt;soap:Envelope
22
+    xmlns:soap=&quot;http://www.w3.org/2001/12/soap-envelope/&quot;
23
+    soap:encodingStyle=&quot;http://www.w3.org/2001/12/soap-encoding&quot;&gt;
24
+  &lt;soap:Body xmlns=&quot;http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap&quot;&gt;
25
+    &lt;GetHit&gt;
26
+      &lt;timeout&gt;5&lt;/timeout&gt;
27
+    &lt;/GetHit&gt;
28
+  &lt;/soap:Body&gt;
29
+&lt;/soap:Envelope&gt;
30
+</pre>
31
+          timeout: time in seconds to wait for field to be hit<br>
32
+        </li>
33
+        <li>
34
+          example response (double bull):
35
+<pre>
36
+&lt;soap:Envelope
37
+    xmlns:soap=&quot;http://www.w3.org/2001/12/soap-envelope/&quot;
38
+    soap:encodingStyle=&quot;http://www.w3.org/2001/12/soap-encoding&quot;&gt;
39
+  &lt;soap:Body xmlns=&quot;http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap&quot;&gt;
40
+    &lt;GetHitResponse&gt;
41
+      &lt;factor&gt;2&lt;/factor&gt;
42
+      &lt;value&gt;25&lt;/value&gt;
43
+    &lt;/GetHitResponse&gt;
44
+  &lt;/soap:Body&gt;
45
+&lt;/soap:Envelope&gt;
46
+</pre>
47
+           
48
+          factor: 1 for single, 2 for double, 3 for triple<br>
49
+          value: value of field that was hit<br>
50
+        </li>
51
+        <li>
52
+          example response (single one):
53
+<pre>
54
+&lt;soap:Envelope
55
+    xmlns:soap=&quot;http://www.w3.org/2001/12/soap-envelope/&quot;
56
+    soap:encodingStyle=&quot;http://www.w3.org/2001/12/soap-encoding&quot;&gt;
57
+  &lt;soap:Body xmlns=&quot;http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap&quot;&gt;
58
+    &lt;GetHitResponse&gt;
59
+      &lt;factor&gt;1&lt;/factor&gt;
60
+      &lt;value&gt;1&lt;/value&gt;
61
+    &lt;/GetHitResponse&gt;
62
+  &lt;/soap:Body&gt;
63
+&lt;/soap:Envelope&gt;
64
+</pre>
65
+          factor: 1 for single, 2 for double, 3 for triple<br>
66
+          value: value of field that was hit<br>
67
+        </li>
68
+        <li>
69
+          example response (nothing hit):
70
+<pre>
71
+&lt;soap:Envelope
72
+    xmlns:soap=&quot;http://www.w3.org/2001/12/soap-envelope/&quot;
73
+    soap:encodingStyle=&quot;http://www.w3.org/2001/12/soap-encoding&quot;&gt;
74
+  &lt;soap:Body xmlns=&quot;http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap&quot;&gt;
75
+    &lt;GetHitResponse&gt;
76
+    &lt;/GetHitResponse&gt;
77
+  &lt;/soap:Body&gt;
78
+&lt;/soap:Envelope&gt;
79
+</pre>
80
+        </li>
81
+      </ul>
82
+    <br><br>
83
+    flaneth - __VERSION__
84
+  </body>
85
+</html>
... ...
@@ -0,0 +1,9 @@
1
+<html>
2
+  <head><title>flaneth - 404 Not Found</title></head>
3
+  <body>
4
+    <h1>flaneth - 404 Not Found</h1>
5
+    The requested URL was not found on this server.<br>
6
+    <br><br>
7
+    flaneth - __VERSION__
8
+  </body>
9
+</html>
... ...
@@ -0,0 +1,104 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <string.h>
9
+
10
+#include "checksum.h"
11
+#include "debug.h"
12
+#include "ethernet.h"
13
+#include "icmp.h"
14
+#include "ip.h"
15
+#include "macros.h"
16
+#include "nethelp.h"
17
+
18
+// send an ICMP packet
19
+// pData must point to a struct IcmpPacket with IcmpHdr.Type, IcmpHdr.Code and IpHdr.Dest already initialized
20
+static void IcmpSend( unsigned char * pData, unsigned short Length )
21
+{
22
+  struct IcmpPacket * pIcmpPack;
23
+  unsigned int chk;
24
+
25
+  // packet too short
26
+  if( Length < sizeof( struct IcmpPacket ) )
27
+    return;
28
+
29
+  // convert pointer to ICMP packet
30
+  // (this saves us from always casting pData)
31
+  pIcmpPack = (struct IcmpPacket *)pData;
32
+
33
+  debug_icmp_printf( "send type=0x%02X len=%u", pIcmpPack->IcmpHdr.Type, Length );
34
+
35
+  // fill in header values
36
+  pIcmpPack->IcmpHdr.Chk = 0x0000;
37
+
38
+  // generate checksum
39
+  chk = Checksum( (unsigned char *)&pIcmpPack->IcmpHdr, Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ), 0x0000, 0x0000 );
40
+  pIcmpPack->IcmpHdr.Chk = htons( chk );
41
+
42
+  // send ICMP packet
43
+  pIcmpPack->IpHdr.Proto = 0x01; // ICMP
44
+  IpSend( pData, Length );
45
+}
46
+
47
+// process a received ICMP echo request packet
48
+static void IcmpEchoReqRecv( unsigned char * pData, unsigned short Length )
49
+{
50
+  struct IcmpEchoPacket * pIcmpEchoPack;
51
+
52
+  // packet too short
53
+  if( Length < sizeof( struct IcmpEchoPacket ) )
54
+    return;
55
+
56
+  // convert pointer to ICMP echo request/reply packet
57
+  // (this saves us from always casting pData)
58
+  pIcmpEchoPack = (struct IcmpEchoPacket *)pData;
59
+
60
+  // code not 0
61
+  if( pIcmpEchoPack->IcmpHdr.Code != 0x00 )
62
+    return;
63
+
64
+  debug_icmp_printf( "icmp echo len=%u", Length );
65
+
66
+  // send an ICMP echo reply
67
+  // - use same buffer to send reply
68
+  // - this saves us from needing to allocate a new buffer
69
+  // - this saves us from needing to copy EchoHdr.Id, EchoHdr.Seq and the data
70
+  pIcmpEchoPack->IcmpHdr.Type = 0x00; // ICMP echo reply
71
+  pIcmpEchoPack->IcmpHdr.Code = 0x00;
72
+  ip_cpy( pIcmpEchoPack->IpHdr.Dest, pIcmpEchoPack->IpHdr.Src ); // destination IP is source IP of request
73
+  IcmpSend( pData, Length );
74
+}
75
+
76
+// process a received ICMP packet
77
+void IcmpRecv( unsigned char * pData, unsigned short Length ) // (extern)
78
+{
79
+  struct IcmpPacket * pIcmpPack;
80
+
81
+  // packet too short
82
+  if( Length < sizeof( struct IcmpPacket ) )
83
+    return;
84
+
85
+  // convert pointer to ICMP packet
86
+  // (this saves us from always casting pData)
87
+  pIcmpPack = (struct IcmpPacket *)pData;
88
+
89
+  // test checksum
90
+  if( Checksum( (unsigned char*)&pIcmpPack->IcmpHdr, Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ), 0x0000, 0x0000 ) != 0 )
91
+    return;
92
+
93
+  debug_icmp_printf( "recv type=0x%02X len=%u", pIcmpPack->IcmpHdr.Type, Length );
94
+
95
+  // branch according to type
96
+  switch( pIcmpPack->IcmpHdr.Type )
97
+  {
98
+    // ICMP echo request
99
+    case 0x08:
100
+      IcmpEchoReqRecv( pData, Length );
101
+      break;
102
+  }
103
+}
104
+
... ...
@@ -0,0 +1,50 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_icmp
9
+#define INC_icmp
10
+
11
+#include "ethernet.h"
12
+#include "ip.h"
13
+
14
+// header of an ICMP packet
15
+struct IcmpHeader
16
+{
17
+  unsigned char Type;
18
+  unsigned char Code;
19
+  unsigned int Chk;
20
+};
21
+
22
+// an ICMP packet
23
+struct IcmpPacket
24
+{
25
+  struct EthernetHeader EthHdr;
26
+  struct IpHeader IpHdr;
27
+  struct IcmpHeader IcmpHdr;
28
+};
29
+
30
+// header of an ICMP echo request/reply packet
31
+struct IcmpEchoHeader
32
+{
33
+  unsigned int Id;
34
+  unsigned int Seq;
35
+};
36
+
37
+// an ICMP echo request/reply packet
38
+struct IcmpEchoPacket
39
+{
40
+  struct EthernetHeader EthHdr;
41
+  struct IpHeader IpHdr;
42
+  struct IcmpHeader IcmpHdr;
43
+  struct IcmpEchoHeader EchoHdr;
44
+};
45
+
46
+// process a received ICMP packet
47
+extern void IcmpRecv( unsigned char * pData, unsigned short Length );
48
+
49
+#endif // #ifdef INC_icmp
50
+
... ...
@@ -0,0 +1,319 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <string.h>
9
+
10
+#include "arp.h"
11
+#include "checksum.h"
12
+#include "config.h"
13
+#include "debug.h"
14
+#include "ethernet.h"
15
+#include "icmp.h"
16
+#include "ip.h"
17
+#include "macros.h"
18
+#include "nethelp.h"
19
+#include "tcp.h"
20
+#include "udp.h"
21
+
22
+// timing parameters
23
+#define IpBufferTicksMax 50 // maximum age of buffered IP packet (in 200ms steps)
24
+
25
+// buffers for IP packets to transmit
26
+// - used if MAC is unknown when packet shall be transmitted
27
+// - packet is sent when MAC becomes known
28
+unsigned char IpBuffer0[80]; // some buffers with different length (IP packets have different length)
29
+unsigned char IpBuffer1[80];
30
+unsigned char IpBuffer2[160];
31
+unsigned char IpBuffer3[320];
32
+struct IpBufferTable // table with buffers
33
+{
34
+  unsigned char * pBuffer; // pointer to buffer for packet
35
+  unsigned short BufferLength; // length of buffer
36
+  unsigned short PacketLength; // length of packet in buffer, 0 if no packet in this buffer
37
+  unsigned char Ticks; // age of entry in 200ms steps
38
+} IpBufferTab[] =
39
+{ // put smaller buffers in front of larger buffers
40
+  // - then short packets will use smaller buffers more often
41
+  { IpBuffer0, sizeof( IpBuffer0 ), 0, 0 },
42
+  { IpBuffer1, sizeof( IpBuffer1 ), 0, 0 },
43
+  { IpBuffer2, sizeof( IpBuffer2 ), 0, 0 },
44
+  { IpBuffer3, sizeof( IpBuffer3 ), 0, 0 },
45
+};
46
+
47
+// tick procedure - call every 200ms
48
+void IpTick200( void ) // (extern)
49
+{
50
+  unsigned char i;
51
+
52
+  // increase age of buffered IP packets and remove timed out ones
53
+  for( i = 0; i < count( IpBufferTab ); i++ )
54
+  {
55
+    if( IpBufferTab[i].PacketLength > 0 ) // buffer in use
56
+    {
57
+      IpBufferTab[i].Ticks++; // increase age
58
+      if( IpBufferTab[i].Ticks > IpBufferTicksMax ) // too old
59
+        IpBufferTab[i].PacketLength = 0; // discard packet
60
+    }
61
+  }
62
+}
63
+
64
+// process a received IP packet
65
+void IpRecv( unsigned char * pData, unsigned short Length ) // (extern)
66
+{
67
+  struct IpPacket * pIpPack;
68
+  unsigned int len;
69
+
70
+  // packet too short
71
+  if( Length < sizeof( struct IpPacket ) )
72
+    return;
73
+
74
+  // convert pointer to IP packet
75
+  // (this saves us from always casting pData)
76
+  pIpPack = (struct IpPacket *)pData;
77
+
78
+  // not IPv4
79
+  if( pIpPack->IpHdr.Ver_HdrLen != 0x45 ) // IPv4 with no options present
80
+    return;
81
+
82
+  // check destination address
83
+  do {
84
+    if( ip_eq( pIpPack->IpHdr.Dest, ConfigIp ) ) // own IP
85
+      break;
86
+    if( ip_eq( pIpPack->IpHdr.Dest, "\xFF\xFF\xFF\xFF" ) ) // broadcast
87
+      break;
88
+    if( pIpPack->IpHdr.Dest[0] == (ConfigIp[0] & ConfigMask[0]) && // local broadcast
89
+        pIpPack->IpHdr.Dest[1] == (ConfigIp[1] & ConfigMask[1]) &&
90
+        pIpPack->IpHdr.Dest[2] == (ConfigIp[2] & ConfigMask[2]) &&
91
+        pIpPack->IpHdr.Dest[3] == (ConfigIp[3] & ConfigMask[3]) )
92
+      break;
93
+    return; // packet not to this node
94
+  } while( 0 );  
95
+
96
+  // ignore packets sent from invalid source adresses
97
+  // - this might be some attack or some router fault
98
+  if( pIpPack->IpHdr.Src[0] >= 0xE0 || // broadcast, reserved or multicast addresses
99
+      pIpPack->IpHdr.Src[0] == 0x7F || // loopback network
100
+      ip_eq( pIpPack->IpHdr.Src, "\x00\x00\x00\x00" ) ) // IP 0.0.0.0
101
+    return;
102
+  // ignore packets sent from local network address or broadcast address
103
+  if( (pIpPack->IpHdr.Src[0] & ConfigMask[0]) == (ConfigIp[0] & ConfigMask[0]) && // source IP is in own subnet
104
+      (pIpPack->IpHdr.Src[1] & ConfigMask[1]) == (ConfigIp[1] & ConfigMask[1]) &&
105
+      (pIpPack->IpHdr.Src[2] & ConfigMask[2]) == (ConfigIp[2] & ConfigMask[2]) &&
106
+      (pIpPack->IpHdr.Src[3] & ConfigMask[3]) == (ConfigIp[3] & ConfigMask[3]) )
107
+  {
108
+    if( (pIpPack->IpHdr.Src[0] & ~ConfigMask[0]) == 0x00 && // local network address
109
+        (pIpPack->IpHdr.Src[1] & ~ConfigMask[1]) == 0x00 &&
110
+        (pIpPack->IpHdr.Src[2] & ~ConfigMask[2]) == 0x00 &&
111
+        (pIpPack->IpHdr.Src[3] & ~ConfigMask[3]) == 0x00 )
112
+      return;
113
+    if( (pIpPack->IpHdr.Src[0] & ~ConfigMask[0]) == 0xFF && // local broadcast address
114
+        (pIpPack->IpHdr.Src[1] & ~ConfigMask[1]) == 0xFF &&
115
+        (pIpPack->IpHdr.Src[2] & ~ConfigMask[2]) == 0xFF &&
116
+        (pIpPack->IpHdr.Src[3] & ~ConfigMask[3]) == 0xFF )
117
+      return;
118
+  }
119
+  // ignore packets sent from own IP address
120
+  if( ip_eq( pIpPack->IpHdr.Src, ConfigIp ) )
121
+    return;
122
+
123
+  // ignore fragmented packets
124
+  // BUG: fragmentation must be supported according to RFC781
125
+  // but there is no way of assembling packets with up to 64kB on a processor with 4kB of RAM
126
+  if( (ntohs( pIpPack->IpHdr.FragOfs ) & 0xBFFF) != 0x0000 ) // fragment offset 0, MoreFrags=0, DontFrag=x, reservedFlag=0
127
+    return;
128
+
129
+  // check total length
130
+  len = sizeof( struct EthernetHeader ) + ntohs( pIpPack->IpHdr.TotalLen ); // length according to IP header
131
+  if( Length < len ) // packet is truncated
132
+    return;
133
+  Length = len; // remove ethernet padding from packet (maybe Length > len)
134
+
135
+  // test header checksum
136
+  if( Checksum( (unsigned char*)&pIpPack->IpHdr, sizeof( struct IpHeader ), 0x0000, 0x0000 ) != 0 )
137
+    return;
138
+
139
+  debug_ip_printf( "recv src=%u.%u.%u.%u protocol=%u len=%u",
140
+                   pIpPack->IpHdr.Src[0], pIpPack->IpHdr.Src[1],
141
+                   pIpPack->IpHdr.Src[2], pIpPack->IpHdr.Src[3],
142
+                   pIpPack->IpHdr.Proto, Length );
143
+
144
+  // branch according to protocol
145
+  switch( pIpPack->IpHdr.Proto )
146
+  {
147
+    // ICMP
148
+    case 0x01:
149
+      IcmpRecv( pData, Length );
150
+      break;
151
+    // TCP
152
+    case 0x06:
153
+      TcpRecv( pData, Length );
154
+      break;
155
+    // UDP
156
+    case 0x11:
157
+      UdpRecv( pData, Length );
158
+      break;
159
+  }
160
+}
161
+
162
+// send an IP packet
163
+// pData must point to a struct IpPacket with IpHdr.Proto and IpHdr.Dest already initialized
164
+void IpSend( unsigned char * pData, unsigned short Length ) // (extern)
165
+{
166
+  struct IpPacket * pIpPack;
167
+  unsigned int chk;
168
+  unsigned char i;
169
+
170
+  // packet too short
171
+  if( Length < sizeof( struct IpPacket ) )
172
+    return;
173
+
174
+  // convert pointer to IP packet
175
+  // (this saves us from always casting pData)
176
+  pIpPack = (struct IpPacket *)pData;
177
+
178
+  debug_ip_printf( "send dest=%u.%u.%u.%u protocol=%u len=%u",
179
+                   pIpPack->IpHdr.Dest[0], pIpPack->IpHdr.Dest[1],
180
+                   pIpPack->IpHdr.Dest[2], pIpPack->IpHdr.Dest[3],
181
+                   pIpPack->IpHdr.Proto, Length );
182
+
183
+  // fill in header values
184
+  pIpPack->IpHdr.Ver_HdrLen = 0x45;
185
+  pIpPack->IpHdr.Tos = 0x00;
186
+  pIpPack->IpHdr.TotalLen = htons( Length - sizeof( struct EthernetHeader ) );
187
+  pIpPack->IpHdr.Id = 0x0000;
188
+  pIpPack->IpHdr.FragOfs = 0x0000;
189
+  pIpPack->IpHdr.Ttl = 0x40;
190
+  pIpPack->IpHdr.HdrChk = 0x0000;
191
+  ip_cpy( pIpPack->IpHdr.Src, ConfigIp );
192
+
193
+  // generate header checksum
194
+  chk = Checksum( (unsigned char *)&pIpPack->IpHdr, sizeof( struct IpHeader ), 0x0000, 0x0000 );
195
+  pIpPack->IpHdr.HdrChk = htons( chk );
196
+
197
+  // destination is in own subnet
198
+  if( (pIpPack->IpHdr.Dest[0] & ConfigMask[0]) == (ConfigIp[0] & ConfigMask[0]) &&
199
+      (pIpPack->IpHdr.Dest[1] & ConfigMask[1]) == (ConfigIp[1] & ConfigMask[1]) &&
200
+      (pIpPack->IpHdr.Dest[2] & ConfigMask[2]) == (ConfigIp[2] & ConfigMask[2]) &&
201
+      (pIpPack->IpHdr.Dest[3] & ConfigMask[3]) == (ConfigIp[3] & ConfigMask[3]) )
202
+  {
203
+    // broadcast
204
+    if( (pIpPack->IpHdr.Dest[0] | ConfigMask[0]) == 255 &&
205
+        (pIpPack->IpHdr.Dest[1] | ConfigMask[1]) == 255 &&
206
+        (pIpPack->IpHdr.Dest[2] | ConfigMask[2]) == 255 &&
207
+        (pIpPack->IpHdr.Dest[3] | ConfigMask[3]) == 255 )
208
+    {
209
+      mac_cpy( pIpPack->EthHdr.Dest, "\xFF\xFF\xFF\xFF\xFF\xFF" );
210
+      i = 0x00;
211
+    }
212
+    // unicast
213
+    else
214
+    {
215
+      // lookup MAC address of destination
216
+      i = ArpLookup( pIpPack->IpHdr.Dest, pIpPack->EthHdr.Dest );
217
+    }
218
+  }
219
+  // destination is not in own subnet
220
+  else
221
+  {
222
+    // broadcast
223
+    if( pIpPack->IpHdr.Dest[0] == 255 &&
224
+        pIpPack->IpHdr.Dest[1] == 255 &&
225
+        pIpPack->IpHdr.Dest[2] == 255 &&
226
+        pIpPack->IpHdr.Dest[3] == 255 )
227
+    {
228
+      mac_cpy( pIpPack->EthHdr.Dest, "\xFF\xFF\xFF\xFF\xFF\xFF" );
229
+      i = 0x00;
230
+    }
231
+    // unicast
232
+    else
233
+    {
234
+      // lookup MAC address of default gateway
235
+      i = ArpLookup( ConfigGw, pIpPack->EthHdr.Dest );
236
+    }
237
+  }
238
+
239
+  // MAC available
240
+  if( i == 0x00 )
241
+  {
242
+    // sent IP packet
243
+    pIpPack->EthHdr.Type = htons( 0x0800 ); // ethernet packet type: IP
244
+    EthernetSend( pData, Length );
245
+    return;
246
+  }
247
+
248
+  // find a buffer to store the packet in
249
+  for( i = 0; i < count( IpBufferTab ); i++ )
250
+  {
251
+    if( IpBufferTab[i].PacketLength == 0 && // buffer not in use
252
+        Length < IpBufferTab[i].BufferLength ) // buffer long enough
253
+    {
254
+      // put packet into buffer
255
+      memcpy( IpBufferTab[i].pBuffer, pData, Length );
256
+      IpBufferTab[i].PacketLength = Length;
257
+      IpBufferTab[i].Ticks = 0;
258
+      debug_ip_printf( "queued" );
259
+      break;
260
+    }
261
+  }
262
+  // if no buffer was found, we cannnot do anything about it and must discard the packet (i.e. do nothing here)
263
+}
264
+
265
+// a MAC address was discovered
266
+// called by ARP to notify IP
267
+void IpGotMac( unsigned char Ip[4], unsigned char Mac[6] ) // (extern)
268
+{
269
+  unsigned char i;
270
+  struct IpPacket * pIpPack;
271
+
272
+  // search for buffered packets that can be sent now
273
+  for( i = 0; i < count( IpBufferTab ); i++ )
274
+  {
275
+    if( IpBufferTab[i].PacketLength > 0 ) // buffer in use
276
+    {
277
+      // convert pointer to IP packet
278
+      pIpPack = (struct IpPacket *)IpBufferTab[i].pBuffer;
279
+
280
+      debug_ip_printf( "send queued dest=%u.%u.%u.%u protocol=%u len=%u",
281
+                       pIpPack->IpHdr.Dest[0], pIpPack->IpHdr.Dest[1],
282
+                       pIpPack->IpHdr.Dest[2], pIpPack->IpHdr.Dest[3],
283
+                       pIpPack->IpHdr.Proto, IpBufferTab[i].PacketLength );
284
+
285
+      // destination is in own subnet
286
+      if( (pIpPack->IpHdr.Dest[0] & ConfigMask[0]) == (ConfigIp[0] & ConfigMask[0]) &&
287
+          (pIpPack->IpHdr.Dest[1] & ConfigMask[1]) == (ConfigIp[1] & ConfigMask[1]) &&
288
+          (pIpPack->IpHdr.Dest[2] & ConfigMask[2]) == (ConfigIp[2] & ConfigMask[2]) &&
289
+          (pIpPack->IpHdr.Dest[3] & ConfigMask[3]) == (ConfigIp[3] & ConfigMask[3]) )
290
+      {
291
+        // packet can be sent to destination
292
+        if( ip_eq( pIpPack->IpHdr.Dest, Ip ) )
293
+        {
294
+          // send IP packet
295
+          pIpPack->EthHdr.Type = htons( 0x0800 ); // ethernet packet type: IP
296
+          mac_cpy( pIpPack->EthHdr.Dest, Mac );
297
+          EthernetSend( IpBufferTab[i].pBuffer, IpBufferTab[i].PacketLength );
298
+          // buffer is now free
299
+          IpBufferTab[i].PacketLength = 0;
300
+        }
301
+      }
302
+      // destination is not in own subnet
303
+      else
304
+      {
305
+        // packet can be sent to gateway
306
+        if( ip_eq( ConfigGw, Ip ) )
307
+        {
308
+          // send IP packet
309
+          pIpPack->EthHdr.Type = htons( 0x0800 ); // ethernet packet type: IP
310
+          mac_cpy( pIpPack->EthHdr.Dest, Mac );
311
+          EthernetSend( IpBufferTab[i].pBuffer, IpBufferTab[i].PacketLength );
312
+          // buffer is now free
313
+          IpBufferTab[i].PacketLength = 0;
314
+        }
315
+      }
316
+    }
317
+  } // for( i ...
318
+}
319
+
... ...
@@ -0,0 +1,50 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_ip
9
+#define INC_ip
10
+
11
+#include "ethernet.h"
12
+
13
+// header of an IP packet
14
+struct IpHeader
15
+{
16
+  unsigned char Ver_HdrLen;
17
+  unsigned char Tos;
18
+  unsigned int TotalLen;
19
+  unsigned int Id;
20
+  unsigned int FragOfs;
21
+  unsigned char Ttl;
22
+  unsigned char Proto;
23
+  unsigned int HdrChk;
24
+  unsigned char Src[4];
25
+  unsigned char Dest[4];
26
+};
27
+
28
+// an IP packet
29
+struct IpPacket
30
+{
31
+  struct EthernetHeader EthHdr;
32
+  struct IpHeader IpHdr;
33
+};
34
+
35
+// tick procedure - call every 200ms
36
+extern void IpTick200( void );
37
+
38
+// process a received IP packet
39
+extern void IpRecv( unsigned char * pData, unsigned short Length );
40
+
41
+// send an IP packet
42
+// pData must point to a struct IpPacket with IpHdr.Proto and IpHdr.Dest already initialized
43
+extern void IpSend( unsigned char * pData, unsigned short Length );
44
+
45
+// a MAC address was discovered
46
+// called by ARP to notify IP
47
+extern void IpGotMac( unsigned char Ip[4], unsigned char Mac[6] );
48
+
49
+#endif // #ifdef INC_ip
50
+
... ...
@@ -0,0 +1,29 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_macros
9
+#define INC_macros
10
+
11
+// minimum and maximum
12
+#define min( a, b ) ((a) < (b) ? (a) : (b))
13
+#define max( a, b ) ((a) > (b) ? (a) : (b))
14
+
15
+// number of entries in an array
16
+#define count( array ) (sizeof( (array) ) / sizeof( (array)[0] ))
17
+
18
+// waiting
19
+#define nop( ) { __asm__ __volatile__ ("nop"::); }
20
+
21
+// bit manipulation
22
+#define bit_set( var, bit ) ((var) |= (1 << (bit)))
23
+#define bit_clear( var, bit ) ((var) &= ~(1 << (bit)))
24
+#define bit_toggle( var, bit ) ((var) ^= (1 << (bit)))
25
+#define is_bit_clear( var, bit ) (!(((var) >> (bit)) & 1))
26
+#define is_bit_set( var, bit ) (((var) >> (bit)) & 1)
27
+
28
+#endif // #ifndef INC_macros
29
+
... ...
@@ -0,0 +1,91 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/interrupt.h>
9
+#include <avr/wdt.h>
10
+
11
+#include "arp.h"
12
+#include "bus.h"
13
+#include "cf.h"
14
+#include "dart.h"
15
+#include "debug.h"
16
+#include "eeprom.h"
17
+#include "http.h"
18
+#include "random.h"
19
+#include "rtl8019.h"
20
+#include "status.h"
21
+#include "tcp.h"
22
+#include "timing.h"
23
+#include "uart.h"
24
+
25
+// main code entry point
26
+int main( void )
27
+{
28
+  wdt_reset( );
29
+#ifdef DEBUG
30
+  wdt_disable( );
31
+#else
32
+  wdt_enable( WDTO_60MS );
33
+#endif
34
+  wdt_reset( );
35
+
36
+  // initialize uart to be able to use stdio
37
+  UartInit( );
38
+
39
+  debug_printf( "" );
40
+  debug_printf( "flaneth" );
41
+
42
+  debug_init_printf( "init" );
43
+
44
+  // initialize low level modules
45
+  BusInit( );
46
+
47
+  // initialize middle level modules
48
+  CfInit( );
49
+  DartInit( );
50
+  RtlInit( );
51
+  StatusInit( );
52
+  TimingInit( );
53
+
54
+  // initialize high level modules
55
+  ArpInit( );
56
+  HttpInit( );
57
+  TcpInit( );
58
+
59
+  // use entropy collected during initialization
60
+  RandomTask( );
61
+
62
+  debug_init_printf( "config" );
63
+
64
+  // get configuration from EEPROM
65
+  EepromGetConfig( );
66
+
67
+  // enable interrupts
68
+  sei( );
69
+
70
+  debug_init_printf( "start" );
71
+
72
+  // main loop
73
+  while( 1 )
74
+  {
75
+    wdt_reset( );
76
+    CfTask( );
77
+    wdt_reset( );
78
+    DartTask( );
79
+    wdt_reset( );
80
+    EepromTask( );
81
+    wdt_reset( );
82
+    RandomTask( );
83
+    wdt_reset( );
84
+    RtlTask( );
85
+    wdt_reset( );
86
+    TimingTask( );
87
+  }
88
+
89
+  return 0;
90
+}
91
+
... ...
@@ -0,0 +1,38 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_nethelp
9
+#define INC_nethelp
10
+
11
+// byte order
12
+#define ntohs( n ) ( ((unsigned short)(n) & 0xFF00) >> 8 | \
13
+                     ((unsigned short)(n) & 0x00FF) << 8 )
14
+#define htons( h ) ( ((unsigned short)(h) & 0xFF00) >> 8 | \
15
+                     ((unsigned short)(h) & 0x00FF) << 8 )
16
+#define ntohl( n ) ( ((unsigned long)(n) & 0xFF000000) >> 24 | \
17
+                     ((unsigned long)(n) & 0x00FF0000) >> 8 | \
18
+                     ((unsigned long)(n) & 0x0000FF00) << 8 | \
19
+                     ((unsigned long)(n) & 0x000000FF) << 24 )
20
+#define htonl( h ) ( ((unsigned long)(h) & 0xFF000000) >> 24 | \
21
+                     ((unsigned long)(h) & 0x00FF0000) >> 8 | \
22
+                     ((unsigned long)(h) & 0x0000FF00) << 8 | \
23
+                     ((unsigned long)(h) & 0x000000FF) << 24 )
24
+
25
+// comparing MACs and IPs
26
+#define mac_eq( a, b ) ( (a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && \
27
+                         (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5] )
28
+#define ip_eq( a, b ) ( (a)[0] == (b)[0] && (a)[1] == (b)[1] && \
29
+                        (a)[2] == (b)[2] && (a)[3] == (b)[3] )
30
+
31
+// copying MACs and IPs
32
+#define mac_cpy( dest, src ) ( (dest)[0] = (src)[0], (dest)[1] = (src)[1], (dest)[2] = (src)[2], \
33
+                               (dest)[3] = (src)[3], (dest)[4] = (src)[4], (dest)[5] = (src)[5] )
34
+#define ip_cpy( dest, src ) ( (dest)[0] = (src)[0], (dest)[1] = (src)[1], \
35
+                              (dest)[2] = (src)[2], (dest)[3] = (src)[3] )
36
+
37
+#endif // #ifndef INC_nethelp
38
+
... ...
@@ -0,0 +1,78 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <stdlib.h>
9
+
10
+#include "random.h"
11
+
12
+// number of complete bytes a call to random( ) returns
13
+#if RANDOM_MAX < 0xFF
14
+#error random number generator is not able to return a random byte
15
+#elif RANDOM_MAX < 0xFFFF
16
+#define RANDOM_BYTES 1
17
+#elif RANDOM_MAX < 0xFFFFFF
18
+#define RANDOM_BYTES 2
19
+#elif RANDOM_MAX < 0xFFFFFFFF
20
+#define RANDOM_BYTES 3
21
+#else
22
+#define RANDOM_BYTES 4
23
+#endif
24
+
25
+// entropy collected so far
26
+unsigned long RandomEntropy = 0; // the entropy itself
27
+unsigned char RandomEntropyCnt // number of times entropy was collected so far
28
+              = sizeof( unsigned long ) * 8 - 5; // (use first entropy (few is better than none))
29
+
30
+// provide some entropy
31
+void RandomProvideEntropy( unsigned char Entropy ) // (extern)
32
+{
33
+  // collect entropy
34
+  RandomEntropy = RandomEntropy << 1 ^ (unsigned int)Entropy;
35
+  RandomEntropyCnt++;
36
+}
37
+
38
+// task function to do the work - call from main loop
39
+void RandomTask( void ) // (extern)
40
+{
41
+  // enough entropy was collected
42
+  if( RandomEntropyCnt >= sizeof( unsigned long ) * 8 ) // one time entropy for every bit of RandomEntropy
43
+  {
44
+    RandomEntropyCnt = 0;
45
+    // re-seed random number generator
46
+    srandom( RandomEntropy );
47
+  }
48
+}
49
+
50
+// get random data
51
+void RandomGetData( unsigned char * pData, unsigned char Length ) // (extern)
52
+{
53
+  unsigned long r;
54
+  unsigned char i;
55
+
56
+  // return random data
57
+  for( ; Length >= RANDOM_BYTES; Length -= RANDOM_BYTES )
58
+  {
59
+    r = random( );
60
+    for( i = 0; i < RANDOM_BYTES; i++ )
61
+    {
62
+      *pData = (unsigned char)r;
63
+      pData++;
64
+      r >>= 8;
65
+    }
66
+  }
67
+  if( Length > 0 )
68
+  {
69
+    r = random( );
70
+    for( i = 0; i < Length; i++ )
71
+    {
72
+      *pData = (unsigned char)r;
73
+      pData++;
74
+      r >>= 8;
75
+    }
76
+  }
77
+}
78
+
... ...
@@ -0,0 +1,20 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_random
9
+#define INC_random
10
+
11
+// provide some entropy
12
+extern void RandomProvideEntropy( unsigned char Entropy );
13
+
14
+// task function to do the work - call from main loop
15
+extern void RandomTask( void );
16
+
17
+// get random data
18
+extern void RandomGetData( unsigned char * pData, unsigned char Length );
19
+
20
+#endif // #ifndef INC_random
... ...
@@ -0,0 +1,546 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/io.h>
9
+
10
+#include "bus.h"
11
+#include "config.h"
12
+#include "debug.h"
13
+#include "ethernet.h"
14
+#include "macros.h"
15
+#include "random.h"
16
+#include "rtl8019.h"
17
+#include "timing.h"
18
+
19
+// maximum receive unit
20
+#define RTL_MRU (640)
21
+
22
+// reinitialization timeout
23
+// - if no reception is detected for this time, the RTL8019 is reinitialized
24
+#define RtlReinitTimeoutTicks (50) // in 200ms steps
25
+
26
+// IO pins of RTL8019
27
+#define RTL_DDR_INT (DDRE)
28
+#define RTL_PORT_INT (PORTE)
29
+#define RTL_BIT_INT (5)
30
+#define RTL_DDR_nAEN (DDRE)
31
+#define RTL_PORT_nAEN (PORTE)
32
+#define RTL_BIT_nAEN (4)
33
+#define RTL_DDR_RST (DDRE)
34
+#define RTL_PORT_RST (PORTE)
35
+#define RTL_BIT_RST (3)
36
+// special pin commands
37
+#define RTL_AEN_ACT( ) (bit_clear( RTL_PORT_nAEN, RTL_BIT_nAEN ))
38
+#define RTL_AEN_IDLE( ) (bit_set( RTL_PORT_nAEN, RTL_BIT_nAEN ))
39
+#define RTL_RESET_ACT( ) (bit_set( RTL_PORT_RST, RTL_BIT_RST ))
40
+#define RTL_RESET_IDLE( ) (bit_clear( RTL_PORT_RST, RTL_BIT_RST ))
41
+
42
+// IO pins of RTL8019 EEPROM interface
43
+#define RTL_DDR_EECS (DDRD)
44
+#define RTL_PORT_EECS (PORTD)
45
+#define RTL_PIN_EECS (PIND)
46
+#define RTL_BIT_EECS (7)
47
+#define RTL_DDR_EESK (DDRD)
48
+#define RTL_PORT_EESK (PORTD)
49
+#define RTL_PIN_EESK (PIND)
50
+#define RTL_BIT_EESK (4)
51
+#define RTL_DDR_EEDI (DDRD)
52
+#define RTL_PORT_EEDI (PORTD)
53
+#define RTL_PIN_EEDI (PIND)
54
+#define RTL_BIT_EEDI (5)
55
+#define RTL_DDR_EEDO (DDRD)
56
+#define RTL_PORT_EEDO (PORTD)
57
+#define RTL_BIT_EEDO (6)
58
+
59
+// RTL8019 registers
60
+#define RTL_REG_CR (0x00)
61
+#define RTL_REG_PSTART (0x01)
62
+#define RTL_REG_PAR0 (0x01)                                          
63
+#define RTL_REG_PSTOP (0x02)
64
+#define RTL_REG_BNRY (0x03)
65
+#define RTL_REG_TPSR (0x04)
66
+#define RTL_REG_TBCR0 (0x05)
67
+#define RTL_REG_TBCR1 (0x06)
68
+#define RTL_REG_ISR (0x07)
69
+#define RTL_REG_CURR (0x07)                                       
70
+#define RTL_REG_RSAR0 (0x08)
71
+#define RTL_REG_CRDA0 (0x08)
72
+#define RTL_REG_RSAR1 (0x09)  
73
+#define RTL_REG_CRDAl (0x09)
74
+#define RTL_REG_RBCR0 (0x0A)
75
+#define RTL_REG_ID0 (0x0A)
76
+#define RTL_REG_ID1 (0x0B)
77
+#define RTL_REG_RBCR1 (0x0B)
78
+#define RTL_REG_RSR (0x0C)
79
+#define RTL_REG_RCR (0x0C)
80
+#define RTL_REG_TCR (0x0D)
81
+#define RTL_REG_CNTR0 (0x0D)
82
+#define RTL_REG_DCR (0x0E)
83
+#define RTL_REG_CNTR1 (0x0E)
84
+#define RTL_REG_IMR (0x0F)
85
+#define RTL_REG_CNTR2 (0x0F)
86
+#define RTL_REG_RDMAPORT (0x10)
87
+#define RTL_REG_RSTPORT (0x18)
88
+
89
+// RTL8019AS CR register bits
90
+#define RTL_CR_STP (0)
91
+#define RTL_CR_STA (1)
92
+#define RTL_CR_TXP (2)
93
+#define RTL_CR_RD0 (3)
94
+#define RTL_CR_RD1 (4)
95
+#define RTL_CR_RD2 (5)
96
+#define RTL_CR_PS0 (6)
97
+#define RTL_CR_PS1 (7)
98
+
99
+// RTL8019 ISR register bits
100
+#define RTL_ISR_PRX (0)
101
+#define RTL_ISR_PTX (1)
102
+#define RTL_ISR_RXE (2)
103
+#define RTL_ISR_TXE (3)
104
+#define RTL_ISR_OVW (4)
105
+#define RTL_ISR_CNT (5)
106
+#define RTL_ISR_RDC (6)
107
+#define RTL_ISR_RST (7)
108
+
109
+// RTL8019 (initial) register values
110
+#define RTL_VAL_RCR (0x04)
111
+#define RTL_VAL_TCR (0x00)
112
+#define RTL_VAL_DCR (0x58)
113
+#define RTL_VAL_IMR (0x00)
114
+#define RTL_VAL_TXSTART (0x40)
115
+#define RTL_VAL_RXSTART (0x46)
116
+#define RTL_VAL_RXSTOP (0x60)
117
+
118
+// write a RTL8019 register
119
+extern inline void RtlWriteReg( unsigned char reg, unsigned char val ) // force inlining by using "extern"
120
+{
121
+  BUS_DATA = val; // output value
122
+  BUS_DATA_DDR = 0xFF; // data port to output
123
+  BUS_ADDR = reg; // output address
124
+  RTL_AEN_ACT( ); // set address enable
125
+  BUS_WRITE_ACT( ); // activate write signal
126
+  nop( );
127
+  nop( );
128
+  BUS_WRITE_IDLE( ); // take back write signal
129
+  RTL_AEN_IDLE( ); // take back address enable
130
+  BUS_DATA_DDR = 0x00; // data back port to input
131
+  BUS_DATA = 0x00; // turn off pullups
132
+}
133
+
134
+// write buffer to RTL8019 register
135
+extern inline void RtlWriteRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern"
136
+{
137
+  BUS_DATA = *p_buf; // output first value to initialize port status before switching to output
138
+  BUS_DATA_DDR = 0xFF; // data port to output
139
+  BUS_ADDR = reg; // output address
140
+  RTL_AEN_ACT( ); // set address enable
141
+  for( ; len > 0; p_buf++, len-- ) {
142
+    BUS_DATA = *p_buf; // output value
143
+    BUS_WRITE_ACT( ); // activate write signal
144
+    nop( );
145
+    nop( );
146
+    BUS_WRITE_IDLE( ); // take back write signal
147
+  }
148
+  RTL_AEN_IDLE( ); // take back address enable
149
+  BUS_DATA_DDR = 0x00; // data back port to input
150
+  BUS_DATA = 0x00; // turn off pullups
151
+}
152
+
153
+// write constant to RTL8019 register multiple times
154
+extern inline void RtlWriteRegConst( unsigned char reg, unsigned char val, unsigned short cnt ) // force inlining by using "extern"
155
+{
156
+  BUS_DATA = val; // output value
157
+  BUS_DATA_DDR = 0xFF; // data port to output
158
+  BUS_ADDR = reg; // output address
159
+  RTL_AEN_ACT( ); // set address enable
160
+  for( ; cnt > 0; cnt-- ) {
161
+    BUS_WRITE_ACT( ); // activate write signal
162
+    nop( );
163
+    nop( );
164
+    BUS_WRITE_IDLE( ); // take back write signal
165
+  }
166
+  RTL_AEN_IDLE( ); // take back address enable
167
+  BUS_DATA_DDR = 0x00; // data back port to input
168
+  BUS_DATA = 0x00; // turn off pullups
169
+}
170
+
171
+// read a RTL8019 register
172
+extern inline void RtlReadReg( unsigned char reg, unsigned char * p_var ) // force inlining by using "extern"
173
+{
174
+  BUS_ADDR = reg; // output address
175
+  RTL_AEN_ACT( ); // set address enable
176
+  BUS_READ_ACT( ); // activate read signal
177
+  nop( );
178
+  nop( );
179
+  *p_var = BUS_DATA_IN; // read data
180
+  BUS_READ_IDLE( ); // take back read signal
181
+  RTL_AEN_IDLE( ); // take back address enable
182
+}
183
+
184
+// read buffer from RTL8019 register
185
+extern inline void RtlReadRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern"
186
+{
187
+  BUS_ADDR = reg; // output address
188
+  RTL_AEN_ACT( ); // set address enable
189
+  for( ; len > 0; p_buf++, len-- ) {
190
+    BUS_READ_ACT( ); // activate read signal
191
+    nop( );
192
+    nop( );
193
+    *p_buf = BUS_DATA_IN; // read data
194
+    BUS_READ_IDLE( ); // take back read signal
195
+  }
196
+  RTL_AEN_IDLE( ); // take back address enable
197
+}
198
+
199
+// read a RTL8019 register multiple times and throw away data
200
+extern inline void RtlReadRegMulti( unsigned char reg, unsigned short cnt ) // force inlining by using "extern"
201
+{
202
+  BUS_ADDR = reg; // output address
203
+  RTL_AEN_ACT( ); // set address enable
204
+  for( ; cnt > 0; cnt-- ) {
205
+    BUS_READ_ACT( ); // activate read signal
206
+    nop( );
207
+    nop( );
208
+    BUS_READ_IDLE( ); // take back read signal
209
+  }
210
+  RTL_AEN_IDLE( ); // take back address enable
211
+}
212
+
213
+// reinitialization timeout counter
214
+unsigned char RtlReinitTimeout = 0;
215
+
216
+// emulate eeprom containing RTL8019AS configuration
217
+static void RtlEmulateEeprom( void )
218
+{
219
+  static const unsigned char timeout = 150;
220
+
221
+  unsigned int addr, data, entropy;
222
+  unsigned char t, i;
223
+
224
+  while( 1 ) {
225
+    entropy = 0;
226
+
227
+    // wait for CS HIGH
228
+    for( t = 0; bit_is_clear( RTL_PIN_EECS, RTL_BIT_EECS ); t++ )
229
+      if( t >= timeout )
230
+        return;
231
+    entropy += t;
232
+
233
+    // ignore one clock
234
+    // wait for clock HIGH
235
+    for( t = 0; bit_is_clear( RTL_PIN_EESK, RTL_BIT_EESK ); t++ )
236
+      if( t >= timeout )
237
+        return;
238
+    entropy += t;
239
+    // wait for clock LOW
240
+    for( t = 0; bit_is_set( RTL_PIN_EESK, RTL_BIT_EESK ); t++ )
241
+      if( t >= timeout )
242
+        return;
243
+    entropy += t;
244
+
245
+    // shift in address
246
+    addr = 0;
247
+    for( i = 0; i < 9; i++ ) {
248
+      // wait for clock HIGH
249
+      for( t = 0; bit_is_clear( RTL_PIN_EESK, RTL_BIT_EESK ); t++ )
250
+        if( t >= timeout )
251
+          return;
252
+      entropy += t;
253
+      // read next bit
254
+      addr <<= 1;
255
+      if( bit_is_set( RTL_PIN_EEDI, RTL_BIT_EEDI ) )
256
+        addr |= 0x01;
257
+      // wait for clock LOW
258
+      for( t = 0; bit_is_set( RTL_PIN_EESK, RTL_BIT_EESK ); t++ )
259
+        if( t >= timeout )
260
+          return;
261
+      entropy += t;
262
+    }
263
+
264
+    // get data
265
+    switch( addr ) {
266
+      // CONFIG 3 = FUDUP,LEDS0; CONFIG 4 = -
267
+      case 0x181:
268
+        data = 0x0050;
269
+        break;
270
+      // output zero by default (as if no EEPROM is connected)
271
+      default:
272
+        data = 0x0000;
273
+        break;
274
+    }
275
+
276
+    // shift out data
277
+    for( i = 0; i < 16; i++ ) {
278
+      // wait for clock HIGH
279
+      for( t = 0; bit_is_clear( RTL_PIN_EESK, RTL_BIT_EESK ); t++ )
280
+        if( t >= timeout )
281
+          return;
282
+      entropy += t;
283
+      // write next bit
284
+      if( data & 0x8000 )
285
+        bit_set( RTL_PORT_EEDO, RTL_BIT_EEDO );
286
+      else
287
+        bit_clear( RTL_PORT_EEDO, RTL_BIT_EEDO );
288
+      data <<= 1;
289
+      // wait for clock LOW
290
+      for( t = 0; bit_is_set( RTL_PIN_EESK, RTL_BIT_EESK ); t++ )
291
+        if( t >= timeout )
292
+          return;
293
+      entropy += t;
294
+    }
295
+
296
+    // wait for CS LOW
297
+    for( t = 0; bit_is_set( RTL_PIN_EECS, RTL_BIT_EECS ); t++ )
298
+      if( t >= timeout )
299
+        return;
300
+    entropy += t;
301
+
302
+    // pass on entropy to randomness generator
303
+    RandomProvideEntropy( (unsigned char)entropy );
304
+
305
+  } // while( 1 )
306
+}
307
+
308
+// initialize
309
+void RtlInit( void ) // (extern)
310
+{
311
+  unsigned char i;
312
+  unsigned short j;
313
+
314
+  // setup ports
315
+  bit_clear( RTL_PORT_INT, RTL_BIT_INT ); // pull-up of interrupt pin off
316
+  bit_clear( RTL_DDR_INT, RTL_BIT_INT ); // interrupt pin to input
317
+  bit_set( RTL_PORT_nAEN, RTL_BIT_nAEN ); // address enable pin to HIGH
318
+  bit_set( RTL_DDR_nAEN, RTL_BIT_nAEN ); // address enable pin to output
319
+  bit_set( RTL_PORT_RST, RTL_BIT_RST ); // reset pin to HIGH
320
+  bit_set( RTL_DDR_RST, RTL_BIT_RST ); // reset pin to output
321
+
322
+  // configuration of EEPROM emulation
323
+  bit_clear( RTL_PORT_EECS, RTL_BIT_EECS ); // EECS := input, no pull-up
324
+  bit_clear( RTL_DDR_EECS, RTL_BIT_EECS );
325
+  bit_clear( RTL_PORT_EESK, RTL_BIT_EESK ); // EESK := input, no pull-up
326
+  bit_clear( RTL_DDR_EESK, RTL_BIT_EESK );
327
+  bit_clear( RTL_PORT_EEDI, RTL_BIT_EEDI ); // EEDI := input, no pull-up
328
+  bit_clear( RTL_DDR_EEDI, RTL_BIT_EEDI );
329
+  bit_clear( RTL_PORT_EEDO, RTL_BIT_EEDO ); // EEDO := output, LOW
330
+  bit_set( RTL_DDR_EEDO, RTL_BIT_EEDO );
331
+
332
+  // take back reset
333
+  for( i = 0; i < 10; i++ )
334
+    nop( );
335
+  RTL_RESET_IDLE( );
336
+  RtlEmulateEeprom( );
337
+  for( j = 0; j < 5000; j++ )
338
+    nop( );
339
+
340
+  // clear software reset
341
+  RtlReadReg( RTL_REG_RSTPORT, &i );
342
+  RtlWriteReg( RTL_REG_RSTPORT, 0xFF );
343
+  for( i = 0; i < 100; i++ )
344
+    nop( );
345
+
346
+  // do the same as in reinitialization
347
+  RtlReinit( );
348
+}
349
+
350
+// re-initialize RT8019 (i.e. if MAC changed)
351
+void RtlReinit( void ) // (extern)
352
+{
353
+  unsigned char i, j;
354
+
355
+  // stop RTL8019
356
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STP | 1<<RTL_CR_RD2 );
357
+  for( i = 0; i < 100; i++ )
358
+    nop( );
359
+
360
+  // output RTL8019 ID
361
+  RtlReadReg( RTL_REG_ID0, &i );
362
+  RtlReadReg( RTL_REG_ID1, &j );
363
+  debug_rtl8019_printf( "RTL8019AS (re)init ID=0x%02X,0x%02X", i, j );
364
+
365
+  // set up RTL8019
366
+  RtlWriteReg( RTL_REG_DCR, RTL_VAL_DCR );
367
+  RtlWriteReg( RTL_REG_RBCR0, 0x00 );
368
+  RtlWriteReg( RTL_REG_RBCR1, 0x00 );
369
+  RtlWriteReg( RTL_REG_RCR, 0x04 );
370
+  RtlWriteReg( RTL_REG_TPSR, RTL_VAL_RXSTART );
371
+  RtlWriteReg( RTL_REG_TCR, 0x02 );
372
+  RtlWriteReg( RTL_REG_PSTART, RTL_VAL_RXSTART );
373
+  RtlWriteReg( RTL_REG_BNRY, RTL_VAL_RXSTART );
374
+  RtlWriteReg( RTL_REG_PSTOP, RTL_VAL_RXSTOP );
375
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STP | 1<<RTL_CR_RD2 | 1<<RTL_CR_PS0 );
376
+  for( i = 0; i < 100; i++ )
377
+    nop( );
378
+
379
+  // write MAC to chip
380
+  RtlWriteReg( RTL_REG_CURR, RTL_VAL_RXSTART );
381
+  for( i = 0; i < 6; i++ )
382
+    RtlWriteReg( RTL_REG_PAR0 + i, ConfigMac[i] );
383
+
384
+  // go on with intializing
385
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STP | 1<<RTL_CR_RD2 );
386
+  RtlWriteReg( RTL_REG_DCR, RTL_VAL_DCR );
387
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 );
388
+  RtlWriteReg( RTL_REG_ISR, 1<<RTL_ISR_PRX | 1<<RTL_ISR_PTX |
389
+                          1<<RTL_ISR_RXE | 1<<RTL_ISR_TXE |
390
+                          1<<RTL_ISR_OVW | 1<<RTL_ISR_CNT |
391
+                          1<<RTL_ISR_RDC | 1<<RTL_ISR_RST );
392
+  RtlWriteReg( RTL_REG_IMR, RTL_VAL_IMR );
393
+  RtlWriteReg( RTL_REG_TCR, RTL_VAL_TCR );
394
+
395
+  // start RTL8019
396
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 );
397
+
398
+  // clear reinitialization timeout
399
+  RtlReinitTimeout = 0;
400
+}
401
+
402
+// tick procedure - call every 200ms
403
+void RtlTick200( void ) // (extern)
404
+{
405
+  // increment reinitialization timeout counter
406
+  RtlReinitTimeout++;
407
+
408
+  // reinitialization timeout
409
+  if( RtlReinitTimeout >= RtlReinitTimeoutTicks )
410
+    // reinitialize RTL8019 (resets reinitialization timeout)
411
+    RtlReinit( );
412
+}
413
+
414
+// fetch and process a received packet
415
+static inline void RtlRecv( void )
416
+{
417
+  unsigned short PacketLen;
418
+  unsigned char Packet[RTL_MRU];
419
+
420
+  // fetch packet from RTL8019
421
+  PacketLen = count( Packet );
422
+  RtlReadFrame( (unsigned char *)Packet, &PacketLen );
423
+
424
+  // pass packet on to ethernet
425
+  EthernetRecv( Packet, PacketLen );
426
+}
427
+
428
+// task function to do the work - call from main loop
429
+void RtlTask( void ) // (extern)
430
+{
431
+  unsigned char isr, bnry, curr;
432
+
433
+  // read interrupt register
434
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 );
435
+  RtlReadReg( RTL_REG_ISR, &isr );
436
+  // a packet was received
437
+  if( isr & 1<<RTL_ISR_PRX )
438
+    // use current timestamp for generating some entropy
439
+    TimingEntropy( );
440
+
441
+  // check if receive ring buffer is not empty
442
+  RtlReadReg( RTL_REG_BNRY, &bnry );
443
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 | 1<<RTL_CR_PS0 );
444
+  RtlReadReg( RTL_REG_CURR, &curr );
445
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 );
446
+  if( bnry != curr )
447
+    // fetch and process a single received packet
448
+    RtlRecv( );
449
+
450
+  // reset interrupt bits of RTL8019
451
+  RtlWriteReg( RTL_REG_ISR, 1<<RTL_ISR_PRX | 1<<RTL_ISR_PTX |
452
+                          1<<RTL_ISR_RXE | 1<<RTL_ISR_TXE |
453
+                          1<<RTL_ISR_OVW | 1<<RTL_ISR_CNT |
454
+                          1<<RTL_ISR_RDC | 1<<RTL_ISR_RST );
455
+
456
+  // put RTL8019 in default state (default page selected, ...)
457
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 );
458
+
459
+  // clear reinitialization timeout
460
+  RtlReinitTimeout = 0;
461
+}
462
+
463
+// write an ethernet frame to the RTL8019
464
+void RtlWriteFrame( unsigned char * pData, unsigned short Length ) // (extern)
465
+{
466
+  unsigned char val;
467
+
468
+  debug_rtl8019_printf( "send len=%u", Length );
469
+
470
+  // initialize RTL8019 to transmit
471
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 );
472
+  RtlWriteReg( RTL_REG_TPSR, RTL_VAL_TXSTART );
473
+  RtlWriteReg( RTL_REG_RSAR0, 0x00 );
474
+  RtlWriteReg( RTL_REG_RSAR1, RTL_VAL_TXSTART );
475
+  RtlWriteReg( RTL_REG_ISR, 1<<RTL_ISR_PRX | 1<<RTL_ISR_PTX |
476
+                          1<<RTL_ISR_RXE | 1<<RTL_ISR_TXE |
477
+                          1<<RTL_ISR_OVW | 1<<RTL_ISR_CNT |
478
+                          1<<RTL_ISR_RDC | 1<<RTL_ISR_RST );
479
+  if( Length < 0x3C ) // minimal length is 60 bytes
480
+  {
481
+    RtlWriteReg( RTL_REG_RBCR0, 0x3C );
482
+    RtlWriteReg( RTL_REG_RBCR1, 0x00 );
483
+  }
484
+  else
485
+  {
486
+    RtlWriteReg( RTL_REG_RBCR0, (unsigned char)Length );
487
+    RtlWriteReg( RTL_REG_RBCR1, (unsigned char)(Length >> 8) );
488
+  }
489
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD1 );
490
+
491
+  // write data to RTL8019
492
+  RtlWriteRegBuf( RTL_REG_RDMAPORT, pData, Length );
493
+  if( Length < 0x3C ) // padding
494
+  RtlWriteRegConst( RTL_REG_RDMAPORT, 0x00, 0x3C - Length );
495
+
496
+  // wait for RTL8019
497
+  do
498
+  {
499
+    RtlReadReg( RTL_REG_ISR, &val );
500
+  }
501
+  while( (val & 1<<RTL_ISR_RDC) == 0x00 );
502
+
503
+  // start transmission
504
+  if( Length < 0x3C ) // minimal length is 60 bytes
505
+  {
506
+    RtlWriteReg( RTL_REG_TBCR0, 0x3C );
507
+    RtlWriteReg( RTL_REG_TBCR1, 0x00 );
508
+  }
509
+  else
510
+  {
511
+    RtlWriteReg( RTL_REG_TBCR0, (unsigned char)Length );
512
+    RtlWriteReg( RTL_REG_TBCR1, (unsigned char)(Length >> 8) );
513
+  }
514
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_TXP | 1<<RTL_CR_RD2 );
515
+}
516
+
517
+// read an ethernet frame from the RTL8019
518
+// *pLength must be initialized to the buffer size
519
+void RtlReadFrame( unsigned char * pData, unsigned short * pLength ) // (extern)
520
+{
521
+  unsigned char tmp1, tmp2;
522
+  unsigned short read_len, len, cnt;
523
+
524
+  // get size of received packet
525
+  RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD0 | 1<<RTL_CR_RD1 );
526
+  RtlReadReg( RTL_REG_RDMAPORT, &tmp1 );
527
+  RtlReadReg( RTL_REG_RDMAPORT, &tmp1 );
528
+  RtlReadReg( RTL_REG_RDMAPORT, &tmp1 );
529
+  RtlReadReg( RTL_REG_RDMAPORT, &tmp2 );
530
+  read_len = ((unsigned short)tmp2 << 8 | (unsigned short)tmp1);
531
+
532
+  // subtract length of CRC (4 bytes)
533
+  len = read_len < 4 ? 0 : read_len - 4;
534
+
535
+  debug_rtl8019_printf( "recv len=%u", len );
536
+
537
+  // read as much data as possible into buffer
538
+  cnt = min( len, *pLength );
539
+  RtlReadRegBuf( RTL_REG_RDMAPORT, pData, cnt );
540
+  *pLength = cnt;
541
+
542
+  // get rest of data (rest of real data that did not fit into buffer, CRC)
543
+  if( read_len > cnt )
544
+    RtlReadRegMulti( RTL_REG_RDMAPORT, read_len - cnt );
545
+}
546
+
... ...
@@ -0,0 +1,31 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_rtl8019
9
+#define INC_rtl8019
10
+
11
+// initialize
12
+extern void RtlInit( void );
13
+
14
+// re-initialize RT8019 (i.e. if MAC changed)
15
+extern void RtlReinit( void );
16
+
17
+// tick procedure - call every 200ms
18
+extern void RtlTick200( void );
19
+
20
+// task function to do the work - call from main loop
21
+extern void RtlTask( void );
22
+
23
+// write an ethernet frame to the RTL8019
24
+extern void RtlWriteFrame( unsigned char * pData, unsigned short Length );
25
+
26
+// read an ethernet frame from the RTL8019
27
+// *pLength must be initialized to the buffer size
28
+extern void RtlReadFrame( unsigned char * pData, unsigned short * pLength );
29
+
30
+#endif // #ifndef INC_rtl8019
31
+
... ...
@@ -0,0 +1,59 @@
1
+<?php
2
+include("nb_easyxml_lite.php");
3
+include("nb_soapfuncs.php");
4
+
5
+/********* Data structures used by this web service *********
6
+*
7
+* type GetHitResult{
8
+*     ['factor']=>{
9
+*     }
10
+*     ['value']=>{
11
+*     }
12
+* }
13
+*
14
+*/
15
+
16
+class service
17
+{
18
+    var $Url;
19
+
20
+/**
21
+* web service consumer method GetHit
22
+* 
23
+* @param timeout : unsigned
24
+* @return GetHitResult 
25
+*/
26
+    function GetHit($timeout) // returns a GetHitResult
27
+    {
28
+        $soapXML = "<soap:Body>\n";
29
+        $soapXML .= "<GetHit xmlns=\"http://localhost:8080/dart\">\n";
30
+        // Parameter unsigned timeout
31
+        $soapXML .= $this->soapify_unsigned($timeout, "timeout");
32
+        $soapXML .= "</GetHit>\n";
33
+        $soapXML .= "</soap:Body>\n";
34
+        $soapXML = nbSOAP_Envelope($soapXML);
35
+        // Send the request (syncronous http 1.0 only at the moment)
36
+        $soapOut = nbSOAP_request10($this->Url, "http://localhost:8080/dart/GetHit", $soapXML);
37
+    // is it an error?
38
+        $soapStart = strpos($soapOut, "<?xml");
39
+        if($soapStart==-1)
40
+          return false;
41
+        $xml = nb_easyxmldoc(substr($soapOut,$soapStart));
42
+        $body = $xml->findElement("Body", 0, "http://schemas.xmlsoap.org/soap/envelope/");
43
+        $cp = $xml->FindChildElement($body);
44
+        if($cp==false) // empty soap:Body
45
+            return null;
46
+        $tn = $xml->getName($cp);
47
+        if($tn=="Fault") // should really report it...
48
+            return desoap_nbSOAPFault($xml, $cp);
49
+        if($tn != "GetHitResponse")
50
+            return null;
51
+        $cp = $xml->FindChildElement($cp);
52
+        if($cp==false) // empty value
53
+            return null;
54
+        $result = $this->desoap_GetHitResult($xml, $cp, "GetHit");
55
+        return $result;
56
+    }
57
+
58
+}
59
+?>
... ...
@@ -0,0 +1,4 @@
1
+from SOAPpy import SOAPProxy
2
+server = SOAPProxy('http://localhost:8080/')
3
+print server.GetHit(5)
4
+
... ...
@@ -0,0 +1,56 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<definitions name="DartService"
3
+   targetNamespace="http://stefan.blinkenarea.org/flaneth/dartboard/"
4
+   xmlns="http://schemas.xmlsoap.org/wsdl/"
5
+   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
6
+   xmlns:tns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"
7
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
8
+ 
9
+   <message name="GetHit">
10
+      <part name="timeout" type="xsd:nonNegativeInteger">
11
+        <documentation>time in seconds to wait for a hit</documentation>
12
+      </part>
13
+   </message>
14
+   <message name="GetHitResponse">
15
+      <part name="factor" type="xsd:positiveInteger">
16
+        <documentation>factor of the hit field</documentation>
17
+      </part>
18
+      <part name="value" type="xsd:positiveInteger">
19
+        <documentation>value of the hit field</documentation>
20
+      </part>
21
+   </message>
22
+ 
23
+   <portType name="GetHitPortType">
24
+      <operation name="GetHitOperation">
25
+         <input message="tns:GetHit"/>
26
+         <output message="tns:GetHitResponse"/>
27
+      </operation>
28
+   </portType>
29
+   
30
+   <binding name="GetHitBinding" type="tns:GetHitPortType">
31
+      <soap:binding style="rpc"
32
+         transport="http://schemas.xmlsoap.org/soap/http"/>
33
+      <operation name="GetHitOperation">
34
+         <soap:operation soapAction="GetHitAction"/>
35
+         <input>
36
+            <soap:body
37
+               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
38
+               use="encoded"/>
39
+         </input>
40
+         <output>
41
+            <soap:body
42
+               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
43
+               use="encoded"/>
44
+         </output>
45
+      </operation>
46
+   </binding>
47
+ 
48
+   <service name="GetHitService">
49
+      <documentation>WSDL File for GetHitService of flaneth dartboard mod</documentation>
50
+      <port binding="tns:GetHitBinding" name="GetHitPort">
51
+         <soap:address 
52
+            location="http://flaneth-dartboard-mod:80/"/>
53
+      </port>
54
+   </service>
55
+</definitions>
56
+
... ...
@@ -0,0 +1,12 @@
1
+POST /dart HTTP/1.0
2
+content-length: 304
3
+
4
+<soap:Envelope
5
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
6
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
7
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
8
+    <GetHit>
9
+      <timeout>5</timeout>
10
+    </GetHit>
11
+  </soap:Body>
12
+</soap:Envelope>
... ...
@@ -0,0 +1,9 @@
1
+<soap:Envelope
2
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
3
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
4
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
5
+    <GetHit>
6
+      <timeout>5</timeout>
7
+    </GetHit>
8
+  </soap:Body>
9
+</soap:Envelope>
... ...
@@ -0,0 +1,17 @@
1
+POST / HTTP/1.0
2
+Host: localhost:8080
3
+User-agent: SOAPpy 0.11.3 (pywebsvcs.sf.net)
4
+Content-type: text/xml; charset="UTF-8"
5
+Content-length: 485
6
+SOAPAction: "GetHit"
7
+
8
+<?xml version="1.0" encoding="UTF-8"?>
9
+<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
10
+<SOAP-ENV:Body>
11
+<GetHit SOAP-ENC:root="1">
12
+<v1>
13
+<timeout xsi:type="xsd:int">5</timeout>
14
+</v1>
15
+</GetHit>
16
+</SOAP-ENV:Body>
17
+</SOAP-ENV:Envelope>
... ...
@@ -0,0 +1,10 @@
1
+<soap:Envelope
2
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
3
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
4
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
5
+    <GetHitResponse>
6
+      <factor>2</factor>
7
+      <value>25</value>
8
+    </GetHitResponse>
9
+  </soap:Body>
10
+</soap:Envelope>
... ...
@@ -0,0 +1,10 @@
1
+<soap:Envelope
2
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
3
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
4
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
5
+    <GetHitResponse>
6
+      <factor>1</factor>
7
+      <value>1</value>
8
+    </GetHitResponse>
9
+  </soap:Body>
10
+</soap:Envelope>
... ...
@@ -0,0 +1,8 @@
1
+<soap:Envelope
2
+    xmlns:soap="http://www.w3.org/2001/12/soap-envelope/"
3
+    soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
4
+  <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap">
5
+    <GetHitResponse>
6
+    </GetHitResponse>
7
+  </soap:Body>
8
+</soap:Envelope>
... ...
@@ -0,0 +1,17 @@
1
+HTTP/1.0 200 OK
2
+Server: <a href="http://pywebsvcs.sf.net">SOAPpy 0.11.3</a> (Python 2.4.4)
3
+Date: Sun, 09 Nov 2008 19:23:10 GMT
4
+Content-type: text/xml; charset="UTF-8"
5
+Content-length: 564
6
+
7
+<?xml version="1.0" encoding="UTF-8"?>
8
+<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
9
+<SOAP-ENV:Body>
10
+<GetHitResponse SOAP-ENC:root="1">
11
+<Result SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array">
12
+<factor>2</factor>
13
+<value>25</value>
14
+</Result>
15
+</GetHitResponse>
16
+</SOAP-ENV:Body>
17
+</SOAP-ENV:Envelope>
... ...
@@ -0,0 +1,91 @@
1
+<?php
2
+include("nb_easyxml_lite.php");
3
+include("nb_soapfuncs.php");
4
+
5
+/********* Data structures used by this web service *********
6
+*
7
+* type GetHitResult{
8
+*     ['factor']=>{
9
+*     }
10
+*     ['value']=>{
11
+*     }
12
+* }
13
+*
14
+*/
15
+
16
+class service extends service_nbSOAP
17
+{
18
+    var $Url;
19
+
20
+/**
21
+* web service provider method GetHit
22
+* 
23
+* @param timeout : unsigned
24
+* @return GetHitResult 
25
+*/
26
+    function GetHit($timeout)
27
+    {
28
+    	return new nbSOAPFault("unimplemented", "The GetHitservice has not been implemented yet", "");
29
+        // Fill in web method fuctionality here.
30
+        // return a GetHitResult
31
+    }
32
+
33
+}
34
+
35
+/********************* Do not alter the generated code below ************************/
36
+
37
+if($_SERVER['REQUEST_METHOD']=="GET")
38
+{
39
+  echo "information call, front page, WSDL or function info. ";
40
+  echo "All this functionality still has to be written...";
41
+}
42
+else
43
+{
44
+    $in = file_get_contents("php://input");
45
+    $action = $_SERVER['HTTP_SOAPACTION'];
46
+    $action = str_replace("\\\"","",$action);
47
+    $SoapClass = new service();
48
+    $soapXML = $SoapClass->PerformSoapAction($in, $action);
49
+    $soapXML = nbSOAP_Envelope($soapXML);
50
+    header("Content-Type: text/xml; charset=utf-8");
51
+    echo $soapXML;
52
+}
53
+
54
+class service_nbSOAP //extends nbSOAP
55
+{
56
+    function PerformSoapAction($in, $action)
57
+    {
58
+        $xml = nb_easyxmldoc($in);
59
+        $body = $xml->findElement("Body", 0, "http://schemas.xmlsoap.org/soap/envelope/");
60
+        if($body == false)
61
+            return "<soap:Fault><faultstring>SOAP body not found</faultstring></soap:Fault>";
62
+        $params = $xml->findChildElement($body);
63
+        switch($action)
64
+        {
65
+        case "http://localhost:8080/dart/GetHit":
66
+            // deserialize parameters
67
+            $pidx = $xml->findChildElement($params, "timeout");
68
+            if($pidx != false)
69
+              $p_timeout = $this->desoap_unsigned($xml, $pidx, "timeout");
70
+            else
71
+                $p_timeout = null;
72
+            // call the method
73
+            $res = $this->GetHit($p_timeout);
74
+            if(is_a($res,"nbSOAPFault"))
75
+            {
76
+                return "<soap:Body>\n" . $res->soapify() . "</soap:Body>";
77
+            }
78
+            // serialize the result
79
+            $soapXML = $this->soapify_GetHitResult($res, "GetHit");
80
+            $soapXML = "<GetHitResponse xmlns=\"http://localhost:8080/dart\">" . $soapXML;
81
+            $soapXML .= "</GetHitResponse>";
82
+            return "<soap:Body>\n" . $soapXML . "</soap:Body>";
83
+            break;
84
+        default:
85
+            return "<soap:Fault><faultstring>Unrecognised SOAP action called.</faultstring></soap:Fault>";
86
+            break;
87
+        }
88
+    }
89
+
90
+}
91
+?>
... ...
@@ -0,0 +1,9 @@
1
+import SOAPpy
2
+
3
+def GetHit( timeout ):
4
+  return ( 2, 25 )
5
+
6
+server = SOAPpy.SOAPServer( ("localhost", 8080) )
7
+server.registerFunction( GetHit )
8
+server.serve_forever( )
9
+
... ...
@@ -0,0 +1,62 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/io.h>
9
+
10
+#include "macros.h"
11
+#include "status.h"
12
+
13
+// IO pins of bus
14
+#define STATUS_DDR (DDRE)
15
+#define STATUS_PORT (PORTE)
16
+#define STATUS_BIT (2)
17
+
18
+// status information
19
+char StatusInfoCfPresent = 0; // presence of working compact flash card (boolean) (extern)
20
+
21
+// number of times to blink status LED
22
+#define StatusBlinkCntIdle (1)
23
+#define StatusBlinkCntIdleWithCf (2)
24
+#define StatusBlinkCntWorking (3)
25
+#define StatusBlinkCntMax (3) 
26
+unsigned char StatusBlinkCnt = StatusBlinkCntIdle;
27
+
28
+// interval counter for blinking status LED
29
+unsigned char StatusBlinkInterval = 0;
30
+
31
+// initialize
32
+void StatusInit( void )
33
+{
34
+  //set up IO pin of status LED as output
35
+  bit_clear( STATUS_PORT, STATUS_BIT );
36
+  bit_set( STATUS_DDR, STATUS_BIT );
37
+}
38
+
39
+// tick procedure - call every 200ms
40
+void StatusTick200( void )
41
+{
42
+  // turn on status LED only in even intervals and if not yet blinked StatusBlinkCnt times
43
+  if( (StatusBlinkInterval & 0x01) == 0 && StatusBlinkInterval >> 1 < StatusBlinkCnt )
44
+    bit_set( STATUS_PORT, STATUS_BIT );
45
+  else
46
+    bit_clear( STATUS_PORT, STATUS_BIT );
47
+
48
+  // next interval
49
+  StatusBlinkInterval++;
50
+
51
+  // blink cycle finished
52
+  if( StatusBlinkInterval >> 1 > StatusBlinkCntMax ) {
53
+    StatusBlinkInterval = 0;
54
+
55
+    // set new blink count depending on status information
56
+    if( StatusInfoCfPresent )
57
+      StatusBlinkCnt = StatusBlinkCntIdleWithCf;
58
+    else
59
+      StatusBlinkCnt = StatusBlinkCntIdle;
60
+  }
61
+}
62
+
... ...
@@ -0,0 +1,21 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_status
9
+#define INC_status
10
+
11
+// status information
12
+extern char StatusInfoCfPresent; // presence of working compact flash card (boolean)
13
+
14
+// initialize
15
+extern void StatusInit( void );
16
+
17
+// tick procedure - call every 200ms
18
+extern void StatusTick200( void );
19
+
20
+#endif // #ifdef INC_status
21
+
... ...
@@ -0,0 +1,1058 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <stdio.h>
9
+
10
+#include "config.h"
11
+#include "checksum.h"
12
+#include "debug.h"
13
+#include "ethernet.h"
14
+#include "http.h"
15
+#include "ip.h"
16
+#include "macros.h"
17
+#include "nethelp.h"
18
+#include "random.h"
19
+#include "tcp.h"
20
+
21
+#define TCP_URG 0x20
22
+#define TCP_ACK 0x10
23
+#define TCP_PSH 0x08
24
+#define TCP_RST 0x04
25
+#define TCP_SYN 0x02
26
+#define TCP_FIN 0x01
27
+#define TCP_FLAGS 0x3F
28
+
29
+#define TcpResendTicks 5 // time after which to resend a packet not ACKed (in 200ms steps, max. 255)
30
+#define TcpTimeWaitTicks 20 // time to wait in TIME_WAIT state (in 200ms steps, max. 255)
31
+#define TcpTimeoutTicks 250 // maximum idle time of connection before it is reset (in 200ms steps, max. 255)
32
+#define TcpMaxLifeTimeTicks 250 // maximum lifetime of connection before it is reset (in 200ms steps, max. 255)
33
+
34
+// TCP connections
35
+struct TcpConnection TcpConns[8];
36
+
37
+// initialize
38
+void TcpInit( void ) // (extern)
39
+{
40
+  unsigned char i;
41
+
42
+  // set all connections to closed
43
+  for( i = 0; i < count( TcpConns ); i++ )
44
+    TcpConns[i].State = TCP_CLOSED;
45
+}
46
+
47
+// send a TCP packet
48
+// pData must point to a struct TcpPacket with TcpHdr.SrcPort, TcpHdr.DestPort,
49
+// TcpHdr.SeqNo, TcpHdr.AckNo, TcpHdr.WndSz and IpHdr.Dest already initialized
50
+static void TcpSendPacket( unsigned char * pData, unsigned short Length, unsigned char optLen, unsigned char flags )
51
+{
52
+  struct TcpPacket * pTcpPack;
53
+  unsigned int chk;
54
+
55
+  // packet too short
56
+  if( Length < sizeof( struct TcpPacket ) + optLen )
57
+    return;
58
+
59
+  // convert pointer to UDP packet
60
+  // (this saves us from always casting pData)
61
+  pTcpPack = (struct TcpPacket *)pData;
62
+
63
+  debug_tcp_printf( "send src=%u dest=%u flags=%s%s%s%s%s%s len=%u",
64
+                    ntohs( pTcpPack->TcpHdr.SrcPort ),
65
+                    ntohs( pTcpPack->TcpHdr.DestPort ),
66
+                    flags & TCP_URG ? "U" : "",
67
+                    flags & TCP_ACK ? "A" : "",
68
+                    flags & TCP_PSH ? "P" : "",
69
+                    flags & TCP_RST ? "R" : "",
70
+                    flags & TCP_SYN ? "S" : "",
71
+                    flags & TCP_FIN ? "F" : "",
72
+                    Length );
73
+
74
+  // fill in header values
75
+  pTcpPack->TcpHdr.Ofs_Flags = htons( (unsigned short)((optLen + 23) & 0x3C) << 10 | (unsigned short)(flags & TCP_FLAGS) );
76
+  pTcpPack->TcpHdr.Chk = 0x0000;
77
+  pTcpPack->TcpHdr.UrgentPtr = 0x0000;
78
+  ip_cpy( pTcpPack->IpHdr.Src, ConfigIp ); // put IP already here into IP header
79
+                                           // because it is needed for calculation of UDP checksum
80
+
81
+  // generate checksum
82
+  chk = Checksum( (unsigned char *)&pTcpPack->IpHdr.Src,
83
+                  Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8,
84
+                  0x0006,
85
+                  Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) );
86
+  pTcpPack->TcpHdr.Chk = htons( chk );
87
+
88
+  // send TCP packet
89
+  pTcpPack->IpHdr.Proto = 0x06; // TCP
90
+  IpSend( pData, Length );
91
+}
92
+
93
+// send an empty segment
94
+static void TcpEmptySegment( struct TcpConnection * pConn, unsigned long seq, unsigned long ack, unsigned char flags )
95
+{
96
+  struct TcpPacket EsPack;
97
+
98
+  // send empty TCP segment
99
+  EsPack.TcpHdr.SrcPort = htons( pConn->LocalPort );
100
+  EsPack.TcpHdr.DestPort = htons( pConn->RemotePort );
101
+  EsPack.TcpHdr.SeqNo = htonl( seq );
102
+  EsPack.TcpHdr.AckNo = htonl( ack );
103
+  EsPack.TcpHdr.WndSz = htons( pConn->RcvWnd );
104
+  ip_cpy( EsPack.IpHdr.Dest, pConn->RemoteIp );
105
+  TcpSendPacket( (unsigned char *)&EsPack, sizeof( EsPack ), 0, flags );
106
+  return;
107
+}
108
+
109
+// send a SYN segment (empty with MSS option set)
110
+static void TcpSynSegment( struct TcpConnection * pConn, unsigned long seq, unsigned long ack, unsigned char flags )
111
+{
112
+  struct
113
+  {
114
+    struct TcpPacket Tcp;
115
+    struct
116
+    {
117
+      unsigned char Kind, Len;
118
+      unsigned short Mss;
119
+    } MssOpt;
120
+  } Pack;
121
+
122
+  // send empty TCP segment with MSS
123
+  Pack.Tcp.TcpHdr.SrcPort = htons( pConn->LocalPort );
124
+  Pack.Tcp.TcpHdr.DestPort = htons( pConn->RemotePort );
125
+  Pack.Tcp.TcpHdr.SeqNo = htonl( seq );
126
+  Pack.Tcp.TcpHdr.AckNo = htonl( ack );
127
+  Pack.Tcp.TcpHdr.WndSz = htons( pConn->RcvWnd );
128
+  ip_cpy( Pack.Tcp.IpHdr.Dest, pConn->RemoteIp );
129
+  Pack.MssOpt.Kind = 2;
130
+  Pack.MssOpt.Len = 4;
131
+  Pack.MssOpt.Mss = htons( 256 );
132
+  TcpSendPacket( (unsigned char *)&Pack, sizeof( Pack ), sizeof( Pack.MssOpt ), flags );
133
+  return;
134
+}
135
+
136
+// send a data segment
137
+static void TcpSendDataSegment( unsigned char connNo, struct TcpConnection * pConn, char needSendAck )
138
+{
139
+  unsigned long sendDataLenL;
140
+  unsigned short sendDataLen, len;
141
+  struct
142
+  {
143
+    struct TcpPacket Tcp;
144
+    unsigned char Data[256]; // do not use larger segments to save stack memory
145
+  } Packet;
146
+
147
+  // if outbound connection is not closed yet
148
+  if( pConn->State == TCP_ESTAB || pConn->State == TCP_CLOSE_WAIT )
149
+  {
150
+    // get maximum number of bytes that might be sent in this segment
151
+    sendDataLenL = (unsigned long)pConn->SndWnd - (pConn->SndNxt - pConn->SndUna);
152
+    if( (signed long)sendDataLenL < 0 ) // just to be on the safe side - this should never happen
153
+      sendDataLen = 0;
154
+    sendDataLen = (unsigned short)min( sendDataLenL, (unsigned long)pConn->Mss );
155
+    sendDataLen = min( sendDataLen, sizeof( Packet.Data ) );
156
+    // get data to send from user
157
+    if( sendDataLen > 0 )
158
+    {
159
+      debug_tcp_printf( "notify send no=%u pos=%lu max_len=%u",
160
+                        connNo, pConn->SndNxt - (pConn->Iss + 1), sendDataLen );
161
+      len = pConn->Notify->Send( connNo, pConn->SndNxt - (pConn->Iss + 1), Packet.Data, sendDataLen );
162
+      if( len > sendDataLen ) // returned 0xFFFF (or any number too large) to close connection
163
+      {
164
+        debug_tcp_printf( "notify send no=%u close", connNo );
165
+        TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // send TCP FIN
166
+        pConn->SndNxt++;
167
+        pConn->State = TCP_FIN_WAIT_1; // go to state FIN-WAIT-1
168
+        debug_tcp_printf( "notify close no=%u", connNo );
169
+        pConn->Notify->Close( connNo ); // signal "connection closed" to user
170
+        return;
171
+      }
172
+      debug_tcp_printf( "notify send no=%u len=%u", connNo, len );
173
+      sendDataLen = len;
174
+    }
175
+  }
176
+  // if outbound connection is already closed
177
+  else
178
+    // do not send data
179
+    sendDataLen = 0;
180
+
181
+  // send a segment if data is available or an ACK needs to be sent
182
+  if( sendDataLen > 0 || needSendAck )
183
+  {
184
+    // send TCP segment
185
+    Packet.Tcp.TcpHdr.SrcPort = htons( pConn->LocalPort );
186
+    Packet.Tcp.TcpHdr.DestPort = htons( pConn->RemotePort );
187
+    Packet.Tcp.TcpHdr.SeqNo = htonl( pConn->SndNxt );
188
+    Packet.Tcp.TcpHdr.AckNo = htonl( pConn->RcvNxt );
189
+    Packet.Tcp.TcpHdr.WndSz = htons( pConn->RcvWnd );
190
+    ip_cpy( Packet.Tcp.IpHdr.Dest, pConn->RemoteIp );
191
+    TcpSendPacket( (unsigned char *)&Packet, sizeof( struct TcpPacket ) + sendDataLen, 0,
192
+                   sendDataLen > 0 ? TCP_ACK | TCP_PSH : TCP_ACK );
193
+    pConn->SndNxt += sendDataLen;
194
+  }
195
+}
196
+
197
+// tick procedure - call every 200ms
198
+void TcpTick200( void ) // (extern)
199
+{
200
+  unsigned char i, MaxTicks;
201
+
202
+  // for all active connections
203
+  for( i = 0; i < count( TcpConns ); i++ )
204
+  {
205
+
206
+    if( TcpConns[i].State != TCP_CLOSED )
207
+    {
208
+      // increase normal timer
209
+      TcpConns[i].Ticks++;
210
+
211
+      // get maximum value for normal timer
212
+      MaxTicks = TcpConns[i].State == TCP_TIME_WAIT ? TcpTimeWaitTicks : TcpResendTicks;
213
+      // normal timer elapsed
214
+      if( TcpConns[i].Ticks >= MaxTicks )
215
+      {
216
+        // reset normal timer
217
+        TcpConns[i].Ticks = 0;
218
+
219
+        // different behaviour in different states
220
+        switch( TcpConns[i].State )
221
+        {
222
+
223
+          case TCP_SYN_RCVD:
224
+            // resend SYN,ACK segment
225
+            TcpSynSegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_SYN | TCP_ACK );
226
+            TcpConns[i].SndNxt = TcpConns[i].SndUna + 1;
227
+            break;
228
+
229
+          case TCP_SYN_SENT:
230
+            // resend SYN segment
231
+            TcpSynSegment( &TcpConns[i], TcpConns[i].SndUna, 0, TCP_SYN );
232
+            TcpConns[i].SndNxt = TcpConns[i].SndUna + 1;
233
+            break;
234
+
235
+          case TCP_ESTAB:
236
+          case TCP_CLOSE_WAIT:
237
+            // if something is not yet ACKed
238
+            if( (long)(TcpConns[i].SndUna - TcpConns[i].SndNxt) < 0 ) {
239
+              // resend data segment
240
+              TcpConns[i].SndNxt = TcpConns[i].SndUna; // some kind of "go back N"
241
+              // BUG: this is not really "go back N"
242
+              // according to RFC793, every segment sent and not acknowledged has to be stored
243
+              // in the resend queue until is is acknowledged
244
+              // but this is not possible on a microcontroller with 4kB of RAM
245
+              TcpSendDataSegment( i, &TcpConns[i], 0 );
246
+            }
247
+            break;
248
+
249
+          case TCP_FIN_WAIT_1:
250
+          case TCP_CLOSING:
251
+          case TCP_LAST_ACK:
252
+            // resend FIN segment
253
+            TcpEmptySegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_FIN | TCP_ACK );
254
+            TcpConns[i].SndNxt = TcpConns[i].SndUna + 1;
255
+            break;
256
+
257
+          case TCP_TIME_WAIT:
258
+            // close connection, free TCB
259
+            TcpConns[i].State = TCP_CLOSED;
260
+            break;
261
+
262
+        } // switch( TcpConns[i].State )
263
+
264
+      } // if( TcpConns[i].Ticks >= ...
265
+
266
+    } // if( TcpConns[i].State != ...
267
+
268
+    if( TcpConns[i].State != TCP_CLOSED )
269
+    {
270
+      // increase timeout timer
271
+      TcpConns[i].Timeout++;
272
+
273
+      // timeout timer elapsed
274
+      if( TcpConns[i].Timeout >= TcpTimeoutTicks )
275
+      {
276
+        // send a RST segment
277
+        TcpEmptySegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_RST );
278
+        // depending on state ...
279
+        switch( TcpConns[i].State )
280
+        {
281
+          case TCP_SYN_RCVD:
282
+          case TCP_ESTAB:
283
+          case TCP_CLOSE_WAIT:
284
+            TcpConns[i].State = TCP_CLOSED; // close connection
285
+            debug_tcp_printf( "notify close no=%u", i );
286
+            TcpConns[i].Notify->Close( i ); // tell user that connection was closed
287
+            break;
288
+          default:
289
+            TcpConns[i].State = TCP_CLOSED; // close connection
290
+        }
291
+
292
+      } // if( TcpConns[i].Timeout >= ...
293
+
294
+    } // if( TcpConns[i].State != ...
295
+
296
+    if( TcpConns[i].State != TCP_CLOSED )
297
+    {
298
+      // increase lifetime timer
299
+      TcpConns[i].LifeTime++;
300
+
301
+      // lifetime timer elapsed
302
+      // - connections may not last forever - even not with traffic on them
303
+      if( TcpConns[i].LifeTime >= TcpMaxLifeTimeTicks )
304
+      {
305
+        // send a RST segment
306
+        TcpEmptySegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_RST );
307
+        // depending on state ...
308
+        switch( TcpConns[i].State )
309
+        {
310
+          case TCP_SYN_RCVD:
311
+          case TCP_ESTAB:
312
+          case TCP_CLOSE_WAIT:
313
+            TcpConns[i].State = TCP_CLOSED; // close connection
314
+            debug_tcp_printf( "notify close no=%u", i );
315
+            TcpConns[i].Notify->Close( i ); // tell user that connection was closed
316
+            break;
317
+          default:
318
+            TcpConns[i].State = TCP_CLOSED; // close connection
319
+        }
320
+      } // if( TcpConns[i].LifeTime >= ...
321
+
322
+    } // if( TcpConns[i].State != ...
323
+
324
+  } // for( i ...
325
+}
326
+
327
+// process a received TCP packet
328
+void TcpRecv( unsigned char * pData, unsigned short Length ) // (extern)
329
+{
330
+  struct TcpPacket * pTcpPack;
331
+  unsigned long seq, ack, seqEnd;
332
+  unsigned short localPort, remotePort, wnd, mss, ofs, len, tmp, rcvWnd;
333
+  unsigned char i, flags, * optPtr, optLen, connNo;
334
+  struct TcpConnection * pConn;
335
+  char accept, sendAck;
336
+  struct TcpNotify * pNotify;
337
+
338
+  // packet too short
339
+  if( Length < sizeof( struct TcpPacket ) )
340
+    return;
341
+
342
+  // convert pointer to TCP packet
343
+  // (this saves us from always casting pData)
344
+  pTcpPack = (struct TcpPacket *)pData;
345
+
346
+  // test checksum
347
+  if( Checksum( (unsigned char*)&pTcpPack->IpHdr.Src,
348
+                Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8,
349
+                0x0006,
350
+                Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) ) != 0 )
351
+    return;
352
+
353
+  // get local and remote port
354
+  localPort = ntohs( pTcpPack->TcpHdr.DestPort );
355
+  remotePort = ntohs( pTcpPack->TcpHdr.SrcPort );
356
+
357
+  // ignore packets sent from or to port 0
358
+  // - this might be some attack
359
+  if( localPort == 0 || remotePort == 0 )
360
+    return;
361
+
362
+  // get sequence number, acknowledge number and window size
363
+  seq = ntohl( pTcpPack->TcpHdr.SeqNo );
364
+  ack = ntohl( pTcpPack->TcpHdr.AckNo );
365
+  wnd = ntohs( pTcpPack->TcpHdr.WndSz );
366
+  // maximum segment size: liberal default according to RFC879
367
+  mss = 536;
368
+
369
+  // get flags
370
+  flags = ntohs( pTcpPack->TcpHdr.Ofs_Flags ) & 0x003F;
371
+
372
+  // get data offset and segment length in bytes
373
+  ofs = (ntohs( pTcpPack->TcpHdr.Ofs_Flags ) & 0xF000) >> 10;
374
+  if( ofs < 20 || ofs > Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) ) // invalid offset
375
+    return; // remote side is unable to build valid TCP packets - ignore
376
+
377
+  // get segment length (length of data in segment)
378
+  len = Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) - ofs;
379
+
380
+  debug_tcp_printf( "recv src=%u dest=%u flags=%s%s%s%s%s%s len=%u",
381
+                    ntohs( pTcpPack->TcpHdr.SrcPort ),
382
+                    ntohs( pTcpPack->TcpHdr.DestPort ),
383
+                    flags & TCP_URG ? "U" : "",
384
+                    flags & TCP_ACK ? "A" : "",
385
+                    flags & TCP_PSH ? "P" : "",
386
+                    flags & TCP_RST ? "R" : "",
387
+                    flags & TCP_SYN ? "S" : "",
388
+                    flags & TCP_FIN ? "F" : "",
389
+                    Length );
390
+
391
+  // process options
392
+  optLen = (unsigned char)(ofs - 20);
393
+  optPtr = (unsigned char *)&pTcpPack->TcpHdr + sizeof( struct TcpHeader );
394
+  while( optLen > 0 )
395
+  {
396
+    switch( *optPtr )
397
+    {
398
+      // end of options
399
+      case 0:
400
+        optLen = 0;
401
+        break;
402
+      // no operation
403
+      case 1:
404
+        optLen--;
405
+        optPtr++;
406
+        break;
407
+      // maximum segment size
408
+      case 2:
409
+        if( optLen < 4 || optPtr[1] != 4 )
410
+        {
411
+          optPtr = NULL; // error
412
+          optLen = 0;
413
+          break;
414
+        }
415
+        mss = ntohs( *(unsigned short *)(optPtr+2) );
416
+        optLen -= 4;
417
+        optPtr += 4;
418
+        break;
419
+      // unknown option
420
+      default:
421
+        if( optLen < 2 || optPtr[1] > optLen )
422
+        {
423
+          optPtr = NULL; // error
424
+          optLen = 0;
425
+        }
426
+        optLen -= optPtr[1]; // ignore this option
427
+        optPtr += optPtr[1];
428
+    } // switch( *optPtr )
429
+  } // while( optLen > 0 )
430
+  if( optPtr == NULL ) // some error during option parsing
431
+    return; // remote side is unable to build valid TCP packets - ignore
432
+
433
+  // get sequence number at end of this segment
434
+  seqEnd = seq + len;
435
+  if( flags & TCP_SYN ) // TCP SYN counts as 1 in sequence number space
436
+    seqEnd++;
437
+  if( flags & TCP_FIN ) // TCP FIN counts as 1 in sequence number space
438
+    seqEnd++;
439
+
440
+  // search connection
441
+  for( i = 0; i < count( TcpConns ); i++ )
442
+    if( TcpConns[i].State != TCP_CLOSED &&
443
+        ip_eq( TcpConns[i].RemoteIp, pTcpPack->IpHdr.Src ) &&
444
+        TcpConns[i].LocalPort == localPort &&
445
+        TcpConns[i].RemotePort == remotePort )
446
+      break;
447
+
448
+  // connection not found, only SYN flag set, no data
449
+  if( i >= count( TcpConns ) && flags == TCP_SYN && len == 0 )
450
+  {
451
+    // accept connections on some ports (note: localPort cannot be 0 because of check above)
452
+    rcvWnd = 0;
453
+    pNotify = NULL;
454
+    // HTTP
455
+    if( localPort == ConfigHttpPort )
456
+    {
457
+      rcvWnd = 256; // connection shall be accepted
458
+      pNotify = &HttpNotify;
459
+    }
460
+    // connection shall be accepted
461
+    if( pNotify != NULL )
462
+    {
463
+      // search empty connection slot
464
+      for( i = 0; i < count( TcpConns ); i++ )
465
+        if( TcpConns[i].State == TCP_CLOSED )
466
+          break;
467
+      // free connection slot found
468
+      if( i < count( TcpConns ) )
469
+      {
470
+        // create new connection (passive) in this slot
471
+        ip_cpy( TcpConns[i].RemoteIp, pTcpPack->IpHdr.Src );
472
+        TcpConns[i].LocalPort = localPort;
473
+        TcpConns[i].RemotePort = remotePort;
474
+        TcpConns[i].State = TCP_LISTEN;
475
+        TcpConns[i].Ticks = 0;
476
+        TcpConns[i].Timeout = 0;
477
+        TcpConns[i].LifeTime = 0;
478
+        TcpConns[i].RcvWnd = rcvWnd;
479
+        TcpConns[i].Notify = pNotify;
480
+      }
481
+    }
482
+  }
483
+
484
+  // connection still not found
485
+  if( i >= count( TcpConns ) )
486
+  {
487
+    struct TcpPacket EsPack;
488
+    unsigned char EsFlags;
489
+
490
+    // do nothing if RST flag is set
491
+    if( flags & TCP_RST )
492
+      return;
493
+
494
+    // send TCP RST
495
+    EsPack.TcpHdr.SrcPort = htons( localPort );
496
+    EsPack.TcpHdr.DestPort = htons( remotePort );
497
+    EsPack.TcpHdr.WndSz = htons( 0 );
498
+    ip_cpy( EsPack.IpHdr.Dest, pTcpPack->IpHdr.Src );
499
+    if( flags & TCP_ACK )
500
+    {
501
+      EsPack.TcpHdr.SeqNo = htonl( ack );
502
+      EsPack.TcpHdr.AckNo = htonl( 0 );
503
+      EsFlags = TCP_RST;
504
+    }
505
+    else
506
+    {
507
+      EsPack.TcpHdr.SeqNo = htonl( 0 );
508
+      EsPack.TcpHdr.AckNo = htonl( seqEnd );
509
+      EsFlags = TCP_RST | TCP_ACK;
510
+    }
511
+    TcpSendPacket( (unsigned char *)&EsPack, sizeof( EsPack ), 0, EsFlags );
512
+    return;
513
+  }
514
+
515
+  // a connection was found - save number and pointer to it
516
+  connNo = i;
517
+  pConn = &TcpConns[i];
518
+
519
+  // reset connection on reception of urgent data (URG flag set)
520
+  // BUG: urgent data must be supported according to RFC793
521
+  // but urgent data is not used in protocols we use, so leave this out here to save time and memory
522
+  if( flags & TCP_URG )
523
+  {
524
+    // send TCP RST
525
+    if( flags & TCP_ACK )
526
+      TcpEmptySegment( pConn, ack, 0, TCP_RST );
527
+    else
528
+      TcpEmptySegment( pConn, 0, seqEnd, TCP_RST | TCP_ACK );
529
+    return;
530
+  }
531
+
532
+  // different behaviour in different states according to RFC793
533
+  switch( pConn->State )
534
+  {
535
+
536
+    case TCP_LISTEN:
537
+      if( flags & TCP_RST ) // An incoming RST should be ignored.
538
+        return;
539
+      if( flags & TCP_ACK ) // Any acknowledgment is bad if it arrives on a connection still in the LISTEN state.
540
+      {
541
+        TcpEmptySegment( pConn, ack, 0, TCP_RST ); // An acceptable reset segment should be formed for any arriving ACK-bearing segment.
542
+        pConn->Ticks = 0; // restart timer
543
+        return;
544
+      }
545
+      if( flags & TCP_SYN ) // third check for a SYN
546
+      {
547
+        pConn->RcvNxt = seq + 1; // Set RCV.NXT to SEG.SEQ+1,
548
+        pConn->Irs = seq; // IRS is set to SEG.SEQ
549
+        RandomGetData( (unsigned char *)&pConn->Iss, sizeof( pConn->Iss ) ); // ISS should be selected (randomly!!!)
550
+        TcpSynSegment( pConn, pConn->Iss, pConn->RcvNxt, TCP_SYN | TCP_ACK ); // and a SYN segment sent
551
+        pConn->SndNxt = pConn->Iss + 1; // SND.NXT is set to ISS+1
552
+        pConn->SndUna = pConn->Iss; // and SND.UNA to ISS
553
+        pConn->State = TCP_SYN_RCVD; // The connection state should be changed to SYN-RECEIVED.
554
+        pConn->SndWnd = wnd; // initialize send window from packet
555
+        pConn->SndWl1 = seq;
556
+        pConn->SndWl2 = ack;
557
+        pConn->Mss = mss; // save maximum segment size
558
+        pConn->Ticks = 0; // restart timer
559
+        return;
560
+      }
561
+      // fourth other text or control
562
+      // So you are unlikely to get here, but if you do, drop the segment, and return.
563
+      return;
564
+
565
+    case TCP_SYN_SENT:
566
+      accept = 0;
567
+      if( flags & TCP_ACK ) // If the ACK bit is set
568
+      {
569
+        if( (long)(ack - pConn->Iss) <= 0 || (long)(ack - pConn->SndNxt) > 0 ) // If SEG.ACK =< ISS, or SEG.ACK > SND.NXT,
570
+          {
571
+            if( ! (flags & TCP_RST) ) // (unless the RST bit is set)
572
+              TcpEmptySegment( pConn, ack, 0, TCP_RST ); // send a reset
573
+            return; // and discard the segment. Return.
574
+          }
575
+        accept = (long)(pConn->SndUna - ack) <= 0 && (long)(ack - pConn->SndNxt) <= 0; // If SND.UNA =< SEG.ACK =< SND.NXT then the ACK is acceptable.
576
+      }
577
+      if( flags & TCP_RST ) // If the RST bit is set
578
+      {
579
+        if( accept ) // If the ACK was acceptable
580
+          pConn->State = TCP_CLOSED; // enter CLOSED state, delete TCB,
581
+        return; // drop the segment and return.
582
+      }
583
+      if( (accept || ! (flags & TCP_ACK)) && // This step should be reached only if the ACK is ok, or there is no ACK,
584
+          flags & TCP_SYN ) // If the SYN bit is on
585
+      {
586
+        pConn->RcvNxt = seq + 1; // RCV.NXT is set to SEG.SEQ+1,
587
+        pConn->Irs = seq; // IRS is set to SEG.SEQ.
588
+        pConn->SndWl2 = pConn->RcvNxt; // last acknowledge number when updating the window size is first acknowledge number at all
589
+        if( accept ) // (if there is an ACK)
590
+          pConn->SndUna = ack; // SND.UNA should be advanced to equal SEG.ACK
591
+        pConn->SndWnd = wnd; // initialize send window from packet
592
+        pConn->SndWl1 = seq;
593
+        pConn->SndWl2 = ack;
594
+        pConn->Mss = mss; // save maximum segment size
595
+        if( (long)(pConn->SndUna - pConn->Iss) > 0 ) // If SND.UNA > ISS (our SYN has been ACKed),
596
+        {
597
+          pConn->State = TCP_ESTAB; // change the connection state to ESTABLISHED,
598
+          debug_tcp_printf( "notify connect no=%u", connNo );
599
+          pConn->Notify->Connect( connNo ); // signal "connected"
600
+          TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK ); // form an ACK segment and send it.
601
+        }
602
+        else // Otherwise
603
+        {
604
+          pConn->State = TCP_SYN_RCVD; // enter SYN-RECEIVED,
605
+          TcpSynSegment( pConn, pConn->Iss, pConn->RcvNxt, TCP_SYN | TCP_ACK ); // form a SYN,ACK segment and send it.
606
+        }
607
+        pConn->Ticks = 0; // restart timer
608
+      }
609
+      return;
610
+
611
+  } // switch( pConn->State )
612
+
613
+  // Otherwise,
614
+
615
+  // first check sequence number
616
+  if( len == 0 )
617
+    if( pConn->RcvWnd == 0 )
618
+      accept = seq == pConn->RcvNxt; // SEG.SEQ = RCV.NXT
619
+    else
620
+      accept = (long)(pConn->RcvNxt - seq) <= 0 && // RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
621
+               (long)(seq - (pConn->RcvNxt + pConn->RcvWnd)) < 0;
622
+  else
623
+    if( pConn->RcvWnd == 0 )
624
+      accept = 0; // not acceptable
625
+    else
626
+      accept = ((long)(pConn->RcvNxt - seq) <= 0 && // RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
627
+                (long)(seq - (pConn->RcvNxt + pConn->RcvWnd)) < 0) ||
628
+               ((long)(pConn->RcvNxt - (seq + len - 1) <= 0) && // or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
629
+                (long)((seq + len - 1) - (pConn->RcvNxt + pConn->RcvWnd)) < 0);
630
+
631
+  // because there is not enough memory to store segments needed later,
632
+  // we only accept segments with SEG.SEQ <= RCV.NXT
633
+  // thus, we reject the segment if SEG.SEQ > RCV.NXT
634
+  // BAD PERFORMANCE: this is _not_ a bug, but a major impact on performace when packets arrive out of order
635
+  // - however, we cannot do something against it,
636
+  // because there is not enough memory available on the controller
637
+  // to store segements for later processing
638
+  if( accept && (long)(seq - pConn->RcvNxt) > 0 )
639
+    accept = 0;
640
+
641
+  // If an incoming segment is not acceptable
642
+  if( ! accept )
643
+  {
644
+    /* disabled this - sometimes it ssems to generates endless ACKs being exchanged with remote host)
645
+    if( ! (flags & TCP_RST) ) // (unless the RST bit is set)
646
+      TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK ); // an acknowledgment should be sent in reply */
647
+    return; // drop the unacceptable segment and return.
648
+  }
649
+
650
+  // if segment contains duplicate data
651
+  tmp = pConn->RcvNxt - seq; // cannot be negative because of checks above
652
+  if( tmp > 0 )
653
+  {
654
+    // remove duplicate SYN flag from segment
655
+    if( flags & TCP_SYN )
656
+    {
657
+      flags &= ~TCP_SYN;
658
+      tmp--;
659
+    }
660
+    // remove duplicate data from segment
661
+    ofs += tmp;
662
+    len -= tmp; // length cannot become negative here because of checks above
663
+    // now this segments starts with the expected sequence number
664
+    seq = pConn->RcvNxt;
665
+  }
666
+
667
+  // if segment extends beyond end of receive window
668
+  if( len > pConn->RcvWnd )
669
+  {
670
+    // remove data behind receive window
671
+    seqEnd -= len - pConn->RcvWnd;
672
+    len = pConn->RcvWnd;
673
+  }
674
+
675
+  // restart timer, because this was an acceptable segment
676
+  pConn->Ticks = 0;
677
+
678
+  // second check the RST bit,
679
+  if( flags & TCP_RST )
680
+  {
681
+    switch( pConn->State )
682
+    {
683
+
684
+      case TCP_SYN_RCVD:
685
+        pConn->State = TCP_CLOSED; // enter the CLOSED state and delete the TCB, an return.
686
+        debug_tcp_printf( "notify close no=%u", connNo );
687
+        pConn->Notify->Close( connNo ); // signal "connection refused"
688
+        return;
689
+
690
+      case TCP_ESTAB:
691
+      case TCP_FIN_WAIT_1:
692
+      case TCP_FIN_WAIT_2:
693
+      case TCP_CLOSE_WAIT:
694
+        pConn->State = TCP_CLOSED; // Enter the CLOSED state, delete the TCB, and return.
695
+        debug_tcp_printf( "notify close no=%u", connNo );
696
+        pConn->Notify->Close( connNo ); // signal "connection reset"
697
+        return;
698
+
699
+      case TCP_CLOSING:
700
+      case TCP_LAST_ACK:
701
+      case TCP_TIME_WAIT:
702
+        pConn->State = TCP_CLOSED; // enter the CLOSED state, delete the TCB, and return.
703
+        return;
704
+
705
+    } // switch( pConn->State )
706
+  } // if( flags & TCP_RST )
707
+
708
+  // third check security and precedence
709
+  // - this does not apply to our implementation because we do not support security and precedence on TCP layer
710
+
711
+  // fourth, check the SYN bit
712
+  if( flags & TCP_SYN )
713
+  {
714
+    switch( pConn->State )
715
+    {
716
+
717
+      case TCP_SYN_RCVD:
718
+      case TCP_ESTAB:
719
+      case TCP_FIN_WAIT_1:
720
+      case TCP_FIN_WAIT_2:
721
+      case TCP_CLOSE_WAIT:
722
+        // If the SYN is in the window it is an error,
723
+        // - this is always the case here, because SYN not in window would habe been removed above
724
+        TcpEmptySegment( pConn, ack, 0, TCP_RST ); // send a reset,
725
+        pConn->State = TCP_CLOSED; // enter the CLOSED state, delete the TCB, and return.
726
+        debug_tcp_printf( "notify close no=%u", connNo );
727
+        pConn->Notify->Close( connNo ); // signal "connection reset"
728
+        return;
729
+
730
+      case TCP_CLOSING:
731
+      case TCP_LAST_ACK:
732
+      case TCP_TIME_WAIT:
733
+        // If the SYN is in the window it is an error,
734
+        // - this is always the case here, because SYN not in window would habe been removed above
735
+        TcpEmptySegment( pConn, ack, 0, TCP_RST ); // send a reset,
736
+        pConn->State = TCP_CLOSED; // enter the CLOSED state, delete the TCB, and return.
737
+        return;
738
+
739
+    } // switch( pConn->State )
740
+  } // if( flags & TCP_SYN )
741
+
742
+  // fifth check the ACK field,
743
+  if( ! (flags & TCP_ACK) ) // if the ACK bit is off
744
+    return; // drop the segment and return
745
+  switch( pConn->State )
746
+  {
747
+
748
+      case TCP_SYN_RCVD:
749
+        if( (long)(pConn->SndUna - ack) <= 0 && // If SND.UNA =< SEG.ACK =< SND.NXT
750
+            (long)(ack - pConn->SndNxt) <= 0 )
751
+        {
752
+          pConn->State = TCP_ESTAB; // then enter ESTABLISHED state
753
+          debug_tcp_printf( "notify connect no=%u", connNo );
754
+          pConn->Notify->Connect( connNo ); // signal "connected"
755
+          // and continue processing.
756
+        }
757
+        else // If the segment acknowledgment is not acceptable,
758
+        {
759
+          TcpEmptySegment( pConn, ack, 0, TCP_RST ); // form a reset segment, and send it.
760
+          return; // drop this segment
761
+        }
762
+        // no break here
763
+
764
+      case TCP_ESTAB:
765
+      case TCP_FIN_WAIT_1:
766
+      case TCP_FIN_WAIT_2:
767
+      case TCP_CLOSE_WAIT:
768
+      case TCP_CLOSING:
769
+        if( (long)(ack - pConn->SndUna) <= 0 ) // If the ACK is a duplicate (SEG.ACK <= SND.UNA),
770
+          break; // it can be ignored.
771
+        if( (long)(ack - pConn->SndNxt) > 0 ) // If the ACK acks something not yet sent (SEG.ACK > SND.NXT)
772
+        {
773
+          TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK ); // then send an ACK,
774
+          return; // drop the segment, and return.
775
+        }
776
+        // here: SND.UNA < SEG.ACK =< SND.NXT
777
+        pConn->SndUna = ack; // set SND.UNA <- SEG.ACK.
778
+        if( (long)(pConn->SndWl1 - seq) < 0 || // If SND.WL1 < SEG.SEQ
779
+            (pConn->SndWl1 == seq && (long)(pConn->SndWl2 - ack) <= 0) ) // or (SND.WL1 = SEG.SEQ and SND.WL2 =< SEG.ACK),
780
+        {
781
+          pConn->SndWnd = wnd; // set SND.WND <- SEG.WND,
782
+          pConn->SndWl1 = seq; // set SND.WL1 <- SEG.SEQ,
783
+          pConn->SndWl2 = ack; // and set SND.WL2 <- SEG.ACK.
784
+        }
785
+        pConn->Timeout = 0; // restart timeout timer
786
+        debug_tcp_printf( "notify sent no=%u pos=%lu",
787
+                          connNo, pConn->SndNxt - (pConn->Iss + 1) );
788
+        pConn->Notify->Sent( connNo, pConn->SndUna - (pConn->Iss + 1) ); // signal "send completed" (up to ack)
789
+        // additional processing
790
+        switch( pConn->State )
791
+        {
792
+          case TCP_FIN_WAIT_1:
793
+            if( pConn->SndUna == pConn->SndNxt ) // if our FIN is now acknowledged
794
+              pConn->State = TCP_FIN_WAIT_2; // then enter FIN-WAIT-2 and continue processing in that state.
795
+            // no break here
796
+          case TCP_FIN_WAIT_2:
797
+            if( pConn->SndUna == pConn->SndNxt ) // if the retransmission queue is empty,
798
+            {
799
+              debug_tcp_printf( "notify close no=%u", connNo );
800
+              pConn->Notify->Close( connNo ); // the user's CLOSE can be acknowledged
801
+            }
802
+            break;
803
+          case TCP_CLOSING:
804
+            if( pConn->SndUna == pConn->SndNxt ) // if the ACK acknowledges our FIN
805
+              pConn->State = TCP_TIME_WAIT; // then enter the TIME-WAIT state,
806
+            else
807
+              return; // otherwise ignore the segment.
808
+            break;
809
+        }
810
+        break;
811
+
812
+      case TCP_LAST_ACK:
813
+        // The only thing that can arrive in this state is an acknowledgment of our FIN.
814
+        if( pConn->SndUna == pConn->SndNxt ) // If our FIN is now acknowledged,
815
+        {
816
+          pConn->State = TCP_CLOSED; // delete the TCB, enter the CLOSED state,
817
+          return; // and return.
818
+        }
819
+        break;
820
+
821
+      case TCP_TIME_WAIT:
822
+        // The only thing that can arrive in this state is a retransmission of the remote FIN.
823
+        TcpEmptySegment( pConn, ack, seqEnd, TCP_ACK ); // Acknowledge it,
824
+        break;
825
+
826
+  } // switch( pConn->State )
827
+
828
+  // sixth, check the URG bit,
829
+  // - this cannot occur, because we have alredy reset the connection if URG was set
830
+
831
+  // no ACK needs to be sent yet
832
+  sendAck = 0;
833
+
834
+  // seventh, process the segment text,
835
+  if( len > 0 )
836
+  {
837
+    switch( pConn->State )
838
+    {
839
+
840
+      case TCP_ESTAB:
841
+      case TCP_FIN_WAIT_1:
842
+      case TCP_FIN_WAIT_2:
843
+        pConn->RcvWnd -= len; // make receive window smaller (len <= pConn->RcvWnd)
844
+        pConn->RcvNxt += len; // advance sequence number of next data to receive
845
+        pConn->Timeout = 0; // restart timeout timer
846
+        debug_tcp_printf( "notify recv no=%u pos=%lu len=%u, min_wnd=%u",
847
+                           connNo, pConn->RcvNxt - (pConn->Irs + 1) - len, len, pConn->RcvWnd );
848
+        pConn->RcvWnd = pConn->Notify->Received( connNo, pConn->RcvNxt - (pConn->Irs + 1) - len, // give received data to user
849
+                                                 (unsigned char *)&pTcpPack->TcpHdr + ofs, len, // (update receive window size)
850
+                                                 pConn->RcvWnd );
851
+        debug_tcp_printf( "notify recv no=%u wnd=%u", connNo, pConn->RcvWnd );
852
+        sendAck = 1; // remember to send an ACK
853
+        break;
854
+
855
+    } // switch( pConn->State )
856
+  } // if( len > 0 )
857
+
858
+  // eighth, check the FIN bit,
859
+  if( flags & TCP_FIN )
860
+  {
861
+    switch( pConn->State )
862
+    {
863
+
864
+      case TCP_SYN_RCVD:
865
+      case TCP_ESTAB:
866
+        sendAck = 1; // remember to send an ACK
867
+        pConn->RcvNxt++; // FIN counts as one in sequence number space
868
+        pConn->State = TCP_CLOSE_WAIT; // Enter the CLOSE-WAIT state.
869
+        // close outbound part of the connection
870
+        // i.e. do an automatic call to close
871
+        TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // send a FIN
872
+        pConn->SndNxt++;
873
+        pConn->State = TCP_CLOSING;
874
+        debug_tcp_printf( "notify close no=%u", connNo );
875
+        pConn->Notify->Close( connNo ); // signal "connection closed" to user
876
+        return; // we do not need to send an ack, becaue we already sent it with our FIN
877
+
878
+      case TCP_FIN_WAIT_1:
879
+        sendAck = 1; // remember to send an ACK
880
+        pConn->RcvNxt++; // FIN counts as one in sequence number space
881
+        pConn->State = TCP_CLOSING; // Enter the CLOSING state.
882
+        break;
883
+
884
+      case TCP_FIN_WAIT_2:
885
+        sendAck = 1; // remember to send an ACK
886
+        pConn->RcvNxt++; // FIN counts as one in sequence number space
887
+        pConn->State = TCP_TIME_WAIT; // Enter the TIME-WAIT state.
888
+        break;
889
+
890
+      case TCP_CLOSING:
891
+      case TCP_CLOSE_WAIT:
892
+      case TCP_LAST_ACK:
893
+      case TCP_TIME_WAIT:
894
+        sendAck = 1; // remember to send an ACK
895
+        break;
896
+
897
+    } // switch( pConn->State )
898
+  }
899
+
900
+  // send data / ACK segment
901
+  TcpSendDataSegment( connNo, pConn, sendAck );
902
+}
903
+
904
+// open a TCP connection
905
+// must not be called from a TCP notification function
906
+// returns the connection number of the new connection of 0xFF in case of error
907
+unsigned char TcpOpen( unsigned char * remoteIp, unsigned short remotePort, // (extern)
908
+                       unsigned short initialWnd, struct TcpNotify * Notify )
909
+#define TcpOpenLocalPortMin 32768
910
+#define TcpOpenLocalPortRange 16384
911
+{
912
+  static unsigned short nextLocalPort = TcpOpenLocalPortMin; // local port to use for next TCP connection
913
+  unsigned short localPort;
914
+  unsigned char i;
915
+
916
+  debug_tcp_printf( "open ip=%u.%u.%u.%u port=%u",
917
+                    remoteIp[0], remoteIp[1], remoteIp[2], remoteIp[3],
918
+                    remotePort );
919
+
920
+  // search an unused local port
921
+  for( localPort = nextLocalPort; ; localPort++ )
922
+  {
923
+    for( i = 0; i < count( TcpConns ); i++ )
924
+      if( TcpConns[i].State != TCP_CLOSED &&
925
+          TcpConns[i].LocalPort == localPort )
926
+        break;
927
+    if( i >= count( TcpConns ) )
928
+      break;
929
+  }
930
+  // save next local port to use
931
+  nextLocalPort = localPort + 1;
932
+  if( nextLocalPort >= TcpOpenLocalPortMin + TcpOpenLocalPortRange )
933
+    nextLocalPort = TcpOpenLocalPortMin;
934
+
935
+  // search empty connection slot
936
+  for( i = 0; i < count( TcpConns ); i++ )
937
+    if( TcpConns[i].State == TCP_CLOSED )
938
+      break;
939
+  // no free connection slot found
940
+  if( i >= count( TcpConns ) )
941
+    return 0xFF;
942
+
943
+  // create new connection in this slot
944
+  ip_cpy( TcpConns[i].RemoteIp, remoteIp );
945
+  TcpConns[i].LocalPort = localPort;
946
+  TcpConns[i].RemotePort = remotePort;
947
+  TcpConns[i].RcvNxt = 0;
948
+  TcpConns[i].Irs = 0;
949
+  RandomGetData( (unsigned char *)&TcpConns[i].Iss, sizeof( TcpConns[i].Iss ) ); // An initial send sequence number (ISS) is selected.
950
+  TcpSynSegment( &TcpConns[i], TcpConns[i].Iss, 0, TCP_SYN ); // A SYN segment of the form <SEQ=ISS><CTL=SYN> is sent.
951
+  TcpConns[i].SndUna = TcpConns[i].Iss; // Set SND.UNA to ISS,
952
+  TcpConns[i].SndNxt = TcpConns[i].Iss + 1; // SND.NXT to ISS+1,
953
+  TcpConns[i].State = TCP_SYN_SENT; // enter SYN-SENT state,
954
+  TcpConns[i].SndWnd = 0; // not allowed to send data for now
955
+  TcpConns[i].SndWl1 = 0; // window size was never updated
956
+  TcpConns[i].SndWl2 = 0;
957
+  TcpConns[i].Ticks = 0; // restart timers
958
+  TcpConns[i].Timeout = 0;
959
+  TcpConns[i].LifeTime = 0;
960
+  TcpConns[i].RcvWnd = initialWnd;
961
+  TcpConns[i].Notify = Notify;
962
+
963
+  debug_tcp_printf( "open no=%u", i );
964
+
965
+  // return connection number
966
+  return i;
967
+}
968
+
969
+// close a TCP connection
970
+// must not be called from a TCP notification function
971
+void TcpClose( unsigned char connNo ) // (extern)
972
+{
973
+  struct TcpConnection * pConn;
974
+
975
+  debug_tcp_printf( "close no=%u", connNo );
976
+
977
+  // connection does not exist
978
+  if( connNo >= count( TcpConns ) || TcpConns[connNo].State == TCP_CLOSED )
979
+    return;
980
+
981
+  // get connection
982
+  pConn = &TcpConns[connNo];
983
+
984
+  // different actions in different states accroding to RFC793
985
+  switch( pConn->State  )
986
+  {
987
+
988
+    case TCP_LISTEN:
989
+    case TCP_SYN_SENT:
990
+      pConn->State = TCP_CLOSED; // Delete TCB, enter CLOSED state,
991
+      break; // and return.
992
+
993
+    case TCP_SYN_RCVD:
994
+    case TCP_ESTAB:
995
+      TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // form a FIN segment and send it,
996
+      pConn->SndNxt++;
997
+      pConn->State = TCP_FIN_WAIT_1; // and enter FIN-WAIT-1 state;
998
+      debug_tcp_printf( "notify close no=%u", connNo );
999
+      pConn->Notify->Close( connNo ); // signal "connection closed" to user
1000
+      break;
1001
+
1002
+    case TCP_CLOSE_WAIT:
1003
+      TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // send a FIN segment,
1004
+      pConn->SndNxt++;
1005
+      pConn->State = TCP_CLOSING; // enter CLOSING state.
1006
+      debug_tcp_printf( "notify close no=%u", connNo );
1007
+      pConn->Notify->Close( connNo ); // signal "connection closed" to user
1008
+      break;
1009
+
1010
+  } // switch( pConn->State  )
1011
+}
1012
+
1013
+// request sending on a TCP connection
1014
+// must not be called from a TCP notification function
1015
+// this makes the send notification to be called if possible
1016
+void TcpSend( unsigned char connNo ) // (extern)
1017
+{
1018
+  struct TcpConnection * pConn;
1019
+
1020
+  debug_tcp_printf( "send no=%u", connNo );
1021
+
1022
+  // connection does not exist
1023
+  if( connNo >= count( TcpConns ) || TcpConns[connNo].State == TCP_CLOSED )
1024
+    return;
1025
+
1026
+  // get connection
1027
+  pConn = &TcpConns[connNo];
1028
+
1029
+  // different behaviour in different states
1030
+  switch( pConn->State )
1031
+  {
1032
+
1033
+    case TCP_ESTAB:
1034
+    case TCP_CLOSE_WAIT:
1035
+      // if nothing is sent and not yet ACKed
1036
+      if( pConn->SndUna == pConn->SndNxt )
1037
+        // send a data segment
1038
+        TcpSendDataSegment( connNo, pConn, 0 );
1039
+      break;
1040
+
1041
+  } // switch( TcpConns[i].State )
1042
+}
1043
+
1044
+// dummy notification functions
1045
+void TcpDummyConnect( unsigned char ConnNo ) { }
1046
+void TcpDummyClose( unsigned char ConnNo ) { }
1047
+unsigned short TcpDummySend( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short MaxLen ) { return 0; }
1048
+void TcpDummySent( unsigned char ConnNo, unsigned long Pos ) { }
1049
+unsigned short TcpDummyReceived( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short Len, unsigned short curWnd ) { return max( curWnd, 128 ); }
1050
+struct TcpNotify TcpDummyNotify = // (extern)
1051
+{
1052
+  .Connect = TcpDummyConnect,
1053
+  .Close = TcpDummyClose,
1054
+  .Send = TcpDummySend,
1055
+  .Sent = TcpDummySent,
1056
+  .Received = TcpDummyReceived,
1057
+};
1058
+
... ...
@@ -0,0 +1,112 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_tcp
9
+#define INC_tcp
10
+
11
+#include "ethernet.h"
12
+#include "ip.h"
13
+
14
+// header of a TCP packet
15
+struct TcpHeader
16
+{
17
+  unsigned int SrcPort;
18
+  unsigned int DestPort;
19
+  unsigned long SeqNo;
20
+  unsigned long AckNo;
21
+  unsigned int Ofs_Flags;
22
+  unsigned int WndSz;
23
+  unsigned int Chk;
24
+  unsigned int UrgentPtr;
25
+};
26
+
27
+// a TCP packet
28
+struct TcpPacket
29
+{
30
+  struct EthernetHeader EthHdr;
31
+  struct IpHeader IpHdr;
32
+  struct TcpHeader TcpHdr;
33
+};
34
+
35
+// TCP notify functions
36
+struct TcpNotify
37
+{
38
+  // called when connection is established
39
+  void (*Connect)( unsigned char ConnNo );
40
+  // called when connection is closed / reset
41
+  // (after this, the connection number may not be used any more)
42
+  void (*Close)( unsigned char ConnNo );
43
+  // called when sending data is possible
44
+  // (return length of available data, 0xFFFF to close connection)
45
+  unsigned short (*Send)( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short MaxLen );
46
+  // called when data was sent and ACKed
47
+  void (*Sent)( unsigned char ConnNo, unsigned long Pos );
48
+  // called when data was received, must return new window size (not smaller than curWnd)
49
+  unsigned short (*Received)( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short Len, unsigned short curWnd );
50
+};
51
+
52
+// a TCP connection (member names according to RFC793)
53
+// BUG: missing urgent pointers, which must be supported according to RFC793
54
+// but urgent data is not used in protocols we use, so leave this out here to save time and memory
55
+#define TCP_CLOSED 0
56
+#define TCP_LISTEN 1
57
+#define TCP_SYN_SENT 2
58
+#define TCP_SYN_RCVD 3
59
+#define TCP_ESTAB 4
60
+#define TCP_FIN_WAIT_1 5
61
+#define TCP_FIN_WAIT_2 6
62
+#define TCP_CLOSE_WAIT 7
63
+#define TCP_LAST_ACK 8
64
+#define TCP_CLOSING 9
65
+#define TCP_TIME_WAIT 10
66
+struct TcpConnection
67
+{
68
+  unsigned char RemoteIp[4];
69
+  unsigned short LocalPort, RemotePort;
70
+  unsigned char State; // one of TCP_*
71
+  unsigned long SndUna; // send unacknowledged
72
+  unsigned long SndNxt; // send next
73
+  unsigned short SndWnd; // send window
74
+  unsigned long SndWl1; // segment sequence number used for last window update
75
+  unsigned long SndWl2; // segment acknowledgment number used for last window update
76
+  unsigned long Iss; // initial send sequence number
77
+  unsigned long RcvNxt; // receive next
78
+  unsigned short RcvWnd; // receive window
79
+  unsigned long Irs; // initial receive sequence number
80
+  unsigned short Mss; // maximum segment size
81
+  unsigned char Ticks; // retransmission and time-wait timer (time since last packet sent or received in 200ms steps)
82
+  unsigned char Timeout; // timeout timer (time since last data was sent or received)
83
+  unsigned char LifeTime; // lifetime timer (time since begin of connection)
84
+  struct TcpNotify * Notify; // notification functions
85
+};
86
+
87
+// initialize
88
+extern void TcpInit( void );
89
+
90
+// tick procedure - call every 200ms
91
+extern void TcpTick200( void );
92
+
93
+// process a received TCP packet
94
+extern void TcpRecv( unsigned char * pData, unsigned short Length );
95
+
96
+// open a TCP connection
97
+// must not be called from a TCP notification function
98
+// returns the connection number of the new connection of 0xFF in case of error
99
+extern unsigned char TcpOpen( unsigned char * remoteIp, unsigned short remotePort,
100
+                              unsigned short initialWnd, struct TcpNotify * Notify );
101
+
102
+// close a TCP connection
103
+// must not be called from a TCP notification function
104
+extern void TcpClose( unsigned char connNo );
105
+
106
+// request sending on a TCP connection
107
+// must not be called from a TCP notification function
108
+// this makes the send notification to be called if possible
109
+extern void TcpSend( unsigned char connNo );
110
+
111
+#endif // #ifdef INC_tcp
112
+
... ...
@@ -0,0 +1,108 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <avr/io.h>
9
+#include <avr/interrupt.h>
10
+
11
+#include "arp.h"
12
+#include "cf.h"
13
+#include "dart.h"
14
+#include "dhcp.h"
15
+#include "ip.h"
16
+#include "http.h"
17
+#include "random.h"
18
+#include "rtl8019.h"
19
+#include "status.h"
20
+#include "tcp.h"
21
+#include "timing.h"
22
+#include "udp.h"
23
+
24
+// 2ms tick counter to generate 20ms ticks
25
+volatile unsigned char Timing2_10 = 0;
26
+
27
+// flag set every 20ms to indicate execution of 20ms ticks
28
+volatile unsigned char Timing20Flag = 0;
29
+
30
+// wrapping around 20ms tick counter
31
+unsigned char Timing20 = 0;
32
+
33
+// 20ms tick counter to generate 200ms ticks
34
+unsigned char Timing20_10 = 0;
35
+
36
+// 2ms interrupt (timer 0 compare match)
37
+SIGNAL( SIG_OUTPUT_COMPARE0 )
38
+{
39
+  // set flag every 20ms
40
+  Timing2_10++;
41
+  if( Timing2_10 >= 10 )
42
+  {
43
+    Timing2_10 = 0;
44
+    Timing20Flag = 1;
45
+  }
46
+}
47
+
48
+// initialize
49
+void TimingInit( void ) // (extern)
50
+{
51
+  // configure timer 0 to 2ms interval
52
+  TCCR0 = 0<<FOC0 | 1<<WGM01 | 0<<WGM00 | // count to OCR0
53
+          0<<COM01 | 0<<COM00 | // no waveform generation
54
+          1<<CS02 | 1<<CS01 | 0<<CS00; // 1/256 of sysclock (16MHz) -> increment every 16us
55
+  OCR0 = 124; // count to 124 -> 2ms interval
56
+
57
+  // enable timer 0 compare match interrupt
58
+  TIMSK |= 1<<OCIE0;
59
+
60
+  // configure timer 1 to count cycles
61
+  TCCR1A = 0<<WGM11 | 0<<WGM10; // normal mode
62
+  TCCR1B = 0<<WGM13 | 0<<WGM12 | 0<<CS12 | 0<<CS11 | 1<<CS10; // normal mode, no prescaler
63
+}
64
+
65
+// provide curent time stamp as entropy to random number generator
66
+void TimingEntropy( void ) // (extern)
67
+{
68
+  unsigned short timestamp = TCNT1;
69
+  RandomProvideEntropy( (unsigned char)timestamp );
70
+  RandomProvideEntropy( (unsigned char)(timestamp >> 8) );
71
+}
72
+
73
+// provide curent 20ms tick counter as entropy to random number generator
74
+void Timing20Entropy( void ) // (extern)
75
+{
76
+  RandomProvideEntropy( Timing20 );
77
+}
78
+
79
+// task function to do the work - call from main loop
80
+void TimingTask( void ) // (extern)
81
+{
82
+  // 20ms not elapsed
83
+  if( ! Timing20Flag )
84
+    return;
85
+  Timing20Flag = 0;
86
+
87
+  // call 20ms tick functions
88
+
89
+  // generate 200ms steps
90
+  Timing20_10++;
91
+  if( Timing20_10 >= 10 )
92
+    Timing20_10 = 0;
93
+
94
+  // call 200ms tick functions at different times
95
+  switch( Timing20_10 )
96
+  {
97
+    case 1: ArpTick200( ); break;
98
+    case 2: DartTick200( ); break;
99
+    case 3: IpTick200( ); break;
100
+    case 4: HttpTick200( ); break;
101
+    case 5: RtlTick200( ); break;
102
+    case 6: StatusTick200( ); break;
103
+    case 7: TcpTick200( ); break;
104
+    case 8: UdpTick200( ); break;
105
+    case 9: DhcpTick200( ); break;
106
+  }
107
+}
108
+
... ...
@@ -0,0 +1,23 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_timing
9
+#define INC_timing
10
+
11
+// initialize
12
+extern void TimingInit( void );
13
+
14
+// provide curent time stamp as entropy to random number generator
15
+extern void TimingEntropy( void );
16
+
17
+// provide curent 20ms tick counter as entropy to random number generator
18
+extern void Timing20Entropy( void );
19
+
20
+// task function to do the work - call from main loop
21
+extern void TimingTask( void );
22
+
23
+#endif // #ifndef INC_timing
... ...
@@ -0,0 +1,43 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <avr/io.h>
10
+#include <avr/wdt.h>
11
+
12
+#include "macros.h"
13
+#include "uart.h"
14
+
15
+#define BAUD_RATE 38400
16
+
17
+// initialize
18
+void UartInit( void ) // (extern)
19
+{
20
+  // enable transmission
21
+  UCSR0B = 1<<TXEN;
22
+  // set baudrate (16MHz crystal) 
23
+  UBRR0L = 16000000 / (BAUD_RATE * 16L) - 1;
24
+
25
+  // set STDOUT to use UartPutchar
26
+  fdevopen( UartPutchar, NULL );
27
+}
28
+
29
+// write a character
30
+int UartPutchar( char c, FILE * file ) // (extern)
31
+{
32
+  // wait until last character was sent
33
+  while( bit_is_clear( UCSR0A, UDRE ) )
34
+    wdt_reset( );
35
+
36
+  // send character
37
+  UDR0 = c;
38
+
39
+  return 0;
40
+
41
+  file = NULL; // keep compiler happy
42
+}
43
+
... ...
@@ -0,0 +1,18 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_uart
9
+#define INC_uart
10
+
11
+// initialize
12
+extern void UartInit( void );
13
+
14
+// write a character
15
+extern int UartPutchar( char c, FILE * file );
16
+
17
+#endif // #ifndef INC_uart
18
+
... ...
@@ -0,0 +1,171 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include "config.h"
9
+#include "checksum.h"
10
+#include "dart.h"
11
+#include "debug.h"
12
+#include "dhcp.h"
13
+#include "ethernet.h"
14
+#include "ip.h"
15
+#include "macros.h"
16
+#include "nethelp.h"
17
+#include "udp.h"
18
+
19
+// some kind of "token bucket" for UDP echo
20
+#define UdpEchoTicks 10 // allowed rate of UDP echo replies (in 200ms steps)
21
+unsigned char UdpEchoTickCnt = 0; // tick counter
22
+#define UdpEchoReliesMax 3 // maximum value for UdpEchoReplies
23
+unsigned char UdpEchoReplies = 0; // number of UDP echo replies that may be sent at the moment
24
+
25
+// tick procedure - call every 200ms
26
+void UdpTick200( void ) // (extern)
27
+{
28
+  // count ticks
29
+  UdpEchoTickCnt++;
30
+  // time to allow one reply more
31
+  if( UdpEchoTickCnt >= UdpEchoTicks )
32
+  {
33
+    UdpEchoTickCnt = 0;
34
+
35
+    // increase reply count if not at maximum
36
+    if( UdpEchoReplies < UdpEchoReliesMax )
37
+      UdpEchoReplies++;
38
+  }
39
+}
40
+
41
+// process a received UDP echo packet
42
+static void UdpEchoRecv( unsigned char * pData, unsigned short Length )
43
+{
44
+  struct UdpPacket * pUdpPack;
45
+
46
+  // convert pointer to UDP packet
47
+  // (this saves us from always casting pData)
48
+  pUdpPack = (struct UdpPacket *)pData;
49
+
50
+  // source port is UDP echo port
51
+  if( pUdpPack->UdpHdr.SrcPort == htons( 7 ) )
52
+    // ignore this packet
53
+    // - UDP echo answer to another UDP echo port will result in endless echoing
54
+    return;
55
+
56
+  // only reply with allowed packet rate
57
+  if( UdpEchoReplies == 0 )
58
+  {
59
+    debug_udp_printf( "echo len=%u (dropped)", Length );
60
+    return;
61
+  }
62
+  UdpEchoReplies--;
63
+
64
+  debug_udp_printf( "echo len=%u", Length );
65
+
66
+  // send an UDP echo
67
+  // - use same buffer to send reply
68
+  // - this saves us from allocating a new buffer
69
+  // - this saves us from copying the data
70
+  pUdpPack->UdpHdr.DestPort = pUdpPack->UdpHdr.SrcPort; // back to originationg port
71
+  pUdpPack->UdpHdr.SrcPort = htons( 7 ); // UDP echo port
72
+  ip_cpy( pUdpPack->IpHdr.Dest, pUdpPack->IpHdr.Src ); // back to originating IP
73
+  UdpSend( pData, Length );
74
+}
75
+
76
+// process a received UDP packet
77
+void UdpRecv( unsigned char * pData, unsigned short Length ) // (extern)
78
+{
79
+  struct UdpPacket * pUdpPack;
80
+  unsigned int len;
81
+
82
+  // packet too short
83
+  if( Length < sizeof( struct UdpPacket ) )
84
+    return;
85
+
86
+  // convert pointer to UDP packet
87
+  // (this saves us from always casting pData)
88
+  pUdpPack = (struct UdpPacket *)pData;
89
+
90
+  // ignore packets sent from or to port 0
91
+  // - this might be some attack
92
+  if( pUdpPack->UdpHdr.SrcPort == htons( 0 ) ||
93
+      pUdpPack->UdpHdr.DestPort == htons( 0 ) )
94
+    return;
95
+
96
+  // check total length
97
+  len = sizeof( struct EthernetHeader ) + sizeof( struct IpHeader ) + ntohs( pUdpPack->UdpHdr.Length ); // length according to UDP header
98
+  if( Length < len ) // packet is truncated
99
+    return;
100
+  Length = len; // remove IP padding from packet (maybe Length > len)
101
+
102
+  // test checksum
103
+  if( Checksum( (unsigned char*)&pUdpPack->IpHdr.Src,
104
+                Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8,
105
+                0x0011,
106
+                ntohs( pUdpPack->UdpHdr.Length ) ) != 0 )
107
+    return;
108
+
109
+  debug_udp_printf( "recv src=%u dest=%u len=%u",
110
+                    ntohs( pUdpPack->UdpHdr.SrcPort ),
111
+                    ntohs( pUdpPack->UdpHdr.DestPort ),
112
+                    Length );
113
+
114
+  // branch according to destination port
115
+  switch( ntohs( pUdpPack->UdpHdr.DestPort ) )
116
+  {
117
+    // UDP echo
118
+    case 7:
119
+      UdpEchoRecv( pData, Length );
120
+      break;
121
+    // DHCP
122
+    case 68:
123
+      DhcpRecv( pData, Length );
124
+      break;
125
+    // dart board
126
+    case 501:
127
+      DartRequest( pUdpPack->IpHdr.Src,
128
+                   ntohs( pUdpPack->UdpHdr.SrcPort ) );
129
+      break;
130
+  }
131
+}
132
+
133
+// send an UDP packet
134
+// pData must point to a struct UdpPacket with UdpHdr.SrcPort, UdpHdr.DestPort and IpHdr.Dest already initialized
135
+void UdpSend( unsigned char * pData, unsigned short Length ) // (extern)
136
+{
137
+  struct UdpPacket * pUdpPack;
138
+  unsigned int chk;
139
+
140
+  // packet too short
141
+  if( Length < sizeof( struct UdpPacket ) )
142
+    return;
143
+
144
+  // convert pointer to UDP packet
145
+  // (this saves us from always casting pData)
146
+  pUdpPack = (struct UdpPacket *)pData;
147
+
148
+  debug_udp_printf( "send src=%u dest=%u len=%u",
149
+                    ntohs( pUdpPack->UdpHdr.SrcPort ),
150
+                    ntohs( pUdpPack->UdpHdr.DestPort ),
151
+                    Length );
152
+
153
+  // fill in header values
154
+  pUdpPack->UdpHdr.Length = htons( Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) );
155
+  pUdpPack->UdpHdr.Chk = 0x0000;
156
+  ip_cpy( pUdpPack->IpHdr.Src, ConfigIp ); // put IP already here into IP header
157
+                                           // because it is needed for calculation of UDP checksum
158
+
159
+  // generate checksum
160
+  chk = Checksum( (unsigned char *)&pUdpPack->IpHdr.Src,
161
+                  Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8,
162
+                  0x0011,
163
+                  ntohs( pUdpPack->UdpHdr.Length ) );
164
+  pUdpPack->UdpHdr.Chk = htons( chk );
165
+
166
+  // send UDP packet
167
+  pUdpPack->IpHdr.Proto = 0x11; // UDP
168
+  IpSend( pData, Length );
169
+}
170
+
171
+
... ...
@@ -0,0 +1,42 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_udp
9
+#define INC_udp
10
+
11
+#include "ethernet.h"
12
+#include "ip.h"
13
+
14
+// header of an UDP packet
15
+struct UdpHeader
16
+{
17
+  unsigned int SrcPort;
18
+  unsigned int DestPort;
19
+  unsigned int Length;
20
+  unsigned int Chk;
21
+};
22
+
23
+// an UDP packet
24
+struct UdpPacket
25
+{
26
+  struct EthernetHeader EthHdr;
27
+  struct IpHeader IpHdr;
28
+  struct UdpHeader UdpHdr;
29
+};
30
+
31
+// tick procedure - call every 200ms
32
+extern void UdpTick200( void );
33
+
34
+// process a received UDP packet
35
+extern void UdpRecv( unsigned char * pData, unsigned short Length );
36
+
37
+// send an UDP packet
38
+// pData must point to a struct UdpPacket with UdpHdr.SrcPort, UdpHdr.DestPort and IpHdr.Dest already initialized
39
+extern void UdpSend( unsigned char * pData, unsigned short Length );
40
+
41
+#endif // #ifdef INC_udp
42
+
... ...
@@ -0,0 +1,86 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#include <stdint.h>
9
+
10
+#include "xtea.h"
11
+
12
+#define delta 0x9E3779B9
13
+
14
+// XTEA encrypt a block of 64 bits
15
+// - this is not block XTEA, it's the basic XTEA algorithm
16
+static void xtea_enc_block( uint32_t key[4], uint8_t rounds, uint32_t in[2], uint32_t out[2] )
17
+{
18
+  uint32_t y, z, sum;
19
+
20
+  y = in[0];
21
+  z = in[1];
22
+  sum = 0;
23
+  for( ; rounds > 0; rounds-- )
24
+  {
25
+    y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
26
+    sum += delta;
27
+    z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
28
+  }
29
+  out[0] = y;
30
+  out[1] = z;
31
+}
32
+
33
+// XTEA decrypt a block of 64 bits
34
+// - this is not block XTEA, it's the basic XTEA algorithm
35
+static void xtea_dec_block( uint32_t key[4], uint8_t rounds, uint32_t in[2], uint32_t out[2] )
36
+{
37
+  uint32_t y, z, sum;
38
+
39
+  y = in[0];
40
+  z = in[1];
41
+  sum = (uint32_t)delta * rounds;
42
+  for( ; rounds > 0; rounds-- )
43
+  {
44
+    z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
45
+    sum -= delta;
46
+    y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
47
+  }
48
+  out[0] = y;
49
+  out[1] = z;
50
+}
51
+
52
+// XTEA encryption
53
+// rounds should be at least 32
54
+// p_in == p_out is allowed
55
+// p_prev must be initialized to zero before first call to this function
56
+void xtea_enc( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev ) // extern
57
+{
58
+  uint64_t in, out;
59
+  unsigned int i;
60
+
61
+  for( i = 0; i < block_cnt; i++ )
62
+  {
63
+    in = p_in[i] ^ *p_prev;
64
+    xtea_enc_block( key, rounds, (uint32_t *)&in, (uint32_t *)&out );
65
+    p_out[i] = out;
66
+    *p_prev = out;
67
+  }
68
+}
69
+
70
+// XTEA decryption
71
+// rounds should be at least 32
72
+// p_in == p_out is allowed
73
+// p_prev must be initialized to zero before first call to this function
74
+void xtea_dec( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev ) // extern
75
+{
76
+  uint64_t in, out;
77
+  unsigned int i;
78
+
79
+  for( i = 0; i < block_cnt; i++ )
80
+  {
81
+    in = p_in[i];
82
+    xtea_dec_block( key, rounds, (uint32_t *)&in, (uint32_t *)&out );
83
+    p_out[i] = out ^ *p_prev;
84
+    *p_prev = in;
85
+  }
86
+}
... ...
@@ -0,0 +1,25 @@
1
+/* flaneth - flash and ethernet - dartboard mod
2
+ * version 0.1 date 2008-11-09
3
+ * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
4
+ * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
5
+ * a BlinkenArea project - http://www.blinkenarea.org/
6
+ */
7
+
8
+#ifndef INC_xtea
9
+#define INC_xtea
10
+
11
+#include <stdint.h>
12
+
13
+// XTEA encryption
14
+// rounds should be at least 32
15
+// p_in == p_out is allowed
16
+// p_prev must be initialized to zero before first call to this function
17
+extern void xtea_enc( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev );
18
+
19
+// XTEA decryption
20
+// rounds should be at least 32
21
+// p_in == p_out is allowed
22
+// p_prev must be initialized to zero before first call to this function
23
+extern void xtea_dec( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev );
24
+
25
+#endif // #ifndef INC_xtea
... ...
@@ -0,0 +1,10 @@
1
+*.d
2
+*.lst
3
+*.o
4
+http_content.inc
5
+main.eep
6
+main.elf
7
+main.hex
8
+main.lss
9
+main.map
10
+main.sym
... ...
@@ -0,0 +1,22 @@
1
+flaneth - flash and ethernet
2
+Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
3
+Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
4
+a BlinkenArea project - http://www.blinkenarea.org/
5
+
6
+0.2 2008-11-08
7
+--------------
8
+added support for DHCP (client)
9
+some small fixes in TCP/HTTP
10
+
11
+0.1.1 2008-05-22
12
+----------------
13
+bugfix CF identification (was identifying card though not detected)
14
+implemented RTL8019AS EEPROM emulation
15
+ - to switch first LED from COL (collision) to LINK
16
+ - to enable FUDUP (full duplex mode)
17
+
18
+0.1 2008-02-11
19
+--------------
20
+first version
21
+based on 8BitAmEthernet 0.4.0
22
+
... ...
@@ -0,0 +1,449 @@
1
+# flaneth - flash and ethernet
2
+# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
3
+# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
4
+# a BlinkenArea project - http://www.blinkenarea.org/
5
+
6
+include Makefile.conf
7
+
8
+# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al.
9
+# Released to the Public Domain
10
+# Please read the make user manual!
11
+#
12
+# Additional material for this makefile was submitted by:
13
+#  Tim Henigan
14
+#  Peter Fleury
15
+#  Reiner Patommel
16
+#  Sander Pool
17
+#  Frederik Rouleau
18
+#  Markus Pfaff
19
+#  Stefan Schuermans
20
+#
21
+# On command line:
22
+#
23
+# make all = Make software.
24
+#
25
+# make clean = Clean out built project files.
26
+#
27
+# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
28
+#
29
+# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
30
+#                4.07 or greater).
31
+#
32
+# make program_fuses = Set the fuse bits of the device, using avrdude.  Please
33
+#                      customize the avrdude settings below first!
34
+#
35
+# make program = Download the hex file to the device, using avrdude.  Please
36
+#                customize the avrdude settings below first!
37
+#
38
+# make filename.s = Just compile filename.c into the assembler code only
39
+#
40
+# To rebuild project do "make clean" then "make all".
41
+#
42
+
43
+
44
+# MCU name
45
+MCU = atmega128
46
+
47
+# Output format. (can be srec, ihex, binary)
48
+FORMAT = ihex
49
+
50
+# Target file name (without extension).
51
+TARGET = main
52
+
53
+# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
54
+# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
55
+OPT = s
56
+
57
+
58
+# List C source files here. (C dependencies are automatically generated.)
59
+SRC = $(TARGET).c
60
+
61
+# If there is more than one source file, append them above, or modify and
62
+# uncomment the following:
63
+SRC += arp.c bus.c cf.c checksum.c config.c dhcp.c eeprom.c \
64
+       ethernet.c http.c icmp.c ip.c random.c rtl8019.c \
65
+       ser62500.c status.c tcp.c timing.c uart.c udp.c \
66
+       xtea.c
67
+
68
+# You can also wrap lines by appending a backslash to the end of the line:
69
+#SRC += baz.c \
70
+#xyzzy.c
71
+
72
+
73
+
74
+# List Assembler source files here.
75
+# Make them always end in a capital .S.  Files ending in a lowercase .s
76
+# will not be considered source files but generated files (assembler
77
+# output from the compiler), and will be deleted upon "make clean"!
78
+# Even though the DOS/Win* filesystem matches both .s and .S the same,
79
+# it will preserve the spelling of the filenames, and gcc itself does
80
+# care about how the name is spelled on its command-line.
81
+ASRC = ser62500_asm.S
82
+
83
+
84
+# List any extra directories to look for include files here.
85
+#     Each directory must be seperated by a space.
86
+EXTRAINCDIRS = 
87
+
88
+
89
+# Optional compiler flags.
90
+#  -g:        generate debugging information (for GDB, or for COFF conversion)
91
+#  -O*:       optimization level
92
+#  -f...:     tuning, see gcc manual and avr-libc documentation
93
+#  -Wall...:  warning level
94
+#  -Wa,...:   tell GCC to pass this to the assembler.
95
+#    -ahlms:  create assembler listing
96
+CFLAGS = -g -O$(OPT) \
97
+-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
98
+-Wall -Wstrict-prototypes \
99
+-Wa,-adhlns=$(<:.c=.lst) \
100
+$(patsubst %,-I%,$(EXTRAINCDIRS)) \
101
+$(DBG_FLAGS)
102
+
103
+
104
+# Set a "language standard" compiler flag.
105
+#   Unremark just one line below to set the language standard to use.
106
+#   gnu99 = C99 + GNU extensions. See GCC manual for more information.
107
+#CFLAGS += -std=c89
108
+#CFLAGS += -std=gnu89
109
+#CFLAGS += -std=c99
110
+CFLAGS += -std=gnu99
111
+
112
+# do not use C99 strict aliasing rules
113
+#   this kills some warnings occuring when casting pointer types
114
+CFLAGS += -fno-strict-aliasing
115
+
116
+
117
+
118
+# Optional assembler flags.
119
+#  -Wa,...:   tell GCC to pass this to the assembler.
120
+#  -ahlms:    create listing
121
+#  -gstabs:   have the assembler create line number information; note that
122
+#             for use in COFF files, additional information about filenames
123
+#             and function names needs to be present in the assembler source
124
+#             files -- see avr-libc docs [FIXME: not yet described there]
125
+ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
126
+
127
+
128
+
129
+# Optional linker flags.
130
+#  -Wl,...:   tell GCC to pass this to linker.
131
+#  -Map:      create map file
132
+#  --cref:    add cross reference to  map file
133
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
134
+
135
+
136
+
137
+# Additional libraries
138
+
139
+# Minimalistic printf version
140
+#LDFLAGS += -Wl,-u,vfprintf -lprintf_min
141
+
142
+# Floating point printf version (requires -lm below)
143
+#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
144
+
145
+# -lm = math library
146
+LDFLAGS += -lm
147
+
148
+
149
+
150
+# rebuilding is required if one of the following files is changed
151
+REBUILD_DEPS = Makefile.conf
152
+
153
+
154
+
155
+# Programming support using avrdude. Settings and variables.
156
+
157
+# Programming hardware: alf avr910 avrisp bascom bsd 
158
+# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
159
+#
160
+# Type: avrdude -c ?
161
+# to get a full listing.
162
+#
163
+#AVRDUDE_PROGRAMMER = stk200
164
+AVRDUDE_PROGRAMMER = avrisp2
165
+
166
+
167
+#AVRDUDE_PORT = com1	# programmer connected to serial device
168
+#AVRDUDE_PORT = lpt1	# programmer connected to parallel port
169
+#AVRDUDE_PORT = /dev/parport0
170
+AVRDUDE_PORT = usb
171
+
172
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
173
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
174
+
175
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
176
+
177
+# Uncomment the following if you want avrdude's erase cycle counter.
178
+# Note that this counter needs to be initialized first using -Yn,
179
+# see avrdude manual.
180
+#AVRDUDE_ERASE += -y
181
+
182
+# Uncomment the following if you do /not/ wish a verification to be
183
+# performed after programming the device.
184
+#AVRDUDE_FLAGS += -V
185
+
186
+# Increase verbosity level.  Please use this when submitting bug
187
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> 
188
+# to submit bug reports.
189
+#AVRDUDE_FLAGS += -v -v
190
+
191
+AVRDUDE_WRITE_FUSES = -u -U lfuse:w:0xAF:m -U hfuse:w:0xC9:m -U efuse:w:0xFF:m
192
+
193
+
194
+
195
+# ---------------------------------------------------------------------------
196
+
197
+# Define directories, if needed.
198
+DIRAVR = 
199
+DIRAVRBIN = 
200
+DIRAVRUTILS = 
201
+DIRINC = 
202
+DIRLIB = 
203
+
204
+
205
+# Define programs and commands.
206
+SHELL = sh
207
+
208
+CC = avr-gcc
209
+
210
+OBJCOPY = avr-objcopy
211
+OBJDUMP = avr-objdump
212
+SIZE = avr-size
213
+
214
+
215
+# Programming support using avrdude.
216
+AVRDUDE = avrdude
217
+
218
+
219
+REMOVE = rm -f
220
+COPY = cp
221
+
222
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
223
+ELFSIZE = $(SIZE) -A $(TARGET).elf
224
+
225
+
226
+
227
+# Define Messages
228
+# English
229
+MSG_ERRORS_NONE = Errors: none
230
+MSG_BEGIN = -------- begin --------
231
+MSG_END = --------  end  --------
232
+MSG_SIZE_BEFORE = Size before: 
233
+MSG_SIZE_AFTER = Size after:
234
+MSG_COFF = Converting to AVR COFF:
235
+MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
236
+MSG_FLASH = Creating load file for Flash:
237
+MSG_EEPROM = Creating load file for EEPROM:
238
+MSG_EXTENDED_LISTING = Creating Extended Listing:
239
+MSG_SYMBOL_TABLE = Creating Symbol Table:
240
+MSG_LINKING = Linking:
241
+MSG_COMPILING = Compiling:
242
+MSG_ASSEMBLING = Assembling:
243
+MSG_CLEANING = Cleaning project:
244
+
245
+
246
+
247
+
248
+# Define all object files.
249
+OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) 
250
+
251
+# Define all listing files.
252
+LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
253
+
254
+# Combine all necessary flags and optional flags.
255
+# Add target processor to flags.
256
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
257
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
258
+
259
+
260
+
261
+# Default target.
262
+all: my_all begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
263
+	$(TARGET).lss $(TARGET).sym sizeafter finished end
264
+
265
+# Debug target.
266
+debug: DBG_FLAGS=-DDEBUG
267
+debug: all
268
+
269
+
270
+# Eye candy.
271
+# AVR Studio 3.x does not check make's exit code but relies on
272
+# the following magic strings to be generated by the compile job.
273
+begin:
274
+	@echo
275
+	@echo $(MSG_BEGIN)
276
+
277
+finished:
278
+	@echo $(MSG_ERRORS_NONE)
279
+
280
+end:
281
+	@echo $(MSG_END)
282
+	@echo
283
+
284
+
285
+# Display size of file.
286
+sizebefore:
287
+	@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
288
+
289
+sizeafter:
290
+	@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
291
+
292
+
293
+
294
+# Display compiler version information.
295
+gccversion : 
296
+	@$(CC) --version
297
+
298
+
299
+
300
+
301
+# Convert ELF to COFF for use in debugging / simulating in
302
+# AVR Studio or VMLAB.
303
+COFFCONVERT=$(OBJCOPY) --debugging \
304
+	--change-section-address .data-0x800000 \
305
+	--change-section-address .bss-0x800000 \
306
+	--change-section-address .noinit-0x800000 \
307
+	--change-section-address .eeprom-0x810000 
308
+
309
+
310
+coff: $(TARGET).elf
311
+	@echo
312
+	@echo $(MSG_COFF) $(TARGET).cof
313
+	$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
314
+
315
+
316
+extcoff: $(TARGET).elf
317
+	@echo
318
+	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
319
+	$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
320
+
321
+
322
+
323
+# Program the device fuses.  
324
+program_fuses:
325
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES)
326
+
327
+# Program the device.  
328
+program: $(TARGET).hex $(TARGET).eep
329
+	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
330
+
331
+
332
+
333
+
334
+# Create final output files (.hex, .eep) from ELF output file.
335
+%.hex: %.elf
336
+	@echo
337
+	@echo $(MSG_FLASH) $@
338
+	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
339
+
340
+%.eep: %.elf
341
+	@echo
342
+	@echo $(MSG_EEPROM) $@
343
+	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
344
+	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
345
+
346
+# Create extended listing file from ELF output file.
347
+%.lss: %.elf
348
+	@echo
349
+	@echo $(MSG_EXTENDED_LISTING) $@
350
+	$(OBJDUMP) -h -S $< > $@
351
+
352
+# Create a symbol table from ELF output file.
353
+%.sym: %.elf
354
+	@echo
355
+	@echo $(MSG_SYMBOL_TABLE) $@
356
+	avr-nm -n $< > $@
357
+
358
+
359
+
360
+# Link: create ELF output file from object files.
361
+.SECONDARY : $(TARGET).elf
362
+.PRECIOUS : $(OBJ)
363
+%.elf: $(OBJ)
364
+	@echo
365
+	@echo $(MSG_LINKING) $@
366
+	$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
367
+
368
+
369
+# Compile: create object files from C source files.
370
+%.o : %.c $(REBUILD_DEPS)
371
+	@echo
372
+	@echo $(MSG_COMPILING) $<
373
+	$(CC) -c $(ALL_CFLAGS) $< -o $@
374
+
375
+
376
+# Compile: create assembler files from C source files.
377
+%.s : %.c $(REBUILD_DEPS)
378
+	$(CC) -S $(ALL_CFLAGS) $< -o $@
379
+
380
+
381
+# Assemble: create object files from assembler source files.
382
+%.o : %.S $(REBUILD_DEPS)
383
+	@echo
384
+	@echo $(MSG_ASSEMBLING) $<
385
+	$(CC) -c $(ALL_ASFLAGS) $< -o $@
386
+
387
+
388
+
389
+
390
+
391
+
392
+# Target: clean project.
393
+clean: my_clean begin clean_list finished end
394
+
395
+clean_list :
396
+	@echo
397
+	@echo $(MSG_CLEANING)
398
+	$(REMOVE) $(TARGET).hex
399
+	$(REMOVE) $(TARGET).eep
400
+	$(REMOVE) $(TARGET).obj
401
+	$(REMOVE) $(TARGET).cof
402
+	$(REMOVE) $(TARGET).elf
403
+	$(REMOVE) $(TARGET).map
404
+	$(REMOVE) $(TARGET).obj
405
+	$(REMOVE) $(TARGET).a90
406
+	$(REMOVE) $(TARGET).sym
407
+	$(REMOVE) $(TARGET).lnk
408
+	$(REMOVE) $(TARGET).lss
409
+	$(REMOVE) $(OBJ)
410
+	$(REMOVE) $(LST)
411
+	$(REMOVE) $(SRC:.c=.s)
412
+	$(REMOVE) $(SRC:.c=.d)
413
+
414
+
415
+# Automatically generate C source code dependencies. 
416
+# (Code originally taken from the GNU make user manual and modified 
417
+# (See README.txt Credits).)
418
+#
419
+# Note that this will work with sh (bash) and sed that is shipped with WinAVR
420
+# (see the SHELL variable defined above).
421
+# This may not work with other shells or other seds.
422
+#
423
+%.d: %.c $(REBUILD_DEPS)
424
+	set -e; $(CC) -MM $(ALL_CFLAGS) $< \
425
+	| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
426
+	[ -s $@ ] || rm -f $@
427
+
428
+http.d: http.c http_content.inc
429
+
430
+
431
+# Remove the '-' if you want to see the dependency files generated.
432
+include $(SRC:.c=.d)
433
+
434
+
435
+
436
+my_all: http_content.inc
437
+
438
+http_content.inc: http_content.pl http_$(HTTP_SKIN)/* $(REBUILD_DEPS)
439
+	./http_content.pl http_$(HTTP_SKIN) http_content.inc || rm -f http_content.inc http_content.inc
440
+
441
+my_clean:
442
+	rm -f http_content.inc
443
+
444
+
445
+
446
+# Listing of phony targets.
447
+.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
448
+	clean clean_list program_fuses program my_all my_clean
449
+
... ...
@@ -0,0 +1,8 @@
1
+# flaneth - flash and ethernet
2
+# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
3
+# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
4
+# a BlinkenArea project - http://www.blinkenarea.org/
5
+
6
+# skin to use on http interface
7
+# HTTP_SKIN=[classic|simple|oldschool|oldschool_de]
8
+HTTP_SKIN = oldschool
... ...
@@ -0,0 +1,238 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include "arp.h"
7
+#include "config.h"
8
+#include "debug.h"
9
+#include "ethernet.h"
10
+#include "ip.h"
11
+#include "macros.h"
12
+#include "nethelp.h"
13
+
14
+// timing parameters
15
+#define ArpTicksMax 150 // maximum age of ARP table entries (in 200ms steps)
16
+#define ArpNoMacTicksMax 50     // maximum age of ARP table entries without
17
+                                // MAC (in 200ms steps)
18
+#define ArpRetryTicks 8 // time after which to retry ARP query (must be power 
19
+                        // of 2, in 200ms steps)
20
+
21
+// ARP table
22
+#define ArpTabFlagInUse 0x01
23
+#define ArpTabFlagMacOk 0x02
24
+struct ArpTable {
25
+  unsigned char Flags;  // flags - see constants
26
+  unsigned char Ticks;  // age of entry in 200ms steps
27
+  unsigned char Mac[6];
28
+  unsigned char Ip[4];
29
+} ArpTab[12];
30
+
31
+// initialize
32
+void ArpInit(void)      // (extern)
33
+{
34
+  unsigned char i;
35
+
36
+  // empty ARP tabale
37
+  for (i = 0; i < count(ArpTab); i++)
38
+    ArpTab[i].Flags = 0;
39
+}
40
+
41
+// send an ARP request
42
+static void ArpSendRequest(unsigned char *pIp)
43
+{
44
+  struct ArpPacket ArpRequest;
45
+
46
+  debug_arp_printf("send req ip=%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]);
47
+
48
+  // build ARP request
49
+  ArpRequest.ArpHdr.HwType = htons(0x0001);     // ethernet
50
+  ArpRequest.ArpHdr.ProtoType = htons(0x0800);  // IP
51
+  ArpRequest.ArpHdr.HwLen = 0x06;       // length of a MAC address
52
+  ArpRequest.ArpHdr.ProtoLen = 0x04;    // length of an IP address
53
+  ArpRequest.ArpHdr.Op = htons(0x0001); // ARP request
54
+  mac_cpy(ArpRequest.ArpHdr.SrcMac, ConfigMac); // own MAC
55
+  ip_cpy(ArpRequest.ArpHdr.SrcIp, ConfigIp);    // own IP
56
+  mac_cpy(ArpRequest.ArpHdr.DestMac, "\xFF\xFF\xFF\xFF\xFF\xFF");       // broadcast 
57
+                                                                        // MAC
58
+  ip_cpy(ArpRequest.ArpHdr.DestIp, pIp);        // requested IP
59
+
60
+  // sent ARP request
61
+  mac_cpy(ArpRequest.EthHdr.Dest, ArpRequest.ArpHdr.DestMac);   // ethernet
62
+                                                                // destination 
63
+                                                                // address
64
+  ArpRequest.EthHdr.Type = htons(0x0806);       // ethernet packet type: ARP
65
+  EthernetSend((unsigned char *)&ArpRequest, sizeof(ArpRequest));
66
+}
67
+
68
+// tick procedure - call every 200ms
69
+void ArpTick200(void)   // (extern)
70
+{
71
+  unsigned char i;
72
+
73
+  // increase age of ARP table entires and remove timed out ones
74
+  for (i = 0; i < count(ArpTab); i++) {
75
+    if (ArpTab[i].Flags & ArpTabFlagInUse)      // entry in use
76
+    {
77
+      ArpTab[i].Ticks++;        // increase age
78
+      if (ArpTab[i].Flags & ArpTabFlagMacOk)    // entry has got a MAC
79
+      {
80
+        if (ArpTab[i].Ticks > ArpTicksMax)      // too old
81
+          ArpTab[i].Flags = 0;  // remove entry
82
+      } else    // entry has not got a MAC
83
+      {
84
+        if (ArpTab[i].Ticks > ArpNoMacTicksMax) // too old
85
+          ArpTab[i].Flags = 0;  // remove entry
86
+        else if ((ArpTab[i].Ticks & (ArpRetryTicks - 1)) == 0)  // retry ARP
87
+                                                                // request
88
+          ArpSendRequest(ArpTab[i].Ip);
89
+      }
90
+    }
91
+  }
92
+}
93
+
94
+// process a received ARP packet
95
+void ArpRecv(unsigned char *pData, unsigned short Length)       // (extern)
96
+{
97
+  struct ArpPacket *pArpPack;
98
+
99
+  // packet too short
100
+  if (Length < sizeof(struct ArpPacket))
101
+    return;
102
+
103
+  // convert pointer to ARP packet
104
+  // (this saves us from always casting pData)
105
+  pArpPack = (struct ArpPacket *)pData;
106
+
107
+  // not IP over ethernet
108
+  if (pArpPack->ArpHdr.HwType != htons(0x0001) ||       // ethernet
109
+      pArpPack->ArpHdr.ProtoType != htons(0x0800) ||    // IP
110
+      pArpPack->ArpHdr.HwLen != 0x06 || // length of a MAC address
111
+      pArpPack->ArpHdr.ProtoLen != 0x04)        // length of an IP address
112
+    // we do not support other protocols than IP over ethernet
113
+    return;
114
+
115
+  // source MAC is broadcast MAC
116
+  if (mac_eq(pArpPack->ArpHdr.SrcMac, "\xFF\xFF\xFF\xFF\xFF\xFF"))
117
+    // broadcast MAC cannot be source, this is some kind of attack, get lost!
118
+    return;
119
+
120
+  // ARP request for own IP address
121
+  if (pArpPack->ArpHdr.Op == htons(0x0001) &&   // ARP request
122
+      ip_eq(pArpPack->ArpHdr.DestIp, ConfigIp)) // own IP address
123
+  {
124
+    struct ArpPacket ArpReply;
125
+    // build ARP reply
126
+    ArpReply.ArpHdr.HwType = htons(0x0001);     // ethernet
127
+    ArpReply.ArpHdr.ProtoType = htons(0x0800);  // IP
128
+    ArpReply.ArpHdr.HwLen = 0x06;       // length of a MAC address
129
+    ArpReply.ArpHdr.ProtoLen = 0x04;    // length of an IP address
130
+    ArpReply.ArpHdr.Op = htons(0x0002); // ARP reply
131
+    mac_cpy(ArpReply.ArpHdr.SrcMac, ConfigMac); // own MAC
132
+    ip_cpy(ArpReply.ArpHdr.SrcIp, ConfigIp);    // own IP
133
+    mac_cpy(ArpReply.ArpHdr.DestMac, pArpPack->ArpHdr.SrcMac);  // requestor's 
134
+                                                                // MAC
135
+    ip_cpy(ArpReply.ArpHdr.DestIp, pArpPack->ArpHdr.SrcIp);     // requestor's 
136
+                                                                // IP
137
+
138
+    debug_arp_printf
139
+        ("recv req src=%02X:%02X:%02X:%02X:%02X:%02X ip=%u.%u.%u.%u",
140
+         pArpPack->ArpHdr.SrcMac[0], pArpPack->ArpHdr.SrcMac[1],
141
+         pArpPack->ArpHdr.SrcMac[2], pArpPack->ArpHdr.SrcMac[3],
142
+         pArpPack->ArpHdr.SrcMac[4], pArpPack->ArpHdr.SrcMac[5],
143
+         pArpPack->ArpHdr.SrcIp[0], pArpPack->ArpHdr.SrcIp[1],
144
+         pArpPack->ArpHdr.SrcIp[2], pArpPack->ArpHdr.SrcIp[3]);
145
+
146
+    // sent ARP reply
147
+    mac_cpy(ArpReply.EthHdr.Dest, ArpReply.ArpHdr.DestMac);     // ethernet
148
+                                                                // destination 
149
+                                                                // address
150
+    ArpReply.EthHdr.Type = htons(0x0806);       // ethernet packet type: ARP
151
+    EthernetSend((unsigned char *)&ArpReply, sizeof(ArpReply));
152
+    return;
153
+  }
154
+  // ARP reply to own MAC address and own IP address
155
+  if (pArpPack->ArpHdr.Op == htons(0x0002) &&   // ARP reply
156
+      mac_eq(pArpPack->ArpHdr.DestMac, ConfigMac) &&    // own MAC address
157
+      ip_eq(pArpPack->ArpHdr.DestIp, ConfigIp)) // own IP address
158
+  {
159
+    unsigned char i;
160
+
161
+    debug_arp_printf
162
+        ("recv reply src=%02X:%02X:%02X:%02X:%02X:%02X ip=%u.%u.%u.%u",
163
+         pArpPack->ArpHdr.SrcMac[0], pArpPack->ArpHdr.SrcMac[1],
164
+         pArpPack->ArpHdr.SrcMac[2], pArpPack->ArpHdr.SrcMac[3],
165
+         pArpPack->ArpHdr.SrcMac[4], pArpPack->ArpHdr.SrcMac[5],
166
+         pArpPack->ArpHdr.SrcIp[0], pArpPack->ArpHdr.SrcIp[1],
167
+         pArpPack->ArpHdr.SrcIp[2], pArpPack->ArpHdr.SrcIp[3]);
168
+
169
+    // search IP in ARP tabale
170
+    for (i = 0; i < count(ArpTab); i++)
171
+      if ((ArpTab[i].Flags & ArpTabFlagInUse) &&
172
+          ip_eq(pArpPack->ArpHdr.SrcIp, ArpTab[i].Ip))
173
+        break;
174
+    // if found in ARP table
175
+    // (we do not want to put an entry in the ARP table
176
+    // if we have not asked for the MAC of this IP)
177
+    if (i < count(ArpTab)) {
178
+      // update ARP table entry
179
+      ArpTab[i].Flags = ArpTabFlagInUse | ArpTabFlagMacOk;
180
+      ArpTab[i].Ticks = 0;
181
+      mac_cpy(ArpTab[i].Mac, pArpPack->ArpHdr.SrcMac);
182
+      // notify IP
183
+      // - IP might be waiting for the MAC to transmit a packet
184
+      IpGotMac(ArpTab[i].Ip, ArpTab[i].Mac);
185
+    }
186
+    return;
187
+  }
188
+
189
+}
190
+
191
+// lookup the MAC for an IP address
192
+// returns 0x00 in case of success, 0x01 if the MAC address is unknown
193
+unsigned char ArpLookup(unsigned char *pIp, unsigned char *pMac)        // (extern)
194
+{
195
+  unsigned char i, j;
196
+
197
+  // own IP
198
+  if (ip_eq(pIp, ConfigIp))
199
+    // own IP may not be looked up via ARP
200
+    return 0x01;
201
+
202
+  // search IP in ARP tabale
203
+  for (i = 0; i < count(ArpTab); i++)
204
+    if ((ArpTab[i].Flags & ArpTabFlagInUse) && ip_eq(pIp, ArpTab[i].Ip))
205
+      break;
206
+
207
+  // not found
208
+  if (i >= count(ArpTab)) {
209
+    // find a free entry
210
+    for (i = 0; i < count(ArpTab); i++)
211
+      if (!(ArpTab[i].Flags & ArpTabFlagInUse))
212
+        break;
213
+
214
+    // no free entry
215
+    if (i >= count(ArpTab)) {
216
+      // find oldest entry
217
+      i = 0;
218
+      for (j = 1; j < count(ArpTab); j++)
219
+        if (ArpTab[j].Ticks > ArpTab[i].Ticks)
220
+          i = j;
221
+    }
222
+    // set up this entry
223
+    ArpTab[i].Flags = ArpTabFlagInUse;
224
+    ArpTab[i].Ticks = 0;
225
+    ip_cpy(ArpTab[i].Ip, pIp);
226
+  }
227
+  // MAC available
228
+  if (ArpTab[i].Flags & ArpTabFlagMacOk) {
229
+    // return MAC and success
230
+    mac_cpy(pMac, ArpTab[i].Mac);
231
+    return 0x00;
232
+  }
233
+  // send ARP request
234
+  ArpSendRequest(pIp);
235
+
236
+  // return no success for now
237
+  return 0x01;
238
+}
... ...
@@ -0,0 +1,43 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_arp
7
+#define INC_arp
8
+
9
+#include "ethernet.h"
10
+
11
+// header of an ARP packet
12
+struct ArpHeader {
13
+  unsigned short HwType;
14
+  unsigned short ProtoType;
15
+  unsigned char HwLen;
16
+  unsigned char ProtoLen;
17
+  unsigned short Op;
18
+  unsigned char SrcMac[6];
19
+  unsigned char SrcIp[4];
20
+  unsigned char DestMac[6];
21
+  unsigned char DestIp[4];
22
+};
23
+
24
+// an ARP packet
25
+struct ArpPacket {
26
+  struct EthernetHeader EthHdr;
27
+  struct ArpHeader ArpHdr;
28
+};
29
+
30
+// initialize
31
+extern void ArpInit(void);
32
+
33
+// tick procedure - call every 200ms
34
+extern void ArpTick200(void);
35
+
36
+// process a received ARP packet
37
+extern void ArpRecv(unsigned char *pData, unsigned short Length);
38
+
39
+// lookup the MAC for an IP address
40
+// returns 0x00 in case of success, 0x01 if the MAC address is unknown
41
+extern unsigned char ArpLookup(unsigned char *pIp, unsigned char *pMac);
42
+
43
+#endif // #ifdef INC_arp
... ...
@@ -0,0 +1,28 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/io.h>
7
+
8
+#include "bus.h"
9
+
10
+// initialize
11
+void BusInit(void)      // (extern)
12
+{
13
+  // address port to output
14
+  BUS_ADDR = 0x00;      // default address
15
+  BUS_ADDR_DDR = 0xFF;  // output
16
+
17
+  // data port to input
18
+  BUS_DATA = 0x00;      // pull-ups off
19
+  BUS_DATA_DDR = 0x00;  // input
20
+
21
+  // read pin to output
22
+  bit_set(BUS_PORT_nRD, BUS_BIT_nRD);   // nRD to high
23
+  bit_set(BUS_DDR_nRD, BUS_BIT_nRD);    // output
24
+
25
+  // write pin to output
26
+  bit_set(BUS_PORT_nWR, BUS_BIT_nWR);   // nWR to high
27
+  bit_set(BUS_DDR_nWR, BUS_BIT_nWR);    // output
28
+}
... ...
@@ -0,0 +1,33 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_bus
7
+#define INC_bus
8
+
9
+#include "macros.h"
10
+
11
+// IO pins of bus
12
+#define BUS_ADDR_DDR (DDRG)
13
+#define BUS_ADDR (PORTG)
14
+#define BUS_DATA_DDR (DDRA)
15
+#define BUS_DATA (PORTA)
16
+#define BUS_DATA_IN (PINA)
17
+#define BUS_DDR_nRD (DDRE)
18
+#define BUS_PORT_nRD (PORTE)
19
+#define BUS_BIT_nRD (6)
20
+#define BUS_DDR_nWR (DDRE)
21
+#define BUS_PORT_nWR (PORTE)
22
+#define BUS_BIT_nWR (7)
23
+
24
+// special pin commands
25
+#define BUS_READ_ACT( ) (bit_clear( BUS_PORT_nRD, BUS_BIT_nRD ))
26
+#define BUS_READ_IDLE( ) (bit_set( BUS_PORT_nRD, BUS_BIT_nRD ))
27
+#define BUS_WRITE_ACT( ) (bit_clear( BUS_PORT_nWR, BUS_BIT_nWR ))
28
+#define BUS_WRITE_IDLE( ) (bit_set( BUS_PORT_nWR, BUS_BIT_nWR ))
29
+
30
+// initialize
31
+extern void BusInit(void);
32
+
33
+#endif // #ifndef INC_bus
... ...
@@ -0,0 +1,664 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/io.h>
7
+
8
+#include "bus.h"
9
+#include "cf.h"
10
+#include "config.h"
11
+#include "debug.h"
12
+#include "macros.h"
13
+#include "status.h"
14
+#include "timing.h"
15
+
16
+// IO pins of compact flash
17
+#define CF_DDR_nCD (DDRB)
18
+#define CF_PORT_nCD (PORTB)
19
+#define CF_PIN_nCD (PINB)
20
+#define CF_BIT_nCD (4)
21
+#define CF_DDR_nRST (DDRB)
22
+#define CF_PORT_nRST (PORTB)
23
+#define CF_BIT_nRST (5)
24
+#define CF_DDR_RDY (DDRB)
25
+#define CF_PORT_RDY (PORTB)
26
+#define CF_PIN_RDY (PINB)
27
+#define CF_BIT_RDY (7)
28
+#define CF_DDR_nCE (DDRB)
29
+#define CF_PORT_nCE (PORTB)
30
+#define CF_BIT_nCE (6)
31
+// special pin commands
32
+#define CF_IS_DETECT() (is_bit_clear(CF_PIN_nCD, CF_BIT_nCD))
33
+#define CF_RESET_ACT() (bit_clear(CF_PORT_nRST, CF_BIT_nRST))
34
+#define CF_RESET_IDLE() (bit_set(CF_PORT_nRST, CF_BIT_nRST))
35
+#define CF_IS_READY() (is_bit_set(CF_PIN_RDY, CF_BIT_RDY))
36
+#define CF_CE_ACT() (bit_clear(CF_PORT_nCE, CF_BIT_nCE))
37
+#define CF_CE_IDLE() (bit_set(CF_PORT_nCE, CF_BIT_nCE))
38
+
39
+// compact flash registers
40
+#define CF_REG_DATA (0x00)
41
+#define CF_REG_ERR (0x01)
42
+#define CF_REG_SEC_CNT (0x02)
43
+#define CF_REG_SEC_NO (0x03)
44
+#define CF_REG_CYL_L (0x04)
45
+#define CF_REG_CYL_H (0x05)
46
+#define CF_REG_HEAD (0x06)
47
+#define CF_REG_STATUS (0x07)
48
+#define CF_REG_CMD (0x07)
49
+
50
+// compact flash status bits
51
+#define CF_SB_BUSY (7)
52
+#define CF_SB_RDY (6)
53
+#define CF_SB_DWF (5)
54
+#define CF_SB_DSC (4)
55
+#define CF_SB_DRQ (3)
56
+#define CF_SB_CORR (2)
57
+#define CF_SB_IDX (1)
58
+#define CF_SB_ERR (0)
59
+
60
+// compact flash commands
61
+#define CF_CMD_IDENTIFY (0xEC)
62
+#define CF_CMD_READ_SEC (0x20)
63
+#define CF_CMD_WRITE_SEC (0x30)
64
+
65
+// some number of bytes
66
+#define CF_BYTES_AT_ONCE (32)   // number of bytes to read/write at once
67
+#define CF_BYTES_IDENTIFY (124) // number of bytes to read for identify
68
+
69
+// interesting locations in identify data
70
+#define CF_ID_OFS_ID_16 (0)     // CF identifier, 16 bit
71
+#define CF_ID_OFS_CAPA_16 (98)  // CF capabilities, 16 bit
72
+#define CF_ID_OFS_SEC_CNT_32 (120)      // number of sectors on CF (in LBA
73
+                                        // mode), 32 bit
74
+
75
+// various CF constants
76
+#define CF_ID (0x848A)  // identifier of compact flash cards
77
+#define CF_CAPA_BIT_LBA (9)     // bit number of the LBA bit in the CF
78
+                                // capabilities
79
+
80
+// timeout value for wait for ready after reset counter (in 20ms steps)
81
+#define CF_WAIT_READY_RESET_20_TIMEOUT (50)    // 1s
82
+
83
+// timeout value for wait for ready counter (in 20ms steps)
84
+#define CF_WAIT_READY_20_TIMEOUT (4)    // 80ms
85
+
86
+// compact flash insertion state
87
+enum CfInsertionState {
88
+  CfInsNone,    // no compact flash inserted
89
+  CfInsNew,     // new compact flash has been inserted, wait for powerup
90
+  CfInsReset,   // resetting new compact flash
91
+  CfInsWait,    // waiting for new compact flash to get ready after reset
92
+  CfInsReady,   // compact flash inserted and ready to work with
93
+  CfInsError,   // compact flash error occured, compact flash deactivated
94
+} CfInsState = CfInsNone;
95
+
96
+// compact flash working state
97
+enum CfWorkingState {
98
+  CfWorkNone,   // no compact flash work to do
99
+  CfWorkIdentify,       // identification of compact flash active
100
+} CfWorkState = CfWorkNone;
101
+
102
+// compact flash working step
103
+enum CfWorkingStep {
104
+  CfStepNone,   // no step in progress
105
+  CfStepCmdStatus,      // checking command status
106
+  CfStepDataTransfer,   // transferring (reading/writing) data
107
+  CfStepDataStatus,     // checking data status
108
+} CfWorkStep = CfStepNone;
109
+
110
+// number of sectors on compact flash card
111
+// - zero if no CF card is present, CF card has not yet been identified or CF 
112
+// card error occured
113
+unsigned long CfSectorCnt = 0;
114
+
115
+// state of active command
116
+unsigned long CfSectorNo = 0;   // current sector number of compact flash
117
+unsigned short CfNextOffset = 0;        // next offset in sector that is
118
+                                        // processed (read, written, ...)
119
+
120
+// wait for ready counter of compact flash
121
+// - counts down in 20ms steps
122
+// - zero if inactive
123
+unsigned char CfWaitReady20 = 0;
124
+
125
+// sector buffer
126
+unsigned char CfSectorBuffer[CF_SECTOR_SIZE];   // (extern)
127
+
128
+// write a compact flash register (returns 1 if successful or 0 on error)
129
+// - returns 0 on success and -1 on error
130
+extern inline char CfWriteReg(unsigned char reg, unsigned char val)     // force 
131
+                                                                        // inlining 
132
+                                                                        // by 
133
+                                                                        // using 
134
+                                                                        // "extern"
135
+{
136
+  if (!CF_IS_DETECT() || !CF_IS_READY())        // check that card is present 
137
+                                                // and ready
138
+    return -1;  // error
139
+  BUS_DATA = val;       // output value
140
+  BUS_DATA_DDR = 0xFF;  // data port to output
141
+  BUS_ADDR = reg;       // output address
142
+  CF_CE_ACT();  // set card enable
143
+  BUS_WRITE_ACT();      // activate write signal
144
+  nop();
145
+  nop();
146
+  nop();
147
+  nop();
148
+  nop();
149
+  nop();
150
+  BUS_WRITE_IDLE();     // take back write signal
151
+  CF_CE_IDLE(); // take back card enable
152
+  BUS_DATA_DDR = 0x00;  // data back port to input
153
+  BUS_DATA = 0x00;      // turn off pullups
154
+  return 0;     // success
155
+}
156
+
157
+// write buffer to compact flash register
158
+// (returns 1 if successful or 0 on error)
159
+// - returns 0 on success and -1 on error
160
+// - force inlining  by using "extern"
161
+extern inline char CfWriteRegBuf(unsigned char reg, unsigned char *p_buf,
162
+                                 unsigned short len)
163
+{
164
+  if (!CF_IS_DETECT() || !CF_IS_READY())        // check that card is present 
165
+                                                // and ready
166
+    return -1;  // error
167
+  BUS_DATA = *p_buf;    // output first value to initialize port status
168
+                        // before switching to output
169
+  BUS_DATA_DDR = 0xFF;  // data port to output
170
+  BUS_ADDR = reg;       // output address
171
+  CF_CE_ACT();  // set card enable
172
+  for (; len > 0; p_buf++, len--) {
173
+    if (!CF_IS_DETECT() || !CF_IS_READY())      // check that card is present 
174
+                                                // and ready
175
+      break;
176
+    BUS_DATA = *p_buf;  // output value
177
+    BUS_WRITE_ACT();    // activate write signal
178
+    nop();
179
+    nop();
180
+    nop();
181
+    nop();
182
+    nop();
183
+    nop();
184
+    BUS_WRITE_IDLE();   // take back write signal
185
+  }
186
+  CF_CE_IDLE(); // take back card enable
187
+  BUS_DATA_DDR = 0x00;  // data back port to input
188
+  BUS_DATA = 0x00;      // turn off pullups
189
+  return len <= 0 ? 0 : -1;     // success if everything has been written
190
+}
191
+
192
+// write constant value to compact flash register multiple times (returns 1
193
+// if successful or 0 on error)
194
+// - returns 0 on success and -1 on error
195
+extern inline char CfWriteRegConst(unsigned char reg, unsigned char val, unsigned short cnt)    // force 
196
+                                                                                                // inlining 
197
+                                                                                                // by 
198
+                                                                                                // using 
199
+                                                                                                // "extern"
200
+{
201
+  if (!CF_IS_DETECT() || !CF_IS_READY())        // check that card is present 
202
+                                                // and ready
203
+    return -1;  // error
204
+  BUS_DATA = val;       // output value
205
+  BUS_DATA_DDR = 0xFF;  // data port to output
206
+  BUS_ADDR = reg;       // output address
207
+  CF_CE_ACT();  // set card enable
208
+  for (; cnt > 0; cnt--) {
209
+    if (!CF_IS_DETECT() || !CF_IS_READY())      // check that card is present 
210
+                                                // and ready
211
+      break;
212
+    BUS_WRITE_ACT();    // activate write signal
213
+    nop();
214
+    nop();
215
+    nop();
216
+    nop();
217
+    nop();
218
+    nop();
219
+    BUS_WRITE_IDLE();   // take back write signal
220
+  }
221
+  CF_CE_IDLE(); // take back card enable
222
+  BUS_DATA_DDR = 0x00;  // data back port to input
223
+  BUS_DATA = 0x00;      // turn off pullups
224
+  return cnt <= 0 ? 0 : -1;     // success if everything has been written
225
+}
226
+
227
+// read a compact flash register (returns 1 if successful or 0 on error)
228
+// - returns 0 on success and -1 on error
229
+extern inline char CfReadReg(unsigned char reg, unsigned char *p_var)   // force 
230
+                                                                        // inlining 
231
+                                                                        // by 
232
+                                                                        // using 
233
+                                                                        // "extern"
234
+{
235
+  if (!CF_IS_DETECT() || !CF_IS_READY())        // check that card is present 
236
+                                                // and ready
237
+    return -1;  // error
238
+  BUS_ADDR = reg;       // output address
239
+  CF_CE_ACT();  // set card enable
240
+  BUS_READ_ACT();       // activate read signal
241
+  nop();
242
+  nop();
243
+  nop();
244
+  nop();
245
+  nop();
246
+  nop();
247
+  *p_var = BUS_DATA_IN; // read data
248
+  BUS_READ_IDLE();      // take back read signal
249
+  CF_CE_IDLE(); // take back card enable
250
+  return 0;     // success
251
+}
252
+
253
+// read buffer from a compact flash register (returns 1 if successful or 0 on 
254
+// error)
255
+// - returns 0 on success and -1 on error
256
+extern inline char CfReadRegBuf(unsigned char reg, unsigned char *p_buf, unsigned short len)    // force 
257
+                                                                                                // inlining 
258
+                                                                                                // by 
259
+                                                                                                // using 
260
+                                                                                                // "extern"
261
+{
262
+  if (!CF_IS_DETECT() || !CF_IS_READY())        // check that card is present 
263
+                                                // and ready
264
+    return -1;  // error
265
+  BUS_ADDR = reg;       // output address
266
+  CF_CE_ACT();  // set card enable
267
+  for (; len > 0; p_buf++, len--) {
268
+    if (!CF_IS_DETECT() || !CF_IS_READY())      // check that card is present 
269
+                                                // and ready
270
+      break;
271
+    BUS_READ_ACT();     // activate read signal
272
+    nop();
273
+    nop();
274
+    nop();
275
+    nop();
276
+    nop();
277
+    nop();
278
+    *p_buf = BUS_DATA_IN;       // read data
279
+    BUS_READ_IDLE();    // take back read signal
280
+  }
281
+  CF_CE_IDLE(); // take back card enable
282
+  return len <= 0 ? 0 : -1;     // success if everything has been read
283
+}
284
+
285
+// read a compact flash register multiple times and throw away data (returns
286
+// 1 if successful or 0 on error)
287
+// - returns 0 on success and -1 on error
288
+extern inline char CfReadRegMulti(unsigned char reg, unsigned short cnt)        // force 
289
+                                                                                // inlining 
290
+                                                                                // by 
291
+                                                                                // using 
292
+                                                                                // "extern"
293
+{
294
+  if (!CF_IS_DETECT() || !CF_IS_READY())        // check that card is present 
295
+                                                // and ready
296
+    return -1;  // error
297
+  BUS_ADDR = reg;       // output address
298
+  CF_CE_ACT();  // set card enable
299
+  for (; cnt > 0; cnt--) {
300
+    if (!CF_IS_DETECT() || !CF_IS_READY())      // check that card is present 
301
+                                                // and ready
302
+      break;
303
+    BUS_READ_ACT();     // activate read signal
304
+    nop();
305
+    nop();
306
+    nop();
307
+    nop();
308
+    nop();
309
+    nop();
310
+    BUS_READ_IDLE();    // take back read signal
311
+  }
312
+  CF_CE_IDLE(); // take back card enable
313
+  return cnt <= 0 ? 0 : -1;     // success if everything has been read
314
+}
315
+
316
+// compact flash work done
317
+static void CfDone(void)
318
+{
319
+  debug_cf_printf("CF done (%lu sectors)", CfSectorCnt);
320
+
321
+  // set working state and step to none
322
+  CfWorkState = CfWorkNone;
323
+  CfWorkStep = CfStepNone;
324
+
325
+  // reset state of active command
326
+  CfSectorNo = 0;
327
+  CfNextOffset = 0;
328
+
329
+  // disable wait for ready counter
330
+  CfWaitReady20 = 0;
331
+}
332
+
333
+// compact flash error occured
334
+static void CfError(void)
335
+{
336
+  debug_cf_printf("CF error");
337
+
338
+  // set insertion state to error
339
+  CfInsState = CfInsError;
340
+
341
+  // set working state and step to none
342
+  CfWorkState = CfWorkNone;
343
+  CfWorkStep = CfStepNone;
344
+
345
+  // reset all information about CF card
346
+  CfSectorCnt = 0;
347
+
348
+  // reset state of active command
349
+  CfSectorNo = 0;
350
+  CfNextOffset = 0;
351
+
352
+  // disable wait for ready counter
353
+  CfWaitReady20 = 0;
354
+}
355
+
356
+// process compact flash insertion
357
+static void CfProcIns(void)
358
+{
359
+  switch (CfInsState) {
360
+
361
+    // no compact flash inserted
362
+  case CfInsNone:
363
+    // if compact flash is detected, set state to new CF
364
+    if (CF_IS_DETECT()) {
365
+      CfInsState = CfInsNew;
366
+      debug_cf_printf("new CF");
367
+      break;
368
+    }
369
+    break;
370
+
371
+    // new compact flash has been inserted, wait for powerup
372
+  case CfInsNew:
373
+    // if compact flash has been removed, set state to none
374
+    if (!CF_IS_DETECT()) {
375
+      CfInsState = CfInsNone;
376
+      break;
377
+    }
378
+    CfInsState = CfInsReset;
379
+    break;
380
+
381
+    // resetting new compact flash
382
+  case CfInsReset:
383
+    // set reset, wait, take back reset
384
+    CF_RESET_ACT();
385
+    nop();
386
+    nop();
387
+    nop();
388
+    CF_RESET_IDLE();
389
+    debug_cf_printf("CF reset");
390
+    // if compact flash has been removed, set state to none
391
+    if (!CF_IS_DETECT()) {
392
+      CfInsState = CfInsNone;
393
+      break;
394
+    }
395
+    // wait for CF to become ready
396
+    CfInsState = CfInsWait;
397
+    CfWaitReady20 = CF_WAIT_READY_RESET_20_TIMEOUT;
398
+    break;
399
+
400
+    // waiting for new compact flash to get ready after reset
401
+  case CfInsWait:
402
+    // if compact flash has been removed, set state to none
403
+    if (!CF_IS_DETECT()) {
404
+      CfInsState = CfInsNone;
405
+      break;
406
+    }
407
+    // if compact flash card is ready, set state to ready
408
+    if (CF_IS_READY()) {
409
+      CfInsState = CfInsReady;
410
+      CfWaitReady20 = 0;
411
+      debug_cf_printf("CF ready");
412
+      break;
413
+    }
414
+    // count down timeout
415
+    CfWaitReady20--;
416
+    if (CfWaitReady20 <= 0) {
417
+      debug_cf_printf("timeout waiting for CF ready");
418
+      // start over
419
+      CfInsState = CfInsNone;
420
+      break;
421
+    }
422
+    break;
423
+
424
+    // compact flash inserted and ready to work with
425
+  case CfInsReady:
426
+    // do nothing here, card work is done by task procedure
427
+    // (task will detect CF removal or timeout and set state to error)
428
+    break;
429
+
430
+    // compact flash error occured, compact flash deactivated
431
+  case CfInsError:
432
+    // if compact flash has been removed, set state to none
433
+    if (!CF_IS_DETECT()) {
434
+      CfInsState = CfInsNone;
435
+      debug_cf_printf("CF removed");
436
+    }
437
+    break;
438
+
439
+  }     // switch( CfInsState )
440
+}
441
+
442
+// detect compact flash timeout
443
+// - called every 20ms
444
+static void CfDetectTimeout20(void)
445
+{
446
+  // only detect CF timeout if insertion state is ready
447
+  // (otherwise, the insertion processing is still doing some work)
448
+  if (CfInsState != CfInsReady)
449
+    return;
450
+
451
+  // wait for ready counter not active
452
+  if (CfWaitReady20 <= 0)
453
+    return;
454
+
455
+  // decrement wait for ready counter
456
+  CfWaitReady20--;
457
+
458
+  // timeout occured
459
+  if (CfWaitReady20 <= 0) {
460
+    debug_cf_printf("timeout while waiting for CF ready");
461
+    CfError();
462
+  }
463
+}
464
+
465
+// continue with identifying compact flash
466
+static void CfProcWorkIdentify(void)
467
+{
468
+  unsigned char status = 0;
469
+  unsigned short len, val16;
470
+
471
+  switch (CfWorkStep) {
472
+
473
+    // no step
474
+  case CfStepNone:
475
+    debug_cf_printf("internal error (identify, CfStepNone)");
476
+    CfError();
477
+    break;
478
+
479
+    // checking command status
480
+  case CfStepCmdStatus:
481
+    // read status register
482
+    CfReadReg(CF_REG_STATUS, &status);
483
+    // check that BUSY=0, RDY=1, DWF=0, DSC=1, IDX=0, ERR=0
484
+    if ((status &
485
+         (1 << CF_SB_BUSY | 1 << CF_SB_RDY | 1 << CF_SB_DWF | 1 << CF_SB_DSC |
486
+          1 << CF_SB_IDX | 1 << CF_SB_ERR)) !=
487
+        (1 << CF_SB_RDY | 1 << CF_SB_DSC)) {
488
+      debug_cf_printf("unexpected status 0x%02X (identify)", status);
489
+      CfError();
490
+    }
491
+    // continue with data transfer
492
+    CfWorkStep = CfStepDataTransfer;
493
+    CfNextOffset = 0;
494
+    break;
495
+
496
+    // transferring data
497
+  case CfStepDataTransfer:
498
+    // still bytes to read
499
+    if (CfNextOffset < CF_BYTES_IDENTIFY) {
500
+      // get number of bytes to read
501
+      len = CF_BYTES_IDENTIFY - CfNextOffset;
502
+      if (len > CF_BYTES_AT_ONCE)
503
+        len = CF_BYTES_AT_ONCE;
504
+      // read bytes
505
+      if (CfReadRegBuf(CF_REG_DATA, &CfSectorBuffer[CfNextOffset], len) != 0) {
506
+        debug_cf_printf
507
+            ("reading from CF failed (identify, offset 0x%03X, length 0x%02X)",
508
+             CfNextOffset, len);
509
+        CfError();
510
+        break;
511
+      }
512
+      CfNextOffset += len;
513
+    }
514
+    // all bytes read
515
+    if (CfNextOffset >= CF_BYTES_IDENTIFY) {
516
+      // check identifier
517
+      val16 = (unsigned short)CfSectorBuffer[CF_ID_OFS_ID_16 + 0]
518
+          | (unsigned short)CfSectorBuffer[CF_ID_OFS_ID_16 + 1] << 8;
519
+      if (val16 != CF_ID) {
520
+        debug_cf_printf("invalid CF identifier: 0x%04X", val16);
521
+        CfError();
522
+        break;
523
+      }
524
+      // check if LBA mode is supported
525
+      val16 = (unsigned short)CfSectorBuffer[CF_ID_OFS_CAPA_16 + 0]
526
+          | (unsigned short)CfSectorBuffer[CF_ID_OFS_CAPA_16 + 1] << 8;
527
+      if ((val16 & 1 << CF_CAPA_BIT_LBA) == 0) {
528
+        debug_cf_printf("CF does not support LBA mode");
529
+        CfError();
530
+        break;
531
+      }
532
+      // get number of sectors on CF
533
+      CfSectorCnt = (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 0]
534
+          | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 1] << 8
535
+          | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 2] << 16
536
+          | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 3] << 24;
537
+      if (CfSectorCnt <= 0) {
538
+        debug_cf_printf("CF does not contain any sectors");
539
+        CfError();
540
+        break;
541
+      }
542
+      // done
543
+      CfDone();
544
+    }
545
+    break;
546
+
547
+    // checking data status
548
+  case CfStepDataStatus:
549
+    debug_cf_printf("internal error (identify, CfStepDataStatus)");
550
+    CfError();
551
+    break;
552
+
553
+  }     // switch( CfWorkStep )
554
+}
555
+
556
+// do normal compact flash work
557
+static void CfProcWork(void)
558
+{
559
+  // only do CF processing if insertion state is ready
560
+  // (otherwise, the insertion processing is still doing some work)
561
+  if (CfInsState != CfInsReady)
562
+    return;
563
+
564
+  // compact flash has been removed -> error
565
+  if (!CF_IS_DETECT()) {
566
+    debug_cf_printf("CF no more present");
567
+    CfError();
568
+    return;
569
+  }
570
+  // compact flash is not ready
571
+  if (!CF_IS_READY()) {
572
+    // wait for ready not active --> error
573
+    if (CfWaitReady20 <= 0) {
574
+      debug_cf_printf("CF no more ready");
575
+      CfError();
576
+    }
577
+    // do nothing if CF is not ready
578
+    return;
579
+  }
580
+
581
+  switch (CfWorkState) {
582
+
583
+    // no compact flash work to do
584
+  case CfWorkNone:
585
+    // nothing to do here
586
+    break;
587
+
588
+    // identification of compact flash active
589
+  case CfWorkIdentify:
590
+    CfProcWorkIdentify();
591
+    break;
592
+
593
+  }     // switch( CfWorkState )
594
+}
595
+
596
+// identify compact flash
597
+// - returns 0 on success, 1 if not idle and -1 on error
598
+static char CfIdentify(void)
599
+{
600
+  // check that no command is being worked on
601
+  if (CfWorkState != CfWorkNone)
602
+    return 1;
603
+
604
+  debug_cf_printf("CF identify");
605
+
606
+  // issue identify drive command
607
+  if (CfWriteReg(CF_REG_CMD, CF_CMD_IDENTIFY) != 0) {
608
+    CfError();
609
+    return -1;
610
+  }
611
+  // now identifying compact flash
612
+  CfWorkState = CfWorkIdentify;
613
+  CfWorkStep = CfStepCmdStatus;
614
+  CfNextOffset = 0;
615
+  CfWaitReady20 = CF_WAIT_READY_20_TIMEOUT;
616
+  return 0;
617
+}
618
+
619
+// initialize
620
+void CfInit(void)       // (extern)
621
+{
622
+  // setup ports
623
+  bit_clear(CF_PORT_nCD, CF_BIT_nCD);   // pull-up of card detect pin off
624
+                                        // (external pull-up is present)
625
+  bit_clear(CF_DDR_nCD, CF_BIT_nCD);    // card detect pin to input
626
+  bit_set(CF_PORT_nRST, CF_BIT_nRST);   // reset not active
627
+  bit_set(CF_DDR_nRST, CF_BIT_nRST);    // reset pin to output
628
+  bit_clear(CF_PORT_RDY, CF_BIT_RDY);   // pull-up of ready pin pin off
629
+                                        // (external pull-up is present)
630
+  bit_clear(CF_DDR_RDY, CF_BIT_RDY);    // ready pin to input
631
+  bit_set(CF_PORT_nCE, CF_BIT_nCE);     // card not enabled
632
+  bit_set(CF_DDR_nCE, CF_BIT_nCE);      // card enable pin to output
633
+}
634
+
635
+// tick procedure - call every 20ms
636
+void CfTick20(void)     // (extern)
637
+{
638
+  // process compact flash insertion
639
+  CfProcIns();
640
+
641
+  // detect compact flash timeout
642
+  CfDetectTimeout20();
643
+}
644
+
645
+// task function to do the work - call from main loop
646
+void CfTask(void)       // (extern)
647
+{
648
+  // do nothing if no CF is inserted
649
+  if (CfInsState != CfInsReady)
650
+    return;
651
+
652
+  // compact flash is ready but not yet identified
653
+  if (CfSectorCnt == 0) {
654
+    // identify compact flash
655
+    CfIdentify();
656
+  }
657
+  // do normal compact flash work
658
+  CfProcWork();
659
+
660
+  // update status
661
+  StatusInfoCfPresent = CfInsState == CfInsReady;       // report working CF
662
+                                                        // if insertion state
663
+                                                        // is ready
664
+}
... ...
@@ -0,0 +1,24 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_cf
7
+#define INC_cf
8
+
9
+// size of a sector in bytes
10
+#define CF_SECTOR_SIZE (512)
11
+
12
+// sector buffer
13
+extern unsigned char CfSectorBuffer[CF_SECTOR_SIZE];
14
+
15
+// initialize
16
+extern void CfInit(void);
17
+
18
+// tick procedure - call every 20ms
19
+extern void CfTick20(void);
20
+
21
+// task function to do the work - call from main loop
22
+extern void CfTask(void);
23
+
24
+#endif // #ifndef INC_cf
... ...
@@ -0,0 +1,38 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include "checksum.h"
7
+#include "macros.h"
8
+#include "nethelp.h"
9
+
10
+// generate a checksum
11
+// also includes Pseudo1 and Pseudo2 in the checksum - set to 0x0000 for
12
+// normal operation
13
+// can also be used to check a checksum (returns 0 if correct)
14
+unsigned short Checksum(unsigned char *pData, unsigned short Length, unsigned short Pseudo1, unsigned short Pseudo2)    // (extern)
15
+{
16
+  unsigned long sum;
17
+
18
+  // sum up data of pseudo header
19
+  sum = Pseudo1;        // convert to 32 bit first
20
+  sum += Pseudo2;
21
+
22
+  // add full 16 bit words in header
23
+  for (; Length >= 2; pData += 2, Length -= 2)
24
+    sum += ntohs(*(unsigned short *)pData);
25
+
26
+  // add last byte
27
+  if (Length >= 1)
28
+    sum += (unsigned short)(*pData << 8);
29
+
30
+  // convert sum to one's complement sum 
31
+  sum = (sum & 0x0000FFFF) + (sum >> 16);       // add carries (bits 31..16)
32
+                                                // to sum (bits 15..0)
33
+  sum = (sum & 0x0000FFFF) + (sum >> 16);       // still a carry possible
34
+                                                // (from last addition)
35
+
36
+  // return complement of one's complement sum
37
+  return ~(unsigned short)sum;
38
+}
... ...
@@ -0,0 +1,17 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_checksum
7
+#define INC_checksum
8
+
9
+// generate a checksum
10
+// also includes Pseudo1 and Pseudo2 in the checksum - set to 0x0000 for
11
+// normal operation
12
+// can also be used to check a checksum (returns 0 if correct)
13
+extern unsigned short Checksum(unsigned char *pData, unsigned short Length,
14
+                               unsigned short Pseudo1,
15
+                               unsigned short Pseudo2);
16
+
17
+#endif // #ifdef INC_checksum
... ...
@@ -0,0 +1,28 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include "config.h"
7
+
8
+// MAC address
9
+unsigned char ConfigMac[6] = { 0x02, 0xF7, 0xA4, 0xE7, 0x80, 0x00 };    // (extern)
10
+
11
+// IP configuration
12
+// - all zero for DHCP
13
+unsigned char ConfigIp[4] = { 192, 168, 0, 234 };     // own IP address (extern)
14
+unsigned char ConfigMask[4] = { 255, 255, 255, 0 };   // subnet mask (extern)
15
+unsigned char ConfigGw[4] = { 192, 168, 0, 1 };     // gateway IP address
16
+                                                // (extern)
17
+
18
+// port for S8P
19
+unsigned short ConfigS8pPort = 8;       // disabled if 0 (extern)
20
+
21
+// symmetric key for S8P
22
+unsigned char ConfigS8pKey[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };    // (extern)
23
+
24
+// port for webserver
25
+unsigned short ConfigHttpPort = 80;     // disabled if 0 (extern)
26
+
27
+// default output state
28
+unsigned char ConfigDefOut = 0x00;      // (extern)
... ...
@@ -0,0 +1,29 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_config
7
+#define INC_config
8
+
9
+// MAC address
10
+extern unsigned char ConfigMac[6];
11
+
12
+// IP configuration
13
+extern unsigned char ConfigIp[4];       // own IP address
14
+extern unsigned char ConfigMask[4];     // subnet mask
15
+extern unsigned char ConfigGw[4];       // gateway IP address
16
+
17
+// port for S8P
18
+extern unsigned short ConfigS8pPort;    // disabled if 0
19
+
20
+// symmetric key for S8P
21
+extern unsigned char ConfigS8pKey[16];
22
+
23
+// port for webserver
24
+extern unsigned short ConfigHttpPort;   // disabled if 0
25
+
26
+// default output state
27
+extern unsigned char ConfigDefOut;
28
+
29
+#endif // #ifndef INC_config
... ...
@@ -0,0 +1,55 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_debug
7
+#define INC_debug
8
+
9
+#include <stdio.h>
10
+#include <avr/pgmspace.h>
11
+
12
+// debug configuration (what to debug)
13
+#define DEBUG_INIT 1
14
+#define DEBUG_EEPROM 1
15
+#define DEBUG_CF 1
16
+#define DEBUG_RTL8019 1
17
+#define DEBUG_ETHER 1
18
+#define DEBUG_ARP 1
19
+#define DEBUG_IP 1
20
+#define DEBUG_ICMP 1
21
+#define DEBUG_UDP 1
22
+#define DEBUG_DHCP 1
23
+#define DEBUG_TCP 1
24
+#define DEBUG_HTTP 1
25
+
26
+// debug version of printf
27
+#ifdef DEBUG
28
+#define debug_printf( fmt, arg... ) \
29
+  { \
30
+    static const PROGMEM char fmt_pgm[] = fmt"\r\n"; \
31
+    char fmt_buf[sizeof( fmt_pgm )]; \
32
+    for( int i = 0; i < sizeof( fmt_pgm ); i++ ) \
33
+      fmt_buf[i] = (char)pgm_read_byte_near( (uint16_t)fmt_pgm + i ); \
34
+    printf( fmt_buf, ##arg ); \
35
+  }
36
+#else
37
+#define debug_printf( fmt, arg... ) { }
38
+#endif
39
+
40
+// specialized debug versions of printf
41
+#define debug_specialized_printf( enabled, fmt, arg... ) { if( enabled ) debug_printf( fmt, ##arg ); }
42
+#define debug_init_printf( fmt, arg... ) debug_specialized_printf( DEBUG_INIT, "init: "fmt, ##arg )
43
+#define debug_eeprom_printf( fmt, arg... ) debug_specialized_printf( DEBUG_EEPROM, "eeprom: "fmt, ##arg )
44
+#define debug_cf_printf( fmt, arg... ) debug_specialized_printf( DEBUG_CF, "cf: "fmt, ##arg )
45
+#define debug_rtl8019_printf( fmt, arg... ) debug_specialized_printf( DEBUG_RTL8019, "rtl8019: "fmt, ##arg )
46
+#define debug_ether_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ETHER, "ether: "fmt, ##arg )
47
+#define debug_arp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ARP, "arp: "fmt, ##arg )
48
+#define debug_ip_printf( fmt, arg... ) debug_specialized_printf( DEBUG_IP, "ip: "fmt, ##arg )
49
+#define debug_icmp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ICMP, "icmp: "fmt, ##arg )
50
+#define debug_udp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_UDP, "udp: "fmt, ##arg )
51
+#define debug_dhcp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_DHCP, "dhcp: "fmt, ##arg )
52
+#define debug_tcp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_TCP, "tcp: "fmt, ##arg )
53
+#define debug_http_printf( fmt, arg... ) debug_specialized_printf( DEBUG_HTTP, "http: "fmt, ##arg )
54
+
55
+#endif // #ifndef INC_debug
... ...
@@ -0,0 +1,499 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <string.h>
7
+
8
+#include "config.h"
9
+#include "checksum.h"
10
+#include "debug.h"
11
+#include "dhcp.h"
12
+#include "ethernet.h"
13
+#include "ip.h"
14
+#include "macros.h"
15
+#include "nethelp.h"
16
+#include "random.h"
17
+#include "udp.h"
18
+
19
+// configuration
20
+static const unsigned char DhcpRetrySecsMax = 10;       // avarage timeout
21
+                                                        // after which to
22
+                                                        // retry DHCP action
23
+static const unsigned char DhcpRetriesMax = 5;  // maximum number of retries
24
+                                                // before aborting DHCP
25
+                                                // action
26
+static const unsigned long DhcpLeaseRestMin = 300;      // when to ask to
27
+                                                        // extend lease
28
+static const unsigned char DhcpLeaseRenewFraction = 8;  // to renw lease when 
29
+                                                        // only this fraction 
30
+                                                        // of lease is left
31
+
32
+// DHCP tick counter to get full seconds
33
+static unsigned char DhcpTicks = 0;
34
+
35
+// time of current DHCP action
36
+static unsigned char DhcpInProgress = 0;        // if DHCP action is in
37
+                                                // progress
38
+static unsigned char DhcpRetries = 0;   // number of retries left
39
+static unsigned char DhcpRetrySecs = 0; // rest of time for current retry
40
+
41
+// current XId
42
+static unsigned char DhcpHaveXId = 0;   // if an XId exists at the moment
43
+static unsigned long DhcpXId = 0;       // the current XId data
44
+static unsigned int DhcpXIdSecs = 0;    // time of XId
45
+
46
+// DHCP server and lease time
47
+static unsigned char DhcpActive = 0;    // if own IP is leased from DHCP
48
+static unsigned char DhcpServer[4];     // IP address of DHCP server own IP
49
+                                        // is leased from
50
+static unsigned long DhcpLeaseTime = 0; // total lease time
51
+static unsigned long DhcpLeaseRest = 0; // rest of lease time
52
+
53
+// send a DHCP packet
54
+// pData must point to a struct DhcpPacket with IpHdr.Dest, DhcpHdr.XId
55
+// DhcpHdr.Secs, DhcpHdr.Flags and DhcpHdr.YIAddr already initialized
56
+static void DhcpSend(unsigned char *pData, unsigned short Length)       // (extern)
57
+{
58
+  struct DhcpPacket *pDhcpPack;
59
+
60
+  // packet too short
61
+  if (Length < sizeof(struct DhcpPacket))
62
+    return;
63
+
64
+  // convert pointer to DHCP packet
65
+  // (this saves us from always casting pData)
66
+  pDhcpPack = (struct DhcpPacket *)pData;
67
+
68
+  debug_dhcp_printf("send xid=%08lX len=%d",
69
+                    ntohl(pDhcpPack->DhcpHdr.XId), Length);
70
+
71
+  // we are DHCP client
72
+  // - source port must be 68
73
+  // - destination port must be 67
74
+  pDhcpPack->UdpHdr.SrcPort = htons(68);
75
+  pDhcpPack->UdpHdr.DestPort = htons(67);
76
+  // set up DHCP header fields as client
77
+  pDhcpPack->DhcpHdr.Op = 1;
78
+  pDhcpPack->DhcpHdr.HType = 1;
79
+  pDhcpPack->DhcpHdr.HLen = 6;
80
+  pDhcpPack->DhcpHdr.HOps = 0;
81
+  memset(pDhcpPack->DhcpHdr.CIAddr, 0, 4);
82
+  memset(pDhcpPack->DhcpHdr.SIAddr, 0, 4);
83
+  memset(pDhcpPack->DhcpHdr.GIAddr, 0, 4);
84
+  mac_cpy(pDhcpPack->DhcpHdr.CHAddr, ConfigMac);
85
+  memset(pDhcpPack->DhcpHdr.CHAddr + 6, 0, 10);
86
+  memset(pDhcpPack->DhcpHdr.SName, 0, 64);
87
+  memset(pDhcpPack->DhcpHdr.File, 0, 128);
88
+  pDhcpPack->DhcpHdr.MCookie = htonl(0x63825363);
89
+
90
+  // send DHCP packet
91
+  UdpSend(pData, Length);
92
+}
93
+
94
+// send a DHCP discover
95
+static void DhcpDiscover(void)
96
+{
97
+  struct {
98
+    struct DhcpPacket DhcpPack;
99
+    unsigned char OptType[3];
100
+    unsigned char OptEnd[2];
101
+  } DhcpDiscover;
102
+
103
+  debug_dhcp_printf("discover");
104
+
105
+  ip_cpy(DhcpDiscover.DhcpPack.IpHdr.Dest, "\xFF\xFF\xFF\xFF"); // broadcast
106
+  DhcpDiscover.DhcpPack.DhcpHdr.XId = htonl(DhcpXId);
107
+  DhcpDiscover.DhcpPack.DhcpHdr.Secs = htons(DhcpXIdSecs);      // use time
108
+                                                                // of XId
109
+  DhcpDiscover.DhcpPack.DhcpHdr.Flags = htons(0x8000);  // broadcast
110
+  memset(DhcpDiscover.DhcpPack.DhcpHdr.YIAddr, 0, 4);
111
+  DhcpDiscover.OptType[0] = 0x35;       // DHCP discover
112
+  DhcpDiscover.OptType[1] = 0x01;
113
+  DhcpDiscover.OptType[2] = 0x01;
114
+  DhcpDiscover.OptEnd[0] = 0xFF;        // end of options
115
+  DhcpDiscover.OptEnd[1] = 0x00;
116
+
117
+  DhcpSend((unsigned char *)&DhcpDiscover, sizeof(DhcpDiscover));
118
+}
119
+
120
+// send a DHCP request
121
+static void DhcpRequest(void)
122
+{
123
+  struct {
124
+    struct DhcpPacket DhcpPack;
125
+    unsigned char OptType[3];
126
+    unsigned char OptReq[6];
127
+    unsigned char OptServer[6];
128
+    unsigned char OptEnd[2];
129
+  } DhcpRequest;
130
+
131
+  debug_dhcp_printf("request ip=%d.%d.%d.%d",
132
+                    ConfigIp[0], ConfigIp[1], ConfigIp[2], ConfigIp[3]);
133
+
134
+  ip_cpy(DhcpRequest.DhcpPack.IpHdr.Dest, DhcpServer);  // send to DHCP
135
+                                                        // server
136
+  DhcpRequest.DhcpPack.DhcpHdr.XId = htonl(DhcpXId);
137
+  DhcpRequest.DhcpPack.DhcpHdr.Secs = htons(DhcpXIdSecs);       // use time
138
+                                                                // of XId
139
+  DhcpRequest.DhcpPack.DhcpHdr.Flags = htons(0x0000);
140
+  ip_cpy(DhcpRequest.DhcpPack.DhcpHdr.YIAddr, ConfigIp);
141
+  DhcpRequest.OptType[0] = 0x35;        // DHCP request
142
+  DhcpRequest.OptType[1] = 0x01;
143
+  DhcpRequest.OptType[2] = 0x03;
144
+  DhcpRequest.OptReq[0] = 0x32; // requested IP
145
+  DhcpRequest.OptReq[1] = 0x04;
146
+  ip_cpy(&DhcpRequest.OptReq[2], ConfigIp);
147
+  DhcpRequest.OptServer[0] = 0x36;      // DHCP server
148
+  DhcpRequest.OptServer[1] = 0x04;
149
+  ip_cpy(&DhcpRequest.OptServer[2], DhcpServer);
150
+  DhcpRequest.OptEnd[0] = 0xFF; // end of options
151
+  DhcpRequest.OptEnd[1] = 0x00;
152
+
153
+  DhcpSend((unsigned char *)&DhcpRequest, sizeof(DhcpRequest));
154
+}
155
+
156
+// abort DHCP action
157
+static void DhcpAbort(void)
158
+{
159
+  // abort DHCP action
160
+  DhcpInProgress = 0;
161
+  DhcpRetries = 0;
162
+  DhcpRetrySecs = 0;
163
+
164
+  // forget XId
165
+  DhcpHaveXId = 0;
166
+  DhcpXId = 0;
167
+  DhcpXIdSecs = 0;
168
+
169
+  // give up IP address if it was leased
170
+  if (DhcpActive) {
171
+    ip_cpy(ConfigIp, "\0\0\0\0");
172
+    ip_cpy(ConfigMask, "\0\0\0\0");
173
+    ip_cpy(ConfigGw, "\0\0\0\0");
174
+    DhcpActive = 0;
175
+    DhcpLeaseTime = 0;
176
+    DhcpLeaseRest = 0;
177
+  }
178
+}
179
+
180
+// retry DHCP action
181
+static void DhcpRetry(void)
182
+{
183
+  // DHCP lease not active ---> re-send DHCP discover
184
+  if (!DhcpActive) {
185
+
186
+    // get time for next try
187
+    RandomGetData((unsigned char *)&DhcpRetrySecs, sizeof(DhcpRetrySecs));
188
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
189
+    // re-send DHCP discover
190
+    DhcpDiscover();
191
+
192
+  }
193
+  // DHCP lease active and lease time almost over ---> re-send DHCP request
194
+  if (DhcpActive && (DhcpLeaseRest < DhcpLeaseRestMin ||
195
+                     DhcpLeaseRest <
196
+                     DhcpLeaseTime / DhcpLeaseRenewFraction)) {
197
+
198
+    // get time for next try
199
+    RandomGetData((unsigned char *)&DhcpRetrySecs, sizeof(DhcpRetrySecs));
200
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
201
+    // re-send DHCP request
202
+    DhcpRequest();
203
+
204
+  }
205
+}
206
+
207
+// start new DHCP action
208
+static void DhcpStart(void)
209
+{
210
+  // DHCP lease not active ---> DHCP discover
211
+  if (!DhcpActive) {
212
+
213
+    // DHCP operation starts
214
+    DhcpInProgress = 1;
215
+    DhcpRetries = DhcpRetriesMax;
216
+    RandomGetData((unsigned char *)&DhcpRetrySecs, sizeof(DhcpRetrySecs));
217
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
218
+    // get new XId
219
+    RandomGetData((unsigned char *)&DhcpXId, sizeof(DhcpXId));
220
+    DhcpXIdSecs++;
221
+    DhcpHaveXId = 1;
222
+    // send DHCP discover
223
+    DhcpDiscover();
224
+
225
+  }
226
+  // DHCP lease active and lease time almost over ---> DHCP request
227
+  if (DhcpActive && (DhcpLeaseRest < DhcpLeaseRestMin ||
228
+                     DhcpLeaseRest <
229
+                     DhcpLeaseTime / DhcpLeaseRenewFraction)) {
230
+
231
+    // DHCP operation starts
232
+    DhcpInProgress = 1;
233
+    DhcpRetries = DhcpRetriesMax;
234
+    RandomGetData((unsigned char *)&DhcpRetrySecs, sizeof(DhcpRetrySecs));
235
+    DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2;
236
+    // get new XId if none available
237
+    if (!DhcpHaveXId) {
238
+      RandomGetData((unsigned char *)&DhcpXId, sizeof(DhcpXId));
239
+      DhcpXIdSecs++;
240
+      DhcpHaveXId = 1;
241
+    }
242
+    // send DHCP request
243
+    DhcpRequest();
244
+
245
+  }
246
+}
247
+
248
+// tick procedure - every 1000ms
249
+static void DhcpTick1000(void)
250
+{
251
+  // DHCP operation in progress
252
+  if (DhcpInProgress) {
253
+
254
+    // count down time of current try of current action
255
+    DhcpRetrySecs--;
256
+    if (DhcpRetrySecs <= 0) {
257
+
258
+      // count down retries
259
+      DhcpRetries--;
260
+
261
+      // no more retries left ---> abort, retry otherwise
262
+      if (DhcpRetries <= 0)
263
+        DhcpAbort();
264
+      else
265
+        DhcpRetry();
266
+
267
+    }
268
+
269
+  }
270
+  // increase time of XId
271
+  DhcpXIdSecs++;
272
+
273
+  // dcrease remaining lease time
274
+  DhcpLeaseRest--;
275
+  // lease timed out ---> abort DHCP (will also invalidate IP)
276
+  if (DhcpLeaseRest <= 0) {
277
+    debug_dhcp_printf("lease expired");
278
+    DhcpAbort();
279
+  }
280
+}
281
+
282
+// tick procedure - call every 200ms
283
+void DhcpTick200(void)  // (extern)
284
+{
285
+  // get 1 second interval
286
+  DhcpTicks++;
287
+  if (DhcpTicks >= 5) {
288
+    DhcpTicks = 0;
289
+    DhcpTick1000();
290
+  }
291
+  // no DHCP operation in progress
292
+  if (!DhcpInProgress) {
293
+    // DHCP lease active or no IP address ---> DHCP allowed (i.e. no static
294
+    // IP)
295
+    if (DhcpActive || ip_eq(ConfigIp, "\0\0\0\0")) {
296
+      // start new DHCP action
297
+      DhcpStart();
298
+    }
299
+  }
300
+}
301
+
302
+// process a received DHCP offer
303
+static void DhcpOffer(unsigned char addr[4], unsigned char mask[4],
304
+                      unsigned char gateway[4], unsigned long time,
305
+                      unsigned char server[4])
306
+{
307
+  debug_dhcp_printf("offer addr=%d.%d.%d.%d mask=%d.%d.%d.%d gw=%d.%d.%d.%d",
308
+                    addr[0], addr[1], addr[2], addr[3],
309
+                    mask[0], mask[1], mask[2], mask[3],
310
+                    gateway[0], gateway[1], gateway[2], gateway[3]);
311
+  debug_dhcp_printf("offer time=%ld server=%d.%d.%d.%d",
312
+                    time, server[0], server[1], server[2], server[3]);
313
+
314
+  // use this IP address, mask and gateway
315
+  ip_cpy(ConfigIp, addr);
316
+  ip_cpy(ConfigMask, mask);
317
+  ip_cpy(ConfigGw, gateway);
318
+
319
+  // store DHCP server and lease time
320
+  DhcpActive = 1;
321
+  ip_cpy(DhcpServer, server);
322
+  DhcpLeaseTime = time;
323
+  DhcpLeaseRest = DhcpLeaseRestMin;     // schedule DHCP request
324
+
325
+  // DHCP action finished
326
+  DhcpInProgress = 0;
327
+  DhcpRetries = 0;
328
+  DhcpRetrySecs = 0;
329
+}
330
+
331
+// process a received DHCP ack
332
+static void DhcpAck(unsigned char addr[4], unsigned char mask[4],
333
+                    unsigned char gateway[4], unsigned long time,
334
+                    unsigned char server[4])
335
+{
336
+  debug_dhcp_printf("ack addr=%d.%d.%d.%d mask=%d.%d.%d.%d gw=%d.%d.%d.%d",
337
+                    addr[0], addr[1], addr[2], addr[3],
338
+                    mask[0], mask[1], mask[2], mask[3],
339
+                    gateway[0], gateway[1], gateway[2], gateway[3]);
340
+  debug_dhcp_printf("ack time=%ld server=%d.%d.%d.%d",
341
+                    time, server[0], server[1], server[2], server[3]);
342
+
343
+  // check if IP address, mask and gateway match
344
+  if (!ip_eq(ConfigIp, addr) ||
345
+      !ip_eq(ConfigMask, mask) || !ip_eq(ConfigGw, gateway)) {
346
+    // mismatch ---> something is wrong, abort
347
+    DhcpAbort();
348
+    return;
349
+  }
350
+  // store DHCP server and lease time
351
+  DhcpActive = 1;
352
+  ip_cpy(DhcpServer, server);
353
+  DhcpLeaseTime = time;
354
+  DhcpLeaseRest = time;
355
+
356
+  // DHCP action finished
357
+  DhcpInProgress = 0;
358
+  DhcpRetries = 0;
359
+  DhcpRetrySecs = 0;
360
+
361
+  // forget XId
362
+  DhcpHaveXId = 0;
363
+  DhcpXId = 0;
364
+  DhcpXIdSecs = 0;
365
+}
366
+
367
+// process a received DHCP packet
368
+void DhcpRecv(unsigned char *pData, unsigned short Length)      // (extern)
369
+{
370
+  struct DhcpPacket *pDhcpPack;
371
+  unsigned char *opt_ptr, tag, len;
372
+  unsigned short opt_len;
373
+  unsigned char type;
374
+  unsigned char have_mask, mask[4], have_gateway, gateway[4];
375
+  unsigned char have_time, have_server, server[4];
376
+  unsigned long time;
377
+
378
+  // packet too short
379
+  if (Length < sizeof(struct DhcpPacket))
380
+    return;
381
+
382
+  // convert pointer to UDP packet
383
+  // (this saves us from always casting pData)
384
+  pDhcpPack = (struct DhcpPacket *)pData;
385
+
386
+  // we are DHCP client
387
+  // - source port must be 67
388
+  // - destination port must be 68
389
+  if (pDhcpPack->UdpHdr.SrcPort != htons(67) ||
390
+      pDhcpPack->UdpHdr.DestPort != htons(68))
391
+    return;
392
+  // check DHCP fields
393
+  if (pDhcpPack->DhcpHdr.Op != 2 ||
394
+      pDhcpPack->DhcpHdr.HType != 1 ||
395
+      pDhcpPack->DhcpHdr.HLen != 6 ||
396
+      pDhcpPack->DhcpHdr.HOps != 0 ||
397
+      pDhcpPack->DhcpHdr.MCookie != htonl(0x63825363))
398
+    return;
399
+
400
+  debug_dhcp_printf("recv xid=%08lX len=%d",
401
+                    ntohl(pDhcpPack->DhcpHdr.XId), Length);
402
+
403
+  // check XId
404
+  if (!DhcpHaveXId || ntohl(pDhcpPack->DhcpHdr.XId) != DhcpXId)
405
+    return;
406
+
407
+  // get options
408
+  opt_ptr = pData + sizeof(struct DhcpPacket);
409
+  opt_len = Length - sizeof(struct DhcpPacket);
410
+
411
+  // parse options
412
+  type = 0;
413
+  have_mask = 0;
414
+  have_gateway = 0;
415
+  time = 0;
416
+  have_time = 0;
417
+  have_server = 0;
418
+  while (opt_len > 2) {
419
+
420
+    // get tag and length
421
+    tag = *opt_ptr++;
422
+    len = *opt_ptr++;
423
+    if (opt_len < 2 + len)
424
+      break;
425
+
426
+    // get option
427
+    switch (tag) {
428
+
429
+      // type
430
+    case 0x35:
431
+      if (len >= 1)
432
+        type = opt_ptr[0];
433
+      break;
434
+
435
+      // subnet mask
436
+    case 0x01:
437
+      if (len >= 4)
438
+        memcpy(mask, opt_ptr, 4);
439
+      have_mask = 1;
440
+      break;
441
+
442
+      // gateway
443
+    case 0x03:
444
+      if (len >= 4) {
445
+        memcpy(gateway, opt_ptr, 4);
446
+        have_gateway = 1;
447
+      }
448
+      break;
449
+
450
+      // lease time
451
+    case 0x33:
452
+      if (len >= 4) {
453
+        time = ntohl(*(unsigned long *)opt_ptr);
454
+        have_time = 1;
455
+      }
456
+      break;
457
+
458
+      // DHCP server
459
+    case 0x36:
460
+      if (len >= 4) {
461
+        memcpy(server, opt_ptr, 4);
462
+        have_server = 1;
463
+      }
464
+      break;
465
+
466
+    }
467
+
468
+    // skip option
469
+    opt_ptr += len;
470
+    opt_len -= len;
471
+  }
472
+
473
+  debug_dhcp_printf("type=%d%s%s%s%s", type,
474
+                    have_mask ? " mask" : "",
475
+                    have_gateway ? " gateway" : "",
476
+                    have_time ? " time" : "", have_server ? " server" : "");
477
+
478
+  // fill in server from source address if not present
479
+  if (!have_server) {
480
+    ip_cpy(server, pDhcpPack->IpHdr.Src);
481
+    have_server = 1;
482
+  }
483
+  // process DHCP response
484
+  switch (type) {
485
+
486
+    // DHCP offer
487
+  case 2:
488
+    if (have_mask && have_gateway && have_time && have_server)
489
+      DhcpOffer(pDhcpPack->DhcpHdr.YIAddr, mask, gateway, time, server);
490
+    break;
491
+
492
+    // DHCP ack
493
+  case 5:
494
+    if (have_mask && have_gateway && have_time && have_server)
495
+      DhcpAck(pDhcpPack->DhcpHdr.YIAddr, mask, gateway, time, server);
496
+    break;
497
+
498
+  }
499
+}
... ...
@@ -0,0 +1,46 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_dhcp
7
+#define INC_dhcp
8
+
9
+#include "ethernet.h"
10
+#include "ip.h"
11
+#include "udp.h"
12
+
13
+// header of an DHCP packet
14
+struct DhcpHeader {
15
+  unsigned char Op;
16
+  unsigned char HType;
17
+  unsigned char HLen;
18
+  unsigned char HOps;
19
+  unsigned long XId;
20
+  unsigned int Secs;
21
+  unsigned int Flags;
22
+  unsigned char CIAddr[4];
23
+  unsigned char YIAddr[4];
24
+  unsigned char SIAddr[4];
25
+  unsigned char GIAddr[4];
26
+  unsigned char CHAddr[16];
27
+  unsigned char SName[64];
28
+  unsigned char File[128];
29
+  unsigned long MCookie;
30
+};
31
+
32
+// a DHCP packet
33
+struct DhcpPacket {
34
+  struct EthernetHeader EthHdr;
35
+  struct IpHeader IpHdr;
36
+  struct UdpHeader UdpHdr;
37
+  struct DhcpHeader DhcpHdr;
38
+};
39
+
40
+// tick procedure - call every 200ms
41
+extern void DhcpTick200(void);
42
+
43
+// process a received UDP packet
44
+extern void DhcpRecv(unsigned char *pData, unsigned short Length);
45
+
46
+#endif // #ifdef INC_dhcp
... ...
@@ -0,0 +1,209 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/interrupt.h>
7
+#include <avr/eeprom.h>
8
+
9
+#include "config.h"
10
+#include "debug.h"
11
+#include "eeprom.h"
12
+#include "macros.h"
13
+#include "rtl8019.h"
14
+
15
+// flags for what needs to be written to the EEPROM
16
+unsigned char EepromNeedWrite = 0x00;   // (extern)
17
+
18
+// writing what where
19
+unsigned char EepromWriteFlags = 0;     // some flags
20
+#define EepromWriteFlagActive 0x01      // if writing something to EEPROM
21
+#define EepromWriteFlagCheck 0x02       // if writing check byte to EEPROM
22
+unsigned char *pEepromWriteSrc; // pointer to source data
23
+unsigned short EepromWriteDestAddr;     // destination address in EEPROM
24
+unsigned char EepromWriteCnt;   // number of bytes still to write
25
+
26
+// memory layout of EEPROM
27
+// - every byte B is stored as B, ~B for data safety
28
+// - so everythings needs double space
29
+#define EEPROM_ADDR_MAC 0
30
+#define EEPROM_ADDR_IP (EEPROM_ADDR_MAC + 2 * sizeof( ConfigMac ))
31
+#define EEPROM_ADDR_MASK (EEPROM_ADDR_IP + 2 * sizeof( ConfigIp ))
32
+#define EEPROM_ADDR_GW (EEPROM_ADDR_MASK + 2 * sizeof( ConfigMask ))
33
+#define EEPROM_ADDR_S8P_PORT (EEPROM_ADDR_GW + 2 * sizeof( ConfigGw ))
34
+#define EEPROM_ADDR_S8P_KEY (EEPROM_ADDR_S8P_PORT + 2 * sizeof( ConfigS8pPort ))
35
+#define EEPROM_ADDR_HTTP_PORT (EEPROM_ADDR_S8P_KEY + 2 * sizeof( ConfigS8pKey ))
36
+#define EEPROM_ADDR_DEF_OUT (EEPROM_ADDR_HTTP_PORT + 2 * sizeof( ConfigHttpPort ))
37
+#define EEPROM_ADDR_FreeFromHere (EEPROM_ADDR_DEF_OUT + 2 * sizeof( ConfigDefOut ))
38
+
39
+// get configuration from EEPROM - helper function
40
+// checks data in EEPROM
41
+// gets data from EEPROM
42
+// returns 0x00 if successful
43
+static inline unsigned char EepromGetConfigHelp(unsigned short SrcAddr,
44
+                                                unsigned char *pDest,
45
+                                                unsigned char Len)
46
+{
47
+  unsigned char i, b;
48
+
49
+  // check data in EEPROM
50
+  EEAR = SrcAddr;
51
+  for (i = 0; i < Len; i++) {
52
+    // read byte
53
+    bit_set(EECR, EERE);
54
+    b = EEDR;
55
+    EEAR++;
56
+    // XOR in check byte
57
+    bit_set(EECR, EERE);
58
+    b ^= EEDR;
59
+    EEAR++;
60
+    // XOR result must be 0xFF
61
+    if (b != 0xFF)
62
+      return 0x01;      // error
63
+  }
64
+
65
+  // read data from EEPROM
66
+  EEAR = SrcAddr;
67
+  for (; Len > 0; Len--) {
68
+    // read byte
69
+    bit_set(EECR, EERE);
70
+    *(pDest++) = EEDR;
71
+    EEAR += 2;  // skip check byte
72
+  }
73
+  return 0x00;  // success
74
+}
75
+
76
+// get configuration from EEPROM
77
+void EepromGetConfig(void)      // (extern)
78
+{
79
+  // get MAC
80
+  if (EepromGetConfigHelp(EEPROM_ADDR_MAC, ConfigMac, sizeof(ConfigMac)) ==
81
+      0x00)
82
+    // re-initialize RTL8019
83
+    RtlReinit();
84
+
85
+  // get IP, subnet mask, gateway IP
86
+  EepromGetConfigHelp(EEPROM_ADDR_IP, ConfigIp, sizeof(ConfigIp));
87
+  EepromGetConfigHelp(EEPROM_ADDR_MASK, ConfigMask, sizeof(ConfigMask));
88
+  EepromGetConfigHelp(EEPROM_ADDR_GW, ConfigGw, sizeof(ConfigGw));
89
+
90
+  // get port for S8P
91
+  EepromGetConfigHelp(EEPROM_ADDR_S8P_PORT, (unsigned char *)&ConfigS8pPort,
92
+                      sizeof(ConfigS8pPort));
93
+
94
+  // get symmetric key for S8P
95
+  EepromGetConfigHelp(EEPROM_ADDR_S8P_KEY, ConfigS8pKey,
96
+                      sizeof(ConfigS8pKey));
97
+
98
+  // get port for webserver
99
+  EepromGetConfigHelp(EEPROM_ADDR_HTTP_PORT, (unsigned char *)&ConfigHttpPort,
100
+                      sizeof(ConfigHttpPort));
101
+
102
+  // get default output state
103
+  EepromGetConfigHelp(EEPROM_ADDR_DEF_OUT, &ConfigDefOut,
104
+                      sizeof(ConfigDefOut));
105
+}
106
+
107
+// task function to do the work - call from main loop
108
+void EepromTask(void)   // (extern)
109
+{
110
+  // not writing something to EEPROM
111
+  if (!(EepromWriteFlags & EepromWriteFlagActive)) {
112
+    // MAC needs to be written
113
+    if (EepromNeedWrite & EepromNeedWriteMac) {
114
+      EepromNeedWrite &= ~EepromNeedWriteMac;
115
+      pEepromWriteSrc = ConfigMac;
116
+      EepromWriteDestAddr = EEPROM_ADDR_MAC;
117
+      EepromWriteCnt = sizeof(ConfigMac);
118
+      EepromWriteFlags = EepromWriteFlagActive;
119
+    }
120
+    // IP needs to be written
121
+    else if (EepromNeedWrite & EepromNeedWriteIp) {
122
+      EepromNeedWrite &= ~EepromNeedWriteIp;
123
+      pEepromWriteSrc = ConfigIp;
124
+      EepromWriteDestAddr = EEPROM_ADDR_IP;
125
+      EepromWriteCnt = sizeof(ConfigIp);
126
+      EepromWriteFlags = EepromWriteFlagActive;
127
+    }
128
+    // subnet mask needs to be written
129
+    else if (EepromNeedWrite & EepromNeedWriteMask) {
130
+      EepromNeedWrite &= ~EepromNeedWriteMask;
131
+      pEepromWriteSrc = ConfigMask;
132
+      EepromWriteDestAddr = EEPROM_ADDR_MASK;
133
+      EepromWriteCnt = sizeof(ConfigMask);
134
+      EepromWriteFlags = EepromWriteFlagActive;
135
+    }
136
+    // gateway IP needs to be written
137
+    else if (EepromNeedWrite & EepromNeedWriteGw) {
138
+      EepromNeedWrite &= ~EepromNeedWriteGw;
139
+      pEepromWriteSrc = ConfigGw;
140
+      EepromWriteDestAddr = EEPROM_ADDR_GW;
141
+      EepromWriteCnt = sizeof(ConfigGw);
142
+      EepromWriteFlags = EepromWriteFlagActive;
143
+    }
144
+    // port for S8P needs to be written
145
+    else if (EepromNeedWrite & EepromNeedWriteS8pPort) {
146
+      EepromNeedWrite &= ~EepromNeedWriteS8pPort;
147
+      pEepromWriteSrc = (unsigned char *)&ConfigS8pPort;
148
+      EepromWriteDestAddr = EEPROM_ADDR_S8P_PORT;
149
+      EepromWriteCnt = sizeof(ConfigS8pPort);
150
+      EepromWriteFlags = EepromWriteFlagActive;
151
+    }
152
+    // symmetric key for S8P needs to be written
153
+    else if (EepromNeedWrite & EepromNeedWriteS8pKey) {
154
+      EepromNeedWrite &= ~EepromNeedWriteS8pKey;
155
+      pEepromWriteSrc = ConfigS8pKey;
156
+      EepromWriteDestAddr = EEPROM_ADDR_S8P_KEY;
157
+      EepromWriteCnt = sizeof(ConfigS8pKey);
158
+      EepromWriteFlags = EepromWriteFlagActive;
159
+    }
160
+    // port for webserver needs to be written
161
+    else if (EepromNeedWrite & EepromNeedWriteHttpPort) {
162
+      EepromNeedWrite &= ~EepromNeedWriteHttpPort;
163
+      pEepromWriteSrc = (unsigned char *)&ConfigHttpPort;
164
+      EepromWriteDestAddr = EEPROM_ADDR_HTTP_PORT;
165
+      EepromWriteCnt = sizeof(ConfigHttpPort);
166
+      EepromWriteFlags = EepromWriteFlagActive;
167
+    }
168
+    // if default output state needs to be written
169
+    else if (EepromNeedWrite & EepromNeedWriteDefOut) {
170
+      EepromNeedWrite &= ~EepromNeedWriteDefOut;
171
+      pEepromWriteSrc = &ConfigDefOut;
172
+      EepromWriteDestAddr = EEPROM_ADDR_DEF_OUT;
173
+      EepromWriteCnt = sizeof(ConfigDefOut);
174
+      EepromWriteFlags = EepromWriteFlagActive;
175
+    }
176
+    // nothing needs to be written
177
+    else
178
+      return;
179
+
180
+    debug_eeprom_printf("write adr=0x%04X len=%u", EepromWriteDestAddr,
181
+                        EepromWriteCnt);
182
+  }
183
+  // EEPROM still busy
184
+  if (bit_is_set(EECR, EEWE))
185
+    // try again later
186
+    return;
187
+
188
+  // disable interrupts
189
+  cli();
190
+
191
+  // get address in EEPROM and data to write
192
+  EEAR = EepromWriteDestAddr++;
193
+  if (EepromWriteFlags & EepromWriteFlagCheck)  // check byte
194
+  {
195
+    EEDR = ~*(pEepromWriteSrc++);       // invert and advance source pointer
196
+    EepromWriteCnt--;   // count down number of bytes to write
197
+    if (EepromWriteCnt <= 0)    // finished
198
+      EepromWriteFlags &= ~EepromWriteFlagActive;
199
+  } else        // not check byte
200
+    EEDR = *pEepromWriteSrc;    // use data byte as it is
201
+  EepromWriteFlags ^= EepromWriteFlagCheck;     // toggle check byte bit
202
+
203
+  // initiate write to EEPROM
204
+  bit_set(EECR, EEMWE);
205
+  bit_set(EECR, EEWE);
206
+
207
+  // enable interrupts
208
+  sei();
209
+}
... ...
@@ -0,0 +1,26 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_eeprom
7
+#define INC_eeprom
8
+
9
+// flags for what needs to be written to the EEPROM
10
+#define EepromNeedWriteMac 0x01
11
+#define EepromNeedWriteIp 0x02
12
+#define EepromNeedWriteMask 0x04
13
+#define EepromNeedWriteGw 0x08
14
+#define EepromNeedWriteS8pPort 0x10
15
+#define EepromNeedWriteS8pKey 0x20
16
+#define EepromNeedWriteHttpPort 0x40
17
+#define EepromNeedWriteDefOut 0x80
18
+extern unsigned char EepromNeedWrite;
19
+
20
+// get configuration from EEPROM
21
+extern void EepromGetConfig(void);
22
+
23
+// task function to do the work - call from main loop
24
+extern void EepromTask(void);
25
+
26
+#endif // #ifndef INC_eeprom
... ...
@@ -0,0 +1,75 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include "arp.h"
7
+#include "config.h"
8
+#include "debug.h"
9
+#include "ethernet.h"
10
+#include "ip.h"
11
+#include "macros.h"
12
+#include "nethelp.h"
13
+#include "rtl8019.h"
14
+
15
+// process a received ethernet packet
16
+void EthernetRecv(unsigned char *pData, unsigned short Length)  // (extern)
17
+{
18
+  struct EthernetPacket *pEthPack;
19
+
20
+  // packet too short
21
+  if (Length < sizeof(struct EthernetPacket))
22
+    return;
23
+
24
+  // convert pointer to ethernet packet
25
+  // (this saves us from always casting pData)
26
+  pEthPack = (struct EthernetPacket *)pData;
27
+
28
+  debug_ether_printf
29
+      ("recv len=%u type=0x%04X src=%02X:%02X:%02X:%02X:%02X:%02X", Length,
30
+       ntohs(pEthPack->EthHdr.Type), pEthPack->EthHdr.Src[0],
31
+       pEthPack->EthHdr.Src[1], pEthPack->EthHdr.Src[2],
32
+       pEthPack->EthHdr.Src[3], pEthPack->EthHdr.Src[4],
33
+       pEthPack->EthHdr.Src[5]);
34
+
35
+  // branch according to packet type
36
+  switch (pEthPack->EthHdr.Type) {
37
+    // ARP
38
+  case htons(0x0806):
39
+    ArpRecv(pData, Length);
40
+    break;
41
+    // IP
42
+  case htons(0x0800):
43
+    IpRecv(pData, Length);
44
+    break;
45
+  }
46
+}
47
+
48
+// send an ethernet packet
49
+// pData must point to a struct EthernetPacket with EthHdr.Dest and
50
+// EthHdr.Type already initialized
51
+void EthernetSend(unsigned char *pData, unsigned short Length)  // (extern)
52
+{
53
+  struct EthernetPacket *pEthPack;
54
+
55
+  // packet too short
56
+  if (Length < sizeof(struct EthernetPacket))
57
+    return;
58
+
59
+  // convert pointer to ethernet packet
60
+  // (this saves us from always casting pData)
61
+  pEthPack = (struct EthernetPacket *)pData;
62
+
63
+  debug_ether_printf
64
+      ("send len=%u type=0x%04X dest=%02X:%02X:%02X:%02X:%02X:%02X", Length,
65
+       ntohs(pEthPack->EthHdr.Type), pEthPack->EthHdr.Dest[0],
66
+       pEthPack->EthHdr.Dest[1], pEthPack->EthHdr.Dest[2],
67
+       pEthPack->EthHdr.Dest[3], pEthPack->EthHdr.Dest[4],
68
+       pEthPack->EthHdr.Dest[5]);
69
+
70
+  // fill in source address
71
+  mac_cpy(pEthPack->EthHdr.Src, ConfigMac);
72
+
73
+  // send packet
74
+  RtlWriteFrame((unsigned char *)pData, Length);
75
+}
... ...
@@ -0,0 +1,29 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_ethernet
7
+#define INC_ethernet
8
+
9
+// header of an ethernet packet
10
+struct EthernetHeader {
11
+  unsigned char Dest[6];
12
+  unsigned char Src[6];
13
+  unsigned short Type;
14
+};
15
+
16
+// an ethernet packet
17
+struct EthernetPacket {
18
+  struct EthernetHeader EthHdr;
19
+};
20
+
21
+// process a received ethernet packet
22
+extern void EthernetRecv(unsigned char *pData, unsigned short Length);
23
+
24
+// send an ethernet packet
25
+// pData must point to a struct EthernetPacket with EthHdr.Dest and
26
+// EthHdr.Type already initialized
27
+extern void EthernetSend(unsigned char *pData, unsigned short Length);
28
+
29
+#endif // #ifdef INC_ethernet
... ...
@@ -0,0 +1,544 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <string.h>
7
+#include <avr/pgmspace.h>
8
+
9
+#include "debug.h"
10
+#include "http.h"
11
+#include "macros.h"
12
+#include "tcp.h"
13
+
14
+// receive states while parsing HTTP request
15
+#define HTTP_RCV_CMD 0  // receiving HTTP command (e.g. GET)
16
+#define HTTP_RCV_FILE 1 // receiving filename
17
+#define HTTP_RCV_HDR_END 2      // receiving header until end
18
+#define HTTP_RCV_DONE 3 // receiving completed
19
+
20
+// knwon HTTP commands
21
+#define HTTP_CMD_UNKNOWN 0      // unknown HTTP command
22
+#define HTTP_CMD_GET 1  // GET command
23
+
24
+// files available using HTTP
25
+#define HTTP_FILE_NOT_FOUND 0   // file not found file
26
+#define HTTP_FILE_INDEX 1       // index file
27
+#define HTTP_FILE_ON_ALL 2      // turn on all link
28
+#define HTTP_FILE_ON_SINGLE 3   // turn on single links (+0..+7)
29
+#define HTTP_FILE_OFF_ALL 11    // turn off all link
30
+#define HTTP_FILE_OFF_SINGLE 12 // turn off single links (+0..+7)
31
+#define HTTP_FILE_IMG1 20       // image: on
32
+#define HTTP_FILE_IMG0 21       // image: off
33
+
34
+// content of webpages and strings to fill in for variables
35
+#include "http_content.inc"
36
+
37
+// table with HTTP connections
38
+struct HttpConnection {
39
+  unsigned char ConnNo; // number of the TCP connection, 0xFF is unused
40
+  unsigned long RcvCnt; // number of received bytes on connection
41
+  unsigned char RcvState;       // what is being received at the moment
42
+  unsigned char RcvBuf[16];     // receive buffer
43
+  unsigned char RcvBufLen;      // length of data in receive buffer
44
+  unsigned char Command;        // the command the client issued
45
+  char PreHttp1;        // flag if a HTTP version before 1.0 is used
46
+  unsigned char File;   // the file the client requested
47
+  uint16_t pSndData;    // the data to send (progmem pointer)
48
+  unsigned short SndDataLen;    // the length of the data to send
49
+  char Vars;    // flag if to interpret variables
50
+} HttpConns[4];
51
+
52
+// parse HTTP command
53
+static void HttpParseCommand(struct HttpConnection *pConn)
54
+{
55
+  // GET command
56
+  if (pConn->RcvBufLen == 3
57
+      && strncasecmp((const char *)pConn->RcvBuf, "GET", 3) == 0)
58
+    pConn->Command = HTTP_CMD_GET;
59
+  // unknown command is the default
60
+  else
61
+    pConn->Command = HTTP_CMD_UNKNOWN;
62
+}
63
+
64
+// parse HTTP file
65
+static void HttpParseFile(struct HttpConnection *pConn)
66
+{
67
+  // index file
68
+  if ((pConn->RcvBufLen == 1
69
+       && strncasecmp((const char *)pConn->RcvBuf, "/", 1) == 0)
70
+      || (pConn->RcvBufLen == 2
71
+          && strncasecmp((const char *)pConn->RcvBuf, "/i", 2) == 0))
72
+    pConn->File = HTTP_FILE_INDEX;
73
+  // turn on all link
74
+  else if (pConn->RcvBufLen == 3
75
+           && strncasecmp((const char *)pConn->RcvBuf, "/on", 3) == 0)
76
+    pConn->File = HTTP_FILE_ON_ALL;
77
+  // turn on single link
78
+  else if (pConn->RcvBufLen == 4
79
+           && strncasecmp((const char *)pConn->RcvBuf, "/on", 3) == 0
80
+           && pConn->RcvBuf[3] >= '1' && pConn->RcvBuf[3] <= '8')
81
+    pConn->File = HTTP_FILE_ON_SINGLE + pConn->RcvBuf[3] - '1';
82
+  // turn off all link
83
+  else if (pConn->RcvBufLen == 4
84
+           && strncasecmp((const char *)pConn->RcvBuf, "/off", 4) == 0)
85
+    pConn->File = HTTP_FILE_OFF_ALL;
86
+  // turn off single link
87
+  else if (pConn->RcvBufLen == 5
88
+           && strncasecmp((const char *)pConn->RcvBuf, "/off", 4) == 0
89
+           && pConn->RcvBuf[4] >= '1' && pConn->RcvBuf[4] <= '8')
90
+    pConn->File = HTTP_FILE_OFF_SINGLE + pConn->RcvBuf[4] - '1';
91
+  // image: on
92
+  else if (pConn->RcvBufLen == 5
93
+           && strncasecmp((const char *)pConn->RcvBuf, "/img1", 5) == 0)
94
+    pConn->File = HTTP_FILE_IMG1;
95
+  // image: off
96
+  else if (pConn->RcvBufLen == 5
97
+           && strncasecmp((const char *)pConn->RcvBuf, "/img0", 5) == 0)
98
+    pConn->File = HTTP_FILE_IMG0;
99
+  // error file is the default
100
+  else
101
+    pConn->File = HTTP_FILE_NOT_FOUND;
102
+}
103
+
104
+// process HTTP request
105
+static void HttpProcessRequest(struct HttpConnection *pConn)
106
+{
107
+  // different commands
108
+  switch (pConn->Command) {
109
+
110
+  case HTTP_CMD_GET:
111
+    // different actions
112
+    switch (pConn->File) {
113
+
114
+    case HTTP_FILE_ON_ALL:
115
+      pConn->File = HTTP_FILE_INDEX;    // "symlink" to index file
116
+      break;
117
+
118
+    case HTTP_FILE_ON_SINGLE + 0:
119
+    case HTTP_FILE_ON_SINGLE + 1:
120
+    case HTTP_FILE_ON_SINGLE + 2:
121
+    case HTTP_FILE_ON_SINGLE + 3:
122
+    case HTTP_FILE_ON_SINGLE + 4:
123
+    case HTTP_FILE_ON_SINGLE + 5:
124
+    case HTTP_FILE_ON_SINGLE + 6:
125
+    case HTTP_FILE_ON_SINGLE + 7:
126
+      pConn->File = HTTP_FILE_INDEX;    // "symlink" to index file
127
+      break;
128
+
129
+    case HTTP_FILE_OFF_ALL:
130
+      pConn->File = HTTP_FILE_INDEX;    // "symlink" to index file
131
+      break;
132
+
133
+    case HTTP_FILE_OFF_SINGLE + 0:
134
+    case HTTP_FILE_OFF_SINGLE + 1:
135
+    case HTTP_FILE_OFF_SINGLE + 2:
136
+    case HTTP_FILE_OFF_SINGLE + 3:
137
+    case HTTP_FILE_OFF_SINGLE + 4:
138
+    case HTTP_FILE_OFF_SINGLE + 5:
139
+    case HTTP_FILE_OFF_SINGLE + 6:
140
+    case HTTP_FILE_OFF_SINGLE + 7:
141
+      pConn->File = HTTP_FILE_INDEX;    // "symlink" to index file
142
+      break;
143
+
144
+    }   // switch( pConn->File )
145
+
146
+    // different files
147
+    switch (pConn->File) {
148
+
149
+    case HTTP_FILE_INDEX:
150
+      if (pConn->PreHttp1) {
151
+        pConn->pSndData = (uint16_t) HttpIndex + HttpIndexHeaderSize;
152
+        pConn->SndDataLen = sizeof(HttpIndex) - 1 - HttpIndexHeaderSize;
153
+      } else {
154
+        pConn->pSndData = (uint16_t) HttpIndex;
155
+        pConn->SndDataLen = sizeof(HttpIndex) - 1;
156
+      }
157
+      pConn->Vars = 1;
158
+      break;
159
+
160
+    case HTTP_FILE_IMG1:
161
+      if (pConn->PreHttp1) {
162
+        pConn->pSndData = (uint16_t) HttpImg1 + HttpImg1HeaderSize;
163
+        pConn->SndDataLen = sizeof(HttpImg1) - 1 - HttpImg1HeaderSize;
164
+      } else {
165
+        pConn->pSndData = (uint16_t) HttpImg1;
166
+        pConn->SndDataLen = sizeof(HttpImg1) - 1;
167
+      }
168
+      pConn->Vars = 0;
169
+      break;
170
+
171
+    case HTTP_FILE_IMG0:
172
+      if (pConn->PreHttp1) {
173
+        pConn->pSndData = (uint16_t) HttpImg0 + HttpImg0HeaderSize;
174
+        pConn->SndDataLen = sizeof(HttpImg0) - 1 - HttpImg0HeaderSize;
175
+      } else {
176
+        pConn->pSndData = (uint16_t) HttpImg0;
177
+        pConn->SndDataLen = sizeof(HttpImg0) - 1;
178
+      }
179
+      pConn->Vars = 0;
180
+      break;
181
+
182
+    case HTTP_FILE_NOT_FOUND:
183
+    default:
184
+      if (pConn->PreHttp1) {
185
+        pConn->pSndData = (uint16_t) HttpNotFound + HttpNotFoundHeaderSize;
186
+        pConn->SndDataLen = sizeof(HttpNotFound) - 1 - HttpNotFoundHeaderSize;
187
+      } else {
188
+        pConn->pSndData = (uint16_t) HttpNotFound;
189
+        pConn->SndDataLen = sizeof(HttpNotFound) - 1;
190
+      }
191
+      pConn->Vars = 0;
192
+
193
+    }   // switch( pConn->File )
194
+    break;
195
+
196
+  case HTTP_CMD_UNKNOWN:
197
+  default:
198
+    if (pConn->PreHttp1) {
199
+      pConn->pSndData = (uint16_t) HttpBadRequest + HttpBadRequestHeaderSize;
200
+      pConn->SndDataLen =
201
+          sizeof(HttpBadRequest) - 1 - HttpBadRequestHeaderSize;
202
+    } else {
203
+      pConn->pSndData = (uint16_t) HttpBadRequest;
204
+      pConn->SndDataLen = sizeof(HttpBadRequest) - 1;
205
+    }
206
+    pConn->Vars = 0;
207
+
208
+  }     // switch( pConn->Command )
209
+}
210
+
211
+// get a variable
212
+// returns progmem pointer to variable and the length of the variable
213
+static void HttpGetVariable(unsigned char VarNo, uint16_t * ppVar,
214
+                            unsigned char *pVarLen)
215
+{
216
+  switch (VarNo) {
217
+
218
+    // current state of output 1..8 ("ON" or "off")
219
+  case 0x81:
220
+  case 0x82:
221
+  case 0x83:
222
+  case 0x84:
223
+  case 0x85:
224
+  case 0x86:
225
+  case 0x87:
226
+  case 0x88:
227
+    *ppVar = (uint16_t) HttpVarOff;
228
+    *pVarLen = sizeof(HttpVarOff);
229
+    break;
230
+
231
+    // current state of output 1..8 ("1" or "0")
232
+  case 0x91:
233
+  case 0x92:
234
+  case 0x93:
235
+  case 0x94:
236
+  case 0x95:
237
+  case 0x96:
238
+  case 0x97:
239
+  case 0x98:
240
+    *ppVar = (uint16_t) HttpVar0;
241
+    *pVarLen = sizeof(HttpVar0);
242
+    break;
243
+
244
+    // unknown variable
245
+  default:
246
+    *ppVar = (uint16_t) HttpVarUnknown;
247
+    *pVarLen = sizeof(HttpVarUnknown);
248
+    break;
249
+
250
+  }     // switch( VarNo );
251
+}
252
+
253
+// called when connection is established
254
+void HttpConnect(unsigned char ConnNo)
255
+{
256
+  unsigned char i;
257
+  struct HttpConnection *pConn;
258
+
259
+  // find connection in table (in case TCP calls us twice, this should never
260
+  // happen)
261
+  for (i = 0; i < count(HttpConns); i++)
262
+    if (HttpConns[i].ConnNo == ConnNo)
263
+      break;
264
+  // connection not found
265
+  if (i >= count(HttpConns)) {
266
+    // find a free entry
267
+    for (i = 0; i < count(HttpConns); i++)
268
+      if (HttpConns[i].ConnNo == 0xFF)
269
+        break;
270
+    if (i >= count(HttpConns))  // no free entry found
271
+      return;   // ignore this connection (will be closed in first call of
272
+                // HttpSend)
273
+  }
274
+  // get pointer to connection
275
+  pConn = &HttpConns[i];
276
+
277
+  debug_http_printf("accept no=%u", ConnNo);
278
+
279
+  // put new connection into table
280
+  pConn->ConnNo = ConnNo;
281
+  pConn->RcvCnt = 0;
282
+  pConn->RcvState = HTTP_RCV_CMD;
283
+  pConn->RcvBufLen = 0;
284
+}
285
+
286
+// called when connection is closed / reset
287
+// (after this, the connection number may not be used any more)
288
+void HttpClose(unsigned char ConnNo)
289
+{
290
+  unsigned char i;
291
+  struct HttpConnection *pConn;
292
+
293
+  // find connection in table
294
+  for (i = 0; i < count(HttpConns); i++)
295
+    if (HttpConns[i].ConnNo == ConnNo)
296
+      break;
297
+  if (i >= count(HttpConns))    // connection not found
298
+    return;     // ignore this (now already closed) connection
299
+  // get pointer to connection
300
+  pConn = &HttpConns[i];
301
+
302
+  debug_http_printf("close no=%u", ConnNo);
303
+
304
+  // drop connection from table
305
+  pConn->ConnNo = 0xFF;
306
+}
307
+
308
+// called when sending data is possible
309
+// (return length of available data, 0xFFFF to close connection)
310
+unsigned short HttpSend(unsigned char ConnNo, unsigned long Pos,
311
+                        unsigned char *pBuffer, unsigned short MaxLen)
312
+{
313
+  unsigned char i, var, VarLen, VarPos;
314
+  struct HttpConnection *pConn;
315
+  unsigned short len, j;
316
+  uint16_t src, srcTmp, pVar;   // progmem pointer
317
+  char chr, *dest;
318
+
319
+  // find connection in table
320
+  for (i = 0; i < count(HttpConns); i++)
321
+    if (HttpConns[i].ConnNo == ConnNo)
322
+      break;
323
+  if (i >= count(HttpConns))    // connection not found
324
+    return 0xFFFF;      // close connection
325
+  // get pointer to connection
326
+  pConn = &HttpConns[i];
327
+
328
+  // not done with receiving
329
+  if (pConn->RcvState != HTTP_RCV_DONE)
330
+    return 0;   // do not send anything yet
331
+
332
+  // at or behind end of data
333
+  if (Pos >= (unsigned long)pConn->SndDataLen)
334
+    return 0xFFFF;      // request to close connection
335
+
336
+  // get number of bytes to send
337
+  len = min(pConn->SndDataLen - (unsigned short)Pos, MaxLen);
338
+  if (len == 0) // nothing to send
339
+    return 0;
340
+
341
+  // no variable in variable buffer
342
+  var = 0;
343
+  VarLen = 0;
344
+  VarPos = 0;
345
+  // if part that should be sent starts with variable
346
+  src = pConn->pSndData + (uint16_t) Pos;
347
+  chr = (char)pgm_read_byte_near(src);  // read first character
348
+  if (pConn->Vars && (unsigned char)chr >= 0x80) {
349
+    // get variable
350
+    var = chr;
351
+    HttpGetVariable(var, &pVar, &VarLen);
352
+    // get position in variable
353
+    for (VarPos = 0, srcTmp = src - 1; srcTmp > pConn->pSndData;
354
+         VarPos++, srcTmp--)
355
+      if ((char)pgm_read_byte_near(srcTmp) != var)      // if normal
356
+                                                        // character or other 
357
+                                                        // variable, we found 
358
+                                                        // the begin of the
359
+                                                        // variable
360
+        break;
361
+  }
362
+  // copy data to buffer
363
+  dest = (char *)pBuffer;
364
+  for (j = 0; j < len; j++) {
365
+    // read current character
366
+    chr = (char)pgm_read_byte_near(src);
367
+    // variable
368
+    if (pConn->Vars && (unsigned char)chr >= 0x80) {
369
+      // new variable
370
+      if (var != chr) {
371
+        // get variable
372
+        var = chr;
373
+        HttpGetVariable(var, &pVar, &VarLen);
374
+        VarPos = 0;
375
+      }
376
+      // copy next character of variable
377
+      if (VarPos < VarLen)      // get next character of variable
378
+        *dest = (char)pgm_read_byte_near(pVar + VarPos++);
379
+      else
380
+        *dest = ' ';    // fill rest of variable with spaces
381
+    }
382
+    // normal character
383
+    else {
384
+      var = 0;  // not a variable
385
+      *dest = chr;      // copy character
386
+    }
387
+    // next character
388
+    src++;
389
+    dest++;
390
+  }     // for( j ...
391
+
392
+  // return length of data in buffer
393
+  debug_http_printf("send no=%u pos=%lu len=%u", ConnNo, Pos, len);
394
+  return len;
395
+}
396
+
397
+// called when data was sent and ACKed
398
+void HttpSent(unsigned char ConnNo, unsigned long Pos)
399
+{
400
+  // nothing needs to be done here
401
+}
402
+
403
+// called when data was received
404
+// must return new window size (not smaller than curWnd)
405
+unsigned short HttpReceived(unsigned char ConnNo, unsigned long Pos,
406
+                            unsigned char *pBuffer, unsigned short Len,
407
+                            unsigned short curWnd)
408
+{
409
+  unsigned char i;
410
+  struct HttpConnection *pConn;
411
+
412
+  // find connection in table
413
+  for (i = 0; i < count(HttpConns); i++)
414
+    if (HttpConns[i].ConnNo == ConnNo)
415
+      break;
416
+  if (i >= count(HttpConns))    // connection not found
417
+    return max(curWnd, 256);    // ignore this connection (will be closed in
418
+                                // first call of HttpSend)
419
+  // get pointer to connection
420
+  pConn = &HttpConns[i];
421
+
422
+  // received duplicate data or missed some data
423
+  // (just to be on the safe side, this should never happen)
424
+  if (pConn->RcvCnt != Pos) {
425
+    // close connection
426
+    TcpClose(pConn->ConnNo);
427
+    pConn->ConnNo = 0xFF;
428
+    return max(curWnd, 256);
429
+  }
430
+  // process received data
431
+  for (; Len > 0; pBuffer++, Len--, pConn->RcvCnt++) {
432
+    // store character in receive buffer (if it fits into it)
433
+    if (pConn->RcvBufLen < sizeof(pConn->RcvBuf)) {
434
+      pConn->RcvBuf[pConn->RcvBufLen] = *pBuffer;
435
+      pConn->RcvBufLen++;
436
+    }
437
+    // actions according to state
438
+    switch (pConn->RcvState) {
439
+
440
+      // receiving HTTP command (e.g GET)
441
+    case HTTP_RCV_CMD:
442
+      if (*pBuffer == '\r' || *pBuffer == '\n') // newline
443
+      {
444
+        pConn->RcvBufLen--;     // remove newline from buffer
445
+        HttpParseCommand(pConn);        // parse command
446
+        pConn->PreHttp1 = 1;    // older than HTTP 1.0
447
+        pConn->File = HTTP_FILE_INDEX;  // send index file
448
+        pConn->RcvState = HTTP_RCV_DONE;        // receiving completed
449
+        debug_http_printf("get+end no=%u", pConn->ConnNo);
450
+        pConn->RcvBufLen = 0;   // empty receive buffer
451
+        HttpProcessRequest(pConn);      // now process request
452
+      } else if (*pBuffer == ' ' || *pBuffer == '\t')   // whitespace
453
+      {
454
+        pConn->RcvBufLen--;     // remove whitespace from buffer
455
+        HttpParseCommand(pConn);        // parse command
456
+        pConn->RcvState = HTTP_RCV_FILE;        // now receive filename
457
+        debug_http_printf("get no=%u", pConn->ConnNo);
458
+        pConn->RcvBufLen = 0;   // empty receive buffer
459
+      }
460
+      break;
461
+
462
+      // receiving filename
463
+    case HTTP_RCV_FILE:
464
+      if (*pBuffer == '\r' || *pBuffer == '\n') // newline
465
+      {
466
+        pConn->RcvBufLen--;     // remove newline from buffer
467
+        HttpParseFile(pConn);   // parse file
468
+        pConn->PreHttp1 = 1;    // older than HTTP 1.0
469
+        pConn->RcvState = HTTP_RCV_DONE;        // receiving completed
470
+        debug_http_printf("file+end no=%u file=%u", pConn->ConnNo,
471
+                          pConn->File);
472
+        pConn->RcvBufLen = 0;   // empty receive buffer
473
+        HttpProcessRequest(pConn);      // now process request
474
+      } else if (*pBuffer == ' ' || *pBuffer == '\t')   // whitespace
475
+      {
476
+        pConn->RcvBufLen--;     // remove whitespace from buffer
477
+        HttpParseFile(pConn);   // parse file
478
+        pConn->PreHttp1 = 0;    // HTTP 1.0 or newer
479
+        pConn->RcvState = HTTP_RCV_HDR_END;     // now receive header until
480
+                                                // end
481
+        debug_http_printf("file no=%u file=%u", pConn->ConnNo, pConn->File);
482
+        pConn->RcvBufLen = 0;   // empty receive buffer
483
+      }
484
+      break;
485
+
486
+      // receiving header until end
487
+    case HTTP_RCV_HDR_END:
488
+      if (*pBuffer != '\r' && *pBuffer != '\n') // not a newline
489
+      {
490
+        pConn->RcvBufLen = 0;   // empty receive buffer
491
+        break;
492
+      }
493
+      if ((pConn->RcvBufLen == 2 && memcmp(pConn->RcvBuf, "\r\r", 2) == 0) ||   // CR 
494
+                                                                                // CR
495
+          (pConn->RcvBufLen == 2 && memcmp(pConn->RcvBuf, "\n\n", 2) == 0) ||   // LF 
496
+                                                                                // LF
497
+          (pConn->RcvBufLen == 3 && memcmp(pConn->RcvBuf, "\r\n\n", 3) == 0) || // CR 
498
+                                                                                // LF 
499
+                                                                                // LF
500
+          (pConn->RcvBufLen == 3 && memcmp(pConn->RcvBuf, "\n\r\n", 3) == 0) || // LF 
501
+                                                                                // CR 
502
+                                                                                // LF
503
+          pConn->RcvBufLen == 4)        // CR LF CR LF (or some other
504
+                                        // combination of 4 times CR or LF)
505
+      {
506
+        pConn->RcvState = HTTP_RCV_DONE;        // receiving completed
507
+        debug_http_printf("end no=%u", pConn->ConnNo);
508
+        pConn->RcvBufLen = 0;   // empty receive buffer
509
+        HttpProcessRequest(pConn);      // now process request
510
+      }
511
+      break;
512
+
513
+      // receiving completed
514
+    case HTTP_RCV_DONE:
515
+      pConn->RcvBufLen = 0;     // ignore any additional data
516
+      break;
517
+
518
+    }   // switch( pConn->RcvState )
519
+  }     // for( ; Len > 0; pBuffer++, Len--, pConn->RcvCnt++ )
520
+
521
+  // return at least 256 bytes window size
522
+  // - we are always able to receive data
523
+  return max(curWnd, 256);
524
+}
525
+
526
+// http notification functions
527
+struct TcpNotify HttpNotify =   // (extern)
528
+{
529
+  .Connect = HttpConnect,
530
+  .Close = HttpClose,
531
+  .Send = HttpSend,
532
+  .Sent = HttpSent,
533
+  .Received = HttpReceived,
534
+};
535
+
536
+// initialize
537
+void HttpInit(void)     // (extern)
538
+{
539
+  unsigned char i;
540
+
541
+  // no HTTP connections yet
542
+  for (i = 0; i < count(HttpConns); i++)
543
+    HttpConns[i].ConnNo = 0xFF;
544
+}
... ...
@@ -0,0 +1,17 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_http
7
+#define INC_http
8
+
9
+#include "tcp.h"
10
+
11
+// initialize
12
+extern void HttpInit(void);
13
+
14
+// http notification functions
15
+extern struct TcpNotify HttpNotify;
16
+
17
+#endif // #ifdef INC_http
... ...
@@ -0,0 +1,9 @@
1
+<html>
2
+  <head><title>flaneth - 400 Bad Request</title></head>
3
+  <body>
4
+    <h1>flaneth - 400 Bad Request</h1>
5
+    Your browser sent a request that this server could not understand.<br>
6
+    <br><br>
7
+    flaneth - __VERSION__
8
+  </body>
9
+</html>
... ...
@@ -0,0 +1,65 @@
1
+<html>
2
+  <head>
3
+    <title>flaneth</title>
4
+    <meta http-equiv="pragma" content="no-cache">
5
+  </head>
6
+  <body bgcolor="#DCDCDC" text="#000000" link="#0000C0" alink="#0000C0" vlink="#0000C0">
7
+    <h1>flaneth</h1>
8
+    <table border="1" cellpadding="3">
9
+      <tr>
10
+        <td align="center"><b>port</b></td>
11
+        <td align="center"><b>state</b></td>
12
+        <td align="center"><b>actions</b></td>
13
+      </tr>
14
+      <tr>
15
+        <td align="center"><b>1</b></td>
16
+        <td align="center"><img src="img__VAR_10_1__" alt="__VAR_ONOFF_1__">&nbsp;__VAR_ONOFF_1__</td>
17
+        <td align="center"><a href="on1">on</a>&nbsp;&nbsp;&nbsp;<a href="off1">off</a></td>
18
+      </tr>
19
+      <tr>
20
+        <td align="center"><b>2</b></td>
21
+        <td align="center"><img src="img__VAR_10_2__" alt="__VAR_ONOFF_2__">&nbsp;__VAR_ONOFF_2__</td>
22
+        <td align="center"><a href="on2">on</a>&nbsp;&nbsp;&nbsp;<a href="off2">off</a></td>
23
+      </tr>
24
+      <tr>
25
+        <td align="center"><b>3</b></td>
26
+        <td align="center"><img src="img__VAR_10_3__" alt="__VAR_ONOFF_3__">&nbsp;__VAR_ONOFF_3__</td>
27
+        <td align="center"><a href="on3">on</a>&nbsp;&nbsp;&nbsp;<a href="off3">off</a></td>
28
+      </tr>
29
+      <tr>
30
+        <td align="center"><b>4</b></td>
31
+        <td align="center"><img src="img__VAR_10_4__" alt="__VAR_ONOFF_4__">&nbsp;__VAR_ONOFF_4__</td>
32
+        <td align="center"><a href="on4">on</a>&nbsp;&nbsp;&nbsp;<a href="off4">off</a></td>
33
+      </tr>
34
+      <tr>
35
+        <td align="center"><b>5</b></td>
36
+        <td align="center"><img src="img__VAR_10_5__" alt="__VAR_ONOFF_5__">&nbsp;__VAR_ONOFF_5__</td>
37
+        <td align="center"><a href="on5">on</a>&nbsp;&nbsp;&nbsp;<a href="off5">off</a></td>
38
+      </tr>
39
+      <tr>
40
+        <td align="center"><b>6</b></td>
41
+        <td align="center"><img src="img__VAR_10_6__" alt="__VAR_ONOFF_6__">&nbsp;__VAR_ONOFF_6__</td>
42
+        <td align="center"><a href="on6">on</a>&nbsp;&nbsp;&nbsp;<a href="off6">off</a></td>
43
+      </tr>
44
+      <tr>
45
+        <td align="center"><b>7</b></td>
46
+        <td align="center"><img src="img__VAR_10_7__" alt="__VAR_ONOFF_7__">&nbsp;__VAR_ONOFF_7__</td>
47
+        <td align="center"><a href="on7">on</a>&nbsp;&nbsp;&nbsp;<a href="off7">off</a></td>
48
+      </tr>
49
+      <tr>
50
+        <td align="center"><b>8</b></td>
51
+        <td align="center"><img src="img__VAR_10_8__" alt="__VAR_ONOFF_8__">&nbsp;__VAR_ONOFF_8__</td>
52
+        <td align="center"><a href="on8">on</a>&nbsp;&nbsp;&nbsp;<a href="off8">off</a></td>
53
+      </tr>
54
+      <tr>
55
+        <td align="center">all</td>
56
+        <td align="center">&nbsp;</td>
57
+        <td align="center"><a href="on">on</a>&nbsp;&nbsp;&nbsp;<a href="off">off</a></td>
58
+      </tr>
59
+    </table>
60
+    <br><br>
61
+    <a href="i">refresh</a>
62
+    <br><br>
63
+    flaneth - __VERSION__
64
+  </body>
65
+</html>
... ...
@@ -0,0 +1,9 @@
1
+<html>
2
+  <head><title>flaneth - 404 Not Found</title></head>
3
+  <body>
4
+    <h1>flaneth - 404 Not Found</h1>
5
+    The requested URL was not found on this server.<br>
6
+    <br><br>
7
+    flaneth - __VERSION__
8
+  </body>
9
+</html>
... ...
@@ -0,0 +1 @@
1
+0
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+1
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+off
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+ON
0 2
\ No newline at end of file
... ...
@@ -0,0 +1,292 @@
1
+#! /usr/bin/perl
2
+
3
+# flaneth - flash and ethernet
4
+# version 0.1 date 2008-11-09
5
+# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
6
+# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
7
+# a BlinkenArea project - http://www.blinkenarea.org/
8
+
9
+use strict;
10
+
11
+my $VERSION="version 0.1 date 2008-11-09";
12
+
13
+
14
+
15
+die( "usage: $0 <http_dir> <http_content.inc>\n" ) if( @ARGV < 2 );
16
+
17
+my $dir = @ARGV[0];
18
+my $output = @ARGV[1];
19
+
20
+
21
+
22
+my $var_on_off_size = max( file_size( $dir . "/var_on.txt" ), file_size( $dir . "/var_off.txt" ) );
23
+my $var_1_0_size = max( file_size( $dir . "/var_1.txt" ), file_size( $dir . "/var_0.txt" ) );
24
+
25
+die( "variable too long (only 255 characters are allowed)\n" ) if( max( $var_on_off_size, $var_1_0_size ) > 255 );
26
+
27
+
28
+
29
+# maximum
30
+# usage: $m = max( $a, $b )
31
+sub max
32
+{
33
+  my $a = shift;
34
+  my $b = shift;
35
+  return $a > $b ? $a : $b;
36
+}
37
+
38
+
39
+
40
+# convert a character to a string
41
+# usage: $txt = chr2str( $ascii_code, $cnt )
42
+sub chr2str
43
+{
44
+  my $ascii_code = shift;
45
+  my $cnt = shift;
46
+
47
+  my $txt = "";
48
+
49
+  for( ; $cnt > 0; $cnt-- ) {
50
+    $txt .= pack( "C", $ascii_code );
51
+  }
52
+
53
+  return $txt;
54
+}
55
+
56
+
57
+
58
+# c string escaping
59
+# usage: $escaped = str_esc( $txt )
60
+sub str_esc
61
+{
62
+  my $txt = shift;
63
+
64
+  my $escaped = "";
65
+  for( my $i = 0; $i < length( $txt ); $i++ ) {
66
+    my $chr = substr( $txt, $i, 1 );
67
+    if( $chr eq '\\' ) {
68
+      $escaped .= "\\\\";
69
+    } elsif( $chr eq '"' ) {
70
+      $escaped .= "\\\"";
71
+    } elsif( $chr eq "\t" ) {
72
+      $escaped .= "\\t";
73
+    } elsif( $chr eq "\r" ) {
74
+      $escaped .= "\\r";
75
+    } elsif( $chr eq "\n" ) {
76
+      $escaped .= "\\n";
77
+    } elsif( $chr ge ' ' && $chr le '~' ) {
78
+      $escaped .= $chr;
79
+    } else {
80
+      $escaped .= sprintf( "\\x%02X", unpack( "C", $chr ) );
81
+    }
82
+  }
83
+
84
+  return $escaped;
85
+}
86
+
87
+
88
+
89
+# replace variables
90
+# usage: $line_replaced = var_replace( $line )
91
+sub var_replace
92
+{
93
+  my $line = shift;
94
+
95
+  $line =~ s/__VERSION__/$VERSION/g;
96
+  for( my $i = 1; $i <= 8; $i++ ) {
97
+    my $var;
98
+    $var = chr2str( 0x80 + $i, $var_on_off_size );
99
+    $line =~ s/__VAR_ONOFF_${i}__/$var/g;
100
+    $var = chr2str( 0x90 + $i, $var_1_0_size );
101
+    $line =~ s/__VAR_10_${i}__/$var/g;
102
+  }
103
+
104
+  return $line;
105
+}
106
+
107
+
108
+
109
+# get file size
110
+# usage: $size = file_size( $filename )
111
+sub file_size
112
+{
113
+  my $filename = shift;
114
+
115
+  my @info = stat( $filename );
116
+
117
+  return @info[7] if( @info > 7 ); # @info[7] is the size (see documentation of stat)
118
+
119
+  return 0;
120
+}
121
+
122
+
123
+
124
+# convert a text file to c code
125
+# usage: $code = textfile2code( $filename )
126
+sub textfile2code
127
+{
128
+  my $filename = shift;
129
+
130
+  my $txt = "";
131
+
132
+  open( TEXTFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" );
133
+
134
+  my $line;
135
+  while( $line = <TEXTFILE> ) {
136
+    $txt .= "\"" . str_esc( var_replace( $line ) ) . "\"\n";
137
+  }
138
+
139
+
140
+  close( TEXTFILE );
141
+
142
+  return $txt;
143
+}
144
+
145
+
146
+
147
+# convert a binary file to c code
148
+# usage: $code = binfile2code( $filename )
149
+sub binfile2code
150
+{
151
+  my $filename = shift;
152
+
153
+  my $txt = "";
154
+
155
+  open( BINFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" );
156
+  binmode( BINFILE );
157
+
158
+  my $val;
159
+  while( 1 ) {
160
+    $txt.= "\"";
161
+    my $i;
162
+    for( $i = 0; $i < 0x10; $i++ ) {
163
+      read( BINFILE, $val, 1 ) or last;
164
+      $txt .= sprintf( "\\x%02X", unpack( "C", $val ) );
165
+    }
166
+    $txt .= "\"\n";
167
+    last if( $i < 0x10 );
168
+  }
169
+
170
+  close( BINFILE );
171
+
172
+  return $txt;
173
+}
174
+
175
+
176
+
177
+# convert a text file to a c string
178
+# usage: $code = textfile2str( $filename )
179
+sub textfile2str
180
+{
181
+  my $filename = shift;
182
+
183
+  open( TEXTFILE, "<$filename" ) or die( "cannot open \"$filename\" for reading: $!\n" );
184
+  my $line = <TEXTFILE>;
185
+  close( TEXTFILE );
186
+
187
+  return "\"" . str_esc( $line ) . "\"";
188
+}
189
+
190
+
191
+
192
+open( OUTPUT, ">$output" ) or die( "cannot open \"$output\" for writing: $!\n" );
193
+
194
+print OUTPUT <<EOF;
195
+//content for webpages
196
+// - characters from 0x80..0xFF indicate 1 character of a variable
197
+//   - e.g. "\\x80\\x80\\x80" indicates to insert the first 3 characters of varibale 0x80
198
+//   - for meaning of variables, see HttpGetVariable
199
+
200
+EOF
201
+
202
+print OUTPUT <<EOF;
203
+#define HttpBadRequestHeaderSize 121
204
+const char PROGMEM HttpBadRequest[] =
205
+"HTTP/1.0 400 Bad Request\\r\\n"
206
+"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
207
+"Connection: close\\r\\n"
208
+"Content-Type: text/html\\r\\n"
209
+"\\r\\n"
210
+EOF
211
+print( OUTPUT textfile2code( $dir . "/bad_request.html" ) );
212
+print OUTPUT <<EOF;
213
+;
214
+
215
+EOF
216
+
217
+print OUTPUT <<EOF;
218
+#define HttpNotFoundHeaderSize 119
219
+const char PROGMEM HttpNotFound[] =
220
+"HTTP/1.0 404 Not Found\\r\\n"
221
+"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
222
+"Connection: close\\r\\n"
223
+"Content-Type: text/html\\r\\n"
224
+"\\r\\n"
225
+EOF
226
+print( OUTPUT textfile2code( $dir . "/not_found.html" ) );
227
+print OUTPUT <<EOF;
228
+;
229
+
230
+EOF
231
+
232
+print OUTPUT <<EOF;
233
+#define HttpIndexHeaderSize 112
234
+const char PROGMEM HttpIndex[] =
235
+"HTTP/1.0 200 Ok\\r\\n"
236
+"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
237
+"Connection: close\\r\\n"
238
+"Content-Type: text/html\\r\\n"
239
+"\\r\\n"
240
+EOF
241
+print( OUTPUT textfile2code( $dir . "/index.html" ) );
242
+print OUTPUT <<EOF;
243
+;
244
+
245
+EOF
246
+
247
+print OUTPUT <<EOF;
248
+#define HttpImg1HeaderSize 112
249
+const char PROGMEM HttpImg1[] =
250
+"HTTP/1.0 200 Ok\\r\\n"
251
+"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
252
+"Connection: close\\r\\n"
253
+"Content-Type: image/png\\r\\n"
254
+"\\r\\n"
255
+EOF
256
+print( OUTPUT binfile2code( $dir . "/image_on.png" ) );
257
+print OUTPUT <<EOF;
258
+;
259
+
260
+EOF
261
+
262
+print OUTPUT <<EOF;
263
+#define HttpImg0HeaderSize 112
264
+const char PROGMEM HttpImg0[] =
265
+"HTTP/1.0 200 Ok\\r\\n"
266
+"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
267
+"Connection: close\\r\\n"
268
+"Content-Type: image/png\\r\\n"
269
+"\\r\\n"
270
+EOF
271
+print( OUTPUT binfile2code( $dir . "/image_off.png" ) );
272
+print OUTPUT <<EOF;
273
+;
274
+
275
+EOF
276
+
277
+print OUTPUT <<EOF;
278
+//text to fill in for variables
279
+// - variables 0x81..0x88: filled with "On"- or "Off"-text (depending on output state 1..8)
280
+// - variables 0x91..0x98: filled with "1"- or "0"-text (depending on output state 1..8)
281
+
282
+EOF
283
+
284
+print( OUTPUT 'const char PROGMEM HttpVarUnknown[] = ' . textfile2str( $dir . "/var_unknown.txt" ) . ";\n" );
285
+print( OUTPUT 'const char PROGMEM HttpVarOn[] = ' . textfile2str( $dir . "/var_on.txt" ) . ";\n" );
286
+print( OUTPUT 'const char PROGMEM HttpVarOff[] = ' . textfile2str( $dir . "/var_off.txt" ) . ";\n" );
287
+print( OUTPUT 'const char PROGMEM HttpVar1[] = ' . textfile2str( $dir . "/var_1.txt" ) . ";\n" );
288
+print( OUTPUT 'const char PROGMEM HttpVar0[] = ' . textfile2str( $dir . "/var_0.txt" ) . ";\n" );
289
+print( OUTPUT "\n" );
290
+
291
+close( OUTPUT );
292
+
... ...
@@ -0,0 +1,13 @@
1
+<html>
2
+ <head>
3
+  <title>flaneth - 400 Bad Request</title>
4
+ </head>
5
+ <body alink="#008000" bgcolor="#000000" link="#008000" text="#008000" vlink="#008000">
6
+  <font face="MONOSPACE">
7
+   <h1>flaneth - 400 Bad Request</h1>
8
+   Your browser sent a request that this server could not understand.<br>
9
+   <br>
10
+   <font size="-1">flaneth<br>__VERSION__</font>
11
+  </font>
12
+ </body>
13
+</html>
... ...
@@ -0,0 +1,86 @@
1
+<html>
2
+ <head>
3
+  <title>flaneth</title>
4
+  <meta http-equiv="pragma" content="no-cache">
5
+ </head>
6
+ <body alink="#008000" bgcolor="#000000" link="#008000" text="#008000" vlink="#008000">
7
+  <font face="MONOSPACE">
8
+   <table width="400" border="0">
9
+    <tr>
10
+     <td>
11
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\|||/<br>
12
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(o o)<br>
13
+     +-oooO--(_)-------+<br>
14
+     |&nbsp;&nbsp;<font color="#7F7F7F">&nbsp;_&nbsp;&nbsp;_&nbsp;&nbsp;_&nbsp;&nbsp;__</font>&nbsp;&nbsp;&nbsp;|<br>
15
+     |&nbsp;&nbsp;<font color="#7F7F7F">(_)|_)|_||_ </font>&nbsp;&nbsp;&nbsp;|<br>
16
+     |&nbsp;&nbsp;<font color="#7F7F7F">(_)|_)| ||__</font>&nbsp;&nbsp;&nbsp;|<br>
17
+     +------------Ooo--+<br>
18
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|__|__|<br>
19
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| ||<br>
20
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ooO Ooo<br>
21
+     <br><font size="+1">
22
+     <font color="#3F3F3F">8</font><font color="#4F4F4F">B</font><font color="#5F5F5F">i</font><font color="#6F6F6F">t</font><font color="#7F7F7F">A</font><font color="#8F8F8F">m</font><font color="#9F9F9F">E</font><font color="#AFAFAF">t</font><font color="#9F9F9F">h</font><font color="#8F8F8F">e</font><font color="#7F7F7F">r</font><font color="#6F6F6F">n</font><font color="#5F5F5F">e</font><font color="#5F5F5F">t</font>
23
+     </font>
24
+     </td>
25
+     <td>
26
+     <center>
27
+     <table border="1" cellpadding="3">
28
+     <tr>
29
+     <td align="center"><b>port</b></td>
30
+     <td align="center"><b>state</b></td>
31
+     <td align="center"><b>action</b></td>
32
+     </tr>
33
+     <tr>
34
+     <td align="center"><b>1</b></td>
35
+     <td align="center">__VAR_ONOFF_1__</font></td>
36
+     <td align="center"><a href="on1">on</a>|<a href="off1">off</a></td>
37
+     </tr>
38
+     <tr>
39
+     <td align="center"><b>2</b></td>
40
+     <td align="center">__VAR_ONOFF_2__</td>
41
+     <td align="center"><a href="on2">on</a>|<a href="off2">off</a></td>
42
+     </tr>
43
+     <tr>
44
+     <td align="center"><b>3</b></td>
45
+     <td align="center">__VAR_ONOFF_3__</td>
46
+     <td align="center"><a href="on3">on</a>|<a href="off3">off</a></td>
47
+     </tr>
48
+     <tr>
49
+     <td align="center"><b>4</b></td>
50
+     <td align="center">__VAR_ONOFF_4__</td>
51
+     <td align="center"><a href="on4">on</a>|<a href="off4">off</a></td>
52
+     </tr>
53
+     <tr>
54
+     <td align="center"><b>5</b></td>
55
+     <td align="center">__VAR_ONOFF_5__</td>
56
+     <td align="center"><a href="on5">on</a>|<a href="off5">off</a></td>
57
+     </tr>
58
+     <tr>
59
+     <td align="center"><b>6</b></td>
60
+     <td align="center">__VAR_ONOFF_6__</td>
61
+     <td align="center"><a href="on6">on</a>|<a href="off6">off</a></td>
62
+     </tr>
63
+     <tr>
64
+     <td align="center"><b>7</b></td>
65
+     <td align="center">__VAR_ONOFF_7__</td>
66
+     <td align="center"><a href="on7">on</a>|<a href="off7">off</a></td>
67
+     </tr>
68
+     <tr>
69
+     <td align="center"><b>8</b></td>
70
+     <td align="center">__VAR_ONOFF_8__</td>
71
+     <td align="center"><a href="on8">on</a>|<a href="off8">off</a></td>
72
+     </tr>
73
+     <tr>
74
+     <td align="center"><b>*</b></td>
75
+     <td align="center">&nbsp;</td>
76
+     <td align="center"><a href="on">on</a>|<a href="off">off</a></td>
77
+     </tr>
78
+     </table><br><a href="/">refresh state</a>
79
+     </center>
80
+     </td>
81
+    </tr>
82
+    <tr><td><font size="-1">flaneth<br>__VERSION__</font></td><td></td></tr>
83
+   </table>
84
+  </font>
85
+ </body>
86
+</html>
... ...
@@ -0,0 +1,2 @@
1
+English oldschool theme
2
+based on German oldschool theme by Stephan 'ST' Kambor <st@blinkenarea.org>
... ...
@@ -0,0 +1,13 @@
1
+<html>
2
+ <head>
3
+  <title>flaneth - 404 Not Found</title>
4
+ </head>
5
+ <body alink="#008000" bgcolor="#000000" link="#008000" text="#008000" vlink="#008000">
6
+  <font face="MONOSPACE">
7
+   <h1>flaneth - 404 Not Found</h1>
8
+   The requested URL was not found on this server.<br>
9
+   <br>
10
+   <font size="-1">flaneth<br>__VERSION__</font>
11
+  </font>
12
+ </body>
13
+</html>
... ...
@@ -0,0 +1 @@
1
+0
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+1
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+<font color="#FF0000">[off]</font>
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+<font color="#FFFF00">[on]</font>
0 2
\ No newline at end of file
... ...
@@ -0,0 +1,13 @@
1
+<html>
2
+ <head>
3
+  <title>flaneth - 400 Fehlerhafte Anfrage</title>
4
+ </head>
5
+ <body alink="#008000" bgcolor="#000000" link="#008000" text="#008000" vlink="#008000">
6
+  <font face="MONOSPACE">
7
+   <h1>flaneth - 400 Fehlerhafte Anfrage</h1>
8
+   Dein Browser hat eine Anfrage gesendet, die dieser Server nicht verstehen konnte.<br>
9
+   <br>
10
+   <font size="-1">flaneth<br>__VERSION__</font>
11
+  </font>
12
+ </body>
13
+</html>
... ...
@@ -0,0 +1,86 @@
1
+<html>
2
+ <head>
3
+  <title>flaneth</title>
4
+  <meta http-equiv="pragma" content="no-cache">
5
+ </head>
6
+ <body alink="#008000" bgcolor="#000000" link="#008000" text="#008000" vlink="#008000">
7
+  <font face="MONOSPACE">
8
+   <table width="400" border="0">
9
+    <tr>
10
+     <td>
11
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\|||/<br>
12
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(o o)<br>
13
+     +-oooO--(_)-------+<br>
14
+     |&nbsp;&nbsp;<font color="#7F7F7F">&nbsp;_&nbsp;&nbsp;_&nbsp;&nbsp;_&nbsp;&nbsp;__</font>&nbsp;&nbsp;&nbsp;|<br>
15
+     |&nbsp;&nbsp;<font color="#7F7F7F">(_)|_)|_||_ </font>&nbsp;&nbsp;&nbsp;|<br>
16
+     |&nbsp;&nbsp;<font color="#7F7F7F">(_)|_)| ||__</font>&nbsp;&nbsp;&nbsp;|<br>
17
+     +------------Ooo--+<br>
18
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|__|__|<br>
19
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| ||<br>
20
+     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ooO Ooo<br>
21
+     <br><font size="+1">
22
+     <font color="#3F3F3F">8</font><font color="#4F4F4F">B</font><font color="#5F5F5F">i</font><font color="#6F6F6F">t</font><font color="#7F7F7F">A</font><font color="#8F8F8F">m</font><font color="#9F9F9F">E</font><font color="#AFAFAF">t</font><font color="#9F9F9F">h</font><font color="#8F8F8F">e</font><font color="#7F7F7F">r</font><font color="#6F6F6F">n</font><font color="#5F5F5F">e</font><font color="#5F5F5F">t</font>
23
+     </font>
24
+     </td>
25
+     <td>
26
+     <center>
27
+     <table border="1" cellpadding="3">
28
+     <tr>
29
+     <td align="center"><b>Port</b></td>
30
+     <td align="center"><b>Status</b></td>
31
+     <td align="center"><b>Aktion</b></td>
32
+     </tr>
33
+     <tr>
34
+     <td align="center"><b>1</b></td>
35
+     <td align="center">__VAR_ONOFF_1__</font></td>
36
+     <td align="center"><a href="on1">ein</a>|<a href="off1">aus</a></td>
37
+     </tr>
38
+     <tr>
39
+     <td align="center"><b>2</b></td>
40
+     <td align="center">__VAR_ONOFF_2__</td>
41
+     <td align="center"><a href="on2">ein</a>|<a href="off2">aus</a></td>
42
+     </tr>
43
+     <tr>
44
+     <td align="center"><b>3</b></td>
45
+     <td align="center">__VAR_ONOFF_3__</td>
46
+     <td align="center"><a href="on3">ein</a>|<a href="off3">aus</a></td>
47
+     </tr>
48
+     <tr>
49
+     <td align="center"><b>4</b></td>
50
+     <td align="center">__VAR_ONOFF_4__</td>
51
+     <td align="center"><a href="on4">ein</a>|<a href="off4">aus</a></td>
52
+     </tr>
53
+     <tr>
54
+     <td align="center"><b>5</b></td>
55
+     <td align="center">__VAR_ONOFF_5__</td>
56
+     <td align="center"><a href="on5">ein</a>|<a href="off5">aus</a></td>
57
+     </tr>
58
+     <tr>
59
+     <td align="center"><b>6</b></td>
60
+     <td align="center">__VAR_ONOFF_6__</td>
61
+     <td align="center"><a href="on6">ein</a>|<a href="off6">aus</a></td>
62
+     </tr>
63
+     <tr>
64
+     <td align="center"><b>7</b></td>
65
+     <td align="center">__VAR_ONOFF_7__</td>
66
+     <td align="center"><a href="on7">ein</a>|<a href="off7">aus</a></td>
67
+     </tr>
68
+     <tr>
69
+     <td align="center"><b>8</b></td>
70
+     <td align="center">__VAR_ONOFF_8__</td>
71
+     <td align="center"><a href="on8">ein</a>|<a href="off8">aus</a></td>
72
+     </tr>
73
+     <tr>
74
+     <td align="center"><b>*</b></td>
75
+     <td align="center">&nbsp;</td>
76
+     <td align="center"><a href="on">ein</a>|<a href="off">aus</a></td>
77
+     </tr>
78
+     </table><br><a href="/">Status aktualisieren</a>
79
+     </center>
80
+     </td>
81
+    </tr>
82
+    <tr><td><font size="-1">flaneth<br>__VERSION__</font></td><td></td></tr>
83
+   </table>
84
+  </font>
85
+ </body>
86
+</html>
... ...
@@ -0,0 +1,2 @@
1
+German oldschool theme
2
+by Stephan 'ST' Kambor <st@blinkenarea.org>
... ...
@@ -0,0 +1,13 @@
1
+<html>
2
+ <head>
3
+  <title>flaneth - 404 Nicht Gefunden</title>
4
+ </head>
5
+ <body alink="#008000" bgcolor="#000000" link="#008000" text="#008000" vlink="#008000">
6
+  <font face="MONOSPACE">
7
+   <h1>flaneth - 404 Nicht Gefunden</h1>
8
+   Die angeforderte URL wurde auf diesem Server nicht gefunden.<br>
9
+   <br>
10
+   <font size="-1">flaneth<br>__VERSION__</font>
11
+  </font>
12
+ </body>
13
+</html>
... ...
@@ -0,0 +1 @@
1
+0
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+1
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+<font color="#FF0000">[aus]</font>
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+<font color="#00FF00">[ein]</font>
0 2
\ No newline at end of file
... ...
@@ -0,0 +1,9 @@
1
+<html>
2
+  <head><title>flaneth - 400 Bad Request</title></head>
3
+  <body>
4
+    <h1>flaneth - 400 Bad Request</h1>
5
+    Your browser sent a request that this server could not understand.<br>
6
+    <br><br>
7
+    flaneth - __VERSION__
8
+  </body>
9
+</html>
... ...
@@ -0,0 +1,65 @@
1
+<html>
2
+  <head>
3
+    <title>flaneth</title>
4
+    <meta http-equiv="pragma" content="no-cache">
5
+  </head>
6
+  <body>
7
+    <h1>flaneth</h1>
8
+    <table border="1" cellpadding="3">
9
+      <tr>
10
+        <td align="center"><b>port</b></td>
11
+        <td align="center"><b>state</b></td>
12
+        <td align="center"><b>actions</b></td>
13
+      </tr>
14
+      <tr>
15
+        <td align="center"><b>1</b></td>
16
+        <td align="center">__VAR_ONOFF_1__</td>
17
+        <td align="center"><a href="on1">on</a>&nbsp;&nbsp;&nbsp;<a href="off1">off</a></td>
18
+      </tr>                                                      
19
+      <tr>                                                       
20
+        <td align="center"><b>2</b></td>                         
21
+        <td align="center">__VAR_ONOFF_2__</td>                  
22
+        <td align="center"><a href="on2">on</a>&nbsp;&nbsp;&nbsp;<a href="off2">off</a></td>
23
+      </tr>                                                      
24
+      <tr>                                                       
25
+        <td align="center"><b>3</b></td>                         
26
+        <td align="center">__VAR_ONOFF_3__</td>                  
27
+        <td align="center"><a href="on3">on</a>&nbsp;&nbsp;&nbsp;<a href="off3">off</a></td>
28
+      </tr>                                                      
29
+      <tr>                                                       
30
+        <td align="center"><b>4</b></td>                         
31
+        <td align="center">__VAR_ONOFF_4__</td>                  
32
+        <td align="center"><a href="on4">on</a>&nbsp;&nbsp;&nbsp;<a href="off4">off</a></td>
33
+      </tr>                                                      
34
+      <tr>                                                       
35
+        <td align="center"><b>5</b></td>                         
36
+        <td align="center">__VAR_ONOFF_5__</td>                  
37
+        <td align="center"><a href="on5">on</a>&nbsp;&nbsp;&nbsp;<a href="off5">off</a></td>
38
+      </tr>                                                      
39
+      <tr>                                                       
40
+        <td align="center"><b>6</b></td>                         
41
+        <td align="center">__VAR_ONOFF_6__</td>                  
42
+        <td align="center"><a href="on6">on</a>&nbsp;&nbsp;&nbsp;<a href="off6">off</a></td>
43
+      </tr>                                                      
44
+      <tr>                                                       
45
+        <td align="center"><b>7</b></td>                         
46
+        <td align="center">__VAR_ONOFF_7__</td>                  
47
+        <td align="center"><a href="on7">on</a>&nbsp;&nbsp;&nbsp;<a href="off7">off</a></td>
48
+      </tr>                                                      
49
+      <tr>                                                       
50
+        <td align="center"><b>8</b></td>                         
51
+        <td align="center">__VAR_ONOFF_8__</td>                  
52
+        <td align="center"><a href="on8">on</a>&nbsp;&nbsp;&nbsp;<a href="off8">off</a></td>
53
+      </tr>
54
+      <tr>
55
+        <td align="center">all</td>
56
+        <td align="center">&nbsp;</td>
57
+        <td align="center"><a href="on">on</a>&nbsp;&nbsp;&nbsp;<a href="off">off</a></td>
58
+      </tr>
59
+    </table>
60
+    <br><br>
61
+    <a href="i">refresh</a>
62
+    <br><br>
63
+    flaneth - __VERSION__
64
+  </body>
65
+</html>
... ...
@@ -0,0 +1,9 @@
1
+<html>
2
+  <head><title>flaneth - 404 Not Found</title></head>
3
+  <body>
4
+    <h1>flaneth - 404 Not Found</h1>
5
+    The requested URL was not found on this server.<br>
6
+    <br><br>
7
+    flaneth - __VERSION__
8
+  </body>
9
+</html>
... ...
@@ -0,0 +1 @@
1
+off
0 2
\ No newline at end of file
... ...
@@ -0,0 +1 @@
1
+ON
0 2
\ No newline at end of file
... ...
@@ -0,0 +1,113 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <string.h>
7
+
8
+#include "checksum.h"
9
+#include "debug.h"
10
+#include "ethernet.h"
11
+#include "icmp.h"
12
+#include "ip.h"
13
+#include "macros.h"
14
+#include "nethelp.h"
15
+
16
+// send an ICMP packet
17
+// pData must point to a struct IcmpPacket with IcmpHdr.Type, IcmpHdr.Code
18
+// and IpHdr.Dest already initialized
19
+static void IcmpSend(unsigned char *pData, unsigned short Length)
20
+{
21
+  struct IcmpPacket *pIcmpPack;
22
+  unsigned int chk;
23
+
24
+  // packet too short
25
+  if (Length < sizeof(struct IcmpPacket))
26
+    return;
27
+
28
+  // convert pointer to ICMP packet
29
+  // (this saves us from always casting pData)
30
+  pIcmpPack = (struct IcmpPacket *)pData;
31
+
32
+  debug_icmp_printf("send type=0x%02X len=%u", pIcmpPack->IcmpHdr.Type,
33
+                    Length);
34
+
35
+  // fill in header values
36
+  pIcmpPack->IcmpHdr.Chk = 0x0000;
37
+
38
+  // generate checksum
39
+  chk =
40
+      Checksum((unsigned char *)&pIcmpPack->IcmpHdr,
41
+               Length - sizeof(struct EthernetHeader) -
42
+               sizeof(struct IpHeader), 0x0000, 0x0000);
43
+  pIcmpPack->IcmpHdr.Chk = htons(chk);
44
+
45
+  // send ICMP packet
46
+  pIcmpPack->IpHdr.Proto = 0x01;        // ICMP
47
+  IpSend(pData, Length);
48
+}
49
+
50
+// process a received ICMP echo request packet
51
+static void IcmpEchoReqRecv(unsigned char *pData, unsigned short Length)
52
+{
53
+  struct IcmpEchoPacket *pIcmpEchoPack;
54
+
55
+  // packet too short
56
+  if (Length < sizeof(struct IcmpEchoPacket))
57
+    return;
58
+
59
+  // convert pointer to ICMP echo request/reply packet
60
+  // (this saves us from always casting pData)
61
+  pIcmpEchoPack = (struct IcmpEchoPacket *)pData;
62
+
63
+  // code not 0
64
+  if (pIcmpEchoPack->IcmpHdr.Code != 0x00)
65
+    return;
66
+
67
+  debug_icmp_printf("icmp echo len=%u", Length);
68
+
69
+  // send an ICMP echo reply
70
+  // - use same buffer to send reply
71
+  // - this saves us from needing to allocate a new buffer
72
+  // - this saves us from needing to copy EchoHdr.Id, EchoHdr.Seq and the
73
+  // data
74
+  pIcmpEchoPack->IcmpHdr.Type = 0x00;   // ICMP echo reply
75
+  pIcmpEchoPack->IcmpHdr.Code = 0x00;
76
+  ip_cpy(pIcmpEchoPack->IpHdr.Dest, pIcmpEchoPack->IpHdr.Src);  // destination 
77
+                                                                // IP is
78
+                                                                // source IP
79
+                                                                // of request
80
+  IcmpSend(pData, Length);
81
+}
82
+
83
+// process a received ICMP packet
84
+void IcmpRecv(unsigned char *pData, unsigned short Length)      // (extern)
85
+{
86
+  struct IcmpPacket *pIcmpPack;
87
+
88
+  // packet too short
89
+  if (Length < sizeof(struct IcmpPacket))
90
+    return;
91
+
92
+  // convert pointer to ICMP packet
93
+  // (this saves us from always casting pData)
94
+  pIcmpPack = (struct IcmpPacket *)pData;
95
+
96
+  // test checksum
97
+  if (Checksum
98
+      ((unsigned char *)&pIcmpPack->IcmpHdr,
99
+       Length - sizeof(struct EthernetHeader) - sizeof(struct IpHeader),
100
+       0x0000, 0x0000) != 0)
101
+    return;
102
+
103
+  debug_icmp_printf("recv type=0x%02X len=%u", pIcmpPack->IcmpHdr.Type,
104
+                    Length);
105
+
106
+  // branch according to type
107
+  switch (pIcmpPack->IcmpHdr.Type) {
108
+    // ICMP echo request
109
+  case 0x08:
110
+    IcmpEchoReqRecv(pData, Length);
111
+    break;
112
+  }
113
+}
... ...
@@ -0,0 +1,43 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_icmp
7
+#define INC_icmp
8
+
9
+#include "ethernet.h"
10
+#include "ip.h"
11
+
12
+// header of an ICMP packet
13
+struct IcmpHeader {
14
+  unsigned char Type;
15
+  unsigned char Code;
16
+  unsigned int Chk;
17
+};
18
+
19
+// an ICMP packet
20
+struct IcmpPacket {
21
+  struct EthernetHeader EthHdr;
22
+  struct IpHeader IpHdr;
23
+  struct IcmpHeader IcmpHdr;
24
+};
25
+
26
+// header of an ICMP echo request/reply packet
27
+struct IcmpEchoHeader {
28
+  unsigned int Id;
29
+  unsigned int Seq;
30
+};
31
+
32
+// an ICMP echo request/reply packet
33
+struct IcmpEchoPacket {
34
+  struct EthernetHeader EthHdr;
35
+  struct IpHeader IpHdr;
36
+  struct IcmpHeader IcmpHdr;
37
+  struct IcmpEchoHeader EchoHdr;
38
+};
39
+
40
+// process a received ICMP packet
41
+extern void IcmpRecv(unsigned char *pData, unsigned short Length);
42
+
43
+#endif // #ifdef INC_icmp
... ...
@@ -0,0 +1,341 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <string.h>
7
+
8
+#include "arp.h"
9
+#include "checksum.h"
10
+#include "config.h"
11
+#include "debug.h"
12
+#include "ethernet.h"
13
+#include "icmp.h"
14
+#include "ip.h"
15
+#include "macros.h"
16
+#include "nethelp.h"
17
+#include "tcp.h"
18
+#include "udp.h"
19
+
20
+// timing parameters
21
+#define IpBufferTicksMax 50     // maximum age of buffered IP packet (in
22
+                                // 200ms steps)
23
+
24
+// buffers for IP packets to transmit
25
+// - used if MAC is unknown when packet shall be transmitted
26
+// - packet is sent when MAC becomes known
27
+unsigned char IpBuffer0[80];    // some buffers with different length (IP
28
+                                // packets have different length)
29
+unsigned char IpBuffer1[80];
30
+unsigned char IpBuffer2[160];
31
+unsigned char IpBuffer3[320];
32
+struct IpBufferTable    // table with buffers
33
+{
34
+  unsigned char *pBuffer;       // pointer to buffer for packet
35
+  unsigned short BufferLength;  // length of buffer
36
+  unsigned short PacketLength;  // length of packet in buffer, 0 if no packet 
37
+                                // in this buffer
38
+  unsigned char Ticks;  // age of entry in 200ms steps
39
+} IpBufferTab[] = {     // put smaller buffers in front of larger buffers
40
+  // - then short packets will use smaller buffers more often
41
+  {
42
+  IpBuffer0, sizeof(IpBuffer0), 0, 0}
43
+  , {
44
+  IpBuffer1, sizeof(IpBuffer1), 0, 0}
45
+  , {
46
+  IpBuffer2, sizeof(IpBuffer2), 0, 0}
47
+  , {
48
+  IpBuffer3, sizeof(IpBuffer3), 0, 0}
49
+,};
50
+
51
+// tick procedure - call every 200ms
52
+void IpTick200(void)    // (extern)
53
+{
54
+  unsigned char i;
55
+
56
+  // increase age of buffered IP packets and remove timed out ones
57
+  for (i = 0; i < count(IpBufferTab); i++) {
58
+    if (IpBufferTab[i].PacketLength > 0)        // buffer in use
59
+    {
60
+      IpBufferTab[i].Ticks++;   // increase age
61
+      if (IpBufferTab[i].Ticks > IpBufferTicksMax)      // too old
62
+        IpBufferTab[i].PacketLength = 0;        // discard packet
63
+    }
64
+  }
65
+}
66
+
67
+// process a received IP packet
68
+void IpRecv(unsigned char *pData, unsigned short Length)        // (extern)
69
+{
70
+  struct IpPacket *pIpPack;
71
+  unsigned int len;
72
+
73
+  // packet too short
74
+  if (Length < sizeof(struct IpPacket))
75
+    return;
76
+
77
+  // convert pointer to IP packet
78
+  // (this saves us from always casting pData)
79
+  pIpPack = (struct IpPacket *)pData;
80
+
81
+  // not IPv4
82
+  if (pIpPack->IpHdr.Ver_HdrLen != 0x45)        // IPv4 with no options
83
+                                                // present
84
+    return;
85
+
86
+  // check destination address
87
+  do {
88
+    if (ip_eq(pIpPack->IpHdr.Dest, ConfigIp))   // own IP
89
+      break;
90
+    if (ip_eq(pIpPack->IpHdr.Dest, "\xFF\xFF\xFF\xFF")) // broadcast
91
+      break;
92
+    if (pIpPack->IpHdr.Dest[0] == (ConfigIp[0] & ConfigMask[0]) &&      // local 
93
+                                                                        // broadcast
94
+        pIpPack->IpHdr.Dest[1] == (ConfigIp[1] & ConfigMask[1]) &&
95
+        pIpPack->IpHdr.Dest[2] == (ConfigIp[2] & ConfigMask[2]) &&
96
+        pIpPack->IpHdr.Dest[3] == (ConfigIp[3] & ConfigMask[3]))
97
+      break;
98
+    return;     // packet not to this node
99
+  } while (0);
100
+
101
+  // ignore packets sent from invalid source adresses
102
+  // - this might be some attack or some router fault
103
+  if (pIpPack->IpHdr.Src[0] >= 0xE0 ||  // broadcast, reserved or multicast
104
+                                        // addresses
105
+      pIpPack->IpHdr.Src[0] == 0x7F ||  // loopback network
106
+      ip_eq(pIpPack->IpHdr.Src, "\x00\x00\x00\x00"))    // IP 0.0.0.0
107
+    return;
108
+  // ignore packets sent from local network address or broadcast address
109
+  if ((pIpPack->IpHdr.Src[0] & ConfigMask[0]) == (ConfigIp[0] & ConfigMask[0]) &&       // source 
110
+                                                                                        // IP 
111
+                                                                                        // is 
112
+                                                                                        // in 
113
+                                                                                        // own 
114
+                                                                                        // subnet
115
+      (pIpPack->IpHdr.Src[1] & ConfigMask[1]) == (ConfigIp[1] & ConfigMask[1])
116
+      && (pIpPack->IpHdr.Src[2] & ConfigMask[2]) ==
117
+      (ConfigIp[2] & ConfigMask[2])
118
+      && (pIpPack->IpHdr.Src[3] & ConfigMask[3]) ==
119
+      (ConfigIp[3] & ConfigMask[3])) {
120
+    if ((pIpPack->IpHdr.Src[0] & ~ConfigMask[0]) == 0x00 &&     // local
121
+                                                                // network
122
+                                                                // address
123
+        (pIpPack->IpHdr.Src[1] & ~ConfigMask[1]) == 0x00 &&
124
+        (pIpPack->IpHdr.Src[2] & ~ConfigMask[2]) == 0x00 &&
125
+        (pIpPack->IpHdr.Src[3] & ~ConfigMask[3]) == 0x00)
126
+      return;
127
+    if ((pIpPack->IpHdr.Src[0] & ~ConfigMask[0]) == 0xFF &&     // local
128
+                                                                // broadcast
129
+                                                                // address
130
+        (pIpPack->IpHdr.Src[1] & ~ConfigMask[1]) == 0xFF &&
131
+        (pIpPack->IpHdr.Src[2] & ~ConfigMask[2]) == 0xFF &&
132
+        (pIpPack->IpHdr.Src[3] & ~ConfigMask[3]) == 0xFF)
133
+      return;
134
+  }
135
+  // ignore packets sent from own IP address
136
+  if (ip_eq(pIpPack->IpHdr.Src, ConfigIp))
137
+    return;
138
+
139
+  // ignore fragmented packets
140
+  // BUG: fragmentation must be supported according to RFC781
141
+  // but there is no way of assembling packets with up to 64kB on a processor 
142
+  // with 4kB of RAM
143
+  if ((ntohs(pIpPack->IpHdr.FragOfs) & 0xBFFF) != 0x0000)       // fragment
144
+                                                                // offset 0,
145
+                                                                // MoreFrags=0, 
146
+                                                                // DontFrag=x, 
147
+                                                                // reservedFlag=0
148
+    return;
149
+
150
+  // check total length
151
+  len = sizeof(struct EthernetHeader) + ntohs(pIpPack->IpHdr.TotalLen); // length 
152
+                                                                        // according 
153
+                                                                        // to 
154
+                                                                        // IP 
155
+                                                                        // header
156
+  if (Length < len)     // packet is truncated
157
+    return;
158
+  Length = len; // remove ethernet padding from packet (maybe Length > len)
159
+
160
+  // test header checksum
161
+  if (Checksum
162
+      ((unsigned char *)&pIpPack->IpHdr, sizeof(struct IpHeader), 0x0000,
163
+       0x0000) != 0)
164
+    return;
165
+
166
+  debug_ip_printf("recv src=%u.%u.%u.%u protocol=%u len=%u",
167
+                  pIpPack->IpHdr.Src[0], pIpPack->IpHdr.Src[1],
168
+                  pIpPack->IpHdr.Src[2], pIpPack->IpHdr.Src[3],
169
+                  pIpPack->IpHdr.Proto, Length);
170
+
171
+  // branch according to protocol
172
+  switch (pIpPack->IpHdr.Proto) {
173
+    // ICMP
174
+  case 0x01:
175
+    IcmpRecv(pData, Length);
176
+    break;
177
+    // TCP
178
+  case 0x06:
179
+    TcpRecv(pData, Length);
180
+    break;
181
+    // UDP
182
+  case 0x11:
183
+    UdpRecv(pData, Length);
184
+    break;
185
+  }
186
+}
187
+
188
+// send an IP packet
189
+// pData must point to a struct IpPacket with IpHdr.Proto and IpHdr.Dest
190
+// already initialized
191
+void IpSend(unsigned char *pData, unsigned short Length)        // (extern)
192
+{
193
+  struct IpPacket *pIpPack;
194
+  unsigned int chk;
195
+  unsigned char i;
196
+
197
+  // packet too short
198
+  if (Length < sizeof(struct IpPacket))
199
+    return;
200
+
201
+  // convert pointer to IP packet
202
+  // (this saves us from always casting pData)
203
+  pIpPack = (struct IpPacket *)pData;
204
+
205
+  debug_ip_printf("send dest=%u.%u.%u.%u protocol=%u len=%u",
206
+                  pIpPack->IpHdr.Dest[0], pIpPack->IpHdr.Dest[1],
207
+                  pIpPack->IpHdr.Dest[2], pIpPack->IpHdr.Dest[3],
208
+                  pIpPack->IpHdr.Proto, Length);
209
+
210
+  // fill in header values
211
+  pIpPack->IpHdr.Ver_HdrLen = 0x45;
212
+  pIpPack->IpHdr.Tos = 0x00;
213
+  pIpPack->IpHdr.TotalLen = htons(Length - sizeof(struct EthernetHeader));
214
+  pIpPack->IpHdr.Id = 0x0000;
215
+  pIpPack->IpHdr.FragOfs = 0x0000;
216
+  pIpPack->IpHdr.Ttl = 0x40;
217
+  pIpPack->IpHdr.HdrChk = 0x0000;
218
+  ip_cpy(pIpPack->IpHdr.Src, ConfigIp);
219
+
220
+  // generate header checksum
221
+  chk =
222
+      Checksum((unsigned char *)&pIpPack->IpHdr, sizeof(struct IpHeader),
223
+               0x0000, 0x0000);
224
+  pIpPack->IpHdr.HdrChk = htons(chk);
225
+
226
+  // destination is in own subnet
227
+  if ((pIpPack->IpHdr.Dest[0] & ConfigMask[0]) ==
228
+      (ConfigIp[0] & ConfigMask[0])
229
+      && (pIpPack->IpHdr.Dest[1] & ConfigMask[1]) ==
230
+      (ConfigIp[1] & ConfigMask[1])
231
+      && (pIpPack->IpHdr.Dest[2] & ConfigMask[2]) ==
232
+      (ConfigIp[2] & ConfigMask[2])
233
+      && (pIpPack->IpHdr.Dest[3] & ConfigMask[3]) ==
234
+      (ConfigIp[3] & ConfigMask[3])) {
235
+    // broadcast
236
+    if ((pIpPack->IpHdr.Dest[0] | ConfigMask[0]) == 255 &&
237
+        (pIpPack->IpHdr.Dest[1] | ConfigMask[1]) == 255 &&
238
+        (pIpPack->IpHdr.Dest[2] | ConfigMask[2]) == 255 &&
239
+        (pIpPack->IpHdr.Dest[3] | ConfigMask[3]) == 255) {
240
+      mac_cpy(pIpPack->EthHdr.Dest, "\xFF\xFF\xFF\xFF\xFF\xFF");
241
+      i = 0x00;
242
+    }
243
+    // unicast
244
+    else {
245
+      // lookup MAC address of destination
246
+      i = ArpLookup(pIpPack->IpHdr.Dest, pIpPack->EthHdr.Dest);
247
+    }
248
+  }
249
+  // destination is not in own subnet
250
+  else {
251
+    // broadcast
252
+    if (pIpPack->IpHdr.Dest[0] == 255 &&
253
+        pIpPack->IpHdr.Dest[1] == 255 &&
254
+        pIpPack->IpHdr.Dest[2] == 255 && pIpPack->IpHdr.Dest[3] == 255) {
255
+      mac_cpy(pIpPack->EthHdr.Dest, "\xFF\xFF\xFF\xFF\xFF\xFF");
256
+      i = 0x00;
257
+    }
258
+    // unicast
259
+    else {
260
+      // lookup MAC address of default gateway
261
+      i = ArpLookup(ConfigGw, pIpPack->EthHdr.Dest);
262
+    }
263
+  }
264
+
265
+  // MAC available
266
+  if (i == 0x00) {
267
+    // sent IP packet
268
+    pIpPack->EthHdr.Type = htons(0x0800);       // ethernet packet type: IP
269
+    EthernetSend(pData, Length);
270
+    return;
271
+  }
272
+  // find a buffer to store the packet in
273
+  for (i = 0; i < count(IpBufferTab); i++) {
274
+    if (IpBufferTab[i].PacketLength == 0 &&     // buffer not in use
275
+        Length < IpBufferTab[i].BufferLength)   // buffer long enough
276
+    {
277
+      // put packet into buffer
278
+      memcpy(IpBufferTab[i].pBuffer, pData, Length);
279
+      IpBufferTab[i].PacketLength = Length;
280
+      IpBufferTab[i].Ticks = 0;
281
+      debug_ip_printf("queued");
282
+      break;
283
+    }
284
+  }
285
+  // if no buffer was found, we cannnot do anything about it and must discard 
286
+  // the packet (i.e. do nothing here)
287
+}
288
+
289
+// a MAC address was discovered
290
+// called by ARP to notify IP
291
+void IpGotMac(unsigned char Ip[4], unsigned char Mac[6])        // (extern)
292
+{
293
+  unsigned char i;
294
+  struct IpPacket *pIpPack;
295
+
296
+  // search for buffered packets that can be sent now
297
+  for (i = 0; i < count(IpBufferTab); i++) {
298
+    if (IpBufferTab[i].PacketLength > 0)        // buffer in use
299
+    {
300
+      // convert pointer to IP packet
301
+      pIpPack = (struct IpPacket *)IpBufferTab[i].pBuffer;
302
+
303
+      debug_ip_printf("send queued dest=%u.%u.%u.%u protocol=%u len=%u",
304
+                      pIpPack->IpHdr.Dest[0], pIpPack->IpHdr.Dest[1],
305
+                      pIpPack->IpHdr.Dest[2], pIpPack->IpHdr.Dest[3],
306
+                      pIpPack->IpHdr.Proto, IpBufferTab[i].PacketLength);
307
+
308
+      // destination is in own subnet
309
+      if ((pIpPack->IpHdr.Dest[0] & ConfigMask[0]) ==
310
+          (ConfigIp[0] & ConfigMask[0])
311
+          && (pIpPack->IpHdr.Dest[1] & ConfigMask[1]) ==
312
+          (ConfigIp[1] & ConfigMask[1])
313
+          && (pIpPack->IpHdr.Dest[2] & ConfigMask[2]) ==
314
+          (ConfigIp[2] & ConfigMask[2])
315
+          && (pIpPack->IpHdr.Dest[3] & ConfigMask[3]) ==
316
+          (ConfigIp[3] & ConfigMask[3])) {
317
+        // packet can be sent to destination
318
+        if (ip_eq(pIpPack->IpHdr.Dest, Ip)) {
319
+          // send IP packet
320
+          pIpPack->EthHdr.Type = htons(0x0800); // ethernet packet type: IP
321
+          mac_cpy(pIpPack->EthHdr.Dest, Mac);
322
+          EthernetSend(IpBufferTab[i].pBuffer, IpBufferTab[i].PacketLength);
323
+          // buffer is now free
324
+          IpBufferTab[i].PacketLength = 0;
325
+        }
326
+      }
327
+      // destination is not in own subnet
328
+      else {
329
+        // packet can be sent to gateway
330
+        if (ip_eq(ConfigGw, Ip)) {
331
+          // send IP packet
332
+          pIpPack->EthHdr.Type = htons(0x0800); // ethernet packet type: IP
333
+          mac_cpy(pIpPack->EthHdr.Dest, Mac);
334
+          EthernetSend(IpBufferTab[i].pBuffer, IpBufferTab[i].PacketLength);
335
+          // buffer is now free
336
+          IpBufferTab[i].PacketLength = 0;
337
+        }
338
+      }
339
+    }
340
+  }     // for( i ...
341
+}
... ...
@@ -0,0 +1,46 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_ip
7
+#define INC_ip
8
+
9
+#include "ethernet.h"
10
+
11
+// header of an IP packet
12
+struct IpHeader {
13
+  unsigned char Ver_HdrLen;
14
+  unsigned char Tos;
15
+  unsigned int TotalLen;
16
+  unsigned int Id;
17
+  unsigned int FragOfs;
18
+  unsigned char Ttl;
19
+  unsigned char Proto;
20
+  unsigned int HdrChk;
21
+  unsigned char Src[4];
22
+  unsigned char Dest[4];
23
+};
24
+
25
+// an IP packet
26
+struct IpPacket {
27
+  struct EthernetHeader EthHdr;
28
+  struct IpHeader IpHdr;
29
+};
30
+
31
+// tick procedure - call every 200ms
32
+extern void IpTick200(void);
33
+
34
+// process a received IP packet
35
+extern void IpRecv(unsigned char *pData, unsigned short Length);
36
+
37
+// send an IP packet
38
+// pData must point to a struct IpPacket with IpHdr.Proto and IpHdr.Dest
39
+// already initialized
40
+extern void IpSend(unsigned char *pData, unsigned short Length);
41
+
42
+// a MAC address was discovered
43
+// called by ARP to notify IP
44
+extern void IpGotMac(unsigned char Ip[4], unsigned char Mac[6]);
45
+
46
+#endif // #ifdef INC_ip
... ...
@@ -0,0 +1,26 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_macros
7
+#define INC_macros
8
+
9
+// minimum and maximum
10
+#define min( a, b ) ((a) < (b) ? (a) : (b))
11
+#define max( a, b ) ((a) > (b) ? (a) : (b))
12
+
13
+// number of entries in an array
14
+#define count( array ) (sizeof( (array) ) / sizeof( (array)[0] ))
15
+
16
+// waiting
17
+#define nop( ) { __asm__ __volatile__ ("nop"::); }
18
+
19
+// bit manipulation
20
+#define bit_set( var, bit ) ((var) |= (1 << (bit)))
21
+#define bit_clear( var, bit ) ((var) &= ~(1 << (bit)))
22
+#define bit_toggle( var, bit ) ((var) ^= (1 << (bit)))
23
+#define is_bit_clear( var, bit ) (!(((var) >> (bit)) & 1))
24
+#define is_bit_set( var, bit ) (((var) >> (bit)) & 1)
25
+
26
+#endif // #ifndef INC_macros
... ...
@@ -0,0 +1,83 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/interrupt.h>
7
+#include <avr/wdt.h>
8
+
9
+#include "arp.h"
10
+#include "bus.h"
11
+#include "cf.h"
12
+#include "debug.h"
13
+#include "eeprom.h"
14
+#include "http.h"
15
+#include "random.h"
16
+#include "rtl8019.h"
17
+#include "status.h"
18
+#include "tcp.h"
19
+#include "timing.h"
20
+#include "uart.h"
21
+
22
+// main code entry point
23
+int main(void)
24
+{
25
+  wdt_reset();
26
+#ifdef DEBUG
27
+  wdt_disable();
28
+#else
29
+  wdt_enable(WDTO_60MS);
30
+#endif
31
+  wdt_reset();
32
+
33
+  // initialize uart to be able to use stdio
34
+  UartInit();
35
+
36
+  debug_printf("");
37
+  debug_printf("flaneth");
38
+
39
+  debug_init_printf("init");
40
+
41
+  // initialize low level modules
42
+  BusInit();
43
+
44
+  // initialize middle level modules
45
+  CfInit();
46
+  RtlInit();
47
+  StatusInit();
48
+  TimingInit();
49
+
50
+  // initialize high level modules
51
+  ArpInit();
52
+  HttpInit();
53
+  TcpInit();
54
+
55
+  // use entropy collected during initialization
56
+  RandomTask();
57
+
58
+  debug_init_printf("config");
59
+
60
+  // get configuration from EEPROM
61
+  EepromGetConfig();
62
+
63
+  // enable interrupts
64
+  sei();
65
+
66
+  debug_init_printf("start");
67
+
68
+  // main loop
69
+  while (1) {
70
+    wdt_reset();
71
+    CfTask();
72
+    wdt_reset();
73
+    EepromTask();
74
+    wdt_reset();
75
+    RandomTask();
76
+    wdt_reset();
77
+    //RtlTask();
78
+    wdt_reset();
79
+    TimingTask();
80
+  }
81
+
82
+  return 0;
83
+}
... ...
@@ -0,0 +1,35 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_nethelp
7
+#define INC_nethelp
8
+
9
+// byte order
10
+#define ntohs( n ) ( ((unsigned short)(n) & 0xFF00) >> 8 | \
11
+                     ((unsigned short)(n) & 0x00FF) << 8 )
12
+#define htons( h ) ( ((unsigned short)(h) & 0xFF00) >> 8 | \
13
+                     ((unsigned short)(h) & 0x00FF) << 8 )
14
+#define ntohl( n ) ( ((unsigned long)(n) & 0xFF000000) >> 24 | \
15
+                     ((unsigned long)(n) & 0x00FF0000) >> 8 | \
16
+                     ((unsigned long)(n) & 0x0000FF00) << 8 | \
17
+                     ((unsigned long)(n) & 0x000000FF) << 24 )
18
+#define htonl( h ) ( ((unsigned long)(h) & 0xFF000000) >> 24 | \
19
+                     ((unsigned long)(h) & 0x00FF0000) >> 8 | \
20
+                     ((unsigned long)(h) & 0x0000FF00) << 8 | \
21
+                     ((unsigned long)(h) & 0x000000FF) << 24 )
22
+
23
+// comparing MACs and IPs
24
+#define mac_eq( a, b ) ( (a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && \
25
+                         (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5] )
26
+#define ip_eq( a, b ) ( (a)[0] == (b)[0] && (a)[1] == (b)[1] && \
27
+                        (a)[2] == (b)[2] && (a)[3] == (b)[3] )
28
+
29
+// copying MACs and IPs
30
+#define mac_cpy( dest, src ) ( (dest)[0] = (src)[0], (dest)[1] = (src)[1], (dest)[2] = (src)[2], \
31
+                               (dest)[3] = (src)[3], (dest)[4] = (src)[4], (dest)[5] = (src)[5] )
32
+#define ip_cpy( dest, src ) ( (dest)[0] = (src)[0], (dest)[1] = (src)[1], \
33
+                              (dest)[2] = (src)[2], (dest)[3] = (src)[3] )
34
+
35
+#endif // #ifndef INC_nethelp
... ...
@@ -0,0 +1,75 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <stdlib.h>
7
+
8
+#include "random.h"
9
+
10
+// number of complete bytes a call to random( ) returns
11
+#if RANDOM_MAX < 0xFF
12
+#error random number generator is not able to return a random byte
13
+#elif RANDOM_MAX < 0xFFFF
14
+#define RANDOM_BYTES 1
15
+#elif RANDOM_MAX < 0xFFFFFF
16
+#define RANDOM_BYTES 2
17
+#elif RANDOM_MAX < 0xFFFFFFFF
18
+#define RANDOM_BYTES 3
19
+#else
20
+#define RANDOM_BYTES 4
21
+#endif
22
+
23
+// entropy collected so far
24
+unsigned long RandomEntropy = 0;        // the entropy itself
25
+unsigned char RandomEntropyCnt  // number of times entropy was collected so
26
+                                // far
27
+    = sizeof(unsigned long) * 8 - 5;    // (use first entropy (few is better
28
+                                        // than none))
29
+
30
+// provide some entropy
31
+void RandomProvideEntropy(unsigned char Entropy)        // (extern)
32
+{
33
+  // collect entropy
34
+  RandomEntropy = RandomEntropy << 1 ^ (unsigned int)Entropy;
35
+  RandomEntropyCnt++;
36
+}
37
+
38
+// task function to do the work - call from main loop
39
+void RandomTask(void)   // (extern)
40
+{
41
+  // enough entropy was collected
42
+  if (RandomEntropyCnt >= sizeof(unsigned long) * 8)    // one time entropy
43
+                                                        // for every bit of
44
+                                                        // RandomEntropy
45
+  {
46
+    RandomEntropyCnt = 0;
47
+    // re-seed random number generator
48
+    srandom(RandomEntropy);
49
+  }
50
+}
51
+
52
+// get random data
53
+void RandomGetData(unsigned char *pData, unsigned char Length)  // (extern)
54
+{
55
+  unsigned long r;
56
+  unsigned char i;
57
+
58
+  // return random data
59
+  for (; Length >= RANDOM_BYTES; Length -= RANDOM_BYTES) {
60
+    r = random();
61
+    for (i = 0; i < RANDOM_BYTES; i++) {
62
+      *pData = (unsigned char)r;
63
+      pData++;
64
+      r >>= 8;
65
+    }
66
+  }
67
+  if (Length > 0) {
68
+    r = random();
69
+    for (i = 0; i < Length; i++) {
70
+      *pData = (unsigned char)r;
71
+      pData++;
72
+      r >>= 8;
73
+    }
74
+  }
75
+}
... ...
@@ -0,0 +1,18 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_random
7
+#define INC_random
8
+
9
+// provide some entropy
10
+extern void RandomProvideEntropy(unsigned char Entropy);
11
+
12
+// task function to do the work - call from main loop
13
+extern void RandomTask(void);
14
+
15
+// get random data
16
+extern void RandomGetData(unsigned char *pData, unsigned char Length);
17
+
18
+#endif // #ifndef INC_random
... ...
@@ -0,0 +1,566 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/io.h>
7
+
8
+#include "bus.h"
9
+#include "config.h"
10
+#include "debug.h"
11
+#include "ethernet.h"
12
+#include "macros.h"
13
+#include "random.h"
14
+#include "rtl8019.h"
15
+#include "timing.h"
16
+
17
+// maximum receive unit
18
+#define RTL_MRU (640)
19
+
20
+// reinitialization timeout
21
+// - if no reception is detected for this time, the RTL8019 is reinitialized
22
+#define RtlReinitTimeoutTicks (50)      // in 200ms steps
23
+
24
+// IO pins of RTL8019
25
+#define RTL_DDR_INT (DDRE)
26
+#define RTL_PORT_INT (PORTE)
27
+#define RTL_BIT_INT (5)
28
+#define RTL_DDR_nAEN (DDRE)
29
+#define RTL_PORT_nAEN (PORTE)
30
+#define RTL_BIT_nAEN (4)
31
+#define RTL_DDR_RST (DDRE)
32
+#define RTL_PORT_RST (PORTE)
33
+#define RTL_BIT_RST (3)
34
+// special pin commands
35
+#define RTL_AEN_ACT( ) (bit_clear( RTL_PORT_nAEN, RTL_BIT_nAEN ))
36
+#define RTL_AEN_IDLE( ) (bit_set( RTL_PORT_nAEN, RTL_BIT_nAEN ))
37
+#define RTL_RESET_ACT( ) (bit_set( RTL_PORT_RST, RTL_BIT_RST ))
38
+#define RTL_RESET_IDLE( ) (bit_clear( RTL_PORT_RST, RTL_BIT_RST ))
39
+
40
+// IO pins of RTL8019 EEPROM interface
41
+#define RTL_DDR_EECS (DDRD)
42
+#define RTL_PORT_EECS (PORTD)
43
+#define RTL_PIN_EECS (PIND)
44
+#define RTL_BIT_EECS (7)
45
+#define RTL_DDR_EESK (DDRD)
46
+#define RTL_PORT_EESK (PORTD)
47
+#define RTL_PIN_EESK (PIND)
48
+#define RTL_BIT_EESK (4)
49
+#define RTL_DDR_EEDI (DDRD)
50
+#define RTL_PORT_EEDI (PORTD)
51
+#define RTL_PIN_EEDI (PIND)
52
+#define RTL_BIT_EEDI (5)
53
+#define RTL_DDR_EEDO (DDRD)
54
+#define RTL_PORT_EEDO (PORTD)
55
+#define RTL_BIT_EEDO (6)
56
+
57
+// RTL8019 registers
58
+#define RTL_REG_CR (0x00)
59
+#define RTL_REG_PSTART (0x01)
60
+#define RTL_REG_PAR0 (0x01)
61
+#define RTL_REG_PSTOP (0x02)
62
+#define RTL_REG_BNRY (0x03)
63
+#define RTL_REG_TPSR (0x04)
64
+#define RTL_REG_TBCR0 (0x05)
65
+#define RTL_REG_TBCR1 (0x06)
66
+#define RTL_REG_ISR (0x07)
67
+#define RTL_REG_CURR (0x07)
68
+#define RTL_REG_RSAR0 (0x08)
69
+#define RTL_REG_CRDA0 (0x08)
70
+#define RTL_REG_RSAR1 (0x09)
71
+#define RTL_REG_CRDAl (0x09)
72
+#define RTL_REG_RBCR0 (0x0A)
73
+#define RTL_REG_ID0 (0x0A)
74
+#define RTL_REG_ID1 (0x0B)
75
+#define RTL_REG_RBCR1 (0x0B)
76
+#define RTL_REG_RSR (0x0C)
77
+#define RTL_REG_RCR (0x0C)
78
+#define RTL_REG_TCR (0x0D)
79
+#define RTL_REG_CNTR0 (0x0D)
80
+#define RTL_REG_DCR (0x0E)
81
+#define RTL_REG_CNTR1 (0x0E)
82
+#define RTL_REG_IMR (0x0F)
83
+#define RTL_REG_CNTR2 (0x0F)
84
+#define RTL_REG_RDMAPORT (0x10)
85
+#define RTL_REG_RSTPORT (0x18)
86
+
87
+// RTL8019AS CR register bits
88
+#define RTL_CR_STP (0)
89
+#define RTL_CR_STA (1)
90
+#define RTL_CR_TXP (2)
91
+#define RTL_CR_RD0 (3)
92
+#define RTL_CR_RD1 (4)
93
+#define RTL_CR_RD2 (5)
94
+#define RTL_CR_PS0 (6)
95
+#define RTL_CR_PS1 (7)
96
+
97
+// RTL8019 ISR register bits
98
+#define RTL_ISR_PRX (0)
99
+#define RTL_ISR_PTX (1)
100
+#define RTL_ISR_RXE (2)
101
+#define RTL_ISR_TXE (3)
102
+#define RTL_ISR_OVW (4)
103
+#define RTL_ISR_CNT (5)
104
+#define RTL_ISR_RDC (6)
105
+#define RTL_ISR_RST (7)
106
+
107
+// RTL8019 (initial) register values
108
+#define RTL_VAL_RCR (0x04)
109
+#define RTL_VAL_TCR (0x00)
110
+#define RTL_VAL_DCR (0x58)
111
+#define RTL_VAL_IMR (0x00)
112
+#define RTL_VAL_TXSTART (0x40)
113
+#define RTL_VAL_RXSTART (0x46)
114
+#define RTL_VAL_RXSTOP (0x60)
115
+
116
+// write a RTL8019 register
117
+extern inline void RtlWriteReg(unsigned char reg, unsigned char val)    // force 
118
+                                                                        // inlining 
119
+                                                                        // by 
120
+                                                                        // using 
121
+                                                                        // "extern"
122
+{
123
+  BUS_DATA = val;       // output value
124
+  BUS_DATA_DDR = 0xFF;  // data port to output
125
+  BUS_ADDR = reg;       // output address
126
+  RTL_AEN_ACT();        // set address enable
127
+  BUS_WRITE_ACT();      // activate write signal
128
+  nop();
129
+  nop();
130
+  BUS_WRITE_IDLE();     // take back write signal
131
+  RTL_AEN_IDLE();       // take back address enable
132
+  BUS_DATA_DDR = 0x00;  // data back port to input
133
+  BUS_DATA = 0x00;      // turn off pullups
134
+}
135
+
136
+// write buffer to RTL8019 register
137
+extern inline void RtlWriteRegBuf(unsigned char reg, unsigned char *p_buf, unsigned short len)  // force 
138
+                                                                                                // inlining 
139
+                                                                                                // by 
140
+                                                                                                // using 
141
+                                                                                                // "extern"
142
+{
143
+  BUS_DATA = *p_buf;    // output first value to initialize port status
144
+                        // before switching to output
145
+  BUS_DATA_DDR = 0xFF;  // data port to output
146
+  BUS_ADDR = reg;       // output address
147
+  RTL_AEN_ACT();        // set address enable
148
+  for (; len > 0; p_buf++, len--) {
149
+    BUS_DATA = *p_buf;  // output value
150
+    BUS_WRITE_ACT();    // activate write signal
151
+    nop();
152
+    nop();
153
+    BUS_WRITE_IDLE();   // take back write signal
154
+  }
155
+  RTL_AEN_IDLE();       // take back address enable
156
+  BUS_DATA_DDR = 0x00;  // data back port to input
157
+  BUS_DATA = 0x00;      // turn off pullups
158
+}
159
+
160
+// write constant to RTL8019 register multiple times
161
+extern inline void RtlWriteRegConst(unsigned char reg, unsigned char val, unsigned short cnt)   // force 
162
+                                                                                                // inlining 
163
+                                                                                                // by 
164
+                                                                                                // using 
165
+                                                                                                // "extern"
166
+{
167
+  BUS_DATA = val;       // output value
168
+  BUS_DATA_DDR = 0xFF;  // data port to output
169
+  BUS_ADDR = reg;       // output address
170
+  RTL_AEN_ACT();        // set address enable
171
+  for (; cnt > 0; cnt--) {
172
+    BUS_WRITE_ACT();    // activate write signal
173
+    nop();
174
+    nop();
175
+    BUS_WRITE_IDLE();   // take back write signal
176
+  }
177
+  RTL_AEN_IDLE();       // take back address enable
178
+  BUS_DATA_DDR = 0x00;  // data back port to input
179
+  BUS_DATA = 0x00;      // turn off pullups
180
+}
181
+
182
+// read a RTL8019 register
183
+extern inline void RtlReadReg(unsigned char reg, unsigned char *p_var)  // force 
184
+                                                                        // inlining 
185
+                                                                        // by 
186
+                                                                        // using 
187
+                                                                        // "extern"
188
+{
189
+  BUS_ADDR = reg;       // output address
190
+  RTL_AEN_ACT();        // set address enable
191
+  BUS_READ_ACT();       // activate read signal
192
+  nop();
193
+  nop();
194
+  *p_var = BUS_DATA_IN; // read data
195
+  BUS_READ_IDLE();      // take back read signal
196
+  RTL_AEN_IDLE();       // take back address enable
197
+}
198
+
199
+// read buffer from RTL8019 register
200
+extern inline void RtlReadRegBuf(unsigned char reg, unsigned char *p_buf, unsigned short len)   // force 
201
+                                                                                                // inlining 
202
+                                                                                                // by 
203
+                                                                                                // using 
204
+                                                                                                // "extern"
205
+{
206
+  BUS_ADDR = reg;       // output address
207
+  RTL_AEN_ACT();        // set address enable
208
+  for (; len > 0; p_buf++, len--) {
209
+    BUS_READ_ACT();     // activate read signal
210
+    nop();
211
+    nop();
212
+    *p_buf = BUS_DATA_IN;       // read data
213
+    BUS_READ_IDLE();    // take back read signal
214
+  }
215
+  RTL_AEN_IDLE();       // take back address enable
216
+}
217
+
218
+// read a RTL8019 register multiple times and throw away data
219
+extern inline void RtlReadRegMulti(unsigned char reg, unsigned short cnt)       // force 
220
+                                                                                // inlining 
221
+                                                                                // by 
222
+                                                                                // using 
223
+                                                                                // "extern"
224
+{
225
+  BUS_ADDR = reg;       // output address
226
+  RTL_AEN_ACT();        // set address enable
227
+  for (; cnt > 0; cnt--) {
228
+    BUS_READ_ACT();     // activate read signal
229
+    nop();
230
+    nop();
231
+    BUS_READ_IDLE();    // take back read signal
232
+  }
233
+  RTL_AEN_IDLE();       // take back address enable
234
+}
235
+
236
+// reinitialization timeout counter
237
+unsigned char RtlReinitTimeout = 0;
238
+
239
+// emulate eeprom containing RTL8019AS configuration
240
+static void RtlEmulateEeprom(void)
241
+{
242
+  static const unsigned char timeout = 150;
243
+
244
+  unsigned int addr, data, entropy;
245
+  unsigned char t, i;
246
+
247
+  while (1) {
248
+    entropy = 0;
249
+
250
+    // wait for CS HIGH
251
+    for (t = 0; bit_is_clear(RTL_PIN_EECS, RTL_BIT_EECS); t++)
252
+      if (t >= timeout)
253
+        return;
254
+    entropy += t;
255
+
256
+    // ignore one clock
257
+    // wait for clock HIGH
258
+    for (t = 0; bit_is_clear(RTL_PIN_EESK, RTL_BIT_EESK); t++)
259
+      if (t >= timeout)
260
+        return;
261
+    entropy += t;
262
+    // wait for clock LOW
263
+    for (t = 0; bit_is_set(RTL_PIN_EESK, RTL_BIT_EESK); t++)
264
+      if (t >= timeout)
265
+        return;
266
+    entropy += t;
267
+
268
+    // shift in address
269
+    addr = 0;
270
+    for (i = 0; i < 9; i++) {
271
+      // wait for clock HIGH
272
+      for (t = 0; bit_is_clear(RTL_PIN_EESK, RTL_BIT_EESK); t++)
273
+        if (t >= timeout)
274
+          return;
275
+      entropy += t;
276
+      // read next bit
277
+      addr <<= 1;
278
+      if (bit_is_set(RTL_PIN_EEDI, RTL_BIT_EEDI))
279
+        addr |= 0x01;
280
+      // wait for clock LOW
281
+      for (t = 0; bit_is_set(RTL_PIN_EESK, RTL_BIT_EESK); t++)
282
+        if (t >= timeout)
283
+          return;
284
+      entropy += t;
285
+    }
286
+
287
+    // get data
288
+    switch (addr) {
289
+      // CONFIG 3 = FUDUP,LEDS0; CONFIG 4 = -
290
+    case 0x181:
291
+      data = 0x0050;
292
+      break;
293
+      // output zero by default (as if no EEPROM is connected)
294
+    default:
295
+      data = 0x0000;
296
+      break;
297
+    }
298
+
299
+    // shift out data
300
+    for (i = 0; i < 16; i++) {
301
+      // wait for clock HIGH
302
+      for (t = 0; bit_is_clear(RTL_PIN_EESK, RTL_BIT_EESK); t++)
303
+        if (t >= timeout)
304
+          return;
305
+      entropy += t;
306
+      // write next bit
307
+      if (data & 0x8000)
308
+        bit_set(RTL_PORT_EEDO, RTL_BIT_EEDO);
309
+      else
310
+        bit_clear(RTL_PORT_EEDO, RTL_BIT_EEDO);
311
+      data <<= 1;
312
+      // wait for clock LOW
313
+      for (t = 0; bit_is_set(RTL_PIN_EESK, RTL_BIT_EESK); t++)
314
+        if (t >= timeout)
315
+          return;
316
+      entropy += t;
317
+    }
318
+
319
+    // wait for CS LOW
320
+    for (t = 0; bit_is_set(RTL_PIN_EECS, RTL_BIT_EECS); t++)
321
+      if (t >= timeout)
322
+        return;
323
+    entropy += t;
324
+
325
+    // pass on entropy to randomness generator
326
+    RandomProvideEntropy((unsigned char)entropy);
327
+
328
+  }     // while( 1 )
329
+}
330
+
331
+// initialize
332
+void RtlInit(void)      // (extern)
333
+{
334
+  unsigned char i;
335
+  unsigned short j;
336
+
337
+  // setup ports
338
+  bit_clear(RTL_PORT_INT, RTL_BIT_INT); // pull-up of interrupt pin off
339
+  bit_clear(RTL_DDR_INT, RTL_BIT_INT);  // interrupt pin to input
340
+  bit_set(RTL_PORT_nAEN, RTL_BIT_nAEN); // address enable pin to HIGH
341
+  bit_set(RTL_DDR_nAEN, RTL_BIT_nAEN);  // address enable pin to output
342
+  bit_set(RTL_PORT_RST, RTL_BIT_RST);   // reset pin to HIGH
343
+  bit_set(RTL_DDR_RST, RTL_BIT_RST);    // reset pin to output
344
+
345
+  // configuration of EEPROM emulation
346
+  bit_clear(RTL_PORT_EECS, RTL_BIT_EECS);       // EECS := input, no pull-up
347
+  bit_clear(RTL_DDR_EECS, RTL_BIT_EECS);
348
+  bit_clear(RTL_PORT_EESK, RTL_BIT_EESK);       // EESK := input, no pull-up
349
+  bit_clear(RTL_DDR_EESK, RTL_BIT_EESK);
350
+  bit_clear(RTL_PORT_EEDI, RTL_BIT_EEDI);       // EEDI := input, no pull-up
351
+  bit_clear(RTL_DDR_EEDI, RTL_BIT_EEDI);
352
+  bit_clear(RTL_PORT_EEDO, RTL_BIT_EEDO);       // EEDO := output, LOW
353
+  bit_set(RTL_DDR_EEDO, RTL_BIT_EEDO);
354
+
355
+  // take back reset
356
+  for (i = 0; i < 10; i++)
357
+    nop();
358
+  RTL_RESET_IDLE();
359
+  RtlEmulateEeprom();
360
+  for (j = 0; j < 5000; j++)
361
+    nop();
362
+
363
+  // clear software reset
364
+  RtlReadReg(RTL_REG_RSTPORT, &i);
365
+  RtlWriteReg(RTL_REG_RSTPORT, 0xFF);
366
+  for (i = 0; i < 100; i++)
367
+    nop();
368
+
369
+  // do the same as in reinitialization
370
+  RtlReinit();
371
+}
372
+
373
+// re-initialize RT8019 (i.e. if MAC changed)
374
+void RtlReinit(void)    // (extern)
375
+{
376
+  unsigned char i, j;
377
+
378
+  // stop RTL8019
379
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STP | 1 << RTL_CR_RD2);
380
+  for (i = 0; i < 100; i++)
381
+    nop();
382
+
383
+  // output RTL8019 ID
384
+  RtlReadReg(RTL_REG_ID0, &i);
385
+  RtlReadReg(RTL_REG_ID1, &j);
386
+  debug_rtl8019_printf("RTL8019AS (re)init ID=0x%02X,0x%02X", i, j);
387
+
388
+  // set up RTL8019
389
+  RtlWriteReg(RTL_REG_DCR, RTL_VAL_DCR);
390
+  RtlWriteReg(RTL_REG_RBCR0, 0x00);
391
+  RtlWriteReg(RTL_REG_RBCR1, 0x00);
392
+  RtlWriteReg(RTL_REG_RCR, 0x04);
393
+  RtlWriteReg(RTL_REG_TPSR, RTL_VAL_RXSTART);
394
+  RtlWriteReg(RTL_REG_TCR, 0x02);
395
+  RtlWriteReg(RTL_REG_PSTART, RTL_VAL_RXSTART);
396
+  RtlWriteReg(RTL_REG_BNRY, RTL_VAL_RXSTART);
397
+  RtlWriteReg(RTL_REG_PSTOP, RTL_VAL_RXSTOP);
398
+  RtlWriteReg(RTL_REG_CR,
399
+              1 << RTL_CR_STP | 1 << RTL_CR_RD2 | 1 << RTL_CR_PS0);
400
+  for (i = 0; i < 100; i++)
401
+    nop();
402
+
403
+  // write MAC to chip
404
+  RtlWriteReg(RTL_REG_CURR, RTL_VAL_RXSTART);
405
+  for (i = 0; i < 6; i++)
406
+    RtlWriteReg(RTL_REG_PAR0 + i, ConfigMac[i]);
407
+
408
+  // go on with intializing
409
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STP | 1 << RTL_CR_RD2);
410
+  RtlWriteReg(RTL_REG_DCR, RTL_VAL_DCR);
411
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STA | 1 << RTL_CR_RD2);
412
+  RtlWriteReg(RTL_REG_ISR, 1 << RTL_ISR_PRX | 1 << RTL_ISR_PTX |
413
+              1 << RTL_ISR_RXE | 1 << RTL_ISR_TXE |
414
+              1 << RTL_ISR_OVW | 1 << RTL_ISR_CNT |
415
+              1 << RTL_ISR_RDC | 1 << RTL_ISR_RST);
416
+  RtlWriteReg(RTL_REG_IMR, RTL_VAL_IMR);
417
+  RtlWriteReg(RTL_REG_TCR, RTL_VAL_TCR);
418
+
419
+  // start RTL8019
420
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STA | 1 << RTL_CR_RD2);
421
+
422
+  // clear reinitialization timeout
423
+  RtlReinitTimeout = 0;
424
+}
425
+
426
+// tick procedure - call every 200ms
427
+void RtlTick200(void)   // (extern)
428
+{
429
+  // increment reinitialization timeout counter
430
+  RtlReinitTimeout++;
431
+
432
+  // reinitialization timeout
433
+  if (RtlReinitTimeout >= RtlReinitTimeoutTicks)
434
+    // reinitialize RTL8019 (resets reinitialization timeout)
435
+    RtlReinit();
436
+}
437
+
438
+// fetch and process a received packet
439
+static inline void RtlRecv(void)
440
+{
441
+  unsigned short PacketLen;
442
+  unsigned char Packet[RTL_MRU];
443
+
444
+  // fetch packet from RTL8019
445
+  PacketLen = count(Packet);
446
+  RtlReadFrame((unsigned char *)Packet, &PacketLen);
447
+
448
+  // pass packet on to ethernet
449
+  EthernetRecv(Packet, PacketLen);
450
+}
451
+
452
+// task function to do the work - call from main loop
453
+void RtlTask(void)      // (extern)
454
+{
455
+  unsigned char isr, bnry, curr;
456
+
457
+  // read interrupt register
458
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STA | 1 << RTL_CR_RD2);
459
+  RtlReadReg(RTL_REG_ISR, &isr);
460
+  // a packet was received
461
+  if (isr & 1 << RTL_ISR_PRX)
462
+    // use current timestamp for generating some entropy
463
+    TimingEntropy();
464
+
465
+  // check if receive ring buffer is not empty
466
+  RtlReadReg(RTL_REG_BNRY, &bnry);
467
+  RtlWriteReg(RTL_REG_CR,
468
+              1 << RTL_CR_STA | 1 << RTL_CR_RD2 | 1 << RTL_CR_PS0);
469
+  RtlReadReg(RTL_REG_CURR, &curr);
470
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STA | 1 << RTL_CR_RD2);
471
+  if (bnry != curr)
472
+    // fetch and process a single received packet
473
+    RtlRecv();
474
+
475
+  // reset interrupt bits of RTL8019
476
+  RtlWriteReg(RTL_REG_ISR, 1 << RTL_ISR_PRX | 1 << RTL_ISR_PTX |
477
+              1 << RTL_ISR_RXE | 1 << RTL_ISR_TXE |
478
+              1 << RTL_ISR_OVW | 1 << RTL_ISR_CNT |
479
+              1 << RTL_ISR_RDC | 1 << RTL_ISR_RST);
480
+
481
+  // put RTL8019 in default state (default page selected, ...)
482
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STA | 1 << RTL_CR_RD2);
483
+
484
+  // clear reinitialization timeout
485
+  RtlReinitTimeout = 0;
486
+}
487
+
488
+// write an ethernet frame to the RTL8019
489
+void RtlWriteFrame(unsigned char *pData, unsigned short Length) // (extern)
490
+{
491
+  unsigned char val;
492
+
493
+  debug_rtl8019_printf("send len=%u", Length);
494
+
495
+  // initialize RTL8019 to transmit
496
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STA | 1 << RTL_CR_RD2);
497
+  RtlWriteReg(RTL_REG_TPSR, RTL_VAL_TXSTART);
498
+  RtlWriteReg(RTL_REG_RSAR0, 0x00);
499
+  RtlWriteReg(RTL_REG_RSAR1, RTL_VAL_TXSTART);
500
+  RtlWriteReg(RTL_REG_ISR, 1 << RTL_ISR_PRX | 1 << RTL_ISR_PTX |
501
+              1 << RTL_ISR_RXE | 1 << RTL_ISR_TXE |
502
+              1 << RTL_ISR_OVW | 1 << RTL_ISR_CNT |
503
+              1 << RTL_ISR_RDC | 1 << RTL_ISR_RST);
504
+  if (Length < 0x3C)    // minimal length is 60 bytes
505
+  {
506
+    RtlWriteReg(RTL_REG_RBCR0, 0x3C);
507
+    RtlWriteReg(RTL_REG_RBCR1, 0x00);
508
+  } else {
509
+    RtlWriteReg(RTL_REG_RBCR0, (unsigned char)Length);
510
+    RtlWriteReg(RTL_REG_RBCR1, (unsigned char)(Length >> 8));
511
+  }
512
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_STA | 1 << RTL_CR_RD1);
513
+
514
+  // write data to RTL8019
515
+  RtlWriteRegBuf(RTL_REG_RDMAPORT, pData, Length);
516
+  if (Length < 0x3C)    // padding
517
+    RtlWriteRegConst(RTL_REG_RDMAPORT, 0x00, 0x3C - Length);
518
+
519
+  // wait for RTL8019
520
+  do {
521
+    RtlReadReg(RTL_REG_ISR, &val);
522
+  }
523
+  while ((val & 1 << RTL_ISR_RDC) == 0x00);
524
+
525
+  // start transmission
526
+  if (Length < 0x3C)    // minimal length is 60 bytes
527
+  {
528
+    RtlWriteReg(RTL_REG_TBCR0, 0x3C);
529
+    RtlWriteReg(RTL_REG_TBCR1, 0x00);
530
+  } else {
531
+    RtlWriteReg(RTL_REG_TBCR0, (unsigned char)Length);
532
+    RtlWriteReg(RTL_REG_TBCR1, (unsigned char)(Length >> 8));
533
+  }
534
+  RtlWriteReg(RTL_REG_CR, 1 << RTL_CR_TXP | 1 << RTL_CR_RD2);
535
+}
536
+
537
+// read an ethernet frame from the RTL8019
538
+// *pLength must be initialized to the buffer size
539
+void RtlReadFrame(unsigned char *pData, unsigned short *pLength)        // (extern)
540
+{
541
+  unsigned char tmp1, tmp2;
542
+  unsigned short read_len, len, cnt;
543
+
544
+  // get size of received packet
545
+  RtlWriteReg(RTL_REG_CR,
546
+              1 << RTL_CR_STA | 1 << RTL_CR_RD0 | 1 << RTL_CR_RD1);
547
+  RtlReadReg(RTL_REG_RDMAPORT, &tmp1);
548
+  RtlReadReg(RTL_REG_RDMAPORT, &tmp1);
549
+  RtlReadReg(RTL_REG_RDMAPORT, &tmp1);
550
+  RtlReadReg(RTL_REG_RDMAPORT, &tmp2);
551
+  read_len = ((unsigned short)tmp2 << 8 | (unsigned short)tmp1);
552
+
553
+  // subtract length of CRC (4 bytes)
554
+  len = read_len < 4 ? 0 : read_len - 4;
555
+
556
+  debug_rtl8019_printf("recv len=%u", len);
557
+
558
+  // read as much data as possible into buffer
559
+  cnt = min(len, *pLength);
560
+  RtlReadRegBuf(RTL_REG_RDMAPORT, pData, cnt);
561
+  *pLength = cnt;
562
+
563
+  // get rest of data (rest of real data that did not fit into buffer, CRC)
564
+  if (read_len > cnt)
565
+    RtlReadRegMulti(RTL_REG_RDMAPORT, read_len - cnt);
566
+}
... ...
@@ -0,0 +1,28 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_rtl8019
7
+#define INC_rtl8019
8
+
9
+// initialize
10
+extern void RtlInit(void);
11
+
12
+// re-initialize RT8019 (i.e. if MAC changed)
13
+extern void RtlReinit(void);
14
+
15
+// tick procedure - call every 200ms
16
+extern void RtlTick200(void);
17
+
18
+// task function to do the work - call from main loop
19
+extern void RtlTask(void);
20
+
21
+// write an ethernet frame to the RTL8019
22
+extern void RtlWriteFrame(unsigned char *pData, unsigned short Length);
23
+
24
+// read an ethernet frame from the RTL8019
25
+// *pLength must be initialized to the buffer size
26
+extern void RtlReadFrame(unsigned char *pData, unsigned short *pLength);
27
+
28
+#endif // #ifndef INC_rtl8019
... ...
@@ -0,0 +1,15 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/io.h>
7
+#include "ser62500.h"
8
+
9
+// send data (in network byte order) with 62500 baud in 9N2 protocol
10
+void Ser62500Send9N2(unsigned char *pData, unsigned short Length)       // (extern)
11
+{
12
+  unsigned short i;
13
+  for (i = 0; i + 1 < Length; i += 2)
14
+    Ser62500Out9N2(pData[i] << 8 | pData[i + 1]);
15
+}
... ...
@@ -0,0 +1,15 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_ser62500
7
+#define INC_ser62500
8
+
9
+// send data (in network byte order) with 62500 baud in 9N2 protocol
10
+extern void Ser62500Send9N2(unsigned char *pData, unsigned short Length);
11
+
12
+// output a data item with 62500 baud in 9N2 protocol
13
+extern void Ser62500Out9N2(unsigned short item);
14
+
15
+#endif // #ifdef INC_ser62500
... ...
@@ -0,0 +1,129 @@
1
+; 8BitAmEthernet - serial output 250kbps
2
+; version 0.4.0 date 2006-04-13
3
+; Copyright 2005-2006 Stefan Schuermans <1stein@schuermans.info>
4
+; Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
5
+
6
+
7
+#include <avr/io.h>
8
+
9
+.section .text
10
+
11
+
12
+
13
+; output  0 = PC0
14
+
15
+
16
+
17
+; output a data item with 62500 baud in 9N2 protocol
18
+; extern void Ser62500Out9N2( unsigned short item );
19
+; extern void SerialOutput( unsigned char value );
20
+.global Ser62500Out9N2
21
+.func Ser62500Out9N2
22
+Ser62500Out9N2:
23
+	push	R16
24
+
25
+	; parameters: R25:R24=value
26
+
27
+	cli
28
+
29
+	ldi	R16,0xFF			; PORTC := output
30
+	sts	DDRC,R16
31
+
32
+	ldi	R16,0x00			; start bit
33
+	sts	PORTC,R16
34
+
35
+	rcall	wait251
36
+
37
+	ldi	R16,0x00			; bit 0
38
+	sbrc	R24,0
39
+	ldi	R16,0xFF
40
+	sts	PORTC,R16
41
+
42
+	rcall	wait251
43
+
44
+	ldi	R16,0x00			; bit 1
45
+	sbrc	R24,1
46
+	ldi	R16,0xFF
47
+	sts	PORTC,R16
48
+
49
+	rcall	wait251
50
+
51
+	ldi	R16,0x00			; bit 2
52
+	sbrc	R24,2
53
+	ldi	R16,0xFF
54
+	sts	PORTC,R16
55
+
56
+	rcall	wait251
57
+
58
+	ldi	R16,0x00			; bit 3
59
+	sbrc	R24,3
60
+	ldi	R16,0xFF
61
+	sts	PORTC,R16
62
+
63
+	rcall	wait251
64
+
65
+	ldi	R16,0x00			; bit 4
66
+	sbrc	R24,4
67
+	ldi	R16,0xFF
68
+	sts	PORTC,R16
69
+
70
+	rcall	wait251
71
+
72
+	ldi	R16,0x00			; bit 5
73
+	sbrc	R24,5
74
+	ldi	R16,0xFF
75
+	sts	PORTC,R16
76
+
77
+	rcall	wait251
78
+
79
+	ldi	R16,0x00			; bit 6
80
+	sbrc	R24,6
81
+	ldi	R16,0xFF
82
+	sts	PORTC,R16
83
+
84
+	rcall	wait251
85
+
86
+	ldi	R16,0x00			; bit 7
87
+	sbrc	R24,7
88
+	ldi	R16,0xFF
89
+	sts	PORTC,R16
90
+
91
+	rcall	wait251
92
+
93
+	ldi	R16,0x00			; bit 8
94
+	sbrc	R25,0
95
+	ldi	R16,0xFF
96
+	sts	PORTC,R16
97
+
98
+	rcall	wait253
99
+
100
+	ldi	R16,0xFF			; 2 stop bits
101
+	sts	PORTC,R16
102
+
103
+	rcall	wait256
104
+	rcall	wait256
105
+
106
+	sei
107
+
108
+	pop	R16
109
+	ret
110
+.endfunc
111
+
112
+
113
+
114
+; wait 256/253/251 cycles (including rcall and ret)
115
+wait256:
116
+	nop					; 3 cycles
117
+	nop
118
+	nop
119
+wait253:
120
+	nop					; 2 cycles
121
+	nop
122
+wait251:
123
+	ldi	R16, 81				; 1 cycle, N := 81
124
+wait_loop:
125
+	dec	R16				; N cycles
126
+	brne	wait_loop			; 2N-1 cycles
127
+	nop					; 1 cycle
128
+	ret					; 7 cycles (including rcall)
129
+
... ...
@@ -0,0 +1,62 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/io.h>
7
+
8
+#include "macros.h"
9
+#include "status.h"
10
+
11
+// IO pins of bus
12
+#define STATUS_DDR (DDRE)
13
+#define STATUS_PORT (PORTE)
14
+#define STATUS_BIT (2)
15
+
16
+// status information
17
+char StatusInfoCfPresent = 0;   // presence of working compact flash card
18
+                                // (boolean) (extern)
19
+
20
+// number of times to blink status LED
21
+#define StatusBlinkCntIdle (1)
22
+#define StatusBlinkCntIdleWithCf (2)
23
+#define StatusBlinkCntWorking (3)
24
+#define StatusBlinkCntMax (3)
25
+unsigned char StatusBlinkCnt = StatusBlinkCntIdle;
26
+
27
+// interval counter for blinking status LED
28
+unsigned char StatusBlinkInterval = 0;
29
+
30
+// initialize
31
+void StatusInit(void)
32
+{
33
+  // set up IO pin of status LED as output
34
+  bit_clear(STATUS_PORT, STATUS_BIT);
35
+  bit_set(STATUS_DDR, STATUS_BIT);
36
+}
37
+
38
+// tick procedure - call every 200ms
39
+void StatusTick200(void)
40
+{
41
+  // turn on status LED only in even intervals and if not yet blinked
42
+  // StatusBlinkCnt times
43
+  if ((StatusBlinkInterval & 0x01) == 0
44
+      && StatusBlinkInterval >> 1 < StatusBlinkCnt)
45
+    bit_set(STATUS_PORT, STATUS_BIT);
46
+  else
47
+    bit_clear(STATUS_PORT, STATUS_BIT);
48
+
49
+  // next interval
50
+  StatusBlinkInterval++;
51
+
52
+  // blink cycle finished
53
+  if (StatusBlinkInterval >> 1 > StatusBlinkCntMax) {
54
+    StatusBlinkInterval = 0;
55
+
56
+    // set new blink count depending on status information
57
+    if (StatusInfoCfPresent)
58
+      StatusBlinkCnt = StatusBlinkCntIdleWithCf;
59
+    else
60
+      StatusBlinkCnt = StatusBlinkCntIdle;
61
+  }
62
+}
... ...
@@ -0,0 +1,19 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_status
7
+#define INC_status
8
+
9
+// status information
10
+extern char StatusInfoCfPresent;        // presence of working compact flash
11
+                                        // card (boolean)
12
+
13
+// initialize
14
+extern void StatusInit(void);
15
+
16
+// tick procedure - call every 200ms
17
+extern void StatusTick200(void);
18
+
19
+#endif // #ifdef INC_status
... ...
@@ -0,0 +1,1188 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <stdio.h>
7
+
8
+#include "config.h"
9
+#include "checksum.h"
10
+#include "debug.h"
11
+#include "ethernet.h"
12
+#include "http.h"
13
+#include "ip.h"
14
+#include "macros.h"
15
+#include "nethelp.h"
16
+#include "random.h"
17
+#include "tcp.h"
18
+
19
+#define TCP_URG 0x20
20
+#define TCP_ACK 0x10
21
+#define TCP_PSH 0x08
22
+#define TCP_RST 0x04
23
+#define TCP_SYN 0x02
24
+#define TCP_FIN 0x01
25
+#define TCP_FLAGS 0x3F
26
+
27
+#define TcpResendTicks 5        // time after which to resend a packet not
28
+                                // ACKed (in 200ms steps, max. 255)
29
+#define TcpTimeWaitTicks 20     // time to wait in TIME_WAIT state (in 200ms
30
+                                // steps, max. 255)
31
+#define TcpTimeoutTicks 50      // maximum idle time of connection before it
32
+                                // is reset (in 200ms steps, max. 255)
33
+#define TcpMaxLifeTimeTicks 150 // maximum lifetime of connection before it
34
+                                // is reset (in 200ms steps, max. 255)
35
+
36
+// TCP connections
37
+struct TcpConnection TcpConns[8];
38
+
39
+// initialize
40
+void TcpInit(void)      // (extern)
41
+{
42
+  unsigned char i;
43
+
44
+  // set all connections to closed
45
+  for (i = 0; i < count(TcpConns); i++)
46
+    TcpConns[i].State = TCP_CLOSED;
47
+}
48
+
49
+// send a TCP packet
50
+// pData must point to a struct TcpPacket with TcpHdr.SrcPort,
51
+// TcpHdr.DestPort,
52
+// TcpHdr.SeqNo, TcpHdr.AckNo, TcpHdr.WndSz and IpHdr.Dest already
53
+// initialized
54
+static void TcpSendPacket(unsigned char *pData, unsigned short Length,
55
+                          unsigned char optLen, unsigned char flags)
56
+{
57
+  struct TcpPacket *pTcpPack;
58
+  unsigned int chk;
59
+
60
+  // packet too short
61
+  if (Length < sizeof(struct TcpPacket) + optLen)
62
+    return;
63
+
64
+  // convert pointer to UDP packet
65
+  // (this saves us from always casting pData)
66
+  pTcpPack = (struct TcpPacket *)pData;
67
+
68
+  debug_tcp_printf("send src=%u dest=%u flags=%s%s%s%s%s%s len=%u",
69
+                   ntohs(pTcpPack->TcpHdr.SrcPort),
70
+                   ntohs(pTcpPack->TcpHdr.DestPort),
71
+                   flags & TCP_URG ? "U" : "",
72
+                   flags & TCP_ACK ? "A" : "",
73
+                   flags & TCP_PSH ? "P" : "",
74
+                   flags & TCP_RST ? "R" : "",
75
+                   flags & TCP_SYN ? "S" : "",
76
+                   flags & TCP_FIN ? "F" : "", Length);
77
+
78
+  // fill in header values
79
+  pTcpPack->TcpHdr.Ofs_Flags =
80
+      htons((unsigned short)((optLen + 23) & 0x3C) << 10 |
81
+            (unsigned short)(flags & TCP_FLAGS));
82
+  pTcpPack->TcpHdr.Chk = 0x0000;
83
+  pTcpPack->TcpHdr.UrgentPtr = 0x0000;
84
+  ip_cpy(pTcpPack->IpHdr.Src, ConfigIp);        // put IP already here into
85
+                                                // IP header
86
+  // because it is needed for calculation of UDP checksum
87
+
88
+  // generate checksum
89
+  chk = Checksum((unsigned char *)&pTcpPack->IpHdr.Src,
90
+                 Length - sizeof(struct EthernetHeader) -
91
+                 sizeof(struct IpHeader) + 8, 0x0006,
92
+                 Length - sizeof(struct EthernetHeader) -
93
+                 sizeof(struct IpHeader));
94
+  pTcpPack->TcpHdr.Chk = htons(chk);
95
+
96
+  // send TCP packet
97
+  pTcpPack->IpHdr.Proto = 0x06; // TCP
98
+  IpSend(pData, Length);
99
+}
100
+
101
+// send an empty segment
102
+static void TcpEmptySegment(struct TcpConnection *pConn, unsigned long seq,
103
+                            unsigned long ack, unsigned char flags)
104
+{
105
+  struct TcpPacket EsPack;
106
+
107
+  // send empty TCP segment
108
+  EsPack.TcpHdr.SrcPort = htons(pConn->LocalPort);
109
+  EsPack.TcpHdr.DestPort = htons(pConn->RemotePort);
110
+  EsPack.TcpHdr.SeqNo = htonl(seq);
111
+  EsPack.TcpHdr.AckNo = htonl(ack);
112
+  EsPack.TcpHdr.WndSz = htons(pConn->RcvWnd);
113
+  ip_cpy(EsPack.IpHdr.Dest, pConn->RemoteIp);
114
+  TcpSendPacket((unsigned char *)&EsPack, sizeof(EsPack), 0, flags);
115
+  return;
116
+}
117
+
118
+// send a SYN segment (empty with MSS option set)
119
+static void TcpSynSegment(struct TcpConnection *pConn, unsigned long seq,
120
+                          unsigned long ack, unsigned char flags)
121
+{
122
+  struct {
123
+    struct TcpPacket Tcp;
124
+    struct {
125
+      unsigned char Kind, Len;
126
+      unsigned short Mss;
127
+    } MssOpt;
128
+  } Pack;
129
+
130
+  // send empty TCP segment with MSS
131
+  Pack.Tcp.TcpHdr.SrcPort = htons(pConn->LocalPort);
132
+  Pack.Tcp.TcpHdr.DestPort = htons(pConn->RemotePort);
133
+  Pack.Tcp.TcpHdr.SeqNo = htonl(seq);
134
+  Pack.Tcp.TcpHdr.AckNo = htonl(ack);
135
+  Pack.Tcp.TcpHdr.WndSz = htons(pConn->RcvWnd);
136
+  ip_cpy(Pack.Tcp.IpHdr.Dest, pConn->RemoteIp);
137
+  Pack.MssOpt.Kind = 2;
138
+  Pack.MssOpt.Len = 4;
139
+  Pack.MssOpt.Mss = htons(256);
140
+  TcpSendPacket((unsigned char *)&Pack, sizeof(Pack), sizeof(Pack.MssOpt),
141
+                flags);
142
+  return;
143
+}
144
+
145
+// send a data segment
146
+static void TcpSendDataSegment(unsigned char connNo,
147
+                               struct TcpConnection *pConn, char needSendAck)
148
+{
149
+  unsigned long sendDataLenL;
150
+  unsigned short sendDataLen, len;
151
+  struct {
152
+    struct TcpPacket Tcp;
153
+    unsigned char Data[256];    // do not use larger segments to save stack
154
+                                // memory
155
+  } Packet;
156
+
157
+  // if outbound connection is not closed yet
158
+  if (pConn->State == TCP_ESTAB || pConn->State == TCP_CLOSE_WAIT) {
159
+    // get maximum number of bytes that might be sent in this segment
160
+    sendDataLenL =
161
+        (unsigned long)pConn->SndWnd - (pConn->SndNxt - pConn->SndUna);
162
+    if ((signed long)sendDataLenL < 0)  // just to be on the safe side - this 
163
+                                        // should never happen
164
+      sendDataLen = 0;
165
+    sendDataLen =
166
+        (unsigned short)min(sendDataLenL, (unsigned long)pConn->Mss);
167
+    sendDataLen = min(sendDataLen, sizeof(Packet.Data));
168
+    // get data to send from user
169
+    if (sendDataLen > 0) {
170
+      debug_tcp_printf("notify send no=%u pos=%lu max_len=%u",
171
+                       connNo, pConn->SndNxt - (pConn->Iss + 1), sendDataLen);
172
+      len =
173
+          pConn->Notify->Send(connNo, pConn->SndNxt - (pConn->Iss + 1),
174
+                              Packet.Data, sendDataLen);
175
+      if (len > sendDataLen)    // returned 0xFFFF (or any number too large)
176
+                                // to close connection
177
+      {
178
+        debug_tcp_printf("notify send no=%u close", connNo);
179
+        TcpEmptySegment(pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK);        // send 
180
+                                                                                        // TCP 
181
+                                                                                        // FIN
182
+        pConn->SndNxt++;
183
+        pConn->State = TCP_FIN_WAIT_1;  // go to state FIN-WAIT-1
184
+        debug_tcp_printf("notify close no=%u", connNo);
185
+        pConn->Notify->Close(connNo);   // signal "connection closed" to user
186
+        return;
187
+      }
188
+      debug_tcp_printf("notify send no=%u len=%u", connNo, len);
189
+      sendDataLen = len;
190
+    }
191
+  }
192
+  // if outbound connection is already closed
193
+  else
194
+    // do not send data
195
+    sendDataLen = 0;
196
+
197
+  // send a segment if data is available or an ACK needs to be sent
198
+  if (sendDataLen > 0 || needSendAck) {
199
+    // send TCP segment
200
+    Packet.Tcp.TcpHdr.SrcPort = htons(pConn->LocalPort);
201
+    Packet.Tcp.TcpHdr.DestPort = htons(pConn->RemotePort);
202
+    Packet.Tcp.TcpHdr.SeqNo = htonl(pConn->SndNxt);
203
+    Packet.Tcp.TcpHdr.AckNo = htonl(pConn->RcvNxt);
204
+    Packet.Tcp.TcpHdr.WndSz = htons(pConn->RcvWnd);
205
+    ip_cpy(Packet.Tcp.IpHdr.Dest, pConn->RemoteIp);
206
+    TcpSendPacket((unsigned char *)&Packet,
207
+                  sizeof(struct TcpPacket) + sendDataLen, 0,
208
+                  sendDataLen > 0 ? TCP_ACK | TCP_PSH : TCP_ACK);
209
+    pConn->SndNxt += sendDataLen;
210
+  }
211
+}
212
+
213
+// tick procedure - call every 200ms
214
+void TcpTick200(void)   // (extern)
215
+{
216
+  unsigned char i, MaxTicks;
217
+
218
+  // for all active connections
219
+  for (i = 0; i < count(TcpConns); i++) {
220
+
221
+    if (TcpConns[i].State != TCP_CLOSED) {
222
+      // increase normal timer
223
+      TcpConns[i].Ticks++;
224
+
225
+      // get maximum value for normal timer
226
+      MaxTicks =
227
+          TcpConns[i].State ==
228
+          TCP_TIME_WAIT ? TcpTimeWaitTicks : TcpResendTicks;
229
+      // normal timer elapsed
230
+      if (TcpConns[i].Ticks >= MaxTicks) {
231
+        // reset normal timer
232
+        TcpConns[i].Ticks = 0;
233
+
234
+        // different behaviour in different states
235
+        switch (TcpConns[i].State) {
236
+
237
+        case TCP_SYN_RCVD:
238
+          // resend SYN,ACK segment
239
+          TcpSynSegment(&TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt,
240
+                        TCP_SYN | TCP_ACK);
241
+          TcpConns[i].SndNxt = TcpConns[i].SndUna + 1;
242
+          break;
243
+
244
+        case TCP_SYN_SENT:
245
+          // resend SYN segment
246
+          TcpSynSegment(&TcpConns[i], TcpConns[i].SndUna, 0, TCP_SYN);
247
+          TcpConns[i].SndNxt = TcpConns[i].SndUna + 1;
248
+          break;
249
+
250
+        case TCP_ESTAB:
251
+        case TCP_CLOSE_WAIT:
252
+          // if something is not yet ACKed
253
+          if ((long)(TcpConns[i].SndUna - TcpConns[i].SndNxt) < 0) {
254
+            // resend data segment
255
+            TcpConns[i].SndNxt = TcpConns[i].SndUna;    // some kind of "go
256
+                                                        // back N"
257
+            // BUG: this is not really "go back N"
258
+            // according to RFC793, every segment sent and not acknowledged
259
+            // has to be stored
260
+            // in the resend queue until is is acknowledged
261
+            // but this is not possible on a microcontroller with 4kB of RAM
262
+            TcpSendDataSegment(i, &TcpConns[i], 0);
263
+          }
264
+          break;
265
+
266
+        case TCP_FIN_WAIT_1:
267
+        case TCP_CLOSING:
268
+        case TCP_LAST_ACK:
269
+          // resend FIN segment
270
+          TcpEmptySegment(&TcpConns[i], TcpConns[i].SndUna,
271
+                          TcpConns[i].RcvNxt, TCP_FIN | TCP_ACK);
272
+          TcpConns[i].SndNxt = TcpConns[i].SndUna + 1;
273
+          break;
274
+
275
+        case TCP_TIME_WAIT:
276
+          // close connection, free TCB
277
+          TcpConns[i].State = TCP_CLOSED;
278
+          break;
279
+
280
+        }       // switch( TcpConns[i].State )
281
+
282
+      } // if( TcpConns[i].Ticks >= ...
283
+
284
+    }   // if( TcpConns[i].State != ...
285
+
286
+    if (TcpConns[i].State != TCP_CLOSED) {
287
+      // increase timeout timer
288
+      TcpConns[i].Timeout++;
289
+
290
+      // timeout timer elapsed
291
+      if (TcpConns[i].Timeout >= TcpTimeoutTicks) {
292
+        // send a RST segment
293
+        TcpEmptySegment(&TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt,
294
+                        TCP_RST);
295
+        // depending on state ...
296
+        switch (TcpConns[i].State) {
297
+        case TCP_SYN_RCVD:
298
+        case TCP_ESTAB:
299
+        case TCP_CLOSE_WAIT:
300
+          TcpConns[i].State = TCP_CLOSED;       // close connection
301
+          debug_tcp_printf("notify close no=%u", i);
302
+          TcpConns[i].Notify->Close(i); // tell user that connection was
303
+                                        // closed
304
+          break;
305
+        default:
306
+          TcpConns[i].State = TCP_CLOSED;       // close connection
307
+        }
308
+
309
+      } // if( TcpConns[i].Timeout >= ...
310
+
311
+    }   // if( TcpConns[i].State != ...
312
+
313
+    if (TcpConns[i].State != TCP_CLOSED) {
314
+      // increase lifetime timer
315
+      TcpConns[i].LifeTime++;
316
+
317
+      // lifetime timer elapsed
318
+      // - connections may not last forever - even not with traffic on them
319
+      if (TcpConns[i].LifeTime >= TcpMaxLifeTimeTicks) {
320
+        // send a RST segment
321
+        TcpEmptySegment(&TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt,
322
+                        TCP_RST);
323
+        // depending on state ...
324
+        switch (TcpConns[i].State) {
325
+        case TCP_SYN_RCVD:
326
+        case TCP_ESTAB:
327
+        case TCP_CLOSE_WAIT:
328
+          TcpConns[i].State = TCP_CLOSED;       // close connection
329
+          debug_tcp_printf("notify close no=%u", i);
330
+          TcpConns[i].Notify->Close(i); // tell user that connection was
331
+                                        // closed
332
+          break;
333
+        default:
334
+          TcpConns[i].State = TCP_CLOSED;       // close connection
335
+        }
336
+      } // if( TcpConns[i].LifeTime >= ...
337
+
338
+    }   // if( TcpConns[i].State != ...
339
+
340
+  }     // for( i ...
341
+}
342
+
343
+// process a received TCP packet
344
+void TcpRecv(unsigned char *pData, unsigned short Length)       // (extern)
345
+{
346
+  struct TcpPacket *pTcpPack;
347
+  unsigned long seq, ack, seqEnd;
348
+  unsigned short localPort, remotePort, wnd, mss, ofs, len, tmp, rcvWnd;
349
+  unsigned char i, flags, *optPtr, optLen, connNo;
350
+  struct TcpConnection *pConn;
351
+  char accept, sendAck;
352
+  struct TcpNotify *pNotify;
353
+
354
+  // packet too short
355
+  if (Length < sizeof(struct TcpPacket))
356
+    return;
357
+
358
+  // convert pointer to TCP packet
359
+  // (this saves us from always casting pData)
360
+  pTcpPack = (struct TcpPacket *)pData;
361
+
362
+  // test checksum
363
+  if (Checksum((unsigned char *)&pTcpPack->IpHdr.Src,
364
+               Length - sizeof(struct EthernetHeader) -
365
+               sizeof(struct IpHeader) + 8, 0x0006,
366
+               Length - sizeof(struct EthernetHeader) -
367
+               sizeof(struct IpHeader)) != 0)
368
+    return;
369
+
370
+  // get local and remote port
371
+  localPort = ntohs(pTcpPack->TcpHdr.DestPort);
372
+  remotePort = ntohs(pTcpPack->TcpHdr.SrcPort);
373
+
374
+  // ignore packets sent from or to port 0
375
+  // - this might be some attack
376
+  if (localPort == 0 || remotePort == 0)
377
+    return;
378
+
379
+  // get sequence number, acknowledge number and window size
380
+  seq = ntohl(pTcpPack->TcpHdr.SeqNo);
381
+  ack = ntohl(pTcpPack->TcpHdr.AckNo);
382
+  wnd = ntohs(pTcpPack->TcpHdr.WndSz);
383
+  // maximum segment size: liberal default according to RFC879
384
+  mss = 536;
385
+
386
+  // get flags
387
+  flags = ntohs(pTcpPack->TcpHdr.Ofs_Flags) & 0x003F;
388
+
389
+  // get data offset and segment length in bytes
390
+  ofs = (ntohs(pTcpPack->TcpHdr.Ofs_Flags) & 0xF000) >> 10;
391
+  if (ofs < 20 || ofs > Length - sizeof(struct EthernetHeader) - sizeof(struct IpHeader))       // invalid 
392
+                                                                                                // offset
393
+    return;     // remote side is unable to build valid TCP packets - ignore
394
+
395
+  // get segment length (length of data in segment)
396
+  len =
397
+      Length - sizeof(struct EthernetHeader) - sizeof(struct IpHeader) - ofs;
398
+
399
+  debug_tcp_printf("recv src=%u dest=%u flags=%s%s%s%s%s%s len=%u",
400
+                   ntohs(pTcpPack->TcpHdr.SrcPort),
401
+                   ntohs(pTcpPack->TcpHdr.DestPort),
402
+                   flags & TCP_URG ? "U" : "",
403
+                   flags & TCP_ACK ? "A" : "",
404
+                   flags & TCP_PSH ? "P" : "",
405
+                   flags & TCP_RST ? "R" : "",
406
+                   flags & TCP_SYN ? "S" : "",
407
+                   flags & TCP_FIN ? "F" : "", Length);
408
+
409
+  // process options
410
+  optLen = (unsigned char)(ofs - 20);
411
+  optPtr = (unsigned char *)&pTcpPack->TcpHdr + sizeof(struct TcpHeader);
412
+  while (optLen > 0) {
413
+    switch (*optPtr) {
414
+      // end of options
415
+    case 0:
416
+      optLen = 0;
417
+      break;
418
+      // no operation
419
+    case 1:
420
+      optLen--;
421
+      optPtr++;
422
+      break;
423
+      // maximum segment size
424
+    case 2:
425
+      if (optLen < 4 || optPtr[1] != 4) {
426
+        optPtr = NULL;  // error
427
+        optLen = 0;
428
+        break;
429
+      }
430
+      mss = ntohs(*(unsigned short *)(optPtr + 2));
431
+      optLen -= 4;
432
+      optPtr += 4;
433
+      break;
434
+      // unknown option
435
+    default:
436
+      if (optLen < 2 || optPtr[1] > optLen) {
437
+        optPtr = NULL;  // error
438
+        optLen = 0;
439
+      }
440
+      optLen -= optPtr[1];      // ignore this option
441
+      optPtr += optPtr[1];
442
+    }   // switch( *optPtr )
443
+  }     // while( optLen > 0 )
444
+  if (optPtr == NULL)   // some error during option parsing
445
+    return;     // remote side is unable to build valid TCP packets - ignore
446
+
447
+  // get sequence number at end of this segment
448
+  seqEnd = seq + len;
449
+  if (flags & TCP_SYN)  // TCP SYN counts as 1 in sequence number space
450
+    seqEnd++;
451
+  if (flags & TCP_FIN)  // TCP FIN counts as 1 in sequence number space
452
+    seqEnd++;
453
+
454
+  // search connection
455
+  for (i = 0; i < count(TcpConns); i++)
456
+    if (TcpConns[i].State != TCP_CLOSED &&
457
+        ip_eq(TcpConns[i].RemoteIp, pTcpPack->IpHdr.Src) &&
458
+        TcpConns[i].LocalPort == localPort &&
459
+        TcpConns[i].RemotePort == remotePort)
460
+      break;
461
+
462
+  // connection not found, only SYN flag set, no data
463
+  if (i >= count(TcpConns) && flags == TCP_SYN && len == 0) {
464
+    // accept connections on some ports (note: localPort cannot be 0 because
465
+    // of check above)
466
+    rcvWnd = 0;
467
+    pNotify = NULL;
468
+    // HTTP
469
+    if (localPort == ConfigHttpPort) {
470
+      rcvWnd = 256;     // connection shall be accepted
471
+      pNotify = &HttpNotify;
472
+    }
473
+    // connection shall be accepted
474
+    if (pNotify != NULL) {
475
+      // search empty connection slot
476
+      for (i = 0; i < count(TcpConns); i++)
477
+        if (TcpConns[i].State == TCP_CLOSED)
478
+          break;
479
+      // free connection slot found
480
+      if (i < count(TcpConns)) {
481
+        // create new connection (passive) in this slot
482
+        ip_cpy(TcpConns[i].RemoteIp, pTcpPack->IpHdr.Src);
483
+        TcpConns[i].LocalPort = localPort;
484
+        TcpConns[i].RemotePort = remotePort;
485
+        TcpConns[i].State = TCP_LISTEN;
486
+        TcpConns[i].Ticks = 0;
487
+        TcpConns[i].Timeout = 0;
488
+        TcpConns[i].LifeTime = 0;
489
+        TcpConns[i].RcvWnd = rcvWnd;
490
+        TcpConns[i].Notify = pNotify;
491
+      }
492
+    }
493
+  }
494
+  // connection still not found
495
+  if (i >= count(TcpConns)) {
496
+    struct TcpPacket EsPack;
497
+    unsigned char EsFlags;
498
+
499
+    // do nothing if RST flag is set
500
+    if (flags & TCP_RST)
501
+      return;
502
+
503
+    // send TCP RST
504
+    EsPack.TcpHdr.SrcPort = htons(localPort);
505
+    EsPack.TcpHdr.DestPort = htons(remotePort);
506
+    EsPack.TcpHdr.WndSz = htons(0);
507
+    ip_cpy(EsPack.IpHdr.Dest, pTcpPack->IpHdr.Src);
508
+    if (flags & TCP_ACK) {
509
+      EsPack.TcpHdr.SeqNo = htonl(ack);
510
+      EsPack.TcpHdr.AckNo = htonl(0);
511
+      EsFlags = TCP_RST;
512
+    } else {
513
+      EsPack.TcpHdr.SeqNo = htonl(0);
514
+      EsPack.TcpHdr.AckNo = htonl(seqEnd);
515
+      EsFlags = TCP_RST | TCP_ACK;
516
+    }
517
+    TcpSendPacket((unsigned char *)&EsPack, sizeof(EsPack), 0, EsFlags);
518
+    return;
519
+  }
520
+  // a connection was found - save number and pointer to it
521
+  connNo = i;
522
+  pConn = &TcpConns[i];
523
+
524
+  // reset connection on reception of urgent data (URG flag set)
525
+  // BUG: urgent data must be supported according to RFC793
526
+  // but urgent data is not used in protocols we use, so leave this out here
527
+  // to save time and memory
528
+  if (flags & TCP_URG) {
529
+    // send TCP RST
530
+    if (flags & TCP_ACK)
531
+      TcpEmptySegment(pConn, ack, 0, TCP_RST);
532
+    else
533
+      TcpEmptySegment(pConn, 0, seqEnd, TCP_RST | TCP_ACK);
534
+    return;
535
+  }
536
+  // different behaviour in different states according to RFC793
537
+  switch (pConn->State) {
538
+
539
+  case TCP_LISTEN:
540
+    if (flags & TCP_RST)        // An incoming RST should be ignored.
541
+      return;
542
+    if (flags & TCP_ACK)        // Any acknowledgment is bad if it arrives on 
543
+                                // a connection still in the LISTEN state.
544
+    {
545
+      TcpEmptySegment(pConn, ack, 0, TCP_RST);  // An acceptable reset
546
+                                                // segment should be formed
547
+                                                // for any arriving
548
+                                                // ACK-bearing segment.
549
+      pConn->Ticks = 0; // restart timer
550
+      return;
551
+    }
552
+    if (flags & TCP_SYN)        // third check for a SYN
553
+    {
554
+      pConn->RcvNxt = seq + 1;  // Set RCV.NXT to SEG.SEQ+1,
555
+      pConn->Irs = seq; // IRS is set to SEG.SEQ
556
+      RandomGetData((unsigned char *)&pConn->Iss, sizeof(pConn->Iss));  // ISS 
557
+                                                                        // should 
558
+                                                                        // be 
559
+                                                                        // selected 
560
+                                                                        // (randomly!!!)
561
+      TcpSynSegment(pConn, pConn->Iss, pConn->RcvNxt, TCP_SYN | TCP_ACK);       // and 
562
+                                                                                // a 
563
+                                                                                // SYN 
564
+                                                                                // segment 
565
+                                                                                // sent
566
+      pConn->SndNxt = pConn->Iss + 1;   // SND.NXT is set to ISS+1
567
+      pConn->SndUna = pConn->Iss;       // and SND.UNA to ISS
568
+      pConn->State = TCP_SYN_RCVD;      // The connection state should be
569
+                                        // changed to SYN-RECEIVED.
570
+      pConn->SndWnd = wnd;      // initialize send window from packet
571
+      pConn->SndWl1 = seq;
572
+      pConn->SndWl2 = ack;
573
+      pConn->Mss = mss; // save maximum segment size
574
+      pConn->Ticks = 0; // restart timer
575
+      return;
576
+    }
577
+    // fourth other text or control
578
+    // So you are unlikely to get here, but if you do, drop the segment, and
579
+    // return.
580
+    return;
581
+
582
+  case TCP_SYN_SENT:
583
+    accept = 0;
584
+    if (flags & TCP_ACK)        // If the ACK bit is set
585
+    {
586
+      if ((long)(ack - pConn->Iss) <= 0 || (long)(ack - pConn->SndNxt) > 0)     // If 
587
+                                                                                // SEG.ACK 
588
+                                                                                // =< 
589
+                                                                                // ISS, 
590
+                                                                                // or 
591
+                                                                                // SEG.ACK 
592
+                                                                                // > 
593
+                                                                                // SND.NXT,
594
+      {
595
+        if (!(flags & TCP_RST)) // (unless the RST bit is set)
596
+          TcpEmptySegment(pConn, ack, 0, TCP_RST);      // send a reset
597
+        return; // and discard the segment. Return.
598
+      }
599
+      accept = (long)(pConn->SndUna - ack) <= 0 && (long)(ack - pConn->SndNxt) <= 0;    // If 
600
+                                                                                        // SND.UNA 
601
+                                                                                        // =< 
602
+                                                                                        // SEG.ACK 
603
+                                                                                        // =< 
604
+                                                                                        // SND.NXT 
605
+                                                                                        // then 
606
+                                                                                        // the 
607
+                                                                                        // ACK 
608
+                                                                                        // is 
609
+                                                                                        // acceptable.
610
+    }
611
+    if (flags & TCP_RST)        // If the RST bit is set
612
+    {
613
+      if (accept)       // If the ACK was acceptable
614
+        pConn->State = TCP_CLOSED;      // enter CLOSED state, delete TCB,
615
+      return;   // drop the segment and return.
616
+    }
617
+    if ((accept || !(flags & TCP_ACK)) &&       // This step should be
618
+                                                // reached only if the ACK is 
619
+                                                // ok, or there is no ACK,
620
+        flags & TCP_SYN)        // If the SYN bit is on
621
+    {
622
+      pConn->RcvNxt = seq + 1;  // RCV.NXT is set to SEG.SEQ+1,
623
+      pConn->Irs = seq; // IRS is set to SEG.SEQ.
624
+      pConn->SndWl2 = pConn->RcvNxt;    // last acknowledge number when
625
+                                        // updating the window size is first
626
+                                        // acknowledge number at all
627
+      if (accept)       // (if there is an ACK)
628
+        pConn->SndUna = ack;    // SND.UNA should be advanced to equal
629
+                                // SEG.ACK
630
+      pConn->SndWnd = wnd;      // initialize send window from packet
631
+      pConn->SndWl1 = seq;
632
+      pConn->SndWl2 = ack;
633
+      pConn->Mss = mss; // save maximum segment size
634
+      if ((long)(pConn->SndUna - pConn->Iss) > 0)       // If SND.UNA > ISS
635
+                                                        // (our SYN has been
636
+                                                        // ACKed),
637
+      {
638
+        pConn->State = TCP_ESTAB;       // change the connection state to
639
+                                        // ESTABLISHED,
640
+        debug_tcp_printf("notify connect no=%u", connNo);
641
+        pConn->Notify->Connect(connNo); // signal "connected"
642
+        TcpEmptySegment(pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK);  // form 
643
+                                                                        // an 
644
+                                                                        // ACK 
645
+                                                                        // segment 
646
+                                                                        // and 
647
+                                                                        // send 
648
+                                                                        // it.
649
+      } else    // Otherwise
650
+      {
651
+        pConn->State = TCP_SYN_RCVD;    // enter SYN-RECEIVED,
652
+        TcpSynSegment(pConn, pConn->Iss, pConn->RcvNxt, TCP_SYN | TCP_ACK);     // form 
653
+                                                                                // a 
654
+                                                                                // SYN,ACK 
655
+                                                                                // segment 
656
+                                                                                // and 
657
+                                                                                // send 
658
+                                                                                // it.
659
+      }
660
+      pConn->Ticks = 0; // restart timer
661
+    }
662
+    return;
663
+
664
+  }     // switch( pConn->State )
665
+
666
+  // Otherwise,
667
+
668
+  // first check sequence number
669
+  if (len == 0)
670
+    if (pConn->RcvWnd == 0)
671
+      accept = seq == pConn->RcvNxt;    // SEG.SEQ = RCV.NXT
672
+    else
673
+      accept = (long)(pConn->RcvNxt - seq) <= 0 &&      // RCV.NXT =< SEG.SEQ 
674
+                                                        // < RCV.NXT+RCV.WND
675
+          (long)(seq - (pConn->RcvNxt + pConn->RcvWnd)) < 0;
676
+  else if (pConn->RcvWnd == 0)
677
+    accept = 0; // not acceptable
678
+  else
679
+    accept = ((long)(pConn->RcvNxt - seq) <= 0 &&       // RCV.NXT =< SEG.SEQ 
680
+                                                        // < RCV.NXT+RCV.WND
681
+              (long)(seq - (pConn->RcvNxt + pConn->RcvWnd)) < 0) || ((long)(pConn->RcvNxt - (seq + len - 1) <= 0) &&    // or 
682
+                                                                                                                        // RCV.NXT 
683
+                                                                                                                        // =< 
684
+                                                                                                                        // SEG.SEQ+SEG.LEN-1 
685
+                                                                                                                        // < 
686
+                                                                                                                        // RCV.NXT+RCV.WND
687
+                                                                     (long)((seq + len - 1) - (pConn->RcvNxt + pConn->RcvWnd)) < 0);
688
+
689
+  // because there is not enough memory to store segments needed later,
690
+  // we only accept segments with SEG.SEQ <= RCV.NXT
691
+  // thus, we reject the segment if SEG.SEQ > RCV.NXT
692
+  // BAD PERFORMANCE: this is _not_ a bug, but a major impact on performace
693
+  // when packets arrive out of order
694
+  // - however, we cannot do something against it,
695
+  // because there is not enough memory available on the controller
696
+  // to store segements for later processing
697
+  if (accept && (long)(seq - pConn->RcvNxt) > 0)
698
+    accept = 0;
699
+
700
+  // If an incoming segment is not acceptable
701
+  if (!accept) {
702
+    /* disabled this - sometimes it ssems to generates endless ACKs being
703
+       exchanged with remote host) if( ! (flags & TCP_RST) ) // (unless the
704
+       RST bit is set) TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt,
705
+       TCP_ACK ); // an acknowledgment should be sent in reply */
706
+    return;     // drop the unacceptable segment and return.
707
+  }
708
+  // if segment contains duplicate data
709
+  tmp = pConn->RcvNxt - seq;    // cannot be negative because of checks above
710
+  if (tmp > 0) {
711
+    // remove duplicate SYN flag from segment
712
+    if (flags & TCP_SYN) {
713
+      flags &= ~TCP_SYN;
714
+      tmp--;
715
+    }
716
+    // remove duplicate data from segment
717
+    ofs += tmp;
718
+    len -= tmp; // length cannot become negative here because of checks above
719
+    // now this segments starts with the expected sequence number
720
+    seq = pConn->RcvNxt;
721
+  }
722
+  // if segment extends beyond end of receive window
723
+  if (len > pConn->RcvWnd) {
724
+    // remove data behind receive window
725
+    seqEnd -= len - pConn->RcvWnd;
726
+    len = pConn->RcvWnd;
727
+  }
728
+  // restart timer, because this was an acceptable segment
729
+  pConn->Ticks = 0;
730
+
731
+  // second check the RST bit,
732
+  if (flags & TCP_RST) {
733
+    switch (pConn->State) {
734
+
735
+    case TCP_SYN_RCVD:
736
+      pConn->State = TCP_CLOSED;        // enter the CLOSED state and delete
737
+                                        // the TCB, an return.
738
+      debug_tcp_printf("notify close no=%u", connNo);
739
+      pConn->Notify->Close(connNo);     // signal "connection refused"
740
+      return;
741
+
742
+    case TCP_ESTAB:
743
+    case TCP_FIN_WAIT_1:
744
+    case TCP_FIN_WAIT_2:
745
+    case TCP_CLOSE_WAIT:
746
+      pConn->State = TCP_CLOSED;        // Enter the CLOSED state, delete the 
747
+                                        // TCB, and return.
748
+      debug_tcp_printf("notify close no=%u", connNo);
749
+      pConn->Notify->Close(connNo);     // signal "connection reset"
750
+      return;
751
+
752
+    case TCP_CLOSING:
753
+    case TCP_LAST_ACK:
754
+    case TCP_TIME_WAIT:
755
+      pConn->State = TCP_CLOSED;        // enter the CLOSED state, delete the 
756
+                                        // TCB, and return.
757
+      return;
758
+
759
+    }   // switch( pConn->State )
760
+  }     // if( flags & TCP_RST )
761
+
762
+  // third check security and precedence
763
+  // - this does not apply to our implementation because we do not support
764
+  // security and precedence on TCP layer
765
+
766
+  // fourth, check the SYN bit
767
+  if (flags & TCP_SYN) {
768
+    switch (pConn->State) {
769
+
770
+    case TCP_SYN_RCVD:
771
+    case TCP_ESTAB:
772
+    case TCP_FIN_WAIT_1:
773
+    case TCP_FIN_WAIT_2:
774
+    case TCP_CLOSE_WAIT:
775
+      // If the SYN is in the window it is an error,
776
+      // - this is always the case here, because SYN not in window would habe 
777
+      // been removed above
778
+      TcpEmptySegment(pConn, ack, 0, TCP_RST);  // send a reset,
779
+      pConn->State = TCP_CLOSED;        // enter the CLOSED state, delete the 
780
+                                        // TCB, and return.
781
+      debug_tcp_printf("notify close no=%u", connNo);
782
+      pConn->Notify->Close(connNo);     // signal "connection reset"
783
+      return;
784
+
785
+    case TCP_CLOSING:
786
+    case TCP_LAST_ACK:
787
+    case TCP_TIME_WAIT:
788
+      // If the SYN is in the window it is an error,
789
+      // - this is always the case here, because SYN not in window would habe 
790
+      // been removed above
791
+      TcpEmptySegment(pConn, ack, 0, TCP_RST);  // send a reset,
792
+      pConn->State = TCP_CLOSED;        // enter the CLOSED state, delete the 
793
+                                        // TCB, and return.
794
+      return;
795
+
796
+    }   // switch( pConn->State )
797
+  }     // if( flags & TCP_SYN )
798
+
799
+  // fifth check the ACK field,
800
+  if (!(flags & TCP_ACK))       // if the ACK bit is off
801
+    return;     // drop the segment and return
802
+  switch (pConn->State) {
803
+
804
+  case TCP_SYN_RCVD:
805
+    if ((long)(pConn->SndUna - ack) <= 0 &&     // If SND.UNA =< SEG.ACK =<
806
+                                                // SND.NXT
807
+        (long)(ack - pConn->SndNxt) <= 0) {
808
+      pConn->State = TCP_ESTAB; // then enter ESTABLISHED state
809
+      debug_tcp_printf("notify connect no=%u", connNo);
810
+      pConn->Notify->Connect(connNo);   // signal "connected"
811
+      // and continue processing.
812
+    } else      // If the segment acknowledgment is not acceptable,
813
+    {
814
+      TcpEmptySegment(pConn, ack, 0, TCP_RST);  // form a reset segment, and
815
+                                                // send it.
816
+      return;   // drop this segment
817
+    }
818
+    // no break here
819
+
820
+  case TCP_ESTAB:
821
+  case TCP_FIN_WAIT_1:
822
+  case TCP_FIN_WAIT_2:
823
+  case TCP_CLOSE_WAIT:
824
+  case TCP_CLOSING:
825
+    if ((long)(ack - pConn->SndUna) <= 0)       // If the ACK is a duplicate
826
+                                                // (SEG.ACK <= SND.UNA),
827
+      break;    // it can be ignored.
828
+    if ((long)(ack - pConn->SndNxt) > 0)        // If the ACK acks something
829
+                                                // not yet sent (SEG.ACK >
830
+                                                // SND.NXT)
831
+    {
832
+      TcpEmptySegment(pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK);    // then 
833
+                                                                        // send 
834
+                                                                        // an 
835
+                                                                        // ACK,
836
+      return;   // drop the segment, and return.
837
+    }
838
+    // here: SND.UNA < SEG.ACK =< SND.NXT
839
+    pConn->SndUna = ack;        // set SND.UNA <- SEG.ACK.
840
+    if ((long)(pConn->SndWl1 - seq) < 0 ||      // If SND.WL1 < SEG.SEQ
841
+        (pConn->SndWl1 == seq && (long)(pConn->SndWl2 - ack) <= 0))     // or 
842
+                                                                        // (SND.WL1 
843
+                                                                        // =
844
+                                                                        // SEG.SEQ 
845
+                                                                        // and 
846
+                                                                        // SND.WL2 
847
+                                                                        // =< 
848
+                                                                        // SEG.ACK),
849
+    {
850
+      pConn->SndWnd = wnd;      // set SND.WND <- SEG.WND,
851
+      pConn->SndWl1 = seq;      // set SND.WL1 <- SEG.SEQ,
852
+      pConn->SndWl2 = ack;      // and set SND.WL2 <- SEG.ACK.
853
+    }
854
+    pConn->Timeout = 0; // restart timeout timer
855
+    debug_tcp_printf("notify sent no=%u pos=%lu",
856
+                     connNo, pConn->SndNxt - (pConn->Iss + 1));
857
+    pConn->Notify->Sent(connNo, pConn->SndUna - (pConn->Iss + 1));      // signal 
858
+                                                                        // "send 
859
+                                                                        // completed" 
860
+                                                                        // (up 
861
+                                                                        // to 
862
+                                                                        // ack)
863
+    // additional processing
864
+    switch (pConn->State) {
865
+    case TCP_FIN_WAIT_1:
866
+      if (pConn->SndUna == pConn->SndNxt)       // if our FIN is now
867
+                                                // acknowledged
868
+        pConn->State = TCP_FIN_WAIT_2;  // then enter FIN-WAIT-2 and continue 
869
+                                        // processing in that state.
870
+      // no break here
871
+    case TCP_FIN_WAIT_2:
872
+      if (pConn->SndUna == pConn->SndNxt)       // if the retransmission
873
+                                                // queue is empty,
874
+      {
875
+        debug_tcp_printf("notify close no=%u", connNo);
876
+        pConn->Notify->Close(connNo);   // the user's CLOSE can be
877
+                                        // acknowledged
878
+      }
879
+      break;
880
+    case TCP_CLOSING:
881
+      if (pConn->SndUna == pConn->SndNxt)       // if the ACK acknowledges
882
+                                                // our FIN
883
+        pConn->State = TCP_TIME_WAIT;   // then enter the TIME-WAIT state,
884
+      else
885
+        return; // otherwise ignore the segment.
886
+      break;
887
+    }
888
+    break;
889
+
890
+  case TCP_LAST_ACK:
891
+    // The only thing that can arrive in this state is an acknowledgment of
892
+    // our FIN.
893
+    if (pConn->SndUna == pConn->SndNxt) // If our FIN is now acknowledged,
894
+    {
895
+      pConn->State = TCP_CLOSED;        // delete the TCB, enter the CLOSED
896
+                                        // state,
897
+      return;   // and return.
898
+    }
899
+    break;
900
+
901
+  case TCP_TIME_WAIT:
902
+    // The only thing that can arrive in this state is a retransmission of
903
+    // the remote FIN.
904
+    TcpEmptySegment(pConn, ack, seqEnd, TCP_ACK);       // Acknowledge it,
905
+    break;
906
+
907
+  }     // switch( pConn->State )
908
+
909
+  // sixth, check the URG bit,
910
+  // - this cannot occur, because we have alredy reset the connection if URG
911
+  // was set
912
+
913
+  // no ACK needs to be sent yet
914
+  sendAck = 0;
915
+
916
+  // seventh, process the segment text,
917
+  if (len > 0) {
918
+    switch (pConn->State) {
919
+
920
+    case TCP_ESTAB:
921
+    case TCP_FIN_WAIT_1:
922
+    case TCP_FIN_WAIT_2:
923
+      pConn->RcvWnd -= len;     // make receive window smaller (len <=
924
+                                // pConn->RcvWnd)
925
+      pConn->RcvNxt += len;     // advance sequence number of next data to
926
+                                // receive
927
+      pConn->Timeout = 0;       // restart timeout timer
928
+      debug_tcp_printf("notify recv no=%u pos=%lu len=%u, min_wnd=%u",
929
+                       connNo, pConn->RcvNxt - (pConn->Irs + 1) - len, len,
930
+                       pConn->RcvWnd);
931
+      pConn->RcvWnd = pConn->Notify->Received(connNo, pConn->RcvNxt - (pConn->Irs + 1) - len,   // give 
932
+                                                                                                // received 
933
+                                                                                                // data 
934
+                                                                                                // to 
935
+                                                                                                // user
936
+                                              (unsigned char *)&pTcpPack->TcpHdr + ofs, len,    // (update 
937
+                                                                                                // receive 
938
+                                                                                                // window 
939
+                                                                                                // size)
940
+                                              pConn->RcvWnd);
941
+      debug_tcp_printf("notify recv no=%u wnd=%u", connNo, pConn->RcvWnd);
942
+      sendAck = 1;      // remember to send an ACK
943
+      break;
944
+
945
+    }   // switch( pConn->State )
946
+  }     // if( len > 0 )
947
+
948
+  // eighth, check the FIN bit,
949
+  if (flags & TCP_FIN) {
950
+    switch (pConn->State) {
951
+
952
+    case TCP_SYN_RCVD:
953
+    case TCP_ESTAB:
954
+      sendAck = 1;      // remember to send an ACK
955
+      pConn->RcvNxt++;  // FIN counts as one in sequence number space
956
+      pConn->State = TCP_CLOSE_WAIT;    // Enter the CLOSE-WAIT state.
957
+      // close outbound part of the connection
958
+      // i.e. do an automatic call to close
959
+      TcpEmptySegment(pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK);  // send 
960
+                                                                                // a 
961
+                                                                                // FIN
962
+      pConn->SndNxt++;
963
+      pConn->State = TCP_CLOSING;
964
+      debug_tcp_printf("notify close no=%u", connNo);
965
+      pConn->Notify->Close(connNo);     // signal "connection closed" to user
966
+      return;   // we do not need to send an ack, becaue we already sent it
967
+                // with our FIN
968
+
969
+    case TCP_FIN_WAIT_1:
970
+      sendAck = 1;      // remember to send an ACK
971
+      pConn->RcvNxt++;  // FIN counts as one in sequence number space
972
+      pConn->State = TCP_CLOSING;       // Enter the CLOSING state.
973
+      break;
974
+
975
+    case TCP_FIN_WAIT_2:
976
+      sendAck = 1;      // remember to send an ACK
977
+      pConn->RcvNxt++;  // FIN counts as one in sequence number space
978
+      pConn->State = TCP_TIME_WAIT;     // Enter the TIME-WAIT state.
979
+      break;
980
+
981
+    case TCP_CLOSING:
982
+    case TCP_CLOSE_WAIT:
983
+    case TCP_LAST_ACK:
984
+    case TCP_TIME_WAIT:
985
+      sendAck = 1;      // remember to send an ACK
986
+      break;
987
+
988
+    }   // switch( pConn->State )
989
+  }
990
+  // send data / ACK segment
991
+  TcpSendDataSegment(connNo, pConn, sendAck);
992
+}
993
+
994
+// open a TCP connection
995
+// must not be called from a TCP notification function
996
+// returns the connection number of the new connection of 0xFF in case of
997
+// error
998
+unsigned char TcpOpen(unsigned char *remoteIp, unsigned short remotePort,       // (extern)
999
+                      unsigned short initialWnd, struct TcpNotify *Notify)
1000
+#define TcpOpenLocalPortMin 32768
1001
+#define TcpOpenLocalPortRange 16384
1002
+{
1003
+  static unsigned short nextLocalPort = TcpOpenLocalPortMin;    // local port 
1004
+                                                                // to use for 
1005
+                                                                // next TCP
1006
+                                                                // connection
1007
+  unsigned short localPort;
1008
+  unsigned char i;
1009
+
1010
+  debug_tcp_printf("open ip=%u.%u.%u.%u port=%u",
1011
+                   remoteIp[0], remoteIp[1], remoteIp[2], remoteIp[3],
1012
+                   remotePort);
1013
+
1014
+  // search an unused local port
1015
+  for (localPort = nextLocalPort;; localPort++) {
1016
+    for (i = 0; i < count(TcpConns); i++)
1017
+      if (TcpConns[i].State != TCP_CLOSED &&
1018
+          TcpConns[i].LocalPort == localPort)
1019
+        break;
1020
+    if (i >= count(TcpConns))
1021
+      break;
1022
+  }
1023
+  // save next local port to use
1024
+  nextLocalPort = localPort + 1;
1025
+  if (nextLocalPort >= TcpOpenLocalPortMin + TcpOpenLocalPortRange)
1026
+    nextLocalPort = TcpOpenLocalPortMin;
1027
+
1028
+  // search empty connection slot
1029
+  for (i = 0; i < count(TcpConns); i++)
1030
+    if (TcpConns[i].State == TCP_CLOSED)
1031
+      break;
1032
+  // no free connection slot found
1033
+  if (i >= count(TcpConns))
1034
+    return 0xFF;
1035
+
1036
+  // create new connection in this slot
1037
+  ip_cpy(TcpConns[i].RemoteIp, remoteIp);
1038
+  TcpConns[i].LocalPort = localPort;
1039
+  TcpConns[i].RemotePort = remotePort;
1040
+  TcpConns[i].RcvNxt = 0;
1041
+  TcpConns[i].Irs = 0;
1042
+  RandomGetData((unsigned char *)&TcpConns[i].Iss, sizeof(TcpConns[i].Iss));    // An 
1043
+                                                                                // initial 
1044
+                                                                                // send 
1045
+                                                                                // sequence 
1046
+                                                                                // number 
1047
+                                                                                // (ISS) 
1048
+                                                                                // is 
1049
+                                                                                // selected.
1050
+  TcpSynSegment(&TcpConns[i], TcpConns[i].Iss, 0, TCP_SYN);     // A SYN
1051
+                                                                // segment of 
1052
+                                                                // the form
1053
+                                                                // <SEQ=ISS><CTL=SYN> 
1054
+                                                                // is sent.
1055
+  TcpConns[i].SndUna = TcpConns[i].Iss; // Set SND.UNA to ISS,
1056
+  TcpConns[i].SndNxt = TcpConns[i].Iss + 1;     // SND.NXT to ISS+1,
1057
+  TcpConns[i].State = TCP_SYN_SENT;     // enter SYN-SENT state,
1058
+  TcpConns[i].SndWnd = 0;       // not allowed to send data for now
1059
+  TcpConns[i].SndWl1 = 0;       // window size was never updated
1060
+  TcpConns[i].SndWl2 = 0;
1061
+  TcpConns[i].Ticks = 0;        // restart timers
1062
+  TcpConns[i].Timeout = 0;
1063
+  TcpConns[i].LifeTime = 0;
1064
+  TcpConns[i].RcvWnd = initialWnd;
1065
+  TcpConns[i].Notify = Notify;
1066
+
1067
+  debug_tcp_printf("open no=%u", i);
1068
+
1069
+  // return connection number
1070
+  return i;
1071
+}
1072
+
1073
+// close a TCP connection
1074
+// must not be called from a TCP notification function
1075
+void TcpClose(unsigned char connNo)     // (extern)
1076
+{
1077
+  struct TcpConnection *pConn;
1078
+
1079
+  debug_tcp_printf("close no=%u", connNo);
1080
+
1081
+  // connection does not exist
1082
+  if (connNo >= count(TcpConns) || TcpConns[connNo].State == TCP_CLOSED)
1083
+    return;
1084
+
1085
+  // get connection
1086
+  pConn = &TcpConns[connNo];
1087
+
1088
+  // different actions in different states accroding to RFC793
1089
+  switch (pConn->State) {
1090
+
1091
+  case TCP_LISTEN:
1092
+  case TCP_SYN_SENT:
1093
+    pConn->State = TCP_CLOSED;  // Delete TCB, enter CLOSED state,
1094
+    break;      // and return.
1095
+
1096
+  case TCP_SYN_RCVD:
1097
+  case TCP_ESTAB:
1098
+    TcpEmptySegment(pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK);    // form 
1099
+                                                                                // a 
1100
+                                                                                // FIN 
1101
+                                                                                // segment 
1102
+                                                                                // and 
1103
+                                                                                // send 
1104
+                                                                                // it,
1105
+    pConn->SndNxt++;
1106
+    pConn->State = TCP_FIN_WAIT_1;      // and enter FIN-WAIT-1 state;
1107
+    debug_tcp_printf("notify close no=%u", connNo);
1108
+    pConn->Notify->Close(connNo);       // signal "connection closed" to user
1109
+    break;
1110
+
1111
+  case TCP_CLOSE_WAIT:
1112
+    TcpEmptySegment(pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK);    // send 
1113
+                                                                                // a 
1114
+                                                                                // FIN 
1115
+                                                                                // segment,
1116
+    pConn->SndNxt++;
1117
+    pConn->State = TCP_CLOSING; // enter CLOSING state.
1118
+    debug_tcp_printf("notify close no=%u", connNo);
1119
+    pConn->Notify->Close(connNo);       // signal "connection closed" to user
1120
+    break;
1121
+
1122
+  }     // switch( pConn->State )
1123
+}
1124
+
1125
+// request sending on a TCP connection
1126
+// must not be called from a TCP notification function
1127
+// this makes the send notification to be called if possible
1128
+void TcpSend(unsigned char connNo)      // (extern)
1129
+{
1130
+  struct TcpConnection *pConn;
1131
+
1132
+  debug_tcp_printf("send no=%u", connNo);
1133
+
1134
+  // connection does not exist
1135
+  if (connNo >= count(TcpConns) || TcpConns[connNo].State == TCP_CLOSED)
1136
+    return;
1137
+
1138
+  // get connection
1139
+  pConn = &TcpConns[connNo];
1140
+
1141
+  // different behaviour in different states
1142
+  switch (pConn->State) {
1143
+
1144
+  case TCP_ESTAB:
1145
+  case TCP_CLOSE_WAIT:
1146
+    // if nothing is sent and not yet ACKed
1147
+    if (pConn->SndUna == pConn->SndNxt)
1148
+      // send a data segment
1149
+      TcpSendDataSegment(connNo, pConn, 0);
1150
+    break;
1151
+
1152
+  }     // switch( TcpConns[i].State )
1153
+}
1154
+
1155
+// dummy notification functions
1156
+void TcpDummyConnect(unsigned char ConnNo)
1157
+{
1158
+}
1159
+
1160
+void TcpDummyClose(unsigned char ConnNo)
1161
+{
1162
+}
1163
+
1164
+unsigned short TcpDummySend(unsigned char ConnNo, unsigned long Pos,
1165
+                            unsigned char *pBuffer, unsigned short MaxLen)
1166
+{
1167
+  return 0;
1168
+}
1169
+
1170
+void TcpDummySent(unsigned char ConnNo, unsigned long Pos)
1171
+{
1172
+}
1173
+
1174
+unsigned short TcpDummyReceived(unsigned char ConnNo, unsigned long Pos,
1175
+                                unsigned char *pBuffer, unsigned short Len,
1176
+                                unsigned short curWnd)
1177
+{
1178
+  return max(curWnd, 128);
1179
+}
1180
+
1181
+struct TcpNotify TcpDummyNotify =       // (extern)
1182
+{
1183
+  .Connect = TcpDummyConnect,
1184
+  .Close = TcpDummyClose,
1185
+  .Send = TcpDummySend,
1186
+  .Sent = TcpDummySent,
1187
+  .Received = TcpDummyReceived,
1188
+};
... ...
@@ -0,0 +1,118 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_tcp
7
+#define INC_tcp
8
+
9
+#include "ethernet.h"
10
+#include "ip.h"
11
+
12
+// header of a TCP packet
13
+struct TcpHeader {
14
+  unsigned int SrcPort;
15
+  unsigned int DestPort;
16
+  unsigned long SeqNo;
17
+  unsigned long AckNo;
18
+  unsigned int Ofs_Flags;
19
+  unsigned int WndSz;
20
+  unsigned int Chk;
21
+  unsigned int UrgentPtr;
22
+};
23
+
24
+// a TCP packet
25
+struct TcpPacket {
26
+  struct EthernetHeader EthHdr;
27
+  struct IpHeader IpHdr;
28
+  struct TcpHeader TcpHdr;
29
+};
30
+
31
+// TCP notify functions
32
+struct TcpNotify {
33
+  // called when connection is established
34
+  void (*Connect) (unsigned char ConnNo);
35
+  // called when connection is closed / reset
36
+  // (after this, the connection number may not be used any more)
37
+  void (*Close) (unsigned char ConnNo);
38
+  // called when sending data is possible
39
+  // (return length of available data, 0xFFFF to close connection)
40
+  unsigned short (*Send) (unsigned char ConnNo, unsigned long Pos,
41
+                          unsigned char *pBuffer, unsigned short MaxLen);
42
+  // called when data was sent and ACKed
43
+  void (*Sent) (unsigned char ConnNo, unsigned long Pos);
44
+  // called when data was received, must return new window size (not smaller
45
+  // than curWnd)
46
+  unsigned short (*Received) (unsigned char ConnNo, unsigned long Pos,
47
+                              unsigned char *pBuffer, unsigned short Len,
48
+                              unsigned short curWnd);
49
+};
50
+
51
+// a TCP connection (member names according to RFC793)
52
+// BUG: missing urgent pointers, which must be supported according to RFC793
53
+// but urgent data is not used in protocols we use, so leave this out here to 
54
+// save time and memory
55
+#define TCP_CLOSED 0
56
+#define TCP_LISTEN 1
57
+#define TCP_SYN_SENT 2
58
+#define TCP_SYN_RCVD 3
59
+#define TCP_ESTAB 4
60
+#define TCP_FIN_WAIT_1 5
61
+#define TCP_FIN_WAIT_2 6
62
+#define TCP_CLOSE_WAIT 7
63
+#define TCP_LAST_ACK 8
64
+#define TCP_CLOSING 9
65
+#define TCP_TIME_WAIT 10
66
+struct TcpConnection {
67
+  unsigned char RemoteIp[4];
68
+  unsigned short LocalPort, RemotePort;
69
+  unsigned char State;  // one of TCP_*
70
+  unsigned long SndUna; // send unacknowledged
71
+  unsigned long SndNxt; // send next
72
+  unsigned short SndWnd;        // send window
73
+  unsigned long SndWl1; // segment sequence number used for last window
74
+                        // update
75
+  unsigned long SndWl2; // segment acknowledgment number used for last window 
76
+                        // update
77
+  unsigned long Iss;    // initial send sequence number
78
+  unsigned long RcvNxt; // receive next
79
+  unsigned short RcvWnd;        // receive window
80
+  unsigned long Irs;    // initial receive sequence number
81
+  unsigned short Mss;   // maximum segment size
82
+  unsigned char Ticks;  // retransmission and time-wait timer (time since
83
+                        // last packet sent or received in 200ms steps)
84
+  unsigned char Timeout;        // timeout timer (time since last data was
85
+                                // sent or received)
86
+  unsigned char LifeTime;       // lifetime timer (time since begin of
87
+                                // connection)
88
+  struct TcpNotify *Notify;     // notification functions
89
+};
90
+
91
+// initialize
92
+extern void TcpInit(void);
93
+
94
+// tick procedure - call every 200ms
95
+extern void TcpTick200(void);
96
+
97
+// process a received TCP packet
98
+extern void TcpRecv(unsigned char *pData, unsigned short Length);
99
+
100
+// open a TCP connection
101
+// must not be called from a TCP notification function
102
+// returns the connection number of the new connection of 0xFF in case of
103
+// error
104
+extern unsigned char TcpOpen(unsigned char *remoteIp,
105
+                             unsigned short remotePort,
106
+                             unsigned short initialWnd,
107
+                             struct TcpNotify *Notify);
108
+
109
+// close a TCP connection
110
+// must not be called from a TCP notification function
111
+extern void TcpClose(unsigned char connNo);
112
+
113
+// request sending on a TCP connection
114
+// must not be called from a TCP notification function
115
+// this makes the send notification to be called if possible
116
+extern void TcpSend(unsigned char connNo);
117
+
118
+#endif // #ifdef INC_tcp
... ...
@@ -0,0 +1,118 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <avr/io.h>
7
+#include <avr/interrupt.h>
8
+
9
+#include "arp.h"
10
+#include "cf.h"
11
+#include "dhcp.h"
12
+#include "ip.h"
13
+#include "random.h"
14
+#include "rtl8019.h"
15
+#include "status.h"
16
+#include "tcp.h"
17
+#include "timing.h"
18
+#include "udp.h"
19
+
20
+// 2ms tick counter to generate 20ms ticks
21
+volatile unsigned char Timing2_10 = 0;
22
+
23
+// flag set every 20ms to indicate execution of 20ms ticks
24
+volatile unsigned char Timing20Flag = 0;
25
+
26
+// wrapping around 20ms tick counter
27
+unsigned char Timing20 = 0;
28
+
29
+// 20ms tick counter to generate 200ms ticks
30
+unsigned char Timing20_10 = 0;
31
+
32
+// 2ms interrupt (timer 0 compare match)
33
+SIGNAL(SIG_OUTPUT_COMPARE0)
34
+{
35
+  // set flag every 20ms
36
+  Timing2_10++;
37
+  if (Timing2_10 >= 10) {
38
+    Timing2_10 = 0;
39
+    Timing20Flag = 1;
40
+  }
41
+}
42
+
43
+// initialize
44
+void TimingInit(void)   // (extern)
45
+{
46
+  // configure timer 0 to 2ms interval
47
+  TCCR0 = 0 << FOC0 | 1 << WGM01 | 0 << WGM00 | // count to OCR0
48
+      0 << COM01 | 0 << COM00 | // no waveform generation
49
+      1 << CS02 | 1 << CS01 | 0 << CS00;        // 1/256 of sysclock (16MHz)
50
+                                                // -> increment every 16us
51
+  OCR0 = 124;   // count to 124 -> 2ms interval
52
+
53
+  // enable timer 0 compare match interrupt
54
+  TIMSK |= 1 << OCIE0;
55
+
56
+  // configure timer 1 to count cycles
57
+  TCCR1A = 0 << WGM11 | 0 << WGM10;     // normal mode
58
+  TCCR1B = 0 << WGM13 | 0 << WGM12 | 0 << CS12 | 0 << CS11 | 1 << CS10; // normal 
59
+                                                                        // mode, 
60
+                                                                        // no 
61
+                                                                        // prescaler
62
+}
63
+
64
+// provide curent time stamp as entropy to random number generator
65
+void TimingEntropy(void)        // (extern)
66
+{
67
+  unsigned short timestamp = TCNT1;
68
+  RandomProvideEntropy((unsigned char)timestamp);
69
+  RandomProvideEntropy((unsigned char)(timestamp >> 8));
70
+}
71
+
72
+// provide curent 20ms tick counter as entropy to random number generator
73
+void Timing20Entropy(void)      // (extern)
74
+{
75
+  RandomProvideEntropy(Timing20);
76
+}
77
+
78
+// task function to do the work - call from main loop
79
+void TimingTask(void)   // (extern)
80
+{
81
+  // 20ms not elapsed
82
+  if (!Timing20Flag)
83
+    return;
84
+  Timing20Flag = 0;
85
+
86
+  // call 20ms tick functions
87
+  CfTick20();
88
+
89
+  // generate 200ms steps
90
+  Timing20_10++;
91
+  if (Timing20_10 >= 10)
92
+    Timing20_10 = 0;
93
+
94
+  // call 200ms tick functions at different times
95
+  switch (Timing20_10) {
96
+  case 1:
97
+    ArpTick200();
98
+    break;
99
+  case 3:
100
+    IpTick200();
101
+    break;
102
+  case 5:
103
+    //RtlTick200();
104
+    break;
105
+  case 6:
106
+    StatusTick200();
107
+    break;
108
+  case 7:
109
+    TcpTick200();
110
+    break;
111
+  case 8:
112
+    UdpTick200();
113
+    break;
114
+  case 9:
115
+    DhcpTick200();
116
+    break;
117
+  }
118
+}
... ...
@@ -0,0 +1,21 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_timing
7
+#define INC_timing
8
+
9
+// initialize
10
+extern void TimingInit(void);
11
+
12
+// provide curent time stamp as entropy to random number generator
13
+extern void TimingEntropy(void);
14
+
15
+// provide curent 20ms tick counter as entropy to random number generator
16
+extern void Timing20Entropy(void);
17
+
18
+// task function to do the work - call from main loop
19
+extern void TimingTask(void);
20
+
21
+#endif // #ifndef INC_timing
... ...
@@ -0,0 +1,40 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <stdio.h>
7
+#include <avr/io.h>
8
+#include <avr/wdt.h>
9
+
10
+#include "macros.h"
11
+#include "uart.h"
12
+
13
+#define BAUD_RATE 38400
14
+
15
+// initialize
16
+void UartInit(void)     // (extern)
17
+{
18
+  // enable transmission
19
+  UCSR0B = 1 << TXEN;
20
+  // set baudrate (16MHz crystal) 
21
+  UBRR0L = 16000000 / (BAUD_RATE * 16L) - 1;
22
+
23
+  // set STDOUT to use UartPutchar
24
+  fdevopen(UartPutchar, NULL);
25
+}
26
+
27
+// write a character
28
+int UartPutchar(char c, FILE * file)    // (extern)
29
+{
30
+  // wait until last character was sent
31
+  while (bit_is_clear(UCSR0A, UDRE))
32
+    wdt_reset();
33
+
34
+  // send character
35
+  UDR0 = c;
36
+
37
+  return 0;
38
+
39
+  file = NULL;  // keep compiler happy
40
+}
... ...
@@ -0,0 +1,15 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_uart
7
+#define INC_uart
8
+
9
+// initialize
10
+extern void UartInit(void);
11
+
12
+// write a character
13
+extern int UartPutchar(char c, FILE * file);
14
+
15
+#endif // #ifndef INC_uart
... ...
@@ -0,0 +1,173 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include "config.h"
7
+#include "checksum.h"
8
+#include "debug.h"
9
+#include "dhcp.h"
10
+#include "ethernet.h"
11
+#include "ip.h"
12
+#include "macros.h"
13
+#include "nethelp.h"
14
+#include "ser62500.h"
15
+#include "udp.h"
16
+
17
+// some kind of "token bucket" for UDP echo
18
+#define UdpEchoTicks 10 // allowed rate of UDP echo replies (in 200ms steps)
19
+unsigned char UdpEchoTickCnt = 0;       // tick counter
20
+#define UdpEchoReliesMax 3      // maximum value for UdpEchoReplies
21
+unsigned char UdpEchoReplies = 0;       // number of UDP echo replies that
22
+                                        // may be sent at the moment
23
+
24
+// tick procedure - call every 200ms
25
+void UdpTick200(void)   // (extern)
26
+{
27
+  // count ticks
28
+  UdpEchoTickCnt++;
29
+  // time to allow one reply more
30
+  if (UdpEchoTickCnt >= UdpEchoTicks) {
31
+    UdpEchoTickCnt = 0;
32
+
33
+    // increase reply count if not at maximum
34
+    if (UdpEchoReplies < UdpEchoReliesMax)
35
+      UdpEchoReplies++;
36
+  }
37
+}
38
+
39
+// process a received UDP echo packet
40
+static void UdpEchoRecv(unsigned char *pData, unsigned short Length)
41
+{
42
+  struct UdpPacket *pUdpPack;
43
+
44
+  // convert pointer to UDP packet
45
+  // (this saves us from always casting pData)
46
+  pUdpPack = (struct UdpPacket *)pData;
47
+
48
+  // source port is UDP echo port
49
+  if (pUdpPack->UdpHdr.SrcPort == htons(7))
50
+    // ignore this packet
51
+    // - UDP echo answer to another UDP echo port will result in endless
52
+    // echoing
53
+    return;
54
+
55
+  // only reply with allowed packet rate
56
+  if (UdpEchoReplies == 0) {
57
+    debug_udp_printf("echo len=%u (dropped)", Length);
58
+    return;
59
+  }
60
+  UdpEchoReplies--;
61
+
62
+  debug_udp_printf("echo len=%u", Length);
63
+
64
+  // send an UDP echo
65
+  // - use same buffer to send reply
66
+  // - this saves us from allocating a new buffer
67
+  // - this saves us from copying the data
68
+  pUdpPack->UdpHdr.DestPort = pUdpPack->UdpHdr.SrcPort; // back to
69
+                                                        // originationg port
70
+  pUdpPack->UdpHdr.SrcPort = htons(7);  // UDP echo port
71
+  ip_cpy(pUdpPack->IpHdr.Dest, pUdpPack->IpHdr.Src);    // back to
72
+                                                        // originating IP
73
+  UdpSend(pData, Length);
74
+}
75
+
76
+// process a received UDP packet
77
+void UdpRecv(unsigned char *pData, unsigned short Length)       // (extern)
78
+{
79
+  struct UdpPacket *pUdpPack;
80
+  unsigned int len;
81
+
82
+  // packet too short
83
+  if (Length < sizeof(struct UdpPacket))
84
+    return;
85
+
86
+  // convert pointer to UDP packet
87
+  // (this saves us from always casting pData)
88
+  pUdpPack = (struct UdpPacket *)pData;
89
+
90
+  // ignore packets sent from or to port 0
91
+  // - this might be some attack
92
+  if (pUdpPack->UdpHdr.SrcPort == htons(0) ||
93
+      pUdpPack->UdpHdr.DestPort == htons(0))
94
+    return;
95
+
96
+  // check total length
97
+  len = sizeof(struct EthernetHeader) + sizeof(struct IpHeader) + ntohs(pUdpPack->UdpHdr.Length);       // length 
98
+                                                                                                        // according 
99
+                                                                                                        // to 
100
+                                                                                                        // UDP 
101
+                                                                                                        // header
102
+  if (Length < len)     // packet is truncated
103
+    return;
104
+  Length = len; // remove IP padding from packet (maybe Length > len)
105
+
106
+  // test checksum
107
+  if (Checksum((unsigned char *)&pUdpPack->IpHdr.Src,
108
+               Length - sizeof(struct EthernetHeader) -
109
+               sizeof(struct IpHeader) + 8, 0x0011,
110
+               ntohs(pUdpPack->UdpHdr.Length)) != 0)
111
+    return;
112
+
113
+  debug_udp_printf("recv src=%u dest=%u len=%u",
114
+                   ntohs(pUdpPack->UdpHdr.SrcPort),
115
+                   ntohs(pUdpPack->UdpHdr.DestPort), Length);
116
+
117
+  // branch according to destination port
118
+  switch (ntohs(pUdpPack->UdpHdr.DestPort)) {
119
+    // UDP echo
120
+  case 7:
121
+    UdpEchoRecv(pData, Length);
122
+    break;
123
+    // DHCP
124
+  case 68:
125
+    DhcpRecv(pData, Length);
126
+    break;
127
+    // serial output with 62500 baud in 9N2 protocol
128
+  case 62500:
129
+    Ser62500Send9N2(pData + sizeof(struct UdpPacket),
130
+                    Length - sizeof(struct UdpPacket));
131
+    break;
132
+  }
133
+}
134
+
135
+// send an UDP packet
136
+// pData must point to a struct UdpPacket with UdpHdr.SrcPort,
137
+// UdpHdr.DestPort and IpHdr.Dest already initialized
138
+void UdpSend(unsigned char *pData, unsigned short Length)       // (extern)
139
+{
140
+  struct UdpPacket *pUdpPack;
141
+  unsigned int chk;
142
+
143
+  // packet too short
144
+  if (Length < sizeof(struct UdpPacket))
145
+    return;
146
+
147
+  // convert pointer to UDP packet
148
+  // (this saves us from always casting pData)
149
+  pUdpPack = (struct UdpPacket *)pData;
150
+
151
+  debug_udp_printf("send src=%u dest=%u len=%u",
152
+                   ntohs(pUdpPack->UdpHdr.SrcPort),
153
+                   ntohs(pUdpPack->UdpHdr.DestPort), Length);
154
+
155
+  // fill in header values
156
+  pUdpPack->UdpHdr.Length =
157
+      htons(Length - sizeof(struct EthernetHeader) - sizeof(struct IpHeader));
158
+  pUdpPack->UdpHdr.Chk = 0x0000;
159
+  ip_cpy(pUdpPack->IpHdr.Src, ConfigIp);        // put IP already here into
160
+                                                // IP header
161
+  // because it is needed for calculation of UDP checksum
162
+
163
+  // generate checksum
164
+  chk = Checksum((unsigned char *)&pUdpPack->IpHdr.Src,
165
+                 Length - sizeof(struct EthernetHeader) -
166
+                 sizeof(struct IpHeader) + 8, 0x0011,
167
+                 ntohs(pUdpPack->UdpHdr.Length));
168
+  pUdpPack->UdpHdr.Chk = htons(chk);
169
+
170
+  // send UDP packet
171
+  pUdpPack->IpHdr.Proto = 0x11; // UDP
172
+  IpSend(pData, Length);
173
+}
... ...
@@ -0,0 +1,38 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_udp
7
+#define INC_udp
8
+
9
+#include "ethernet.h"
10
+#include "ip.h"
11
+
12
+// header of an UDP packet
13
+struct UdpHeader {
14
+  unsigned int SrcPort;
15
+  unsigned int DestPort;
16
+  unsigned int Length;
17
+  unsigned int Chk;
18
+};
19
+
20
+// an UDP packet
21
+struct UdpPacket {
22
+  struct EthernetHeader EthHdr;
23
+  struct IpHeader IpHdr;
24
+  struct UdpHeader UdpHdr;
25
+};
26
+
27
+// tick procedure - call every 200ms
28
+extern void UdpTick200(void);
29
+
30
+// process a received UDP packet
31
+extern void UdpRecv(unsigned char *pData, unsigned short Length);
32
+
33
+// send an UDP packet
34
+// pData must point to a struct UdpPacket with UdpHdr.SrcPort,
35
+// UdpHdr.DestPort and IpHdr.Dest already initialized
36
+extern void UdpSend(unsigned char *pData, unsigned short Length);
37
+
38
+#endif // #ifdef INC_udp
... ...
@@ -0,0 +1,82 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#include <stdint.h>
7
+
8
+#include "xtea.h"
9
+
10
+#define delta 0x9E3779B9
11
+
12
+// XTEA encrypt a block of 64 bits
13
+// - this is not block XTEA, it's the basic XTEA algorithm
14
+static void xtea_enc_block(uint32_t key[4], uint8_t rounds, uint32_t in[2],
15
+                           uint32_t out[2])
16
+{
17
+  uint32_t y, z, sum;
18
+
19
+  y = in[0];
20
+  z = in[1];
21
+  sum = 0;
22
+  for (; rounds > 0; rounds--) {
23
+    y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
24
+    sum += delta;
25
+    z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
26
+  }
27
+  out[0] = y;
28
+  out[1] = z;
29
+}
30
+
31
+// XTEA decrypt a block of 64 bits
32
+// - this is not block XTEA, it's the basic XTEA algorithm
33
+static void xtea_dec_block(uint32_t key[4], uint8_t rounds, uint32_t in[2],
34
+                           uint32_t out[2])
35
+{
36
+  uint32_t y, z, sum;
37
+
38
+  y = in[0];
39
+  z = in[1];
40
+  sum = (uint32_t) delta *rounds;
41
+  for (; rounds > 0; rounds--) {
42
+    z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]);
43
+    sum -= delta;
44
+    y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]);
45
+  }
46
+  out[0] = y;
47
+  out[1] = z;
48
+}
49
+
50
+// XTEA encryption
51
+// rounds should be at least 32
52
+// p_in == p_out is allowed
53
+// p_prev must be initialized to zero before first call to this function
54
+void xtea_enc(uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev)    // extern
55
+{
56
+  uint64_t in, out;
57
+  unsigned int i;
58
+
59
+  for (i = 0; i < block_cnt; i++) {
60
+    in = p_in[i] ^ *p_prev;
61
+    xtea_enc_block(key, rounds, (uint32_t *) & in, (uint32_t *) & out);
62
+    p_out[i] = out;
63
+    *p_prev = out;
64
+  }
65
+}
66
+
67
+// XTEA decryption
68
+// rounds should be at least 32
69
+// p_in == p_out is allowed
70
+// p_prev must be initialized to zero before first call to this function
71
+void xtea_dec(uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev)    // extern
72
+{
73
+  uint64_t in, out;
74
+  unsigned int i;
75
+
76
+  for (i = 0; i < block_cnt; i++) {
77
+    in = p_in[i];
78
+    xtea_dec_block(key, rounds, (uint32_t *) & in, (uint32_t *) & out);
79
+    p_out[i] = out ^ *p_prev;
80
+    *p_prev = in;
81
+  }
82
+}
... ...
@@ -0,0 +1,27 @@
1
+/* flaneth - flash and ethernet version 0.2 date 2008-11-08 Copyright (C)
2
+   2007-2008 Stefan Schuermans <stefan@schuermans.info> Copyleft: GNU public
3
+   license V2 - http://www.gnu.org/copyleft/gpl.html a BlinkenArea project -
4
+   http://www.blinkenarea.org/ */
5
+
6
+#ifndef INC_xtea
7
+#define INC_xtea
8
+
9
+#include <stdint.h>
10
+
11
+// XTEA encryption
12
+// rounds should be at least 32
13
+// p_in == p_out is allowed
14
+// p_prev must be initialized to zero before first call to this function
15
+extern void xtea_enc(uint32_t key[4], uint8_t rounds, uint64_t * p_in,
16
+                     uint64_t * p_out, unsigned int block_cnt,
17
+                     uint64_t * p_prev);
18
+
19
+// XTEA decryption
20
+// rounds should be at least 32
21
+// p_in == p_out is allowed
22
+// p_prev must be initialized to zero before first call to this function
23
+extern void xtea_dec(uint32_t key[4], uint8_t rounds, uint64_t * p_in,
24
+                     uint64_t * p_out, unsigned int block_cnt,
25
+                     uint64_t * p_prev);
26
+
27
+#endif // #ifndef INC_xtea
0 28