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