Rev Author Line No. Line
1274 kakl 1 /**** IR Mrakomer 4 ****/
2 #define VERSION "4.0"
1277 kakl 3 #define ID "$Id: irmrak4.c 1298 2009-01-16 23:40:59Z kakl $"
1293 kakl 4  
1274 kakl 5 #include "irmrak4.h"
6  
1293 kakl 7 #bit CREN = 0x18.4 // USART registers
8 #bit SPEN = 0x18.7
9 #bit OERR = 0x18.1
10 #bit FERR = 0x18.2
11  
12 #include <string.h>
1298 kakl 13 //!!! #include "bloader.c" // Boot Loader driver
1293 kakl 14  
1289 kakl 15 #CASE // Case sensitive compiler
16  
1280 kakl 17 #define MAXHEAT 20 // Number of cycles for heating
18 #define MAXOPEN 20 // Number of cycles for dome open
1287 kakl 19 #define MEASURE_DELAY 6000 // Delay to a next measurement
1280 kakl 20 #define RESPONSE_DELAY 100 // Reaction time after receiving a command
1287 kakl 21 #define SAFETY_COUNT 90 // Time of one emergency cycle
1280 kakl 22 #define SEND_DELAY 50 // Time between two characters on RS232
1275 kakl 23  
1274 kakl 24 #define DOME PIN_B4 // Dome controll port
25 #define HEATING PIN_B3 // Heating for defrosting
26  
27  
1280 kakl 28 char VER[4]=VERSION; // Buffer for concatenate of a version string
1274 kakl 29  
1280 kakl 30 int8 heat; // Status variables
1274 kakl 31 int8 open;
32  
1284 kakl 33 inline void toggle_dome(void) // Wire exercise
1275 kakl 34 {
35 if (open>0)
1285 kakl 36 {output_toggle(DOME);} // Toggle = Open Dome
37 else
38 {output_high(DOME);} // Do not toggle = Close Dome
1275 kakl 39 }
1274 kakl 40  
1284 kakl 41 void delay(int16 cycles) // Wire exercise with delay
1274 kakl 42 {
1275 kakl 43 int16 i;
1278 kakl 44  
1275 kakl 45 for(i=0; i<cycles; i++) {toggle_dome(); delay_us(100);}
46 }
1274 kakl 47  
1284 kakl 48 void welcome(void) // Welcome message
49 {
1293 kakl 50 char REV[50]=ID; // Buffer for concatenate of a version string
51  
52 if (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0;
53 printf("\n\r# Mrakomer %s (C) 2007 KAKL\n\r",VER); // Welcome message
54 printf("#%s\n\r",&REV[4]);
55 printf("# <sequence> <ambient[1/100 C]> <sky[1/100 C]> ");
56 printf("<heating[s]> <dome[s]> <check>\n\r\n\r");
1284 kakl 57 }
1274 kakl 58  
59  
1284 kakl 60 #include "smb.c" // System Management Bus driver
1274 kakl 61  
1284 kakl 62  
1293 kakl 63 // Read sensor's RAM
1280 kakl 64 // Returns temperature in °K
1281 kakl 65 int16 ReadTemp(int8 addr, int8 select)
1274 kakl 66 {
67 unsigned char arr[6]; // Buffer for the sent bytes
68 int8 crc; // Readed CRC
69 int16 temp; // Readed temperature
70  
1275 kakl 71 addr<<=1;
72  
1284 kakl 73 SMB_STOP_bit(); //If slave send NACK stop comunication
74 SMB_START_bit(); //Start condition
1275 kakl 75 SMB_TX_byte(addr);
76 SMB_TX_byte(RAM_Access|select);
1284 kakl 77 SMB_START_bit(); //Repeated Start condition
1275 kakl 78 SMB_TX_byte(addr);
1284 kakl 79 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
1289 kakl 81 temp=make16(arr[1],arr[2]);
1284 kakl 82 crc=SMB_RX_byte(NACK); //Read PEC byte, master must send NACK
83 SMB_STOP_bit(); //Stop condition
1274 kakl 84  
85 arr[5]=addr;
86 arr[4]=RAM_Access|select;
87 arr[3]=addr;
88 arr[0]=0;
89 if (crc != PEC_calculation(arr)) temp=0; // Calculate and check CRC
90  
91 return temp;
92 }
93  
1298 kakl 94  
95 /*-------------------------------- MAIN --------------------------------------*/
96 void real_main()
1274 kakl 97 {
1280 kakl 98 unsigned int16 seq, temp, tempa;
1274 kakl 99 signed int16 ta, to;
1280 kakl 100 int8 safety_counter;
1288 kakl 101 int1 repeat;
1274 kakl 102  
1285 kakl 103 output_high(DOME); // Close Dome
1274 kakl 104 output_low(HEATING); // Heating off
105  
106 delay_ms(1000);
107 restart_wdt();
1284 kakl 108  
1285 kakl 109 seq=0; // Variables initiation
110 heat=0;
111 open=0;
1291 kakl 112 repeat=TRUE;
1289 kakl 113  
1284 kakl 114 welcome();
1285 kakl 115  
1274 kakl 116 tempa=ReadTemp(SA, RAM_Tamb); // Dummy read
117 temp=ReadTemp(SA, RAM_Tobj1);
118  
1286 kakl 119 delay_ms(1000);
1280 kakl 120 //---WDT
1274 kakl 121 restart_wdt();
122  
1284 kakl 123 while(TRUE) // Main Loop
1274 kakl 124 {
1284 kakl 125 safety_counter=SAFETY_COUNT; // Heating and Dome Count Down
1278 kakl 126 do
1274 kakl 127 {
1280 kakl 128 if (safety_counter<SAFETY_COUNT) safety_counter++;
1274 kakl 129  
1280 kakl 130 delay(RESPONSE_DELAY);
131  
132 if (safety_counter>=SAFETY_COUNT)
133 {
1288 kakl 134 if (heat>0) heat--;
1280 kakl 135 if (open>0) open--;
136  
1290 kakl 137 if (heat>0) { output_high(HEATING); } else { output_low(HEATING); }
138  
1280 kakl 139 safety_counter=0;
140 //---WDT
141 restart_wdt();
142 }
1288 kakl 143 } while (!kbhit()&&!repeat);
1285 kakl 144  
1280 kakl 145 //---WDT
146 restart_wdt();
1284 kakl 147 { // Retrieve command
1288 kakl 148 char ch='k';
1278 kakl 149  
1288 kakl 150 if(kbhit()) ch=getc();
1278 kakl 151  
1274 kakl 152 switch (ch)
153 {
154 case 'h':
1280 kakl 155 heat=MAXHEAT; // Need heating
1274 kakl 156 break;
1278 kakl 157  
1274 kakl 158 case 'c':
1280 kakl 159 heat=0; // Need colder
1274 kakl 160 break;
1278 kakl 161  
1274 kakl 162 case 'o':
163 open=MAXOPEN; // Open the dome
164 break;
1278 kakl 165  
1284 kakl 166 case 'x':
167 open=MAXOPEN; // Open the dome
168 heat=MAXHEAT; // Need heating
169 break;
170  
1274 kakl 171 case 'l':
172 open=0; // Lock the dome
173 break;
1284 kakl 174  
175 case 'i':
1287 kakl 176 if (open==0) welcome(); // Information about version, etc...
177 break; // Only when dome is closed
1288 kakl 178  
179 case 'r':
1292 kakl 180 repeat=TRUE; // Repeated measure mode
1288 kakl 181 break;
182  
183 case 's':
184 repeat=FALSE; // Single measure mode
185 break;
1293 kakl 186  
187 case 'u':
1298 kakl 188 // load_program(); // Update firmware
1274 kakl 189 }
190 }
1288 kakl 191 // while(kbhit()) getc(); // Flush USART buffer
192 CREN=0; CREN=1; // Reinitialise USART
1274 kakl 193  
1280 kakl 194 seq++; // Increment the number of measurement
1274 kakl 195  
196 tempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensor
197 temp=ReadTemp(SA, RAM_Tobj1);
198  
199 ta=tempa*2-27315; // °K -> °C
200 to=temp*2-27315;
201  
202 { // printf
1284 kakl 203 char output[8]; // Output buffer
204 int8 j; // String pointer
1293 kakl 205 int8 check=0; // Checksum is calculated between '$' and '*'
1278 kakl 206  
1282 kakl 207 delay(SEND_DELAY);
1293 kakl 208 putc('$');
209 delay(SEND_DELAY);
210 sprintf(output,"M%s ",VER);
211 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
212 sprintf(output,"%Lu ", seq);
213 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1282 kakl 214 sprintf(output,"%Ld ", ta);
1293 kakl 215 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1282 kakl 216 sprintf(output,"%Ld ", to);
1293 kakl 217 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
1283 kakl 218 sprintf(output,"%u ", heat);
1293 kakl 219 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
220 sprintf(output,"%u ", open);
221 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }
222 sprintf(output,"*%X\n\r\0", check);
1282 kakl 223 j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); }
1293 kakl 224 delay(SEND_DELAY);
1274 kakl 225 }
1280 kakl 226  
227 delay(MEASURE_DELAY); // Delay to a next measurement
228 //---WDT
229 restart_wdt();
1274 kakl 230 }
231 }
1298 kakl 232  
233  
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
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"