1
1
// Atmega chip fuse caculator
2
2
// Author: Nick Gammon
3
- // Date: 9th May 2012
4
- // Version: 1.2
3
+ // Date: 222nd May 2012
4
+ // Version: 1.3
5
5
6
6
// Version 1.1: Output an 8 MHz clock on pin 9
7
7
// Version 1.2: Corrected flash size for Atmega1284P.
8
+ // Version 1.3: Added signatures for ATtiny2313A, ATtiny4313, ATtiny13
8
9
9
10
/*
10
11
52
53
programAcknowledge = 0x53 ,
53
54
54
55
readSignatureByte = 0x30 ,
56
+ readCalibrationByte = 0x38 ,
55
57
56
58
readLowFuseByte = 0x50 , readLowFuseByteArg2 = 0x00 ,
57
59
readExtendedFuseByte = 0x50 , readExtendedFuseByteArg2 = 0x08 ,
@@ -64,18 +66,19 @@ enum {
64
66
}; // end of enum
65
67
66
68
// copy of fuses/lock bytes found for this processor
67
- byte fuses [4 ];
69
+ byte fuses [5 ];
68
70
69
71
// meaning of bytes in above array
70
72
enum {
71
73
lowFuse,
72
74
highFuse,
73
75
extFuse,
74
- lockByte
76
+ lockByte,
77
+ calibrationByte
75
78
};
76
79
77
80
// handler for special things like bootloader size
78
- typedef void (*specialHandlerFunction) (const byte val, const byte mask, const unsigned int bootLoaderSize);
81
+ typedef void (*specialHandlerFunction) (const byte val, const unsigned int bootLoaderSize);
79
82
80
83
// item for one piece of fuse information
81
84
typedef struct {
@@ -102,7 +105,7 @@ char PROGMEM descOCDEnable [] = "OCD Enable";
102
105
char PROGMEM descJtagEnable [] = " JTAG Enable" ;
103
106
104
107
// calculate size of bootloader
105
- void fBootloaderSize (const byte val, const byte mask, const unsigned int bootLoaderSize)
108
+ void fBootloaderSize (const byte val, const unsigned int bootLoaderSize)
106
109
{
107
110
Serial.print (F (" Bootloader size: " ));
108
111
unsigned int len = bootLoaderSize;
@@ -119,22 +122,22 @@ void fBootloaderSize (const byte val, const byte mask, const unsigned int bootLo
119
122
} // end of fBootloaderSize
120
123
121
124
// show brownout level
122
- void fBrownoutDetectorLevel (const byte val, const byte mask, const unsigned int bootLoaderSize)
125
+ void fBrownoutDetectorLevel (const byte val, const unsigned int bootLoaderSize)
123
126
{
124
127
Serial.print (F (" Brownout detection at: " ));
125
- switch (val)
128
+ switch (val & 3 )
126
129
{
127
- case 0b111 : Serial.println (F (" disabled." )); break ;
128
- case 0b110 : Serial.println (F (" 1.8V." )); break ;
129
- case 0b101 : Serial.println (F (" 2.7V." )); break ;
130
- case 0b100 : Serial.println (F (" 4.3V." )); break ;
130
+ case 0b11 : Serial.println (F (" disabled." )); break ;
131
+ case 0b10 : Serial.println (F (" 1.8V." )); break ;
132
+ case 0b01 : Serial.println (F (" 2.7V." )); break ;
133
+ case 0b00 : Serial.println (F (" 4.3V." )); break ;
131
134
default : Serial.println (F (" reserved." )); break ;
132
135
} // end of switch
133
136
134
137
} // end of fBrownoutDetectorLevel
135
138
136
139
// show brownout level (alternative)
137
- void fBrownoutDetectorLevelAtmega8U2 (const byte val, const byte mask, const unsigned int bootLoaderSize)
140
+ void fBrownoutDetectorLevelAtmega8U2 (const byte val, const unsigned int bootLoaderSize)
138
141
{
139
142
Serial.print (F (" Brownout detection at: " ));
140
143
switch (val)
@@ -151,7 +154,7 @@ void fBrownoutDetectorLevelAtmega8U2 (const byte val, const byte mask, const uns
151
154
} // end of fBrownoutDetectorLevelAtmega8U2
152
155
153
156
// show clock start-up times
154
- void fStartUpTime (const byte val, const byte mask, const unsigned int bootLoaderSize)
157
+ void fStartUpTime (const byte val, const unsigned int bootLoaderSize)
155
158
{
156
159
Serial.print (F (" Start-up time: SUT0:" ));
157
160
if ((val & 1 ) == 0 ) // if zero, the fuse is "programmed"
@@ -167,7 +170,7 @@ void fStartUpTime (const byte val, const byte mask, const unsigned int bootLoade
167
170
} // end of fStartUpTime
168
171
169
172
// work out clock source
170
- void fClockSource (const byte val, const byte mask, const unsigned int bootLoaderSize)
173
+ void fClockSource (const byte val, const unsigned int bootLoaderSize)
171
174
{
172
175
Serial.print (F (" Clock source: " ));
173
176
switch (val)
@@ -296,6 +299,46 @@ fuseMeaning PROGMEM ATmega164P_fuses [] =
296
299
297
300
}; // end of ATmega164P_fuses
298
301
302
+ fuseMeaning PROGMEM ATtiny4313_fuses [] =
303
+ {
304
+ { extFuse, 0x01 , descSelfProgrammingEnable },
305
+
306
+ { highFuse, 0x80 , descDebugWireEnable },
307
+ { highFuse, 0x40 , descEEPROMsave },
308
+ { highFuse, 0x20 , descSerialProgrammingEnable },
309
+ { highFuse, 0x10 , descWatchdogTimerAlwaysOn },
310
+ { highFuse, 0x01 , descExternalResetDisable },
311
+
312
+ { lowFuse, 0x80 , descDivideClockBy8 },
313
+ { lowFuse, 0x40 , descClockOutput },
314
+
315
+ // special (combined) bits
316
+ { lowFuse, 0x30 , NULL , fStartUpTime },
317
+ { lowFuse, 0x0F , NULL , fClockSource },
318
+
319
+ { highFuse, 0x0E , NULL , fBrownoutDetectorLevel },
320
+
321
+ }; // end of ATtiny4313_fuses
322
+
323
+ fuseMeaning PROGMEM ATtiny13_fuses [] =
324
+ {
325
+ { highFuse, 0x10 , descSelfProgrammingEnable },
326
+ { highFuse, 0x08 , descDebugWireEnable },
327
+ { highFuse, 0x01 , descExternalResetDisable },
328
+
329
+ { lowFuse, 0x80 , descSerialProgrammingEnable },
330
+ { lowFuse, 0x40 , descEEPROMsave },
331
+ { lowFuse, 0x20 , descWatchdogTimerAlwaysOn },
332
+ { lowFuse, 0x10 , descDivideClockBy8 },
333
+
334
+ // special (combined) bits
335
+ { lowFuse, 0x0C , NULL , fStartUpTime },
336
+ { lowFuse, 0x03 , NULL , fClockSource },
337
+
338
+ { highFuse, 0x06 , NULL , fBrownoutDetectorLevel },
339
+
340
+ }; // end of ATtiny13_fuses
341
+
299
342
// structure for information about a single processor
300
343
typedef struct {
301
344
byte sig [3 ];
@@ -309,7 +352,7 @@ typedef struct {
309
352
const unsigned long kb = 1024 ;
310
353
311
354
// see Atmega328 datasheet page 298
312
- signatureType signatures [] =
355
+ const signatureType signatures [] =
313
356
{
314
357
// signature description flash size bootloader size
315
358
@@ -349,6 +392,13 @@ signatureType signatures [] =
349
392
// ATmega1284P family
350
393
{ { 0x1E , 0x97 , 0x05 }, " ATmega1284P" , 128 * kb, 1 * kb, ATmega164P_fuses, NUMITEMS (ATmega164P_fuses) }, // same as ATmega164P
351
394
395
+ // ATtiny4313 family
396
+ { { 0x1E , 0x91 , 0x0A }, " ATtiny2313A" , 2 * kb, 0 , ATtiny4313_fuses, NUMITEMS (ATtiny4313_fuses) },
397
+ { { 0x1E , 0x92 , 0x0D }, " ATtiny4313" , 4 * kb, 0 , ATtiny4313_fuses, NUMITEMS (ATtiny4313_fuses) },
398
+
399
+ // ATtiny13 family
400
+ { { 0x1E , 0x90 , 0x07 }, " ATtiny13A" , 1 * kb, 0 , ATtiny13_fuses, NUMITEMS (ATtiny13_fuses) },
401
+
352
402
}; // end of signatures
353
403
354
404
// if signature found in above table, this is its index
@@ -481,7 +531,17 @@ void showFuseMeanings ()
481
531
482
532
// some fuses use multiple bits so we'll call a special handling function
483
533
if (thisFuse.specialHandler )
484
- thisFuse.specialHandler (fuses [val] & mask, mask, signatures [foundSig].baseBootSize );
534
+ {
535
+ // get value into low-order bits
536
+ byte adjustedVal = fuses [val] & mask;
537
+ while ((mask & 1 ) == 0 )
538
+ {
539
+ adjustedVal >>= 1 ;
540
+ mask >>= 1 ;
541
+ }
542
+
543
+ thisFuse.specialHandler (adjustedVal, signatures [foundSig].baseBootSize );
544
+ } // end if special handler
485
545
486
546
} // end of for each fuse meaning
487
547
@@ -493,6 +553,7 @@ void getFuseBytes ()
493
553
fuses [highFuse] = program (readHighFuseByte, readHighFuseByteArg2);
494
554
fuses [extFuse] = program (readExtendedFuseByte, readExtendedFuseByteArg2);
495
555
fuses [lockByte] = program (readLockByte, readLockByteArg2);
556
+ fuses [calibrationByte] = program (readCalibrationByte);
496
557
497
558
Serial.print (" LFuse = " );
498
559
showHex (fuses [lowFuse], true );
@@ -502,6 +563,9 @@ void getFuseBytes ()
502
563
showHex (fuses [extFuse], true );
503
564
Serial.print (" Lock byte = " );
504
565
showHex (fuses [lockByte], true );
566
+ Serial.print (F (" Clock calibration = " ));
567
+ showHex (fuses [calibrationByte], true );
568
+
505
569
} // end of getFuseBytes
506
570
507
571
void setup ()
0 commit comments