Rev 1300 Rev 1705
1 /**** BootLoader ****/ 1 /**** BootLoader ****/
2 #define VERSION "1.0" 2 #define VERSION "1.1"
3 #define ID "$Id: bloader.c 1300 2009-01-17 08:41:49Z kakl $" 3 #define ID "$Id: bloader.c 1705 2010-12-05 19:24:34Z kakl $"
4   4  
5 #CASE // Case sensitive compiler 5 #CASE // Case sensitive compiler
6   6  
-   7 #define FLASH_BLOCK_SIZE 32
-   8 #define BLOADER_MAIN_LENGTH 139 // Rezervovane misto pro main BootLoaderu
-   9 #define RESERVED_BLOCKS 24 // Pocet rezervovanych bloku Flash pro BootLoader
-   10 #define LOADER_RESERVED getenv("PROGRAM_MEMORY")-RESERVED_BLOCKS*FLASH_BLOCK_SIZE
-   11 #define BUFFER_LEN_LOD 46
-   12 #if FLASH_BLOCK_SIZE != getenv("FLASH_ERASE_SIZE")/2
-   13 #error Wrong length of the Flash Block Size. getenv("FLASH_ERASE_SIZE")/getenv("FLASH_WRITE_SIZE")
-   14 #endif
-   15  
7 #include "bloader.h" 16 #include "bloader.h"
8 #include <string.h> 17 #include <string.h>
9   18  
10 #bit CREN = 0x18.4 // USART registers 19 #bit CREN = 0x18.4 // USART registers
11 #bit SPEN = 0x18.7 20 #bit SPEN = 0x18.7
12 #bit OERR = 0x18.1 21 #bit OERR = 0x18.1
13 #bit FERR = 0x18.2 22 #bit FERR = 0x18.2
14   23  
15   24  
16 #INT_RDA 25 #INT_RDA
17 rs232_handler() 26 void rs232_handler()
18 { 27 {
19 putchar(getc()); 28 putchar(getc());
20 } 29 }
21   30  
22 void welcome(void) // Welcome message 31 void welcome(void) // Welcome message
23 { 32 {
24 char REV[50]=ID; // Buffer for concatenate of a version string 33 char REV[50]=ID; // Buffer for concatenate of a version string
25 char VER[4]=VERSION; // Buffer for concatenate of a version string 34 char VER[4]=VERSION; // Buffer for concatenate of a version string
26   35  
27 if (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0; 36 if (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0;
28 printf("\n\r\n\r# BLoader %s (C) 2007 KAKL\n\r",VER); // Welcome message 37 printf("\r\n\r\n# BLoader %s (C) 2007 KAKL\r\n",VER); // Welcome message
29 printf("#%s\n\r",&REV[4]); 38 printf("#%s\r\n",&REV[4]);
30 } 39 }
31   40  
32   41  
33 /*-------------------------------- MAIN --------------------------------------*/ 42 /*-------------------------------- MAIN --------------------------------------*/
34 #SEPARATE 43 #SEPARATE
35 void real_main() 44 void real_main()
36 { 45 {
37 int8 i=0; 46 int8 i=0;
38   47  
39 welcome(); 48 welcome();
40   49  
-   50 printf("# Reserved: %Lu\r\n", RESERVED_BLOCKS*FLASH_BLOCK_SIZE);
-   51
41 printf("# Boot Loader Test >>>\n\r# "); 52 printf("# Boot Loader Test >>>\r\n# ");
42 enable_interrupts(INT_RDA); 53 enable_interrupts(INT_RDA);
43 enable_interrupts(GLOBAL); 54 enable_interrupts(GLOBAL);
44 while(TRUE) 55 while(TRUE)
45 { 56 {
46 printf("%u|",i++); 57 printf("%u|",i++);
47 delay_ms(100); 58 delay_ms(100);
48 } 59 }
49 } 60 }
50   61  
51   62  
52 /*------------------- BOOT LOADER --------------------------------------------*/ 63 /*------------------- BOOT LOADER --------------------------------------------*/
53 #define FLASH_BLOCK_SIZE 32 -  
54 #define LOADER_RESERVED getenv("PROGRAM_MEMORY")-26*FLASH_BLOCK_SIZE -  
55 #define BUFFER_LEN_LOD 46 -  
56 #if FLASH_BLOCK_SIZE != getenv("FLASH_ERASE_SIZE")/2 -  
57 #error Wrong length of the Flash Block Size. getenv("FLASH_ERASE_SIZE")/getenv("FLASH_WRITE_SIZE") -  
58 #endif -  
59   -  
60   64  
61 #BUILD(INTERRUPT=FLASH_BLOCK_SIZE) // Redirect Interrupt routine above first flash block 65 #BUILD(INTERRUPT=FLASH_BLOCK_SIZE) // Redirect Interrupt routine above first flash block
62 #ORG 4,5 66 #ORG 4,5
63 void JumpToTheInterrupt() // Jump to the Interrupt Handler 67 void JumpToTheInterrupt() // Jump to the Interrupt Handler
64 { #asm GOTO FLASH_BLOCK_SIZE #endasm } 68 { #asm GOTO FLASH_BLOCK_SIZE #endasm }
65 #ORG 6,FLASH_BLOCK_SIZE-1 {} // First Flash block is reserved 69 #ORG 6,FLASH_BLOCK_SIZE-1 {} // First Flash block is reserved
66   70  
67   71  
68 #ORG LOADER_RESERVED,LOADER_RESERVED+FLASH_BLOCK_SIZE-1 auto=0 72 #ORG LOADER_RESERVED,LOADER_RESERVED+FLASH_BLOCK_SIZE-1 auto=0
69 #SEPARATE 73 #SEPARATE
70 void dummy_main() // Main on the fix position 74 void dummy_main() // Main on the fix position
71 { 75 {
72 real_main(); 76 real_main();
73 } 77 }
74   78  
75 #ORG LOADER_RESERVED+FLASH_BLOCK_SIZE,getenv("PROGRAM_MEMORY")-130 auto=0 default 79 #ORG LOADER_RESERVED+FLASH_BLOCK_SIZE,getenv("PROGRAM_MEMORY")-BLOADER_MAIN_LENGTH auto=0 default
76   80  
77 unsigned int atoi_b16(char *s) // Convert two hex characters to an int8 81 unsigned int atoi_b16(char *s) // Convert two hex characters to an int8
78 { 82 {
79 unsigned int result = 0; 83 unsigned int result = 0;
80 int i; 84 int i;
81   85  
82 for (i=0; i<2; i++,s++) { 86 for (i=0; i<2; i++,s++) {
83 if (*s >= 'A') 87 if (*s >= 'A')
84 result = 16*result + (*s) - 'A' + 10; 88 result = 16*result + (*s) - 'A' + 10;
85 else 89 else
86 result = 16*result + (*s) - '0'; 90 result = 16*result + (*s) - '0';
87 } 91 }
88   92  
89 return(result); 93 return(result);
90 } 94 }
91   95  
92 void assert(int1 Condition, int8 ErrorCode) 96 void assert(int1 Condition, int8 ErrorCode)
93 { 97 {
94 if(Condition) 98 if(Condition)
95 { 99 {
96 putchar('E'); 100 putchar('E');
97 putchar(ErrorCode+'1'); 101 putchar(ErrorCode+'1');
98 reset_cpu(); 102 reset_cpu();
99 } 103 }
100 } 104 }
101   105  
102 void pause() 106 void pause()
103 { 107 {
104 int16 timeout; 108 int16 timeout;
105   109  
106 for(timeout=0; timeout<65535; timeout++); // Delay cca 300ms 110 for(timeout=0; timeout<65535; timeout++); // Delay cca 300ms
107 } 111 }
108   112  
109 #SEPARATE 113 #SEPARATE
110 boot_loader() 114 void boot_loader()
111 { 115 {
112 int buffidx; 116 int buffidx;
113 char buffer[BUFFER_LEN_LOD]; 117 char buffer[BUFFER_LEN_LOD];
114   118  
115 int8 checksum, line_type; 119 int8 checksum, line_type;
116 int16 l_addr,h_addr=0; 120 int16 l_addr,h_addr=0;
117 int16 addr; 121 int16 addr;
118 int32 next_addr; 122 int32 next_addr;
119   123  
120 int8 dataidx, i, count; 124 int8 dataidx, i;
121 union program_data { 125 union program_data {
122 int8 i8[16]; 126 int8 i8[16];
123 int16 i16[8]; 127 int16 i16[8];
124 } data; 128 } data;
125   129  
126 putchar('@'); 130 putchar('@');
127   131  
128 //nesmaze obsluhu preruseni a jump na main 132 //nesmaze obsluhu preruseni a jump na main
129 for(addr=getenv("FLASH_ERASE_SIZE")/2;addr<=LOADER_RESERVED;addr+=getenv("FLASH_ERASE_SIZE")/2) 133 for(addr=getenv("FLASH_ERASE_SIZE")/2;addr<=LOADER_RESERVED;addr+=getenv("FLASH_ERASE_SIZE")/2)
130 { 134 {
131 erase_program_eeprom(addr); 135 erase_program_eeprom(addr);
132 putchar('.'); 136 putchar('.');
133 } 137 }
134   138  
135 putchar('!'); 139 putchar('!');
136   140  
137 while(!kbhit()) restart_wdt(); 141 while(!kbhit()) restart_wdt();
138   142  
139 while(TRUE) 143 while(TRUE)
140 { 144 {
141 //---WDT 145 //---WDT
142 while (getc()!=':') restart_wdt(); // Only process data blocks that starts with ':' 146 while (getc()!=':') restart_wdt(); // Only process data blocks that starts with ':'
143   147  
144 buffidx = 0; // Read into the buffer until fill is received or buffer is full 148 buffidx = 0; // Read into the buffer until fill is received or buffer is full
145 do 149 do
146 { 150 {
147 buffer[buffidx] = getc(); 151 buffer[buffidx] = getc();
148 } while ( (buffer[buffidx++] < 'g') && (buffidx < BUFFER_LEN_LOD) ); 152 } while ( (buffer[buffidx++] < 'g') && (buffidx < BUFFER_LEN_LOD) );
149 assert(buffidx == BUFFER_LEN_LOD,1); // Error 1 - Buffer Overrun 153 assert(buffidx == BUFFER_LEN_LOD,1); // Error 1 - Buffer Overrun
150   154  
151 //---WDT 155 //---WDT
152 restart_wdt(); 156 restart_wdt();
153   157  
154 checksum = 0; // Sum the bytes to find the check sum value 158 checksum = 0; // Sum the bytes to find the check sum value
155 for (i=0; i<(buffidx-3); i+=2) 159 for (i=0; i<(buffidx-3); i+=2)
156 checksum += atoi_b16 (&buffer[i]); 160 checksum += atoi_b16 (&buffer[i]);
157 checksum = 0xFF - checksum + 1; 161 checksum = 0xFF - checksum + 1;
158 assert(checksum != atoi_b16 (&buffer[buffidx-3]),2); // Error 2 - Bad CheckSum 162 assert(checksum != atoi_b16 (&buffer[buffidx-3]),2); // Error 2 - Bad CheckSum
159   163  
160 // count = atoi_b16 (&buffer[0]); // Get the number of bytes from the buffer 164 // count = atoi_b16 (&buffer[0]); // Get the number of bytes from the buffer
161   165  
162 // Get the lower 16 bits of address 166 // Get the lower 16 bits of address
163 l_addr = make16(atoi_b16(&buffer[2]),atoi_b16(&buffer[4])); 167 l_addr = make16(atoi_b16(&buffer[2]),atoi_b16(&buffer[4]));
164   168  
165 line_type = atoi_b16 (&buffer[6]); 169 line_type = atoi_b16 (&buffer[6]);
166   170  
167 addr = make32(h_addr,l_addr); 171 addr = make32(h_addr,l_addr);
168   172  
169 addr /= 2; // PIC16 uses word addresses 173 addr /= 2; // PIC16 uses word addresses
170   174  
171 // If the line type is 1, then data is done being sent 175 // If the line type is 1, then data is done being sent
172 if (line_type == 1) 176 if (line_type == 1)
173 { 177 {
174 putchar('#'); 178 putchar('#');
175 reset_cpu(); 179 reset_cpu();
176 } 180 }
177   181  
178 assert (line_type == 4,4); // Error 4 - Line type 4 182 assert (line_type == 4,4); // Error 4 - Line type 4
179   183  
180 { 184 {
181   185  
182 if (line_type == 0) 186 if (line_type == 0)
183 { 187 {
184 // Read old program memory content 188 // Read old program memory content
185 for (i=0,next_addr=addr;i<8;i++) 189 for (i=0,next_addr=addr;i<8;i++)
186 data.i16[i]=read_program_eeprom(next_addr++); 190 data.i16[i]=read_program_eeprom(next_addr++);
187 // Loops through all of the data and stores it in data 191 // Loops through all of the data and stores it in data
188 // The last 2 bytes are the check sum, hence buffidx-3 192 // The last 2 bytes are the check sum, hence buffidx-3
189 for (i=8,dataidx=0; i < buffidx-3; i += 2) 193 for (i=8,dataidx=0; i < buffidx-3; i += 2)
190 data.i8[dataidx++]=atoi_b16(&buffer[i]); 194 data.i8[dataidx++]=atoi_b16(&buffer[i]);
191   195  
192 if (addr == 0) 196 if (addr == 0)
193 { 197 {
194   198  
195 // Write 8 words to the Loader location 199 // Write 8 words to the Loader location
196 addr=LOADER_RESERVED; 200 addr=LOADER_RESERVED;
197 for (i=0;i<8;i++) 201 for (i=0;i<8;i++)
198 write_program_eeprom(addr++, data.i16[i]); 202 write_program_eeprom(addr++, data.i16[i]);
199 putchar('%'); 203 putchar('%');
200 } 204 }
201 else 205 else
202 if (addr > 7 && addr < LOADER_RESERVED) 206 if (addr > 7 && addr < LOADER_RESERVED)
203 { 207 {
204 // Write 8 words 208 // Write 8 words
205 for (i=0;i<8;i++) 209 for (i=0;i<8;i++)
206 write_program_eeprom(addr++, data.i16[i]); 210 write_program_eeprom(addr++, data.i16[i]);
207 putchar('*'); 211 putchar('*');
208 } 212 }
209 else putchar('.'); 213 else putchar('.');
210 //---WDT 214 //---WDT
211 restart_wdt(); 215 restart_wdt();
212 CREN=0; CREN=1; // Reinitialise USART 216 CREN=0; CREN=1; // Reinitialise USART
213 } 217 }
214 } 218 }
215 } 219 }
216 } 220 }
217   221  
218 #ORG default 222 #ORG default
219   223  
220 #ORG getenv("PROGRAM_MEMORY")-129,getenv("PROGRAM_MEMORY")-1 auto=0 224 #ORG getenv("PROGRAM_MEMORY")-BLOADER_MAIN_LENGTH+1,getenv("PROGRAM_MEMORY")-1 auto=0
221 void main() 225 void main()
222 { 226 {
223 int8 timeout; 227 int8 timeout;
224   228  
225 disable_interrupts(GLOBAL); 229 disable_interrupts(GLOBAL);
226 setup_wdt(WDT_2304MS); // Setup Watch Dog 230 setup_wdt(WDT_2304MS); // Setup Watch Dog
227 setup_adc_ports(NO_ANALOGS); 231 setup_adc_ports(NO_ANALOGS);
228 setup_adc(ADC_OFF); 232 setup_adc(ADC_OFF);
229 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); 233 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
230 setup_timer_1(T1_DISABLED); 234 setup_timer_1(T1_DISABLED);
231 setup_timer_2(T2_DISABLED,0,1); 235 setup_timer_2(T2_DISABLED,0,1);
232 setup_comparator(NC_NC_NC_NC); 236 setup_comparator(NC_NC_NC_NC);
233 setup_vref(FALSE); 237 setup_vref(FALSE);
234 setup_oscillator(OSC_8MHZ|OSC_INTRC); 238 setup_oscillator(OSC_8MHZ|OSC_INTRC);
235   239  
236 for(timeout=0; timeout<255; timeout++) //cca 50s 240 for(timeout=0; timeout<255; timeout++) //cca 50s
237 { 241 {
238 if (kbhit()) 242 if (kbhit())
239 if (getc()=='u') // "uf" as Update Firmware 243 if (getc()=='u') // "uf" as Update Firmware
240 { 244 {
241 if (getc()=='f') 245 if (getc()=='f')
242 { 246 {
243 restart_wdt(); 247 restart_wdt();
244 boot_loader(); // Update Firmware starter 248 boot_loader(); // Update Firmware starter
245 } 249 }
246 } 250 }
247 else break; 251 else break;
248 putchar('u'); putchar('f'); putchar('?'); 252 putchar('u'); putchar('f'); putchar('?');
249 pause(); 253 pause();
250 CREN=0; CREN=1; // Reinitialise USART 254 CREN=0; CREN=1; // Reinitialise USART
251 restart_wdt(); 255 restart_wdt();
252 }; 256 };
253   257  
254 CREN=0; CREN=1; // Reinitialise USART 258 CREN=0; CREN=1; // Reinitialise USART
255 restart_wdt(); 259 restart_wdt();
256 goto_address(LOADER_RESERVED); // Jump to the location where is the jump to the main 260 goto_address(LOADER_RESERVED); // Jump to the location where is the jump to the main
257 } 261 }
258   262