Rev 1298 Rev 1300
1 /**** IR Mrakomer 4 ****/ 1 /**** IR Mrakomer 4 ****/
2 #define VERSION "4.0" 2 #define VERSION "4.0"
3 #define ID "$Id: irmrak4.c 1298 2009-01-16 23:40:59Z kakl $" 3 #define ID "$Id: irmrak4.c 1300 2009-01-17 08:41:49Z kakl $"
4   4  
5 #include "irmrak4.h" 5 #include "irmrak4.h"
6   6  
7 #bit CREN = 0x18.4 // USART registers 7 #bit CREN = 0x18.4 // USART registers
8 #bit SPEN = 0x18.7 8 #bit SPEN = 0x18.7
9 #bit OERR = 0x18.1 9 #bit OERR = 0x18.1
10 #bit FERR = 0x18.2 10 #bit FERR = 0x18.2
11   11  
12 #include <string.h> 12 #include <string.h>
13 //!!! #include "bloader.c" // Boot Loader driver -  
14   13  
15 #CASE // Case sensitive compiler 14 #CASE // Case sensitive compiler
16   15  
17 #define MAXHEAT 20 // Number of cycles for heating 16 #define MAXHEAT 20 // Number of cycles for heating
18 #define MAXOPEN 20 // Number of cycles for dome open 17 #define MAXOPEN 20 // Number of cycles for dome open
19 #define MEASURE_DELAY 6000 // Delay to a next measurement 18 #define MEASURE_DELAY 6000 // Delay to a next measurement
20 #define RESPONSE_DELAY 100 // Reaction time after receiving a command 19 #define RESPONSE_DELAY 100 // Reaction time after receiving a command
21 #define SAFETY_COUNT 90 // Time of one emergency cycle 20 #define SAFETY_COUNT 90 // Time of one emergency cycle
22 #define SEND_DELAY 50 // Time between two characters on RS232 21 #define SEND_DELAY 50 // Time between two characters on RS232
23   22  
24 #define DOME PIN_B4 // Dome controll port 23 #define DOME PIN_B4 // Dome controll port
25 #define HEATING PIN_B3 // Heating for defrosting 24 #define HEATING PIN_B3 // Heating for defrosting
26   25  
27   26  
28 char VER[4]=VERSION; // Buffer for concatenate of a version string 27 char VER[4]=VERSION; // Buffer for concatenate of a version string
29   28  
30 int8 heat; // Status variables 29 int8 heat; // Status variables
31 int8 open; 30 int8 open;
32   31  
33 inline void toggle_dome(void) // Wire exercise 32 inline void toggle_dome(void) // Wire exercise
34 { 33 {
35 if (open>0) 34 if (open>0)
36 {output_toggle(DOME);} // Toggle = Open Dome 35 {output_toggle(DOME);} // Toggle = Open Dome
37 else 36 else
38 {output_high(DOME);} // Do not toggle = Close Dome 37 {output_high(DOME);} // Do not toggle = Close Dome
39 } 38 }
40   39  
41 void delay(int16 cycles) // Wire exercise with delay 40 void delay(int16 cycles) // Wire exercise with delay
42 { 41 {
43 int16 i; 42 int16 i;
44   43  
45 for(i=0; i<cycles; i++) {toggle_dome(); delay_us(100);} 44 for(i=0; i<cycles; i++) {toggle_dome(); delay_us(100);}
46 } 45 }
47   46  
48 void welcome(void) // Welcome message 47 void welcome(void) // Welcome message
49 { 48 {
50 char REV[50]=ID; // Buffer for concatenate of a version string 49 char REV[50]=ID; // Buffer for concatenate of a version string
51   50  
52 if (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0; 51 if (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0;
53 printf("\n\r# Mrakomer %s (C) 2007 KAKL\n\r",VER); // Welcome message 52 printf("\n\r# Mrakomer %s (C) 2007 KAKL\n\r",VER); // Welcome message
54 printf("#%s\n\r",&REV[4]); 53 printf("#%s\n\r",&REV[4]);
55 printf("# <sequence> <ambient[1/100 C]> <sky[1/100 C]> "); 54 printf("# <sequence> <ambient[1/100 C]> <sky[1/100 C]> ");
56 printf("<heating[s]> <dome[s]> <check>\n\r\n\r"); 55 printf("<heating[s]> <dome[s]> <check>\n\r\n\r");
57 } 56 }
58   57  
59   58  
60 #include "smb.c" // System Management Bus driver 59 #include "smb.c" // System Management Bus driver
61   60  
62   61  
63 // Read sensor's RAM 62 // Read sensor's RAM
64 // Returns temperature in °K 63 // Returns temperature in °K
65 int16 ReadTemp(int8 addr, int8 select) 64 int16 ReadTemp(int8 addr, int8 select)
66 { 65 {
67 unsigned char arr[6]; // Buffer for the sent bytes 66 unsigned char arr[6]; // Buffer for the sent bytes
68 int8 crc; // Readed CRC 67 int8 crc; // Readed CRC
69 int16 temp; // Readed temperature 68 int16 temp; // Readed temperature
70   69  
71 addr<<=1; 70 addr<<=1;
72   71  
73 SMB_STOP_bit(); //If slave send NACK stop comunication 72 SMB_STOP_bit(); //If slave send NACK stop comunication
74 SMB_START_bit(); //Start condition 73 SMB_START_bit(); //Start condition
75 SMB_TX_byte(addr); 74 SMB_TX_byte(addr);
76 SMB_TX_byte(RAM_Access|select); 75 SMB_TX_byte(RAM_Access|select);
77 SMB_START_bit(); //Repeated Start condition 76 SMB_START_bit(); //Repeated Start condition
78 SMB_TX_byte(addr); 77 SMB_TX_byte(addr);
79 arr[2]=SMB_RX_byte(ACK); //Read low data,master must send ACK 78 arr[2]=SMB_RX_byte(ACK); //Read low data,master must send ACK
80 arr[1]=SMB_RX_byte(ACK); //Read high data,master must send ACK 79 arr[1]=SMB_RX_byte(ACK); //Read high data,master must send ACK
81 temp=make16(arr[1],arr[2]); 80 temp=make16(arr[1],arr[2]);
82 crc=SMB_RX_byte(NACK); //Read PEC byte, master must send NACK 81 crc=SMB_RX_byte(NACK); //Read PEC byte, master must send NACK
83 SMB_STOP_bit(); //Stop condition 82 SMB_STOP_bit(); //Stop condition
84   83  
85 arr[5]=addr; 84 arr[5]=addr;
86 arr[4]=RAM_Access|select; 85 arr[4]=RAM_Access|select;
87 arr[3]=addr; 86 arr[3]=addr;
88 arr[0]=0; 87 arr[0]=0;
89 if (crc != PEC_calculation(arr)) temp=0; // Calculate and check CRC 88 if (crc != PEC_calculation(arr)) temp=0; // Calculate and check CRC
90   89  
91 return temp; 90 return temp;
92 } 91 }
93   92  
94   93  
95 /*-------------------------------- MAIN --------------------------------------*/ 94 /*-------------------------------- MAIN --------------------------------------*/
96 void real_main() 95 void main()
97 { 96 {
98 unsigned int16 seq, temp, tempa; 97 unsigned int16 seq, temp, tempa;
99 signed int16 ta, to; 98 signed int16 ta, to;
100 int8 safety_counter; 99 int8 safety_counter;
101 int1 repeat; 100 int1 repeat;
102   101  
103 output_high(DOME); // Close Dome 102 output_high(DOME); // Close Dome
104 output_low(HEATING); // Heating off 103 output_low(HEATING); // Heating off
105   104  
106 delay_ms(1000); 105 delay_ms(1000);
107 restart_wdt(); 106 restart_wdt();
108   107  
109 seq=0; // Variables initiation 108 seq=0; // Variables initiation
110 heat=0; 109 heat=0;
111 open=0; 110 open=0;
112 repeat=TRUE; 111 repeat=TRUE;
113   112  
114 welcome(); 113 welcome();
115   114  
116 tempa=ReadTemp(SA, RAM_Tamb); // Dummy read 115 tempa=ReadTemp(SA, RAM_Tamb); // Dummy read
117 temp=ReadTemp(SA, RAM_Tobj1); 116 temp=ReadTemp(SA, RAM_Tobj1);
118   117  
119 delay_ms(1000); 118 delay_ms(1000);
120 //---WDT 119 //---WDT
121 restart_wdt(); 120 restart_wdt();
122   121  
123 while(TRUE) // Main Loop 122 while(TRUE) // Main Loop
124 { 123 {
125 safety_counter=SAFETY_COUNT; // Heating and Dome Count Down 124 safety_counter=SAFETY_COUNT; // Heating and Dome Count Down
126 do 125 do
127 { 126 {
128 if (safety_counter<SAFETY_COUNT) safety_counter++; 127 if (safety_counter<SAFETY_COUNT) safety_counter++;
129   128  
130 delay(RESPONSE_DELAY); 129 delay(RESPONSE_DELAY);
131   130  
132 if (safety_counter>=SAFETY_COUNT) 131 if (safety_counter>=SAFETY_COUNT)
133 { 132 {
134 if (heat>0) heat--; 133 if (heat>0) heat--;
135 if (open>0) open--; 134 if (open>0) open--;
136   135  
137 if (heat>0) { output_high(HEATING); } else { output_low(HEATING); } 136 if (heat>0) { output_high(HEATING); } else { output_low(HEATING); }
138   137  
139 safety_counter=0; 138 safety_counter=0;
140 //---WDT 139 //---WDT
141 restart_wdt(); 140 restart_wdt();
142 } 141 }
143 } while (!kbhit()&&!repeat); 142 } while (!kbhit()&&!repeat);
144   143  
145 //---WDT 144 //---WDT
146 restart_wdt(); 145 restart_wdt();
147 { // Retrieve command 146 { // Retrieve command
148 char ch='k'; 147 char ch='k';
149   148  
150 if(kbhit()) ch=getc(); 149 if(kbhit()) ch=getc();
151   150  
152 switch (ch) 151 switch (ch)
153 { 152 {
154 case 'h': 153 case 'h':
155 heat=MAXHEAT; // Need heating 154 heat=MAXHEAT; // Need heating
156 break; 155 break;
157   156  
158 case 'c': 157 case 'c':
159 heat=0; // Need colder 158 heat=0; // Need colder
160 break; 159 break;
161   160  
162 case 'o': 161 case 'o':
163 open=MAXOPEN; // Open the dome 162 open=MAXOPEN; // Open the dome
164 break; 163 break;
165   164  
166 case 'x': 165 case 'x':
167 open=MAXOPEN; // Open the dome 166 open=MAXOPEN; // Open the dome
168 heat=MAXHEAT; // Need heating 167 heat=MAXHEAT; // Need heating
169 break; 168 break;
170   169  
171 case 'l': 170 case 'l':
172 open=0; // Lock the dome 171 open=0; // Lock the dome
173 break; 172 break;
174   173  
175 case 'i': 174 case 'i':
176 if (open==0) welcome(); // Information about version, etc... 175 if (open==0) welcome(); // Information about version, etc...
177 break; // Only when dome is closed 176 break; // Only when dome is closed
178   177  
179 case 'r': 178 case 'r':
180 repeat=TRUE; // Repeated measure mode 179 repeat=TRUE; // Repeated measure mode
181 break; 180 break;
182   181  
183 case 's': 182 case 's':
184 repeat=FALSE; // Single measure mode 183 repeat=FALSE; // Single measure mode
185 break; 184 break;
186   185  
187 case 'u': 186 case 'u':
188 // load_program(); // Update firmware 187 reset_cpu(); // Update firmware
189 } 188 }
190 } 189 }
191 // while(kbhit()) getc(); // Flush USART buffer 190 // while(kbhit()) getc(); // Flush USART buffer
192 CREN=0; CREN=1; // Reinitialise USART 191 CREN=0; CREN=1; // Reinitialise USART
193   192  
194 seq++; // Increment the number of measurement 193 seq++; // Increment the number of measurement
195   194  
196 tempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensor 195 tempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensor
197 temp=ReadTemp(SA, RAM_Tobj1); 196 temp=ReadTemp(SA, RAM_Tobj1);
198   197  
199 ta=tempa*2-27315; // °K -> °C 198 ta=tempa*2-27315; // °K -> °C
200 to=temp*2-27315; 199 to=temp*2-27315;
201   200  
202 { // printf 201 { // printf
203 char output[8]; // Output buffer 202 char output[8]; // Output buffer
204 int8 j; // String pointer 203 int8 j; // String pointer
205 int8 check=0; // Checksum is calculated between '$' and '*' 204 int8 check=0; // Checksum is calculated between '$' and '*'
206   205  
207 delay(SEND_DELAY); 206 delay(SEND_DELAY);
208 putc('$'); 207 putc('$');
209 delay(SEND_DELAY); 208 delay(SEND_DELAY);
210 sprintf(output,"M%s ",VER); 209 sprintf(output,"M%s ",VER);
211 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; } 210 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
212 sprintf(output,"%Lu ", seq); 211 sprintf(output,"%Lu ", seq);
213 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; } 212 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
214 sprintf(output,"%Ld ", ta); 213 sprintf(output,"%Ld ", ta);
215 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; } 214 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
216 sprintf(output,"%Ld ", to); 215 sprintf(output,"%Ld ", to);
217 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; } 216 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
218 sprintf(output,"%u ", heat); 217 sprintf(output,"%u ", heat);
219 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; } 218 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
220 sprintf(output,"%u ", open); 219 sprintf(output,"%u ", open);
221 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; } 220 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
222 sprintf(output,"*%X\n\r\0", check); 221 sprintf(output,"*%X\n\r\0", check);
223 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); } 222 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); }
224 delay(SEND_DELAY); 223 delay(SEND_DELAY);
225 } 224 }
226   225  
227 delay(MEASURE_DELAY); // Delay to a next measurement 226 delay(MEASURE_DELAY); // Delay to a next measurement
228 //---WDT 227 //---WDT
229 restart_wdt(); 228 restart_wdt();
230 } 229 }
231 } 230 }
232   231  
233   232  
234 /*------------------- BOOT LOADER --------------------------------------------*/ -  
235 #define LOADER_RESERVED getenv("PROGRAM_MEMORY")-getenv("FLASH_ERASE_SIZE")-800 -  
236 #define BUFFER_LEN_LOD 46 -  
237   -  
238 #ORG LOADER_RESERVED,getenv("PROGRAM_MEMORY")-201 auto=0 default -  
239   -  
240 unsigned int atoi_b16(char *s) { // Convert two hex characters to a int8 -  
241 unsigned int result = 0; -  
242 int i; -  
243   -  
244 for (i=0; i<2; i++,s++) { -  
245 if (*s >= 'A') -  
246 result = 16*result + (*s) - 'A' + 10; -  
247 else -  
248 result = 16*result + (*s) - '0'; -  
249 } -  
250   -  
251 return(result); -  
252 } -  
253   -  
254 void assert(int1 Condition, int8 ErrorCode) -  
255 { -  
256 if(Condition) -  
257 { -  
258 putchar('E'); -  
259 putchar(ErrorCode+'1'); -  
260 reset_cpu(); -  
261 } -  
262 } -  
263   -  
264 void pause() -  
265 { -  
266 int16 timeout; -  
267   -  
268 for(timeout=0; timeout<65535; timeout++); // Delay cca 300ms -  
269 } -  
270   -  
271 boot_loader() -  
272 { -  
273 int buffidx; -  
274 char buffer[BUFFER_LEN_LOD]; -  
275   -  
276 int8 checksum, line_type; -  
277 int16 l_addr,h_addr=0; -  
278 int32 addr; -  
279 #if getenv("FLASH_ERASE_SIZE")>2 -  
280 int32 next_addr; -  
281 #endif -  
282   -  
283 //!!! #error ble getenv("FLASH_ERASE_SIZE") getenv("FLASH_WRITE_SIZE") -  
284   -  
285 int8 dataidx, i, count; -  
286 union program_data { -  
287 int8 i8[16]; -  
288 int16 i16[8]; -  
289 } data; -  
290   -  
291 putchar('@'); -  
292   -  
293 //!!!nesmaze obsluhu preruseni -  
294 for(i=getenv("FLASH_ERASE_SIZE")+1;i<LOADER_RESERVED;i+=getenv("FLASH_ERASE_SIZE")) -  
295 erase_program_eeprom(i); -  
296   -  
297 putchar('@'); -  
298   -  
299 while(TRUE) -  
300 { -  
301 //---WDT -  
302 //!!! musi fungovat watchdog -  
303 while (getc()!=':') restart_wdt(); // Only process data blocks that starts with ':' -  
304   -  
305 buffidx = 0; // Read into the buffer until 'x' is received or buffer is full -  
306 do -  
307 { -  
308 buffer[buffidx] = getc(); -  
309 } while ( (buffer[buffidx++] != 'x') && (buffidx < BUFFER_LEN_LOD) ); -  
310 assert(buffidx == BUFFER_LEN_LOD,1); // Overrun buffer? -  
311   -  
312 //---WDT -  
313 restart_wdt(); -  
314   -  
315 checksum = 0; // Sum the bytes to find the check sum value 233 #include "dbloader.c" // Space reservation for the BootLoader
316 for (i=0; i<(buffidx-3); i+=2) -  
317 checksum += atoi_b16 (&buffer[i]); -  
318 checksum = 0xFF - checksum + 1; -  
319 assert(checksum != atoi_b16 (&buffer[buffidx-3]),2); // Bad CheckSum? -  
320   -  
321 count = atoi_b16 (&buffer[0]); // Get the number of bytes from the buffer -  
322   -  
323 // Get the lower 16 bits of address -  
324 l_addr = make16(atoi_b16(&buffer[2]),atoi_b16(&buffer[4])); -  
325   -  
326 line_type = atoi_b16 (&buffer[6]); -  
327   -  
328 addr = make32(h_addr,l_addr); -  
329   -  
330 addr /= 2; // PIC16 uses word addresses -  
331   -  
332 // If the line type is 1, then data is done being sent -  
333 if (line_type == 1) -  
334 { -  
335 putchar('#'); -  
336 reset_cpu(); -  
337 } -  
338   -  
339 assert (line_type == 4,4); -  
340   -  
341   -  
342 //!!! pozor, nevypalilo by to obsluhu preruseni -  
343 if (addr > 3 || addr < LOADER_RESERVED) -  
344 { -  
345   -  
346 if (line_type == 0) -  
347 { -  
348 for (i=0,next_addr=addr;i<8;i++) -  
349 data.i16[i]=read_program_eeprom(next_addr++); -  
350 // Loops through all of the data and stores it in data -  
351 // The last 2 bytes are the check sum, hence buffidx-3 -  
352 for (i=8,dataidx=0; i < buffidx-3; i += 2) -  
353 data.i8[dataidx++]=atoi_b16(&buffer[i]); -  
354   -  
355 write_program_memory(addr, data.i8, count); -  
356 } -  
357 putchar('*'); -  
358 } -  
359 } -  
360 } -  
361   -  
362 #ORG default -  
363   -  
364 #ORG getenv("PROGRAM_MEMORY")-200,getenv("PROGRAM_MEMORY")-1 -  
365 void main() -  
366 { -  
367 int8 timeout; -  
368   -  
369 disable_interrupts(GLOBAL); -  
370 setup_wdt(WDT_2304MS); // Setup Watch Dog -  
371 setup_adc_ports(NO_ANALOGS); -  
372 setup_adc(ADC_OFF); -  
373 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); -  
374 setup_timer_1(T1_DISABLED); -  
375 setup_timer_2(T2_DISABLED,0,1); -  
376 setup_comparator(NC_NC_NC_NC); -  
377 setup_vref(FALSE); -  
378 setup_oscillator(OSC_8MHZ|OSC_INTRC); -  
379   -  
380 /* -  
381 for(timeout=0; timeout<(3*20); timeout++) //cca 20s -  
382 if (kbhit()) -  
383 { -  
384 if (getc()=='u') if (getc()=='f') boot_loader(); // Update Firmware starter -  
385 pause(); -  
386 CREN=0; CREN=1; -  
387 restart_wdt(); -  
388 }; -  
389 */ -  
390 real_main(); -  
391 } -  
392   -  
393 #include "dbloader.c" -