1 | ' (c) 1995-2009, MCS VERSION 2 of the BOOTLOADER. The waiting for the NAK is
|
2 | ' stretched.further a bug was resolved for the M64/128 that have a big page size
|
3 | '-------------------------------------------------------------------------------
|
4 | $crystal = 16000000
|
5 | $baud = 9600
|
6 |
|
7 |
|
8 | $regfile = "M328def.dat"
|
9 | Const Loaderchip = 328
|
10 |
|
11 |
|
12 | $prog &HFF , &H7F , &HD8 , &H00 ' generated. Take care that the chip supports all fuse bytes.
|
13 |
|
14 | #if Loaderchip = 328 ' Mega32
|
15 | $loader = $3c00 ' 1024 words
|
16 | Const Maxwordbit = 6 'Z6 is maximum bit '
|
17 | Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
|
18 | #endif
|
19 |
|
20 |
|
21 | Const Maxword =(2 ^ Maxwordbit) * 2 '128
|
22 | Const Maxwordshift = Maxwordbit + 1
|
23 |
|
24 | 'Dim the used variables
|
25 | Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte
|
26 | Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte
|
27 | Dim J As Byte , Spmcrval As Byte ' self program command byte value
|
28 |
|
29 | Dim Z As Long 'this is the Z pointer word
|
30 | Dim Vl As Byte , Vh As Byte ' these bytes are used for the data values
|
31 | Dim Wrd As Word , Page As Word 'these vars contain the page and word address
|
32 | Dim Bkind As Byte , Bstarted As Byte
|
33 | 'Mega 88 : 32 words, 128 pages
|
34 |
|
35 | Disable Interrupts 'we do not use ints
|
36 |
|
37 | 'Waitms 100 'wait 100 msec sec
|
38 | 'We start with receiving a file. The PC must send this binary file
|
39 |
|
40 | 'some constants used in serial com
|
41 | Const Nak = &H15
|
42 | Const Ack = &H06
|
43 | Const Can = &H18
|
44 |
|
45 | $timeout = 400000 'we use a timeout
|
46 | 'When you get LOADER errors during the upload, increase the timeout value
|
47 | 'for example at 16 Mhz, use 200000
|
48 |
|
49 | Bretries = 5 'we try 5 times
|
50 | Testfor123:
|
51 |
|
52 | Bstatus = Waitkey() ' wait for the loader to send a byte
|
53 |
|
54 | Print Chr(bstatus); ' got - return value
|
55 |
|
56 | If Bstatus = 123 Then 'did we received value 123 ?
|
57 | Bkind = 0 'normal flash loader
|
58 | Goto Loader
|
59 | Elseif Bstatus = 124 Then ' EEPROM
|
60 | Bkind = 1 ' EEPROM loader
|
61 | Goto Loader
|
62 | Elseif Bstatus <> 0 Then
|
63 | Decr Bretries
|
64 | If Bretries <> 0 Then Goto Testfor123 'we test again
|
65 | End If
|
66 |
|
67 | 'For J = 1 To 10 'this is a simple indication that we start the normal reset vector
|
68 | ' Toggle Portb.2 : Waitms 100
|
69 | 'Next
|
70 |
|
71 | Goto _reset 'goto the normal reset vector at address 0
|
72 |
|
73 | '---[this is the loader routine. It is a Xmodem-checksum reception routine]-----
|
74 | Loader:
|
75 | Do 'Clear buffer
|
76 | Bstatus = Waitkey()
|
77 | Loop Until Bstatus = 0
|
78 |
|
79 | ' For J = 1 To 3 'this is a simple indication that we start the normal reset vector
|
80 | ' Toggle Portb.2 : Waitms 50
|
81 | ' Next
|
82 |
|
83 | If Bkind = 0 Then
|
84 | Spmcrval = 3 : Gosub Do_spm ' erase the first page
|
85 | Spmcrval = 17 : Gosub Do_spm ' re-enable page
|
86 | End If
|
87 |
|
88 | Bretries = 10 'number of retries
|
89 |
|
90 | 'Blockaufbau:
|
91 | '------------
|
92 | ' Das ASCII-Zeichen Start Of Header (SOH, hex01) (1 Byte),
|
93 | ' Blocknummer (1 Byte), 0...255
|
94 | ' Daten (128 Byte),
|
95 | ' Prüfsumme (1 Byte) die Prüfsumme ist hier die arithmetische Summe der Datenbytes modulo 256 und deshalb fehleranfällig
|
96 |
|
97 | 'Protokoll:
|
98 | '----------
|
99 | ' Die Übertragung wird durch den Empfänger angestoßen, indem er ein NAK sendet.
|
100 | 'Eine fehlerfrei empfangene Checksumme wird mit Acknowledgement (ACK, hex06) bestätigt.
|
101 | ' Bei einer Checksumme ungleich der berechneten Checksumme ist ein Fehler aufgetreten.
|
102 | ' Der Block wird mit Negative Acknowledgement (NAK, hex15) abgelehnt und dann bis zu zehnmal neu versendet.
|
103 | ' Das Ende einer Übertragung wird vom Sender mit End Of Transmission (EOT, hex04) angezeigt.
|
104 | ' Auch dieses muss mit einem ACK bestätigt werden.
|
105 |
|
106 | Do
|
107 | Bstarted = 0 ' we were not started yet
|
108 | Csum = 0 'checksum is 0 when we start
|
109 | Print Chr(nak); ' first time send a nack
|
110 | Do
|
111 |
|
112 | Bstatus = Waitkey() 'wait for status byte
|
113 |
|
114 | Select Case Bstatus
|
115 | Case 1: ' start of heading, PC is ready to send (hex01)
|
116 | Incr Bblocklocal ' increase local block count
|
117 |
|
118 | Csum = 1 ' checksum is 1
|
119 |
|
120 | Bblock = Waitkey() : Csum = Csum + Bblock 'get block-number
|
121 |
|
122 | Bcsum1 = Waitkey() : Csum = Csum + Bcsum1 'get checksum first-byte
|
123 |
|
124 | For J = 1 To 128 'get 128 bytes (Data)
|
125 | Buf(j) = Waitkey() : Csum = Csum + Buf(j)
|
126 | Next
|
127 |
|
128 | Bcsum2 = Waitkey() 'get second checksum byte
|
129 |
|
130 | If Bblocklocal = Bblock Then 'are the blocks the same?
|
131 | If Bcsum2 = Csum Then 'is the checksum the same?
|
132 | Gosub Writepage 'yes go write the page
|
133 | Print Chr(ack); 'acknowledge
|
134 | Else 'no match so send nak
|
135 | Print Chr(nak);
|
136 | End If
|
137 | Else
|
138 | Print Chr(nak); 'blocks do not match
|
139 | End If
|
140 | Case 4: ' end of transmission , file is transmitted
|
141 | If Wrd > 0 And Bkind = 0 Then ' if there was something left in the page
|
142 | Wrd = 0 'Z pointer needs wrd to be 0
|
143 | Spmcrval = 5 : Gosub Do_spm 'write page
|
144 | Spmcrval = 17 : Gosub Do_spm ' re-enable page
|
145 | End If
|
146 | Print Chr(ack); ' send ack and ready
|
147 |
|
148 | ' Portb.3 = 0 ' simple indication that we are finished and ok
|
149 | Waitms 20
|
150 | Goto _reset ' start new program
|
151 | Case &H18: ' PC aborts transmission
|
152 | Goto _reset ' ready
|
153 | Case 123 : Exit Do 'was probably still in the buffer
|
154 | Case 124 : Exit Do
|
155 | Case Else
|
156 | Exit Do ' no valid data
|
157 | End Select
|
158 | Loop
|
159 |
|
160 | If Bretries > 0 Then 'attempte left?
|
161 | Waitms 1000
|
162 | Decr Bretries 'decrease attempts
|
163 | Else
|
164 | Goto _reset 'reset chip
|
165 | End If
|
166 |
|
167 | Loop
|
168 |
|
169 | '---[write one or more pages]---------------------------------------------------
|
170 | Writepage:
|
171 | If Bkind = 0 Then
|
172 | For J = 1 To 128 Step 2 'we write 2 bytes into a page
|
173 | Vl = Buf(j) : Vh = Buf(j + 1) 'get Low and High bytes
|
174 | lds r0, {vl} 'store them into r0 and r1 registers
|
175 | lds r1, {vh}
|
176 | Spmcrval = 1 : Gosub Do_spm 'write value into page at word address
|
177 | Wrd = Wrd + 2 ' word address increases with 2 because LS bit of Z is not used
|
178 | If Wrd = Maxword Then ' page is full
|
179 | Wrd = 0 'Z pointer needs wrd to be 0
|
180 | Spmcrval = 5 : Gosub Do_spm 'write page
|
181 | Spmcrval = 17 : Gosub Do_spm ' re-enable page
|
182 |
|
183 | Page = Page + 1 'next page
|
184 | Spmcrval = 3 : Gosub Do_spm ' erase next page
|
185 | Spmcrval = 17 : Gosub Do_spm ' re-enable page
|
186 | End If
|
187 | Next
|
188 |
|
189 | Else 'eeprom
|
190 | For J = 1 To 128
|
191 | Writeeeprom Buf(j) , Wrd
|
192 | Wrd = Wrd + 1
|
193 | Next
|
194 | End If
|
195 | Return
|
196 |
|
197 | Do_spm:
|
198 | Bitwait Spmcsr.0 , Reset ' check for previous SPM complete
|
199 | Bitwait Eecr.1 , Reset 'wait for eeprom
|
200 |
|
201 | Z = Page 'make equal to page
|
202 | Shift Z , Left , Maxwordshift 'shift to proper place
|
203 | Z = Z + Wrd 'add word
|
204 | lds r30,{Z}
|
205 | lds r31,{Z+1}
|
206 |
|
207 | #if _romsize > 65536
|
208 | lds r24,{Z+2}
|
209 | sts rampz,r24 ' we need to set rampz also for the M128
|
210 | #endif
|
211 |
|
212 | Spmcsr = Spmcrval 'assign register
|
213 | spm 'this is an asm instruction
|
214 | nop
|
215 | nop
|
216 | Return
|