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