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