summaryrefslogtreecommitdiff
path: root/sp12dev.txt
blob: 3e8d720c22e113ca38f18d514015fe612dccaaf8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

_SP12DEV RUNTIME COMMAND DEFINITION ENTRIES

   Sp12 version 2.0 is a serial mode (in-circuit) programmer for the
   AVR family of microcontrollers. It should be able to support all of
   them, but we've added entries to _sp12dev only for the uCs we use
   ourselves, and for some very close relatives. You can easily add
   entries for missing family members; it's mostly a matter of
   copying parts of the `serial programming instruction set' table
   in the datasheet.

   Editing _sp12dev also allows you to customize some of sp12's
   behaviour. Let's have a look at what has been defined for the
   ATtiny15:

 begin 0690
 -i690
 -iT15
 
   The device code consists of two `signature bytes' which the uC
   will normally report to sp12. In some cases, two different device
   codes apply to the same device; in that case, there have to be
   two `begin' lines. (Have a look at the entry for the ATmega103.)
   When a device is locked, it may not report a valid device code.
   In that case, recognition has to be forced with the -i option
   (see sp12.txt). The line `-i690' tells sp12 to expect the device 
   code as identifier, but you can also use a name like -iTiny15,
   -iTiny15L, or an abbreviation as short as -iT15.
   Sp12 attempts to match what's on the command line with the -i<name>
   definitions in _sp12dev by first looking for the first defined
   character, in this case the `T' (which has to be upper case in 
   _sp12dev, but case is ignored on the command line). Everything 
   before the `T' is ignored; defined characters following the `T' 
   must all be there, and digits must match (be all there and in 
   the right order, no undefined digits allowed), but superfluous
   letters are allowed. So -S1200 in _sp12dev matches -iAT90S1200
   on the command line, and also -iat90ls1200, -iat90s1200a, 
   -iLS1200 and so on. The definition for ATmega8 is just M8, which 
   matches names like -iMega8L, but not -iMega128.
   
 DEVICENAME = ATtiny15L
 FLASHSIZE = 512
 EEPROMSIZE = 64
 PAGEMODE = 0
 PAGESIZE =

   The above lines define the name, the flash size in (16-bit) words
   and the size of the eeprom area, also in (8-bit) words.
   The page mode is zero because the Tiny15's flash is programmed
   one address at a time, which means there is no page size to
   define.
   
 READ_LOCK = lhlh hlll xxxx xxxx xxxx xxxx xxxx x21x
 WRITE_LOCK = hlhl hhll hhhh h21h xxxx xxxx xxxx xxxx

   Commands are defined nearly as shown in the `serial programming
   instruction set'. That table shows for instance:

      Write lock bits  1010 1100 1111 1211 xxxx xxxx xxxx xxxx

   With the `21' marking the lock bits in a slightly different font.
   Sp12 wants a one belonging to the command written as h, and a
   zero as l, to get a clear difference between those and the lock
   or fuse bits, which appear variously as numbers, capital letters
   or i's and o's.
 
 LOCK_MESSAGE = 11 - no lock
 LOCK_MESSAGE = 10 - write protected
 LOCK_MESSAGE = 00 - read/write protected

   You can define any message you like. To sp12 it's just a string,
   put on screen when the associated read or write command is used.
   For instance,    sp12 -rL   results in:

      11 are the lock bits read from an ATtiny15L
      11 - no lock
      10 - write protected
      00 - read/write protected
 
   NOTE: Some AVR uC lock commands reverse the bit sequence on readout,
   examples being the AT90S8535, 4434, 2323, 2343 and Tiny22. And these 
   uCs have no `read locks' command; the locks and fuses are separately
   programmed, but read together. So you write-protect them with
   sp12 -wL10    while the result can be read back with    sp12 -rF
   resulting in:

      01011111 are the fuse bits read from an AT90S8535
      11xccccx - no lock
      01xccccx - write protected
      00xccccx - read/write protected
      xx0ccccx - serial programming enabled
      xxxcccc0 - FSTRT reset delay, datasheet p20

   The more often used read and write protection is done with a less 
   confusing   sp12 -wL00

 WRITE_FUSES = hlhl hhll hlhx xxxx xxxx xxxx 87lh hh43
 READ_FUSES = lhlh llll xxxx xxxx xxxx xxxx 8765 xx43

   Here matters get a little more complicated. The Tiny15 does in
   fact allow you to write the fuses 6 (SPIEN) and 5 (RSTDSBL).
   But setting the first to `1' or the second to `0' would block
   further serial mode programming access, making the uC useless
   when you have no `high voltage' programmer, or need to program
   in-circuit. That's why `lh' replaces these fuses in our write
   command, fixing their values. An accidentally wrong command
   like    sp12 -wF10100010   is largely ignored by the programmer,
   as shown by its response:

      10011110 are the fuse bits written into an ATtiny15L
      0x0111xx - BODLEVEL 4V (default 2.7V)
      x00111xx - brownout detection enabled
      xx0111CK - reset delay select (datasheet p15)

 FUSES_MESSAGE = 0x0111xx - BODLEVEL 4V (default 2.7V)
 FUSES_MESSAGE = x00111xx - brownout detection enabled
 FUSES_MESSAGE = xx0111CK - reset delay select (datasheet p15)

   The fuses message can be altered into anything you like.

 WRITE_HIGH_FUSES =
 READ_HIGH_FUSES =
 HIGH_FUSES_MESSAGE =
 WRITE_EXTD_FUSES = 
 READ_EXTD_FUSES = 
 EXTD_FUSES_MESSAGE = 
 READ_CALIBRATION = llhh hlll xxxx xxxx llll llll oooo oooo
 CALIB_MESSAGE = single calibration byte (datasheet p55)

   The final command to define is `read calibration byte', as the
   little uC as no high or extended fuses.


   An entry for the rather more complex ATmega8 needs a bit more
   work:

 begin 0793
 -i793
 -iM8
 DEVICENAME = ATmega8
 FLASHSIZE = 4096
 EEPROMSIZE = 512
 PAGEMODE = 1
 PAGESIZE = 32

   The page size has to be entered in (16-bit) words.

 READ_LOCK = lhlh hlll llll llll xxxx xxxx xxoo oooo
 WRITE_LOCK = hlhl hhll hhhx xxxx xxxx xxxx hhii iiii
 LOCK_MESSAGE = xxxx11 - no lock
 LOCK_MESSAGE = xxxx10 - write protected
 LOCK_MESSAGE = xxxx00 - read/write protected
 LOCK_MESSAGE = BTLKxx - Boot lock, datasheet p116
 READ_FUSES = lhlh llll llll llll xxxx xxxx oooo oooo
 WRITE_FUSES = hlhl hhll hlhl llll xxxx xxxx iiii iiii
 FUSES_MESSAGE = 0xxxxxxx - BODLEVEL 4V (default 2.7V)
 FUSES_MESSAGE = x0xxxxxx - brownout detection enabled
 FUSES_MESSAGE = xxSUxxxx - reset delay, datasheet p28
 FUSES_MESSAGE = xxxxCKSE - clock select, datasheet p24
 WRITE_HIGH_FUSES = hlhl hhll hlhl hlll xxxx xxxx hili iiii
 READ_HIGH_FUSES = lhlh hlll llll hlll xxxx xxxx oooo oooo

   Note the h and l between the i's in the write fuses command.
   Bit-7 is the RSTDSBL fuse; if set to zero, it makes further
   serial mode programming impossible, so it has been defined high.
   According to the datasheet we can't change bit-5 (SPIEN), but it
   has been defined low anyway. 
   Taking away bit-7 causes sp12 to expect a -wH string which is
   seven bits long, for instance    sp12 -wH1010001   resulting in:

       1010001 are the high fuse bits written into an ATmega8
      1xxxxxxx - PC6 is reset pin
      x0xxxxxx - WDT always on
      xx0xxxxx - serial programming enabled
      xxx0xxxx - CKOPT max, datasheet p24
      xxxx0xxx - eeprom not erased
      xxxxxBZx - boot size, datasheet p215
      xxxxxxx0 - reset at boot loader, p204

   Assuming you're using a fixed pitch font, the 7-bit string will
   be correctly aligned with the 8-bit message lines.

 HIGH_FUSES_MESSAGE = 1xxxxxxx - PC6 is reset pin
 HIGH_FUSES_MESSAGE = x0xxxxxx - WDT always on
 HIGH_FUSES_MESSAGE = xx0xxxxx - serial programming enabled
 HIGH_FUSES_MESSAGE = xxx0xxxx - CKOPT max, datasheet p24
 HIGH_FUSES_MESSAGE = xxxx0xxx - eeprom not erased
 HIGH_FUSES_MESSAGE = xxxxxBZx - boot size, datasheet p215
 HIGH_FUSES_MESSAGE = xxxxxxx0 - reset at boot loader, p204
 WRITE_EXTD_FUSES = 
 READ_EXTD_FUSES = 
 EXTD_FUSES_MESSAGE = 
 READ_CALIBRATION = llhh hlll llxx xxxx llll llll oooo oooo
 CALIB_MESSAGE = four calibration bytes (datasheet p28 p29 p218)
 

 An entry for the new Tiny2313 is no more difficult than the above,
 but do note that use of the `debugwire' feature means you lose the 
 resetpin - so it can't be used when you depend on a serial mode
 programmer like sp12. The entry in the current _sp12dev guards 
 accidental changes of the DWEN, SPIEN and RSTDISBL fuses:

 WRITE_HIGH_FUSES = hlhl hhll hlhl hlll xxxx xxxx hili iiih

 A new command introduced in the Tiny2313 is `poll rdy/bsy':
 
 POLL_RDY_BSY = hhhh llll llll llll xxxx xxxx xxxx xxxo

 When this command is part of an _sp12dev entry, the -o option
 is ignored. And for devices which obey this new programming 
 command, -o must be ignored, as -o1 would cause errors.
 

   I hope it will indeed prove easy to add entries to _sp12dev. Do
   be sure to use the latest datasheets and errata when making them.
   I had some trouble with an older sheet for the Mega163, which
   contained a totally wrong `read lock bits' command...