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